Refactored physics to reduce duplicate code.
This commit is contained in:
parent
cdefd3bb70
commit
89623b5007
Binary file not shown.
|
Before Width: | Height: | Size: 35 MiB |
@ -40,7 +40,7 @@ export class App {
|
||||
|
||||
constructor() {
|
||||
const config = AppConfig.config;
|
||||
log.setLevel('warn');
|
||||
log.setLevel('debug');
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.style.width = "100%";
|
||||
canvas.style.height = "100%";
|
||||
@ -125,7 +125,6 @@ export class App {
|
||||
this.scene.gamepadManager.onGamepadConnectedObservable.add((gamepad) => {
|
||||
try {
|
||||
const dualshock = (gamepad as DualShockPad);
|
||||
|
||||
dualshock.onButtonDownObservable.add((button: any) => {
|
||||
const buttonEvent = DualshockEventMapper.mapButtonEvent(button, 1);
|
||||
if (buttonEvent.objectName) {
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import {
|
||||
AbstractMesh,
|
||||
HavokPlugin,
|
||||
PhysicsAggregate,
|
||||
PhysicsMotionType,
|
||||
PhysicsShapeType,
|
||||
Scene,
|
||||
TransformNode,
|
||||
Vector3,
|
||||
@ -44,9 +42,7 @@ export class Base {
|
||||
this.controller = controller;
|
||||
|
||||
this.scene = scene;
|
||||
this.scene.onAfterRenderObservable.add(() => {
|
||||
|
||||
}, -1, false, this);
|
||||
|
||||
this.scene.onBeforeRenderObservable.add(() => {
|
||||
if (this?.grabbedMesh?.physicsBody) {
|
||||
@ -106,7 +102,16 @@ export class Base {
|
||||
|
||||
}
|
||||
|
||||
private grab(mesh) {
|
||||
private setupTransformNode(mesh: TransformNode) {
|
||||
const transformNode = new TransformNode("grabAnchor, this.scene");
|
||||
transformNode.id = "grabAnchor";
|
||||
transformNode.position = mesh.position.clone();
|
||||
transformNode.rotationQuaternion = mesh.rotationQuaternion.clone();
|
||||
transformNode.setParent(this.controller.motionController.rootMesh);
|
||||
return transformNode;
|
||||
}
|
||||
|
||||
private grab(mesh: AbstractMesh) {
|
||||
|
||||
if (this.xr.pointerSelection.getMeshUnderPointer) {
|
||||
mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId);
|
||||
@ -130,12 +135,9 @@ export class Base {
|
||||
|
||||
if ("toolbox" != mesh?.parent?.parent?.id) {
|
||||
if (mesh.physicsBody) {
|
||||
const transformNode = new TransformNode("grabAnchor, this.scene");
|
||||
transformNode.id = "grabAnchor";
|
||||
transformNode.position = mesh.position.clone();
|
||||
transformNode.rotationQuaternion = mesh.rotationQuaternion.clone();
|
||||
transformNode.setParent(this.controller.motionController.rootMesh);
|
||||
mesh.physicsBody.setMotionType(PhysicsMotionType.STATIC);
|
||||
|
||||
const transformNode = this.setupTransformNode(mesh);
|
||||
mesh.physicsBody.setMotionType(PhysicsMotionType.ANIMATED);
|
||||
//mesh.setParent(transformNode);
|
||||
this.grabbedMeshParentId = transformNode.id;
|
||||
} else {
|
||||
@ -143,18 +145,7 @@ export class Base {
|
||||
}
|
||||
this.grabbedMesh = mesh;
|
||||
} else {
|
||||
const config = AppConfig.config;
|
||||
const newMesh = this.diagramManager.createCopy(mesh);
|
||||
newMesh.position = mesh.absolutePosition.clone();
|
||||
if (mesh.absoluteRotationQuaternion) {
|
||||
newMesh.rotation = mesh.absoluteRotationQuaternion.toEulerAngles().clone();
|
||||
} else {
|
||||
newMesh.rotation = mesh.absoluteRotation.clone();
|
||||
}
|
||||
|
||||
newMesh.scaling = config.createSnapVal;
|
||||
newMesh.material = mesh.material;
|
||||
newMesh.metadata = mesh.metadata;
|
||||
const transformNode = new TransformNode("grabAnchor, this.scene");
|
||||
transformNode.id = "grabAnchor";
|
||||
transformNode.position = newMesh.position.clone();
|
||||
@ -163,14 +154,11 @@ export class Base {
|
||||
} else {
|
||||
transformNode.rotation = newMesh.rotation.clone();
|
||||
}
|
||||
|
||||
transformNode.setParent(this.controller.motionController.rootMesh);
|
||||
//newMesh?.physicsBody?.setMotionType(PhysicsMotionType.STATIC);
|
||||
//mesh.setParent(transformNode);
|
||||
this.grabbedMeshParentId = transformNode.id;
|
||||
const aggregate = new PhysicsAggregate(newMesh,
|
||||
PhysicsShapeType.BOX, {mass: 10, restitution: .1, friction: .9}, this.scene);
|
||||
aggregate.body.setMotionType(PhysicsMotionType.STATIC);
|
||||
MeshConverter
|
||||
.applyPhysics(newMesh, this.scene)
|
||||
.setMotionType(PhysicsMotionType.ANIMATED);
|
||||
|
||||
|
||||
//newMesh && newMesh.setParent(this.controller.motionController.rootMesh);
|
||||
@ -199,10 +187,6 @@ export class Base {
|
||||
}
|
||||
|
||||
private reparent(mesh: AbstractMesh) {
|
||||
const config = AppConfig.config;
|
||||
const snappedRotation = config.snapRotateVal(mesh.absoluteRotationQuaternion.toEulerAngles().clone());
|
||||
const snappedPosition = config.snapGridVal(mesh.absolutePosition.clone());
|
||||
|
||||
if (this.previousParentId) {
|
||||
const parent = this.scene.getMeshById(this.previousParentId);
|
||||
if (parent) {
|
||||
@ -211,21 +195,28 @@ export class Base {
|
||||
//@note: this is not implemented yet
|
||||
} else {
|
||||
//mesh.setParent(null);
|
||||
mesh.rotation = snappedRotation;
|
||||
mesh.position = snappedPosition;
|
||||
this.applyTransform(mesh)
|
||||
mesh?.physicsBody?.setMotionType(PhysicsMotionType.DYNAMIC);
|
||||
}
|
||||
} else {
|
||||
const parent = this.scene.getTransformNodeById(this.grabbedMeshParentId);
|
||||
if (parent) {
|
||||
parent.rotation = snappedRotation;
|
||||
parent.position = snappedPosition;
|
||||
this.applyTransform(parent);
|
||||
this.grabbedMeshParentId = null;
|
||||
parent.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private applyTransform(mesh: TransformNode) {
|
||||
const config = AppConfig.config;
|
||||
const snappedRotation = config.snapRotateVal(mesh.absoluteRotationQuaternion.toEulerAngles().clone());
|
||||
const snappedPosition = config.snapGridVal(mesh.absolutePosition.clone());
|
||||
|
||||
mesh.rotation = snappedRotation;
|
||||
mesh.position = snappedPosition;
|
||||
}
|
||||
|
||||
private drop() {
|
||||
const mesh = this.grabbedMesh;
|
||||
if (!mesh) {
|
||||
@ -258,11 +249,7 @@ export class Base {
|
||||
//body.setLinearVelocity(this.lastPosition.subtract(body.transformNode.absolutePosition).scale(20));
|
||||
this.logger.debug(this.lastPosition.subtract(body.transformNode.absolutePosition).scale(20));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private initGrip(grip: WebXRControllerComponent) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {Color3, Vector3} from "@babylonjs/core";
|
||||
import {BmenuState} from "../menus/MenuState";
|
||||
|
||||
export enum DiagramEventType {
|
||||
ADD,
|
||||
REMOVE,
|
||||
@ -11,6 +12,8 @@ export enum DiagramEventType {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export type DiagramEvent = {
|
||||
type: DiagramEventType;
|
||||
menustate?: BmenuState;
|
||||
|
||||
@ -6,9 +6,7 @@ import {
|
||||
InstancedMesh,
|
||||
Mesh,
|
||||
Observable,
|
||||
PhysicsAggregate,
|
||||
PhysicsMotionType,
|
||||
PhysicsShapeType,
|
||||
PlaySoundAction,
|
||||
Scene,
|
||||
WebXRExperienceHelper
|
||||
@ -19,6 +17,7 @@ import {MeshConverter} from "./meshConverter";
|
||||
import log from "loglevel";
|
||||
import {Controllers} from "../controllers/controllers";
|
||||
import {DiaSounds} from "../util/diaSounds";
|
||||
import {AppConfig} from "../util/appConfig";
|
||||
|
||||
export class DiagramManager {
|
||||
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
|
||||
@ -72,8 +71,17 @@ export class DiagramManager {
|
||||
newMesh = new InstancedMesh("new", (mesh as InstancedMesh).sourceMesh);
|
||||
}
|
||||
newMesh.actionManager = this.actionManager;
|
||||
return newMesh;
|
||||
newMesh.position = mesh.absolutePosition.clone();
|
||||
if (mesh.absoluteRotationQuaternion) {
|
||||
newMesh.rotation = mesh.absoluteRotationQuaternion.toEulerAngles().clone();
|
||||
} else {
|
||||
this.logger.error("no rotation quaternion");
|
||||
}
|
||||
newMesh.scaling = AppConfig.config.createSnapVal;
|
||||
newMesh.material = mesh.material;
|
||||
newMesh.metadata = mesh.metadata;
|
||||
|
||||
return newMesh;
|
||||
}
|
||||
|
||||
private onRemoteEvent(event: DiagramEntity) {
|
||||
@ -91,8 +99,8 @@ export class DiagramManager {
|
||||
if (event.parent) {
|
||||
mesh.parent = this.scene.getMeshById(event.parent);
|
||||
}
|
||||
const body = new PhysicsAggregate(mesh, PhysicsShapeType.BOX, {mass: 10, restitution: .1}, this.scene);
|
||||
body.body.setMotionType(PhysicsMotionType.DYNAMIC);
|
||||
MeshConverter.applyPhysics(mesh, this.scene)
|
||||
.setMotionType(PhysicsMotionType.DYNAMIC);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,9 @@ import {
|
||||
InstancedMesh,
|
||||
Mesh,
|
||||
MeshBuilder,
|
||||
PhysicsAggregate,
|
||||
PhysicsBody,
|
||||
PhysicsShapeType,
|
||||
Scene,
|
||||
StandardMaterial
|
||||
} from "@babylonjs/core";
|
||||
@ -110,6 +113,37 @@ export class MeshConverter {
|
||||
|
||||
}
|
||||
|
||||
public static applyPhysics(mesh: AbstractMesh, scene: Scene): PhysicsBody {
|
||||
if (!mesh?.metadata?.template || !scene) {
|
||||
this.logger.error("applyPhysics: mesh or scene is null");
|
||||
return null;
|
||||
}
|
||||
if (mesh.physicsBody) {
|
||||
return mesh.physicsBody;
|
||||
}
|
||||
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 aggregate = new PhysicsAggregate(mesh,
|
||||
shapeType, {mass: 20, restitution: .2, friction: .9}, scene);
|
||||
aggregate.body.setLinearDamping(.9);
|
||||
aggregate.body.setAngularDamping(.5);
|
||||
|
||||
|
||||
return aggregate.body;
|
||||
|
||||
}
|
||||
|
||||
public static updateTextNode(mesh: AbstractMesh, text: string) {
|
||||
if (!mesh) {
|
||||
this.logger.error("updateTextNode: mesh is null");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user