Вы не можете использовать Physijs для обнаружения столкновений в одиночку. Он просто полностью оснащен физикой реального времени, основанной на библиотеке ammo.js. Когда вы устанавливаете массу ячеек на 0
, это делает их статическими. Затем они не реагировали на внешние силы, такие как реакции столкновения (т. Е. Изменение скорости, приложенной к сетке после обнаружения столкновения) или гравитации. Кроме того, две статические сетки, которые перекрываются друг с другом , не пожара события столкновения.
Решение: Используйте ammo.js непосредственно
адаптированное из Bullet Physics, библиотека предоставляет необходимые инструменты для создания физики моделирования, или просто обнаружить столкновения между определенными формами (которые Physijs не хотят нас видеть). Вот фрагмент кода для обнаружения столкновения между 2 жесткими сферами:
var bt_collision_configuration;
var bt_dispatcher;
var bt_broadphase;
var bt_collision_world;
var scene_size = 500;
var max_objects = 10; // Tweak this as needed
bt_collision_configuration = new Ammo.btDefaultCollisionConfiguration();
bt_dispatcher = new Ammo.btCollisionDispatcher(bt_collision_configuration);
var wmin = new Ammo.btVector3(-scene_size, -scene_size, -scene_size);
var wmax = new Ammo.btVector3(scene_size, scene_size, scene_size);
// This is one type of broadphase, Ammo.js has others that might be faster
bt_broadphase = new Ammo.bt32BitAxisSweep3(
wmin, wmax, max_objects, 0, true /* disable raycast accelerator */);
bt_collision_world = new Ammo.btCollisionWorld(bt_dispatcher, bt_broadphase, bt_collision_configuration);
// Create two collision objects
var sphere_A = new Ammo.btCollisionObject();
var sphere_B = new Ammo.btCollisionObject();
// Move each to a specific location
sphere_A.getWorldTransform().setOrigin(new Ammo.btVector3(2, 1.5, 0));
sphere_B.getWorldTransform().setOrigin(new Ammo.btVector3(2, 0, 0));
// Create the sphere shape with a radius of 1
var sphere_shape = new Ammo.btSphereShape(1);
// Set the shape of each collision object
sphere_A.setCollisionShape(sphere_shape);
sphere_B.setCollisionShape(sphere_shape);
// Add the collision objects to our collision world
bt_collision_world.addCollisionObject(sphere_A);
bt_collision_world.addCollisionObject(sphere_B);
// Perform collision detection
bt_collision_world.performDiscreteCollisionDetection();
var numManifolds = bt_collision_world.getDispatcher().getNumManifolds();
// For each contact manifold
for(var i = 0; i < numManifolds; i++){
var contactManifold = bt_collision_world.getDispatcher().getManifoldByIndexInternal(i);
var obA = contactManifold.getBody0();
var obB = contactManifold.getBody1();
contactManifold.refreshContactPoints(obA.getWorldTransform(), obB.getWorldTransform());
var numContacts = contactManifold.getNumContacts();
// For each contact point in that manifold
for(var j = 0; j < numContacts; j++){
// Get the contact information
var pt = contactManifold.getContactPoint(j);
var ptA = pt.getPositionWorldOnA();
var ptB = pt.getPositionWorldOnB();
var ptdist = pt.getDistance();
// Do whatever else you need with the information...
}
}
// Oh yeah! Ammo.js wants us to deallocate
// the objects with 'Ammo.destroy(obj)'
я трансформировал this C++ code в его JS эквивалент. Возможно, отсутствовал синтаксис, поэтому вы можете проверить Ammo.js API binding changes на все, что не работает.
Раствор В: Используйте три луча в МНЛЗ
Луч МНЛЗ является менее точным, но может быть более точным, с добавлением дополнительного количества вершин в ваших формах. Вот код для обнаружения столкновения между 2 коробки:
// General box mesh data
var boxGeometry = new THREE.CubeGeometry(100, 100, 20, 1, 1, 1);
var boxMaterial = new THREE.MeshBasicMaterial({color: 0x8888ff, wireframe: true});
// Create box that detects collision
var dcube = new THREE.Mesh(boxGeometry, boxMaterial);
// Create box to check collision with
var ocube = new THREE.Mesh(boxGeometry, boxMaterial);
// Create ray caster
var rcaster = new THREE.Raycaster(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 1, 0));
// Cast a ray through every vertex or extremity
for(var vi = 0, l = dcube.geometry.vertices.length; vi < l; vi++){
var glovert = dcube.geometry.vertices[vi].clone().applyMatrix4(dcube.matrix);
var dirv = glovert.sub(dcube.position);
// Setup ray caster
rcaster.set(dcubeOrigin, dirv.clone().normalize());
// Get collision result
var hitResult = rcaster.intersectObject(ocube);
// Check if collision is within range of other cube
if(hitResult.length && hitResult[0].distance < dirv.length()){
// There was a hit detected between dcube and ocube
}
}
Проверьте эти ссылки для получения дополнительной информации (и, возможно, их исходный код):
какой отличный ответ! мне нравится с решением боеприпасов. я попробую его на вогнутой сетке и посмотрю, как это работает. – lpic
решение для боеприпасов работает очень хорошо для вогнутых сеток ... еще раз спасибо – lpic
@ XavCo7, пожалуйста, взгляните на https: // stackoverflow.com/questions/46423290/drag-a-mesh-over-another-and-limit-it-inside-the-sides-three-js, я объяснил это требование. Мне нужно перетащить окно через стену в пределах стены. Я создал все приложение в three.js. Будет ли Physijs работать для этой задачи? – Deeps