碰撞体
碰撞体定义物体响应碰撞的实际物理性状,通常在渲染层是不可见的。通过碰撞体组件的设定,物理系统可以判定两个物体是否相交,从而产生碰撞效果。
碰撞体组件概览
我们封装了以下几个常见的碰撞体形状类型,方便用户使用:
- 盒型碰撞体
ts
import { BoxColliderShape } from '@orillusion/physics'
// some codes here to create object...
let collider = object.addComponent(Collider);
collider.shape = new BoxColliderShape();
// set shape parameters...
collider.shape.size = new Vector3(2, 2, 2);
参数 | 类型 | 描述 |
---|---|---|
size | Vecter3 | 盒型碰撞体的大小。默认以物体中心为长方体中心,通过新建Vecter3实例分别指定长方体沿x、y、z坐标轴的长度大小 |
- 球形碰撞体
ts
import { SphereColliderShape } from '@orillusion/physics'
// some codes here to create object...
let collider = object.addComponent(Collider);
collider.shape = new SphereColliderShape();
// set shape parameters...
collider.radius = 5;
参数 | 类型 | 描述 |
---|---|---|
radius | number | 球形碰撞体的半径。默认以物体中心为球体中心 |
- 胶囊碰撞体
ts
import { CapsuleColliderShape } from '@orillusion/physics'
// some codes here to create object...
let collider = object.addComponent(Collider);
collider.shape = new CapsuleColliderShape();
// set shape parameters...
collider.radius = 2.5;
collider.height = 10;
参数 | 类型 | 描述 |
---|---|---|
radius | number | 胶囊碰撞体上下半球体的半径 |
height | number | 胶囊碰撞体的高度,默认以物体中心为胶囊体中心 |
碰撞体组件应用示例
在为对象添加了刚体组件后,我们再为它添加一个碰撞体,并指定碰撞体的形状类型,便可以让该对象响应碰撞了:
ts
import { Vecter3D, Object3D } from '@orillusion/core'
import { BoxColliderShape, Rigidbody } from '@orillusion/physics'
let object = new Object3D();
object.addComponent(Rigidbody);
let collider = obj.addComponent(Collider);
collider.shape = new BoxColliderShape();
collider.shape.size = new Vector3(2, 2, 2);
利用碰撞组件,我们可以模拟出逼真的物理效果,下面我们通过展示一个更复杂的示例,进一步了解物理系统可以实现的效果。
ts
import { BoxColliderShape, BoxGeometry, Camera3D, Collider, Color, ComponentBase, DirectLight, Engine3D, ForwardRenderJob, LitMaterial, HoverCameraController, MeshRenderer, Object3D, PlaneGeometry, Scene3D, Vector2, Vector3 } from "@orillusion/core";
import { Physics, Rigidbody } from "@orillusion/physics";
export class Sample_colliders {
constructor() {}
addPlane (scene: Scene3D, size: Vector2, pos: Vector3, rot: Vector3) {
// 新建对象
const obj = new Object3D();
// 为对象添 MeshRenderer
let mr = obj.addComponent(MeshRenderer);
// 设置几何体
//mr.geometry = new CubeGeometry(10, 10, 10)
mr.geometry = new PlaneGeometry(size.x, size.y);
// 设置材质
mr.material = new LitMaterial();
mr.material.baseColor = new Color(0.04, 0.42, 0.45, 1);
// 设置缩放
obj.localPosition = pos;
obj.localRotation = rot;
// 添加刚体碰撞体
let rigidbody = obj.addComponent(Rigidbody);
rigidbody.mass = 0;
let collider = obj.addComponent(Collider);
collider.shape = new BoxColliderShape();
collider.shape.size = new Vector3(size.x, 0.1, size.y);
scene.addChild(obj);
return obj;
}
loop() {
if (Physics.isInited) {
Physics.update();
}
}
async run() {
await Physics.init();
// 初始化引擎环境;
await Engine3D.init({
renderLoop: () => this.loop()
});
let scene3D = new Scene3D();
// 新建摄像机实例
let cameraObj = new Object3D();
let mainCamera = cameraObj.addComponent(Camera3D);
// 调整摄像机视角
mainCamera.lookAt(new Vector3(0, 0, 10), new Vector3(0, 0, 0));
mainCamera.perspective(60, window.innerWidth / window.innerHeight, 1, 5000.0);
let controller = mainCamera.object3D.addComponent(HoverCameraController);
controller.setCamera(45, -15, 150, new Vector3(0, 30, 0));
// 添加相机节点
scene3D.addChild(cameraObj);
// 新建光照
let light: Object3D = new Object3D();
// 添加直接光组件
let component = light.addComponent(DirectLight);
// 调整光照参数
light.rotationX = 45;
light.rotationY = 30;
component.lightColor = new Color(1.0, 1.0, 1.0, 1.0);
component.intensity = 1;
// 添加光照对象
scene3D.addChild(light);
this.addPlane(scene3D, new Vector2(100, 100), new Vector3(0, 0, 0), new Vector3(0, 0, 0))
scene3D.addComponent(BoxGenerator);
// 新建前向渲染业务
let renderJob = new ForwardRenderJob(scene3D);
// 开始渲染
Engine3D.startRender(renderJob);
}
}
class BoxGenerator extends ComponentBase {
// 记录添加桌子的间隔时间
private _lastTime: number = performance.now()
// 脚本更新回调
public update(): void {
// 计算新的间隔时间
let now: number = performance.now()
// 每间隔300ms,添加一个桌子
if (now - this._lastTime > 300) {
// 添加桌子
this._addBox();
// 删除最早的物体,保持场景数量
if(this.object3D.entityChildren.length > 500)
this.object3D.removeChildByIndex(4)
// 重置间隔时间
this._lastTime = now;
}
}
// 添加桌子的函数
private _addBox(): void {
// 新建对象
const obj = new Object3D();
// 为对象添 MeshRenderer
let mr = obj.addComponent(MeshRenderer);
// 设置几何体
mr.geometry = new BoxGeometry(5, 5, 5);
// 设置材质
mr.material = new LitMaterial();
mr.material.baseColor = new Color(Math.random(), Math.random(), Math.random(), 1.0);
// 设置位置旋转
obj.localPosition = new Vector3(Math.random() * 70 - 35, 50, Math.random() * 70 - 35)
obj.localRotation = new Vector3(Math.random() * 360, Math.random() * 360, Math.random() * 360)
// 添加刚体碰撞体
let rigidbody = obj.addComponent(Rigidbody);
rigidbody.mass = 10;
let collider = obj.addComponent(Collider);
collider.shape = new BoxColliderShape();
collider.shape.size = new Vector3(5, 5, 5);
this.object3D.addChild(obj);
}
}
new Sample_colliders().run();