唯杰地图 logo唯杰地图
VJMAP
EN

物理引擎

vjmap3d/references/plugin/physics.md 5.8 KB182 行
原文

使用

通过 vjmap3d.loadPhysicsEngine 加载物理引擎插件库

或 通过 vjmap3d.Plugins.loadLibrary("physics") 加载(physics 是 lib 类库,用 loadLibrary 而非 loadPlugin)

示例

let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {
        gridHelper: { visible: true } // 是否显示坐标网格
    },
    camera: {  // 相机设置
        viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
    }
})
await app.enablePhysicsEngine();
app.addPhysicsGround();
const boxGeo1 = new THREE.BoxGeometry(1, 1, 1);
const boxMat1 = new THREE.MeshStandardMaterial({
    color: 0xffffff * Math.random()
});
const meshBox = new THREE.Mesh(boxGeo1, boxMat1);
meshBox.position.set(5, 5, 3) 
let entBox = new vjmap3d.MeshEntity(meshBox);
entBox.addTo(app);
entBox.add(vjmap3d.PhysicsModule, {
    type: vjmap3d.ShapeType2.BOX
})
//
const sphereGeo = new THREE.SphereGeometry(1);
const sphereMat = new THREE.MeshStandardMaterial({
    color: 0xff0000
});
const mesh = new THREE.Mesh(sphereGeo, sphereMat);
mesh.position.set(-5, 1, 3) 
let ent= new vjmap3d.MeshEntity(mesh);
ent.addTo(app);
let mod = ent.add(vjmap3d.PhysicsModule, {
    type: vjmap3d.ShapeType2.SPHERE
})
let sphereBody = mod.getBody();
let CANNON = app.physicsEngine;
const radius = 1
const impulse = new CANNON.Vec3(8, 0, 0)
const topPoint = new CANNON.Vec3(0, radius, 0)
sphereBody.applyImpulse(impulse, topPoint)
sphereBody.linearDamping = 0.3
sphereBody.angularDamping = 0.3
//
const boxGeo = new THREE.BoxGeometry(1, 1, 1);
const boxMat = new THREE.MeshStandardMaterial({
    color: 0x00ffff
});
const boxMesh = new THREE.Mesh(boxGeo, boxMat);
boxMesh.position.set(0, 1, 3) 
let boxEnt = new vjmap3d.MeshEntity(boxMesh);
boxEnt.addTo(app);
let boxMod = boxEnt.add(vjmap3d.PhysicsModule, {
    type: vjmap3d.ShapeType2.BOX,
    body: {
        isTrigger: true,
        mass: 0
    }
})
let triggerBody = boxMod.getBody();
// It is possible to run code on the exit/enter of the trigger.
triggerBody.addEventListener('collide', (event) => {
    if (event.body === sphereBody) {
        let object = sphereBody.entity?.node;
        // @ts-ignore
        object.material.color = new THREE.Color(0x00ff00)
        console.log('The sphere entered the trigger!', event)
    }
})
app.physicsWorld.addEventListener('endContact', (event) => {
    if (
    (event.bodyA === sphereBody && event.bodyB === triggerBody) ||
    (event.bodyB === sphereBody && event.bodyA === triggerBody)
    ) {
        let object = sphereBody.entity?.node;
        // @ts-ignore
        object.material.color = new THREE.Color(0xff0000)
        console.log('The sphere exited the trigger!', event)
    }
})
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {
        gridHelper: { visible: true } // 是否显示坐标网格
    },
    camera: {  // 相机设置
        viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
    }
})
await app.enablePhysicsEngine();
app.addPhysicsGround();
const boxGeo1 = new THREE.BoxGeometry(1, 1, 1);
const boxMat1 = new THREE.MeshStandardMaterial({
    color: 0xffffff * Math.random()
});
const meshBox = new THREE.Mesh(boxGeo1, boxMat1);
meshBox.position.set(5, 5, 3) 
let entBox = new vjmap3d.MeshEntity(meshBox);
entBox.addTo(app);
entBox.add(vjmap3d.PhysicsModule, {
    type: vjmap3d.ShapeType2.BOX
})
//
const sphereGeo = new THREE.SphereGeometry(1);
const sphereMat = new THREE.MeshStandardMaterial({
    color: 0xff0000
});
const mesh = new THREE.Mesh(sphereGeo, sphereMat);
mesh.position.set(-5, 1, 3) 
let ent= new vjmap3d.MeshEntity(mesh);
ent.addTo(app);
let mod = ent.add(vjmap3d.PhysicsModule, {
    type: vjmap3d.ShapeType2.SPHERE
})
let sphereBody = mod.getBody();
let CANNON = app.physicsEngine;
const radius = 1
const impulse = new CANNON.Vec3(8, 0, 0)
const topPoint = new CANNON.Vec3(0, radius, 0)
sphereBody.applyImpulse(impulse, topPoint)
sphereBody.linearDamping = 0.3
sphereBody.angularDamping = 0.3
//
const boxGeo = new THREE.BoxGeometry(1, 1, 1);
const boxMat = new THREE.MeshStandardMaterial({
    color: 0x00ffff
});
const boxMesh = new THREE.Mesh(boxGeo, boxMat);
boxMesh.position.set(0, 1, 3) 
let boxEnt = new vjmap3d.MeshEntity(boxMesh);
boxEnt.addTo(app);
let boxMod = boxEnt.add(vjmap3d.PhysicsModule, {
    type: vjmap3d.ShapeType2.BOX,
    body: {
        isTrigger: true,
        mass: 0
    }
})
let triggerBody = boxMod.getBody();
// It is possible to run code on the exit/enter of the trigger.
triggerBody.addEventListener('collide', (event) => {
    if (event.body === sphereBody) {
        let object = sphereBody.entity?.node;
        // @ts-ignore
        object.material.color = new THREE.Color(0x00ff00)
        console.log('The sphere entered the trigger!', event)
    }
})
app.physicsWorld.addEventListener('endContact', (event) => {
    if (
    (event.bodyA === sphereBody && event.bodyB === triggerBody) ||
    (event.bodyB === sphereBody && event.bodyA === triggerBody)
    ) {
        let object = sphereBody.entity?.node;
        // @ts-ignore
        object.material.color = new THREE.Color(0xff0000)
        console.log('The sphere exited the trigger!', event)
    }
})

文档

物理引擎基于开源的 cannon-es, 具体文档可参考 https://pmndrs.github.io/cannon-es/docs/index.html