mirror of
https://github.com/cocos/cocos-engine.git
synced 2026-09-06 15:48:37 +08:00
71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
import { Vec3 } from '@base/math';
|
|
import { physics } from '../../exports/physics-framework';
|
|
import { Node } from '../../cocos/scene-graph';
|
|
import { director } from '../../cocos/game';
|
|
import { PhysicsTestEnv } from './physics.test';
|
|
|
|
export default function(env: PhysicsTestEnv) {
|
|
describe(`Stability test`, () => {
|
|
test.each([1, 0.5])(`Stable %s`, (v) => {
|
|
doTest(env, 500, v);
|
|
});
|
|
|
|
if (env.backendId === 'physx') {
|
|
test.each([0.25, 0.15])(`Stable for small scale in PhysX %s`, (v) => {
|
|
doTest(env, 500, v);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This function is used to test stability of the physics
|
|
*/
|
|
function doTest(env: PhysicsTestEnv, steps = 500, scale = 0.5) {
|
|
const { rootNode: parent } = env;
|
|
|
|
const nodeStatic = new Node('StaticB');
|
|
parent.addChild(nodeStatic);
|
|
nodeStatic.addComponent(physics.BoxCollider);
|
|
nodeStatic.worldScale = new Vec3(20, 0.01, 20);
|
|
nodeStatic.worldPosition = new Vec3(0, -0.005, 0);
|
|
|
|
const size = new Vec3(scale, scale, scale);
|
|
const X = 8, Y = 8, Z = 4;
|
|
let x = 0, y = 0, z = 0;
|
|
for (let i = 0; i < Y; i++) {
|
|
y = size.y / 2 + size.y * i;
|
|
const CX = X - i;
|
|
for (let j = 0; j < CX; j++) {
|
|
x = CX * -size.x / 2 + j * size.x;
|
|
for (let k = 0; k < Z; k++) {
|
|
const nodeDynamic = new Node(`${i}-${j}`);
|
|
parent.addChild(nodeDynamic);
|
|
nodeDynamic.worldScale = size;
|
|
nodeDynamic.worldPosition = new Vec3(x, y, z + k * size.z * 2);
|
|
nodeDynamic.addComponent(physics.RigidBody);
|
|
nodeDynamic.addComponent(physics.BoxCollider);
|
|
}
|
|
}
|
|
}
|
|
|
|
const dt = physics.PhysicsSystem.instance.fixedTimeStep;
|
|
const bodies = parent.getComponentsInChildren(physics.RigidBody) as physics.RigidBody[];
|
|
const middle = Math.floor(steps / 2);
|
|
for (let i = 0; i < steps; i++) {
|
|
if (i === middle) {
|
|
bodies.forEach((v) => {
|
|
v.wakeUp();
|
|
expect(v.isSleeping).toBe(false);
|
|
expect(v.isAwake).toBe(true);
|
|
});
|
|
}
|
|
director.tick(dt);
|
|
}
|
|
|
|
bodies.forEach((v) => {
|
|
expect(v.isSleeping).toBe(true);
|
|
expect(v.isAwake).toBe(false);
|
|
});
|
|
}
|