前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ammo.js-bullet物理引擎碰撞检测

ammo.js-bullet物理引擎碰撞检测

作者头像
周星星9527
发布2020-08-18 14:34:00
3.8K0
发布2020-08-18 14:34:00
举报

之前用ammojs写了一点点动画:微信小程序体验3D物理引擎-ammo.js,把碰撞检测的代码写一下,Mark下,记个笔记:

碰撞检测

代码语言:javascript
复制
function updatePhysics(deltaTime) {
    physicsWorld.stepSimulation(deltaTime);
    //physicsWorld.performDiscreteCollisionDetection();
    var numManifolds=dispatcher.getNumManifolds();
    for(var i=0; i<numManifolds; i++){
        var contactManifold=dispatcher.getManifoldByIndexInternal(i);
        var objA=contactManifold.getBody0();
        var objB=contactManifold.getBody1();
        var numContacts = contactManifold.getNumContacts();
        //console.log(numContacts,objA,objB);
        for(var j=0; j<numContacts; j++)
        {
            var pt = contactManifold.getContactPoint(j);
            if(pt.getDistance()<=0.0){
                var posA = pt.getPositionWorldOnA();
                var posB = pt.getPositionWorldOnB();
                console.log("A:",i, posA.x(), posA.y(), posA.z()); // 碰撞点
                console.log("B:",i, posB.x(), posB.y(), posB.z());
            }
        }
    }

    // 更新物体位置
    for (var i = 0, iL = rigidBodies.length; i <iL; i++ ){
        var objThree = rigidBodies[i];
        var objPhys = objThree.userData.physicsBody;
        var ms = objPhys.getMotionState();
        if (ms) {
            ms.getWorldTransform(transformAux1);
            var p = transformAux1.getOrigin();
            var q = transformAux1.getRotation();
            objThree.position.set(p.x(), p.y(), p.z());
            objThree.quaternion.set(q.x(), q.y(), q.z(), q.w());
        }
    }
}

创建TriangleMesh的Shape:

代码语言:javascript
复制
function createTriangleShapeByGeometry(geometry) {
    var mesh = new Ammo.btTriangleMesh(true, true);
    var vertices = geometry.vertices;
    for (var i = 0; i < geometry.faces.length; i++) {
        var face = geometry.faces[i];
        if (face instanceof THREE.Face3) {
            mesh.addTriangle(
                new Ammo.btVector3(vertices[face.a].x, vertices[face.a].y, vertices[face.a].z),
                new Ammo.btVector3(vertices[face.b].x, vertices[face.b].y, vertices[face.b].z),
                new Ammo.btVector3(vertices[face.c].x, vertices[face.c].y, vertices[face.c].z),
                false
            );
        } else if (face instanceof THREE.Face4) {
            mesh.addTriangle(
                new Ammo.btVector3(vertices[face.a].x, vertices[face.a].y, vertices[face.a].z),
                new Ammo.btVector3(vertices[face.b].x, vertices[face.b].y, vertices[face.b].z),
                new Ammo.btVector3(vertices[face.d].x, vertices[face.d].y, vertices[face.d].z),
                false
            );
            mesh.addTriangle(
                new Ammo.btVector3(vertices[face.b].x, vertices[face.b].y, vertices[face.b].z),
                new Ammo.btVector3(vertices[face.c].x, vertices[face.c].y, vertices[face.c].z),
                new Ammo.btVector3(vertices[face.d].x, vertices[face.d].y, vertices[face.d].z),
                false
            );
        }
    }
    var shape = new Ammo.btBvhTriangleMeshShape(mesh, true, true);
    return shape;
}    

例如创建一条管道的Shape:

代码语言:javascript
复制
var ballMass = 35;
var ballRadius = 0.4;

var path = new CustomSinCurve( 1.0 );
var geometry = new THREE.TubeGeometry( path, 20, 0.2, 8, false );
//var geometry=new THREE.SphereGeometry( ballRadius, 14, 10 );
var ball = new THREE.Mesh( geometry, ballMaterial );
ball.castShadow = true;
ball.receiveShadow = true;
var ballShape = createTriangleShapeByGeometry(geometry);//new Ammo.btSphereShape( ballRadius );
ballShape.setMargin( margin );
var pos = new THREE.Vector3();
var quat = new THREE.Quaternion();
pos.copy( raycaster.ray.direction );
pos.add( raycaster.ray.origin );
quat.set( 0, 0, 0, 1 );
var ballBody = createRigidBody( ball, ballShape, ballMass, pos, quat );

pos.copy( raycaster.ray.direction );
pos.multiplyScalar( 24 );
ballBody.setLinearVelocity( new Ammo.btVector3( pos.x, pos.y, pos.z ) );

管道Factory代码:

代码语言:javascript
复制
function CustomSinCurve( scale ) {
    THREE.Curve.call( this );
    this.scale = ( scale === undefined ) ? 1 : scale;
}

CustomSinCurve.prototype = Object.create( THREE.Curve.prototype );
CustomSinCurve.prototype.constructor = CustomSinCurve;

CustomSinCurve.prototype.getPoint = function ( t ) {
    var tx = t * 3 - 1.5;
    var ty = Math.sin( 2 * Math.PI * t );
    var tz = 0;

    return new THREE.Vector3( tx, ty, tz ).multiplyScalar( this.scale );
};

Demo:

点击体验3D物理引擎bullet的javascript版本。源码参考了:https://github.com/THISISAGOODNAME/learn-ammojs,感谢原作者!

(正文完!)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 传输过程数值模拟学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档