diff --git a/public/outdoor_field.jpeg b/public/outdoor_field.jpeg deleted file mode 100644 index d86b095..0000000 Binary files a/public/outdoor_field.jpeg and /dev/null differ diff --git a/src/app.ts b/src/app.ts index ed83514..c4f1320 100644 --- a/src/app.ts +++ b/src/app.ts @@ -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) { diff --git a/src/controllers/base.ts b/src/controllers/base.ts index 160b77b..39f31e4 100644 --- a/src/controllers/base.ts +++ b/src/controllers/base.ts @@ -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) { diff --git a/src/diagram/diagramEntity.ts b/src/diagram/diagramEntity.ts index d233b93..1da0b27 100644 --- a/src/diagram/diagramEntity.ts +++ b/src/diagram/diagramEntity.ts @@ -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; diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index 140a3f3..75cb487 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -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 = 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); } diff --git a/src/diagram/meshConverter.ts b/src/diagram/meshConverter.ts index 1515b7c..aca19ad 100644 --- a/src/diagram/meshConverter.ts +++ b/src/diagram/meshConverter.ts @@ -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");