Javascript Physijs无重力的网格间简单碰撞

Javascript Physijs无重力的网格间简单碰撞,javascript,physijs,Javascript,Physijs,我正在使用Physijs确定网格之间的静态碰撞。因为我需要知道哪些曲面相交 我黑了一个简单的演示,似乎工作 目前,我必须将场景配置为使用重力,这会阻止我在网格开始下落或浮动时将网格定位在任何y位置 是否有简单的方法可以从模拟中移除重力,并仅使用网格碰撞检测 --更新--- 我必须明确地将每个网格的质量设置为0,而不是空白。质量=0时,重力没有影响。太好了 但是,网格不会报告碰撞。 你知道我哪里出错了吗 谢谢 -lp不能单独使用Physijs进行碰撞检测。它完全配备了基于ammo.js库的实时物理

我正在使用Physijs确定网格之间的静态碰撞。因为我需要知道哪些曲面相交

我黑了一个简单的演示,似乎工作

目前,我必须将场景配置为使用重力,这会阻止我在网格开始下落或浮动时将网格定位在任何y位置

是否有简单的方法可以从模拟中移除重力,并仅使用网格碰撞检测

--更新--- 我必须明确地将每个网格的质量设置为0,而不是空白。质量=0时,重力没有影响。太好了

但是,网格不会报告碰撞。 你知道我哪里出错了吗

谢谢


-lp

不能单独使用Physijs进行碰撞检测。它完全配备了基于ammo.js库的实时物理模拟。当您将网格的质量设置为
0
时,会使其处于静态状态。然后,它们对外力(例如碰撞响应(即检测到碰撞后施加在网格上的速度变化)或重力)没有响应。另外,两个相互重叠的静态网格不会触发碰撞事件

解决方案A:直接使用ammo.js 该库从移植而来,提供了生成物理模拟所需的工具,或者只检测定义形状之间的碰撞(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)'
var-bt\u-collision\u配置;
var-bt_调度员;
宽相位无功功率;
世界银行;
var场景大小=500;
var max_objects=10;//根据需要对其进行调整
bt_collision_configuration=新弹药。btDefaultCollisionConfiguration();
bt_dispatcher=新弹药。btCollisionDispatcher(bt_碰撞_配置);
var wmin=新弹药.btVector3(-scene_size,-scene_size,-scene_size);
var wmax=新弹药.btVector3(场景大小、场景大小、场景大小);
//这是一种宽相位,Ammo.js还有其他可能更快的
bt_broadphase=新弹药。BT323(
wmin,wmax,max_对象,0,true/*禁用光线投射加速器*/);
bt_collision_world=新弹药.btCollisionWorld(bt_调度程序、bt_宽相位、bt_collision_配置);
//创建两个碰撞对象
var sphere_A=新弹药.btCollisionObject();
var sphere_B=新弹药。btCollisionObject();
//将每个移动到特定位置
sphere_A.getWorldTransform().setOrigin(新Ammo.btVector3(2,1.5,0));
sphere_B.getWorldTransform().setOrigin(新Ammo.btVector3(2,0,0));
//创建半径为1的球体形状
var sphere_shape=新弹药。b SphereShape(1);
//设置每个碰撞对象的形状
sphere_A.设置碰撞形状(sphere_形状);
sphere_B.setCollisionShape(sphere_形状);
//将碰撞对象添加到碰撞世界
bt_collision_world.addCollisionObject(球体A);
bt_collision_world.addCollisionObject(球体B);
//执行碰撞检测
bt_collision_world.performDiscreteCollisionDetection();
var numManifolds=bt_collision_world.getDispatcher().getNumManifolds();
//对于每个接触歧管
对于(var i=0;i
我转换成它的JS等价物。可能缺少一些语法,因此可以检查是否存在任何不起作用的语法

解决方案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
    }
}
//常规长方体网格数据
var boxGeometry=新的三立方测量法(100,100,20,1,1,1);
var-boxMaterial=new THREE.MeshBasicMaterial({颜色:0x8888ff,线框:true});
//创建检测碰撞的框
var dcube=新的三网格(boxGeometry,boxMaterial);
//创建用于检查碰撞的框
var ocube=新的三网格(boxGeometry,boxMaterial);
//创建光线投射器
var rcaster=new THREE.Raycaster(new THREE.Vector3(0,0,0),new THREE.Vector3(0,1,0));
//通过每个顶点或端点投射光线
对于(var vi=0,l=dcube.geometry.vertices.length;vi
查看这些链接了解更多信息(可能还有它们的源代码):


多么好的回答!我喜欢弹药溶液。我将在凹面网格上试用,看看它的性能如何。弹药解决方案对凹面网格非常有效…谢谢again@XavCo7,请看一下,我已经解释了要求。我必须在墙的范围内把窗户拖过墙。我已经在three.js中创建了整个应用程序。Physijs能完成任务吗?