refactored grabbing.
This commit is contained in:
parent
88668c3d64
commit
d59e75ddc9
@ -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();
|
||||
}
|
||||
|
||||
26
src/controllers/functions/reparent.ts
Normal file
26
src/controllers/functions/reparent.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/controllers/functions/setupTransformNode.ts
Normal file
10
src/controllers/functions/setupTransformNode.ts
Normal 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;
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user