mirror of
https://github.com/galacean/engine.git
synced 2026-06-07 16:27:35 +08:00
147 lines
4.3 KiB
TypeScript
147 lines
4.3 KiB
TypeScript
/**
|
|
* @title Physx Collision Group
|
|
* @category Physics
|
|
*/
|
|
import {
|
|
WebGLEngine,
|
|
SphereColliderShape,
|
|
DynamicCollider,
|
|
BoxColliderShape,
|
|
Vector3,
|
|
MeshRenderer,
|
|
PointLight,
|
|
PrimitiveMesh,
|
|
Camera,
|
|
Script,
|
|
StaticCollider,
|
|
ColliderShape,
|
|
PBRMaterial,
|
|
Entity,
|
|
Layer
|
|
} from "@galacean/engine";
|
|
|
|
import { PhysXPhysics } from "@galacean/engine-physics-physx";
|
|
import { initScreenshot, updateForE2E } from "./.mockForE2E";
|
|
|
|
class CheckScript extends Script {
|
|
onTriggerEnter(other: ColliderShape) {
|
|
console.log("onTriggerEnter", other);
|
|
// Change color to green when collision occurs
|
|
(this.entity.getComponent(MeshRenderer).getMaterial() as PBRMaterial).baseColor.set(0, 1, 0, 1);
|
|
}
|
|
|
|
onContactEnter(other: ColliderShape) {
|
|
console.log("onContactEnter", other);
|
|
// Change color to green when collision occurs
|
|
(this.entity.getComponent(MeshRenderer).getMaterial() as PBRMaterial).baseColor.set(0, 1, 0, 1);
|
|
}
|
|
}
|
|
|
|
// Create a sphere with physics
|
|
function createPhysicsSphere(
|
|
rootEntity: Entity,
|
|
name: string,
|
|
position: Vector3,
|
|
radius: number,
|
|
color: Vector3,
|
|
collisionLayer: number
|
|
) {
|
|
const sphereEntity = rootEntity.createChild(name);
|
|
sphereEntity.transform.setPosition(position.x, position.y, position.z);
|
|
|
|
// Add visual representation
|
|
const sphereMtl = new PBRMaterial(rootEntity.engine);
|
|
const sphereRenderer = sphereEntity.addComponent(MeshRenderer);
|
|
sphereMtl.baseColor.set(color.x, color.y, color.z, 1.0);
|
|
sphereMtl.metallic = 0.0;
|
|
sphereMtl.roughness = 0.5;
|
|
sphereRenderer.mesh = PrimitiveMesh.createSphere(rootEntity.engine, radius);
|
|
sphereRenderer.setMaterial(sphereMtl);
|
|
|
|
// Add physics
|
|
const physicsSphere = new SphereColliderShape();
|
|
physicsSphere.radius = radius;
|
|
physicsSphere.material.bounciness = 0.8;
|
|
|
|
const sphereCollider = sphereEntity.addComponent(DynamicCollider);
|
|
sphereCollider.collisionLayer = collisionLayer;
|
|
sphereEntity.addComponent(CheckScript);
|
|
sphereCollider.addShape(physicsSphere);
|
|
|
|
return sphereEntity;
|
|
}
|
|
|
|
WebGLEngine.create({ canvas: "canvas", physics: new PhysXPhysics() }).then((engine) => {
|
|
engine.canvas.resizeByClientSize();
|
|
const scene = engine.sceneManager.activeScene;
|
|
const rootEntity = scene.createRootEntity("root");
|
|
|
|
// Set up ambient lighting
|
|
scene.ambientLight.diffuseSolidColor.set(1, 1, 1, 1);
|
|
scene.ambientLight.diffuseIntensity = 1.2;
|
|
|
|
// Set up camera
|
|
const cameraEntity = rootEntity.createChild("camera");
|
|
const camera = cameraEntity.addComponent(Camera);
|
|
// 调整相机位置以便更好地观察穿透效果
|
|
cameraEntity.transform.setPosition(0, 3, 15);
|
|
cameraEntity.transform.lookAt(new Vector3(0, 0, 0));
|
|
|
|
// Add point light
|
|
const light = rootEntity.createChild("light");
|
|
light.transform.setPosition(0, 10, 0);
|
|
const pointLight = light.addComponent(PointLight);
|
|
pointLight.intensity = 1.5;
|
|
|
|
// 创建立方体作为地面
|
|
const groundEntity = rootEntity.createChild("ground");
|
|
|
|
// 设置立方体的位置和大小
|
|
groundEntity.transform.setPosition(0, 1, 0);
|
|
|
|
// Visual representation of the ground cube
|
|
const groundMtl = new PBRMaterial(engine);
|
|
groundMtl.baseColor.set(0.5, 0.5, 0.5, 1.0);
|
|
groundMtl.roughness = 0.7;
|
|
// 设置半透明以便能看到穿透的球体
|
|
groundMtl.baseColor.a = 0.5;
|
|
|
|
const cubeSize = new Vector3(10, 0.2, 10);
|
|
const groundRenderer = groundEntity.addComponent(MeshRenderer);
|
|
groundRenderer.mesh = PrimitiveMesh.createCuboid(engine, cubeSize.x, cubeSize.y, cubeSize.z);
|
|
groundRenderer.setMaterial(groundMtl);
|
|
|
|
// Physics for the ground cube
|
|
const groundCollider = groundEntity.addComponent(StaticCollider);
|
|
const groundShape = new BoxColliderShape();
|
|
groundShape.size = cubeSize;
|
|
groundCollider.addShape(groundShape);
|
|
|
|
groundCollider.collisionLayer = Layer.Layer3;
|
|
|
|
// 创建可以碰撞的红色球体
|
|
const sphere1 = createPhysicsSphere(
|
|
rootEntity,
|
|
"RedSphere",
|
|
new Vector3(-2, 5, 0),
|
|
0.5,
|
|
new Vector3(1, 0, 0),
|
|
Layer.Layer1
|
|
);
|
|
|
|
// 创建可以穿透的蓝色球体
|
|
const sphere2 = createPhysicsSphere(
|
|
rootEntity,
|
|
"BlueSphere",
|
|
new Vector3(2, 5, 0),
|
|
0.5,
|
|
new Vector3(0, 0, 1),
|
|
Layer.Layer2
|
|
);
|
|
|
|
scene.physics.setColliderLayerCollision(Layer.Layer2, Layer.Layer3, false);
|
|
|
|
updateForE2E(engine, 110);
|
|
initScreenshot(engine, camera);
|
|
});
|