refactored grabbing.

This commit is contained in:
Michael Mainguy 2023-08-23 08:57:12 -05:00
parent 88668c3d64
commit d59e75ddc9
4 changed files with 79 additions and 71 deletions

View File

@ -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();
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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);
}