API
World
gravity
重力设置
World.gravity: Vec3;
const world = new CANNON.World();world.gravity.set(0, -9.8, 0);addBody
添加刚体
World.addBody(body: Body): void
world.addBody(body);addConstraint
添加约束,例如 PointToPointConstraint(点对点约束)
World.addConstraint(c: Constraint): voidstep
按照设置时间,计算物理世界
World.step(dt: number, timeSinceLastCalled?: number, maxSubSteps?: number): void
function animate() { world.step(1 / 60); requestAnimationFrame(animate);}Body
mass
质量
World.mass: number
world.mass = 10;position
位置
World.position: Vec3;
World.position = new CANNON.Vec3(0, 2, -5), // 刚体位置type
刚体类型,有如下类型
- DYNAMIC = 1: 受到物理力学影响,可以改变运动,可参与交互
- KINEMATIC = 4:不受物理学影响,可以改变运动,可参与交互
- STATIC = 2: 不受物理学影响,不可以改变运动,可参与交互
当创建 Body 时,如果未指定 type,则如果刚体的质量大于 0,则默认为 DYNAMIC,否则为 STATIC
World.type: BodyType;shape
刚体形状
World.shape: Shape;velocity
速度
Shape
Box
盒子(长方体),参数中的长宽高均为实际的一半
new CANNON.Box(halfExtents: Vec3);Plane
平面,可认为平面无限长
new CANNON.Plane();Cylinder
圆柱
new Cylinder(radiusTop?: number, radiusBottom?: number, height?: number, numSegments?: number): CylinderRaycastVehicle
射线投射车辆,可组成汽车
// 车身刚体const chassisBody = new CANNON.Body({ mass: 10, shape: new CANNON.Box(new CANNON.Vec3(1, 0.5, 2)), position: new CANNON.Vec3(0, 2, -5),});
// 整车const vehicle = new CANNON.RaycastVehicle({ chassisBody: chassisBody, // 底盘刚体 // 0表示X,1表示Y,2表示Z // indexRightAxis: 2, // indexUpAxis: 1, // indexForwardAxis: 0,});
// 轮子参数const wheelOptions = { radius: 0.8, // 车轮半径 directionLocal: new CANNON.Vec3(0, -1, 0), // 车轮向下方向 axleLocal: new CANNON.Vec3(0, 0, 1), // 车轴方向(轴心) chassisConnectionPointLocal: new CANNON.Vec3(1, 1, 0),
suspensionStiffness: 30, suspensionRestLength: 1, frictionSlip: 5, dampingRelaxation: 2.3, dampingCompression: 4.4, maxSuspensionForce: 100000, rollInfluence: 0.01, maxSuspensionTravel: 0.3, customSlidingRotationalSpeed: -30, useCustomSlidingRotationalSpeed: true,};
// 添加四个车轮vehicle.addWheel({ ...wheelOptions, chassisConnectionPointLocal: new CANNON.Vec3(-1, 1, 1.5), // 左前轮});vehicle.addWheel({ ...wheelOptions, chassisConnectionPointLocal: new CANNON.Vec3(1, 1, 1.5), // 右前轮});vehicle.addWheel({ ...wheelOptions, chassisConnectionPointLocal: new CANNON.Vec3(-1, 1, -1.5), // 左后轮});vehicle.addWheel({ ...wheelOptions, chassisConnectionPointLocal: new CANNON.Vec3(1, 1, -1.5), // 右后轮});
for (let i = 0; i < 4; i++) { // 车轮形状 const cylinderShape = new CANNON.Cylinder( wheelOptions.radius, wheelOptions.radius, wheelOptions.radius / 2, 20 );
// 车轮刚体 const wheelBody = new CANNON.Body({ type: CANNON.Body.KINEMATIC, // 防止车身和车轮相互计算 mass: 5, });
// 旋转车轮和车身适配 const q = new CANNON.Quaternion(); q.setFromAxisAngle(new CANNON.Vec3(0, 0, 1), -Math.PI / 2); const q1 = new CANNON.Quaternion(); q1.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), -Math.PI / 2);
const total = q1.clone(); total.mult(q, total); total.normalize();
wheelBody.addShape(cylinderShape, new CANNON.Vec3(), total);}vehicle.addToWorld(world);CANNON 同步 THREE
function animate() { requestAnimationFrame(animate);
// 更新物理世界 world.step(1 / 60);
// 计算车辆状态 vehicle.updateVehicle(1 / 60);
// 同步刚体的位置和旋转,chassisMesh 为 THREE 的 Mesh chassisMesh.position.copy(chassisBody.position); chassisMesh.quaternion.copy(chassisBody.quaternion);
// 渲染场景 renderer.render(scene, camera);}