物理:没有重力的网格之间的简单碰撞
Physijs simple collision between meshes without gravity
我正在使用Physijs来确定我的网格之间的静态碰撞。因为我需要知道哪些面相交。
我黑了一个简单的演示,似乎工作。
目前我必须配置我的场景使用重力,这可以防止我在任何y位置放置我的网格,因为它们开始下降或浮动。
是否有简单的方法来消除重力从模拟,只是使用网格碰撞检测?
——更新我必须明确地将每个网格的质量设置为0,而不是空白。质量=0时,重力没有影响。太棒了!
然而网格没有报告碰撞。你知道我哪里做错了吗?
感谢lp
你不能单独使用Physijs进行碰撞检测。它只是完全配备了实时物理模拟,基于amo .js库。当你将网格的质量设置为0
时,它使它们成为静态的。然后,它们对外力没有反应,例如碰撞响应(即在检测到碰撞后施加在网格上的速度变化)或重力。另外,两个相互重叠的静态网格不会触发碰撞事件。
方案A:直接使用amo .js
从Bullet Physics移植过来,这个库提供了生成物理模拟的必要工具,或者只是检测定义形状之间的碰撞(Physijs不想让我们看到)。下面是检测两个刚性球体之间碰撞的代码片段:
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)'
我把这段c++代码转换成JS代码。可能有一些语法缺失,所以你可以检查amo .js API绑定的更改是否有任何不工作的地方。
方案B:使用THREE的光线投射器
光线投射器不太精确,但可以在你的形状中添加额外的顶点计数来更精确。下面是一些检测两个框之间碰撞的代码:
// 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
}
}
查看这些链接以获取更多信息(可能还有它们的源代码):
- Three.js-Collision-Detection
- 使用Three.js进行基本的碰撞检测,光线投射
- THREE's ray caster docs
相关文章:
- 无法在 JS 树和 JQ 网格行之间实现拖放
- 在帖子的网格循环之间插入Javascript(Adsense)
- 标题中大写字母之间的角度UI网格空间
- 可在角网格中的小部件之间拖动
- ExtJS:网格和表单之间的双向绑定
- 如何在 2 个角度 UI 网格之间同步列排序
- 在网格视图中的复选框和单击按钮时的验证之间切换
- 在Twitter引导程序中创建网格跨度之间的空间
- ExtJS:在网格和图表之间共享存储
- 在网格之间切换问题
- 移除网格单元格之间的空间
- 暂停在执行拖放时显示窗口的拖放事件的处理;在网格之间下降
- 物理:没有重力的网格之间的简单碰撞
- HTML5可访问性:如何指示网格和列表布局之间的切换
- JQGrid -在网格之间复制选定的行
- 如何在ExtJS网格和Jquery图表之间建立关联
- 有角度的ui.grid.在两个网格之间移动行
- 自动折叠垂直间距的帖子之间的网格主题
- 如何在一个网格中使用两个存储之间的切换
- ExtJS使用Tab键在两个网格之间导航