77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import {AbstractMesh, PhysicsAggregate, PhysicsBody, PhysicsMotionType, PhysicsShapeType, Scene} from "@babylonjs/core";
|
|
import log from "loglevel";
|
|
import {isDiagramEntity} from "./isDiagramEntity";
|
|
|
|
|
|
const MASS_FACTOR = 10;
|
|
|
|
export function applyPhysics(
|
|
mesh: AbstractMesh,
|
|
scene: Scene,
|
|
motionType?: PhysicsMotionType) {
|
|
const logger = log.getLogger('DiagramShapePhysics');
|
|
if (!isDiagramEntity(mesh)) {
|
|
logger.error("applyPhysics: mesh.metadata.template is null", mesh);
|
|
return;
|
|
}
|
|
if (mesh.metadata.template == '#connection-template') {
|
|
return;
|
|
}
|
|
if (!scene) {
|
|
logger.error("applyPhysics: mesh or scene is null");
|
|
return;
|
|
}
|
|
if (mesh.physicsBody) {
|
|
mesh.physicsBody.dispose();
|
|
}
|
|
let shapeType = PhysicsShapeType.BOX;
|
|
switch (mesh.metadata.template) {
|
|
case "#sphere-template":
|
|
shapeType = PhysicsShapeType.SPHERE;
|
|
break;
|
|
case "#cylinder-template":
|
|
shapeType = PhysicsShapeType.CYLINDER;
|
|
break;
|
|
case "#cone-template":
|
|
shapeType = PhysicsShapeType.CONVEX_HULL;
|
|
break;
|
|
}
|
|
const mass = mesh.scaling.x * mesh.scaling.y * mesh.scaling.z * MASS_FACTOR;
|
|
const aggregate = new PhysicsAggregate(mesh,
|
|
shapeType, {mass: mass, restitution: .02, friction: .9}, scene);
|
|
const body = aggregate.body;
|
|
applyMotionType(motionType, body, mesh);
|
|
|
|
body.setCollisionCallbackEnabled(true);
|
|
/*body.getCollisionObservable().add((event) => {
|
|
if (event.impulse < 10 && event.impulse > 1) {
|
|
const sound = sounds.bounce;
|
|
sound.setVolume(event.impulse / 10);
|
|
sound.attachToMesh(mesh);
|
|
sound.play();
|
|
}
|
|
}, -1, false);*/
|
|
applyPhysicsDefaults(body);
|
|
}
|
|
|
|
function applyPhysicsDefaults(body: PhysicsBody) {
|
|
body.setLinearDamping(.95);
|
|
body.setAngularDamping(.99);
|
|
body.setGravityFactor(0);
|
|
}
|
|
|
|
function applyMotionType(motionType: PhysicsMotionType, body: PhysicsBody, mesh: AbstractMesh) {
|
|
if (motionType) {
|
|
body
|
|
.setMotionType(motionType);
|
|
} else {
|
|
if (mesh.parent) {
|
|
body
|
|
.setMotionType(PhysicsMotionType.ANIMATED);
|
|
} else {
|
|
body
|
|
.setMotionType(PhysicsMotionType.DYNAMIC);
|
|
}
|
|
}
|
|
}
|