From 81627853e49a714227136d96984d0564b14626aa Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Tue, 8 Aug 2023 12:18:18 -0500 Subject: [PATCH] Fixed snapping with physics enabled. --- src/diagram/diagramManager.ts | 10 +++-- src/integration/drawioManager.ts | 71 +------------------------------- src/util/appConfig.ts | 2 +- src/util/customPhysics.ts | 33 ++++++++++++++- 4 files changed, 40 insertions(+), 76 deletions(-) diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index 681002d..64d6d9f 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -211,6 +211,9 @@ class DiagramShapePhysics { private static logger: log.Logger = log.getLogger('DiagramShapePhysics'); public static applyPhysics(mesh: AbstractMesh, scene: Scene, motionType?: PhysicsMotionType) { + if (!AppConfig.config.physicsEnabled) { + return; + } if (!mesh?.metadata?.template) { this.logger.error("applyPhysics: mesh.metadata.template is null", mesh); return; @@ -222,9 +225,7 @@ class DiagramShapePhysics { this.logger.error("applyPhysics: mesh or scene is null"); return; } - if (!AppConfig.config.physicsEnabled) { - return; - } + if (mesh.physicsBody) { mesh.physicsBody.dispose(); } @@ -247,6 +248,9 @@ class DiagramShapePhysics { const aggregate = new PhysicsAggregate(mesh, shapeType, {mass: mass, restitution: .02, friction: .9}, scene); const body = aggregate.body; + body.setLinearDamping(.95); + body.setAngularDamping(.99); + if (motionType) { body .setMotionType(motionType); diff --git a/src/integration/drawioManager.ts b/src/integration/drawioManager.ts index 480c7e3..747d181 100644 --- a/src/integration/drawioManager.ts +++ b/src/integration/drawioManager.ts @@ -1,16 +1,5 @@ import log from "loglevel"; -import { - AbstractMesh, - Axis, - Color3, - DynamicTexture, - MeshBuilder, - Scene, - Space, - StandardMaterial, - TransformNode, - Vector3 -} from "@babylonjs/core"; +import {Color3, Scene, TransformNode, Vector3} from "@babylonjs/core"; import {DiagramManager} from "../diagram/diagramManager"; import {DiagramEventType} from "../diagram/diagramEntity"; @@ -30,49 +19,7 @@ export class DrawioManager { this.getGraph(); } - public static updateTextNode(mesh: AbstractMesh, text: string): AbstractMesh { - //Set font - const height = 0.1; - const font_size = 24; - const font = "bold " + font_size + "px Arial"; - //Set height for dynamic texture - const DTHeight = 1.5 * font_size; //or set as wished - //Calc Ratio - const ratio = height / DTHeight; - //Use a temporary dynamic texture to calculate the length of the text on the dynamic texture canvas - const temp = new DynamicTexture("DynamicTexture", 32, mesh.getScene()); - const tmpctx = temp.getContext(); - tmpctx.font = font; - const DTWidth = tmpctx.measureText(text).width + 8; - - //Calculate width the plane has to be - const planeWidth = DTWidth * ratio; - - //Create dynamic texture and write the text - const dynamicTexture = new DynamicTexture("DynamicTexture", { - width: DTWidth, - height: DTHeight - }, mesh.getScene(), false); - const mat = new StandardMaterial("mat", mesh.getScene()); - mat.diffuseTexture = dynamicTexture; - dynamicTexture.drawText(text, null, null, font, "#000000", "#ffffff", true); - - //Create plane and set dynamic texture as material - const plane = MeshBuilder.CreatePlane("text", {width: planeWidth, height: height}, mesh.getScene()); - plane.material = mat; - //plane.billboardMode = Mesh.BILLBOARDMODE_ALL; - plane.parent = mesh; - plane.position.z = .51; - plane.scaling.y = 1 / mesh.scaling.y; - plane.scaling.x = 1 / mesh.scaling.x; - plane.scaling.z = 1 / mesh.scaling.z; - plane.rotate(Axis.Z, Math.PI, Space.LOCAL); - plane.rotate(Axis.Y, Math.PI, Space.LOCAL); - //plane.rotate(Axis.X, Math.PI, Space.LOCAL); - - return plane; - } private async getGraph() { this.logger.debug("starting to get graph"); @@ -141,23 +88,7 @@ export class DrawioManager { const anchor = new TransformNode('anchor', this.scene); if (entities.length > 0) { - //const basebox = MeshBuilder.CreateBox("box", { - // height: 1, - // width: 1, depth: 1 - //}, this.scene); - - //const material: StandardMaterial = new StandardMaterial("mat", this.scene); - //material.diffuseColor = new Color3(0.5, 0.5, 0.5); - //material.alpha = .4; - //basebox.material = material; entities.forEach((entity) => { - /* const box = new InstancedMesh("box", basebox); - box.scaling.z = .1; - box.scaling.y = entity.geometry.height * scale; - box.scaling.x = entity.geometry.width * scale; - box.position.x = (entity.geometry.x - this.minX) * scale + (entity.geometry.width * scale / 2); - box.position.y = (entity.geometry.y - this.minY) * scale + (entity.geometry.height * scale / 2); - box.position.z = 2 + this.zdepth.get(entity.id); */ this.diagramManager.onDiagramEventObservable.notifyObservers( { type: DiagramEventType.ADD, diff --git a/src/util/appConfig.ts b/src/util/appConfig.ts index 35a0ada..5396327 100644 --- a/src/util/appConfig.ts +++ b/src/util/appConfig.ts @@ -16,7 +16,7 @@ export class AppConfig { private _turnSnap = 0; private rotateSnap = 0; private createSnap = 0; - _physicsEnabled = false; + _physicsEnabled = true; private readonly defaultGridSnapIndex = 1; private persistenceManager: IPersistenceManager = null; private gridSnapArray: SnapValue[] = diff --git a/src/util/customPhysics.ts b/src/util/customPhysics.ts index a63165b..850d1db 100644 --- a/src/util/customPhysics.ts +++ b/src/util/customPhysics.ts @@ -1,5 +1,6 @@ -import {HavokPlugin, Scene, Vector3} from "@babylonjs/core"; +import {HavokPlugin, Quaternion, Scene, Vector3} from "@babylonjs/core"; import HavokPhysics from "@babylonjs/havok"; +import {AppConfig} from "./appConfig"; export class CustomPhysics { private scene: Scene; @@ -9,9 +10,37 @@ export class CustomPhysics { } public async initializeAsync() { - const havok = await HavokPhysics() + const havok = await HavokPhysics(); const havokPlugin = new HavokPlugin(true, havok); this.scene.enablePhysics(new Vector3(0, -9.8, 0), havokPlugin); this.scene.collisionsEnabled = true; + this.scene.onAfterPhysicsObservable.add(() => { + this.scene.meshes.forEach((mesh) => { + if (mesh?.metadata?.template && mesh.physicsBody) { + const body = mesh.physicsBody; + const linearVelocity = new Vector3(); + body.getLinearVelocityToRef(linearVelocity); + if (linearVelocity.length() < .1) { + body.disablePreStep = false; + const bodyId = body._pluginData.hpBodyId[0]; + // const position = body._pluginData._hknp.HP_Body_GetPosition(bodyId); + const pos: Vector3 = body.getObjectCenterWorld(); + const val: Vector3 = AppConfig.config.snapGridVal(pos); + //body.setTargetTransform(val, body.transformNode.rotationQuaternion); + body.transformNode.position.set(val.x, val.y, val.z); + const rot: Quaternion = + Quaternion.FromEulerVector(AppConfig.config.snapRotateVal(body.transformNode.rotationQuaternion.toEulerAngles())) + + body.transformNode.rotationQuaternion.set( + rot.x, rot.y, rot.z, rot.w + ); + + body.disablePreStep = true; + } + //mesh.position = mesh.physicsImpostor.physicsBody.position; + //mesh.rotationQuaternion = mesh.physicsImpostor.physicsBody.quaternion; + } + }); + }); } } \ No newline at end of file