diff --git a/src/controllers/base.ts b/src/controllers/base.ts index 447767d..4af70fd 100644 --- a/src/controllers/base.ts +++ b/src/controllers/base.ts @@ -14,6 +14,8 @@ import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity"; import log from "loglevel"; import {Controllers} from "./controllers"; import {toDiagramEntity} from "../diagram/functions/toDiagramEntity"; +import {setupTransformNode} from "./functions/setupTransformNode"; +import {reparent} from "./functions/reparent"; export class Base { static stickVector = Vector3.Zero(); @@ -92,20 +94,8 @@ export class Base { this.controller.pointer.setEnabled(true); } - 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); - } + private grab() { + const mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId); if (!mesh) { return; } @@ -123,18 +113,20 @@ export class Base { } } this.previousParentId = mesh?.parent?.id; + this.logger.warn("grabbed " + mesh?.id + " parent " + this.previousParentId); this.previousRotation = mesh?.rotation.clone(); this.previousScaling = mesh?.scaling.clone(); this.previousPosition = mesh?.position.clone(); if ("toolbox" != mesh?.parent?.parent?.id) { if (mesh.physicsBody) { - const transformNode = this.setupTransformNode(mesh); + const transformNode = setupTransformNode(mesh, this.controller.motionController.rootMesh); mesh.physicsBody.setMotionType(PhysicsMotionType.ANIMATED); this.grabbedMeshParentId = transformNode.id; } else { mesh.setParent(this.controller.motionController.rootMesh); } + this.grabbedMesh = mesh; } else { const newMesh = this.diagramManager.createCopy(mesh); @@ -148,9 +140,6 @@ export class Base { } transformNode.setParent(this.controller.motionController.rootMesh); this.grabbedMeshParentId = transformNode.id; - - - //newMesh && newMesh.setParent(this.controller.motionController.rootMesh); this.grabbedMesh = newMesh; this.previousParentId = null; const event: DiagramEvent = { @@ -158,14 +147,12 @@ export class Base { entity: toDiagramEntity(newMesh) } this.diagramManager.onDiagramEventObservable.notifyObservers(event); - } } - private handleGrabbed(mesh: AbstractMesh): boolean { + private toolboxHandleWasGrabbed(mesh: AbstractMesh): boolean { if (!mesh?.metadata?.template && mesh?.id == "handle") { - //mesh && mesh.setParent(null); this.grabbedMesh = null; this.previousParentId = null; mesh.setParent(null); @@ -174,38 +161,18 @@ export class Base { return false; } } - - private reparent(mesh: AbstractMesh) { - if (this.previousParentId) { - const parent = this.scene.getMeshById(this.previousParentId); - if (parent) { - //mesh && mesh.setParent(this.scene.getMeshById(this.previousParentId)); - log.getLogger("Base").warn("Base", "Have not implemented snapping to parent yet"); - //@note: this is not implemented yet - } else { - mesh.setParent(null); - } - } else { - const parent = this.scene.getTransformNodeById(this.grabbedMeshParentId); - if (parent) { - this.grabbedMeshParentId = null; - parent.dispose(); - } else { - mesh.setParent(null); - } - } - } - private drop() { const mesh = this.grabbedMesh; if (!mesh) { return; } - if (this.handleGrabbed(mesh)) { + if (this.toolboxHandleWasGrabbed(mesh)) { return; } - this.reparent(mesh); + reparent(mesh, this.previousParentId, this.grabbedMeshParentId); + this.grabbedMeshParentId = null; + if (!mesh.physicsBody) { mesh.position = this.diagramManager.config.snapGridVal(mesh.position, this.diagramManager.config.current.gridSnap); mesh.rotation = this.diagramManager.config.snapRotateVal(mesh.rotation, this.diagramManager.config.current.rotateSnap); @@ -242,7 +209,7 @@ export class Base { grip.onButtonStateChangedObservable.add(() => { if (grip.changes.pressed) { if (grip.pressed) { - this.grab(this.scene.meshUnderPointer); + this.grab(); } else { this.drop(); } diff --git a/src/controllers/functions/reparent.ts b/src/controllers/functions/reparent.ts new file mode 100644 index 0000000..b29331d --- /dev/null +++ b/src/controllers/functions/reparent.ts @@ -0,0 +1,26 @@ +import {AbstractMesh} from "@babylonjs/core"; +import log from "loglevel"; + +const logger = log.getLogger('reparent'); + +export function reparent(mesh: AbstractMesh, previousParentId: string, grabbedMeshParentId: string) { + if (previousParentId) { + const parent = mesh.getScene().getMeshById(previousParentId); + if (parent) { + //mesh && mesh.setParent(this.scene.getMeshById(this.previousParentId)); + logger.warn('not yet implemented') + //@note: this is not implemented yet + } else { + mesh.setParent(null); + } + } else { + const parent = mesh.getScene().getTransformNodeById(grabbedMeshParentId); + if (parent) { + logger.warn('setting parent to null', grabbedMeshParentId, parent) + //this.grabbedMeshParentId = null; + parent.dispose(); + } else { + mesh.setParent(null); + } + } +} \ No newline at end of file diff --git a/src/controllers/functions/setupTransformNode.ts b/src/controllers/functions/setupTransformNode.ts new file mode 100644 index 0000000..d54af00 --- /dev/null +++ b/src/controllers/functions/setupTransformNode.ts @@ -0,0 +1,10 @@ +import {AbstractMesh, TransformNode} from "@babylonjs/core"; + +export function setupTransformNode(mesh: TransformNode, parent: AbstractMesh) { + const transformNode = new TransformNode("grabAnchor, this.scene"); + transformNode.id = "grabAnchor"; + transformNode.position = mesh.position.clone(); + transformNode.rotationQuaternion = mesh.rotationQuaternion.clone(); + transformNode.setParent(parent); + return transformNode; +} \ No newline at end of file diff --git a/src/diagram/functions/diagramShapePhysics.ts b/src/diagram/functions/diagramShapePhysics.ts index 57d1125..3567eae 100644 --- a/src/diagram/functions/diagramShapePhysics.ts +++ b/src/diagram/functions/diagramShapePhysics.ts @@ -1,9 +1,14 @@ import {DiaSounds} from "../../util/diaSounds"; -import {AbstractMesh, PhysicsAggregate, PhysicsMotionType, PhysicsShapeType, Scene} from "@babylonjs/core"; +import {AbstractMesh, PhysicsAggregate, PhysicsBody, PhysicsMotionType, PhysicsShapeType, Scene} from "@babylonjs/core"; import log from "loglevel"; -export function applyPhysics(sounds: DiaSounds, mesh: AbstractMesh, scene: Scene, motionType?: PhysicsMotionType) { - const logger = log.getLogger('DiagramShapePhysics'); +const logger = log.getLogger('DiagramShapePhysics'); +const MASS_FACTOR = 10; + +export function applyPhysics(sounds: DiaSounds, + mesh: AbstractMesh, + scene: Scene, + motionType?: PhysicsMotionType) { if (!mesh?.metadata?.template) { logger.error("applyPhysics: mesh.metadata.template is null", mesh); return; @@ -15,11 +20,9 @@ export function applyPhysics(sounds: DiaSounds, mesh: AbstractMesh, scene: 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": @@ -31,16 +34,32 @@ export function applyPhysics(sounds: DiaSounds, mesh: AbstractMesh, scene: Scene case "#cone-template": shapeType = PhysicsShapeType.CONVEX_HULL; break; - } - let mass = mesh.scaling.x * mesh.scaling.y * mesh.scaling.z * 10; - + 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; - body.setLinearDamping(1.95); - body.setAngularDamping(1.99); + 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); @@ -53,18 +72,4 @@ export function applyPhysics(sounds: DiaSounds, mesh: AbstractMesh, scene: Scene .setMotionType(PhysicsMotionType.DYNAMIC); } } - 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, this); - //body.setMotionType(PhysicsMotionType.ANIMATED); - body.setLinearDamping(.95); - body.setAngularDamping(.99); - body.setGravityFactor(0); -} \ No newline at end of file +}