added capability to create items in diagram.
This commit is contained in:
parent
91144571c0
commit
46efe08535
1
package-lock.json
generated
1
package-lock.json
generated
@ -21,6 +21,7 @@
|
|||||||
"google-static-maps-tile": "1.0.0",
|
"google-static-maps-tile": "1.0.0",
|
||||||
"query-string": "^8.1.0",
|
"query-string": "^8.1.0",
|
||||||
"ring-client-api": "^11.8.0",
|
"ring-client-api": "^11.8.0",
|
||||||
|
"uuid": "^9.0.0",
|
||||||
"vite-express": "^0.9.1"
|
"vite-express": "^0.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@ -24,7 +24,8 @@
|
|||||||
"google-static-maps-tile": "1.0.0",
|
"google-static-maps-tile": "1.0.0",
|
||||||
"query-string": "^8.1.0",
|
"query-string": "^8.1.0",
|
||||||
"vite-express": "^0.9.1",
|
"vite-express": "^0.9.1",
|
||||||
"express-http-proxy": "^1.6.3"
|
"express-http-proxy": "^1.6.3",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
|
|||||||
BIN
public/outdoor_field.jpeg
Normal file
BIN
public/outdoor_field.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 MiB |
69
src/app.ts
69
src/app.ts
@ -8,6 +8,7 @@ import {
|
|||||||
HemisphericLight,
|
HemisphericLight,
|
||||||
MeshBuilder,
|
MeshBuilder,
|
||||||
PBRMetallicRoughnessMaterial,
|
PBRMetallicRoughnessMaterial,
|
||||||
|
PhotoDome,
|
||||||
PhysicsAggregate,
|
PhysicsAggregate,
|
||||||
PhysicsShapeType,
|
PhysicsShapeType,
|
||||||
Scene,
|
Scene,
|
||||||
@ -21,8 +22,8 @@ import {Left} from "./controllers/left";
|
|||||||
import {Bmenu} from "./menus/bmenu";
|
import {Bmenu} from "./menus/bmenu";
|
||||||
import HavokPhysics from "@babylonjs/havok";
|
import HavokPhysics from "@babylonjs/havok";
|
||||||
import {Rigplatform} from "./controllers/rigplatform";
|
import {Rigplatform} from "./controllers/rigplatform";
|
||||||
import {Cameras} from "./integration/ring/cameras";
|
|
||||||
import {Mapt} from "./util/mapt";
|
import {DiagramManager} from "./diagram/diagramManager";
|
||||||
|
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
@ -43,6 +44,7 @@ class App {
|
|||||||
|
|
||||||
const engine = new Engine(canvas, true);
|
const engine = new Engine(canvas, true);
|
||||||
const scene = new Scene(engine);
|
const scene = new Scene(engine);
|
||||||
|
const diagramManager = new DiagramManager(scene);
|
||||||
const havokInstance = await HavokPhysics();
|
const havokInstance = await HavokPhysics();
|
||||||
const havokPlugin = new HavokPlugin(true, havokInstance);
|
const havokPlugin = new HavokPlugin(true, havokInstance);
|
||||||
scene.enablePhysics(new Vector3(0, -9.8, 0), havokPlugin);
|
scene.enablePhysics(new Vector3(0, -9.8, 0), havokPlugin);
|
||||||
@ -51,65 +53,21 @@ class App {
|
|||||||
camera.attachControl(canvas, true);
|
camera.attachControl(canvas, true);
|
||||||
new HemisphericLight("light1", new Vector3(1, 1, 0), scene);
|
new HemisphericLight("light1", new Vector3(1, 1, 0), scene);
|
||||||
|
|
||||||
const rig = new Rigplatform(scene);
|
|
||||||
//const envTexture = new CubeTexture("/assets/textures/SpecularHDR.dds", scene);
|
//const envTexture = new CubeTexture("/assets/textures/SpecularHDR.dds", scene);
|
||||||
//scene.createDefaultSkybox(envTexture, true, 1000);
|
//scene.createDefaultSkybox(envTexture, true, 1000);
|
||||||
|
|
||||||
/*const photoDome = new PhotoDome('sky',
|
const photoDome = new PhotoDome('sky',
|
||||||
'./outdoor_field.jpeg', {},
|
'./outdoor_field.jpeg', {},
|
||||||
scene);
|
scene);
|
||||||
*/
|
|
||||||
const xr = await WebXRDefaultExperience.CreateAsync(scene, {
|
const xr = await WebXRDefaultExperience.CreateAsync(scene, {
|
||||||
floorMeshes: [this.createGround(scene)],
|
floorMeshes: [this.createGround(scene)],
|
||||||
optionalFeatures: true
|
optionalFeatures: true
|
||||||
});
|
});
|
||||||
xr.baseExperience.camera.parent = rig.rigMesh;
|
const rig = new Rigplatform(scene, xr);
|
||||||
const b = new Bmenu(scene, rig, xr.baseExperience);
|
//const ring = new Cameras(scene, this.token);
|
||||||
//const box = MeshBuilder.CreateBox("box", {size: 1}, scene);
|
//ring.getCameras().then(() => ring.createCameras());
|
||||||
//box.position.z = -4;
|
|
||||||
|
|
||||||
|
|
||||||
/*box.actionManager.registerAction(
|
|
||||||
new InterpolateValueAction(
|
|
||||||
ActionManager.OnPointerOverTrigger,box, 'visibility', 0.2, 500
|
|
||||||
)
|
|
||||||
);
|
|
||||||
box.actionManager.registerAction(
|
|
||||||
new InterpolateValueAction(
|
|
||||||
ActionManager.OnPointerOutTrigger,box, 'visibility', 1, 200
|
|
||||||
)
|
|
||||||
);*/
|
|
||||||
|
|
||||||
//const edit = new ObjectEditor(scene, box);
|
|
||||||
//const edit = new ObjectEditor(scene, box);
|
|
||||||
const ring = new Cameras(scene, this.token);
|
|
||||||
ring.getCameras().then(() => ring.createCameras());
|
|
||||||
|
|
||||||
const stickVector = Vector3.Zero();
|
|
||||||
xr.input.onControllerAddedObservable.add((source, state) => {
|
|
||||||
let controller;
|
|
||||||
switch (source.inputSource.handedness) {
|
|
||||||
case "right":
|
|
||||||
controller = new Right(source);
|
|
||||||
rig.right = controller;
|
|
||||||
controller.setBMenu(b);
|
|
||||||
break;
|
|
||||||
case "left":
|
|
||||||
controller = new Left(source);
|
|
||||||
rig.left = controller;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
xr.baseExperience.camera.position = new Vector3(0, 1.6, 0);
|
|
||||||
if (controller) {
|
|
||||||
controller.setStickVector(stickVector);
|
|
||||||
controller.setCamera(xr.baseExperience.camera);
|
|
||||||
controller.setRig(rig.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(source);
|
|
||||||
console.log(state);
|
|
||||||
});
|
|
||||||
xr.teleportation.detach();
|
xr.teleportation.detach();
|
||||||
|
|
||||||
// hide/show the Inspector
|
// hide/show the Inspector
|
||||||
@ -123,12 +81,7 @@ class App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const map = new Mapt(scene);
|
|
||||||
map.buildMapImage();
|
|
||||||
//map.createMapTiles(26.443397,-82.111512);
|
|
||||||
|
|
||||||
|
|
||||||
// run the main render loop
|
|
||||||
engine.runRenderLoop(() => {
|
engine.runRenderLoop(() => {
|
||||||
scene.render();
|
scene.render();
|
||||||
});
|
});
|
||||||
@ -142,6 +95,7 @@ class App {
|
|||||||
groundMaterial.baseTexture = gText;
|
groundMaterial.baseTexture = gText;
|
||||||
groundMaterial.metallic = 0;
|
groundMaterial.metallic = 0;
|
||||||
groundMaterial.roughness = 1;
|
groundMaterial.roughness = 1;
|
||||||
|
|
||||||
const ground = MeshBuilder.CreateGround("ground", {width: 100, height: 100, subdivisions: 1}, scene);
|
const ground = MeshBuilder.CreateGround("ground", {width: 100, height: 100, subdivisions: 1}, scene);
|
||||||
|
|
||||||
ground.material = groundMaterial;
|
ground.material = groundMaterial;
|
||||||
@ -149,5 +103,6 @@ class App {
|
|||||||
return ground;
|
return ground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new App();
|
const app = new App();
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import {PhysicsBody, Vector3, WebXRCamera, WebXRInputSource} from "@babylonjs/core";
|
import {PhysicsBody, Vector3, WebXRCamera, WebXRInputSource} from "@babylonjs/core";
|
||||||
|
import {Rigplatform} from "./rigplatform";
|
||||||
|
|
||||||
export class Base {
|
export class Base {
|
||||||
|
static stickVector = Vector3.Zero();
|
||||||
protected controller: WebXRInputSource;
|
protected controller: WebXRInputSource;
|
||||||
protected stickVector: Vector3;
|
protected rig: Rigplatform;
|
||||||
protected body: PhysicsBody;
|
|
||||||
protected camera: WebXRCamera;
|
|
||||||
protected speedFactor = 4;
|
protected speedFactor = 4;
|
||||||
|
|
||||||
constructor(controller:
|
constructor(controller:
|
||||||
@ -12,7 +12,9 @@ export class Base {
|
|||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||||
if (init.components['xr-standard-trigger']) {
|
if (init.components['xr-standard-trigger']) {
|
||||||
init.components['xr-standard-trigger'].onButtonStateChangedObservable.add((value) => {
|
init.components['xr-standard-trigger']
|
||||||
|
.onButtonStateChangedObservable
|
||||||
|
.add((value) => {
|
||||||
if (value.value == 1) {
|
if (value.value == 1) {
|
||||||
console.log(value);
|
console.log(value);
|
||||||
}
|
}
|
||||||
@ -20,16 +22,7 @@ export class Base {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
setRig(rig: Rigplatform) {
|
||||||
setRig(body: PhysicsBody) {
|
this.rig = rig;
|
||||||
this.body = body;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCamera(camera: WebXRCamera) {
|
|
||||||
this.camera = camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
setStickVector(vector: Vector3) {
|
|
||||||
this.stickVector = vector;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
import {Quaternion, Vector3, WebXRInputSource} from "@babylonjs/core";
|
import {Vector3, WebXRInputSource} from "@babylonjs/core";
|
||||||
import {Base} from "./base";
|
import {Base} from "./base";
|
||||||
|
|
||||||
export class Left extends Base {
|
export class Left extends Base {
|
||||||
private x90 = Quaternion.RotationAxis(Vector3.Up(), 1.5708);
|
|
||||||
|
|
||||||
constructor(controller:
|
constructor(controller:
|
||||||
WebXRInputSource) {
|
WebXRInputSource) {
|
||||||
@ -11,26 +11,23 @@ export class Left extends Base {
|
|||||||
if (init.components['xr-standard-thumbstick']) {
|
if (init.components['xr-standard-thumbstick']) {
|
||||||
init.components['xr-standard-thumbstick']
|
init.components['xr-standard-thumbstick']
|
||||||
.onAxisValueChangedObservable.add((value) => {
|
.onAxisValueChangedObservable.add((value) => {
|
||||||
const ray = this.camera.getForwardRay();
|
|
||||||
if (Math.abs(value.x) > .1) {
|
if (Math.abs(value.x) > .1) {
|
||||||
const direction = ray.direction.applyRotationQuaternion(this.x90).scale(value.x*this.speedFactor);
|
this.rig.leftright(value.x*this.speedFactor);
|
||||||
this.body.setLinearVelocity(direction);
|
Base.stickVector.x = 1;
|
||||||
this.stickVector.x = 1;
|
|
||||||
} else {
|
} else {
|
||||||
this.stickVector.x = 0;
|
Base.stickVector.x = 0;
|
||||||
}
|
}
|
||||||
if (Math.abs(value.y) > .1) {
|
if (Math.abs(value.y) > .1) {
|
||||||
let direction = Vector3.Zero();
|
this.rig.updown(value.y*this.speedFactor);
|
||||||
this.body.getLinearVelocityToRef(direction);
|
Base.stickVector.y = 1;
|
||||||
direction.y = (value.y*-1*this.speedFactor);
|
|
||||||
this.body.setLinearVelocity(direction);
|
|
||||||
this.stickVector.y = 1;
|
|
||||||
} else {
|
} else {
|
||||||
this.stickVector.y = 0;
|
Base.stickVector.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.stickVector.equals(Vector3.Zero())) {
|
if (Base.stickVector.equals(Vector3.Zero())) {
|
||||||
this.body.setLinearVelocity(Vector3.Zero());
|
this.rig.updown(0);
|
||||||
|
this.rig.leftright(0)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,37 @@
|
|||||||
import {Base} from "./base";
|
import {Base} from "./base";
|
||||||
import {Mesh, Vector3, WebXRInputSource} from "@babylonjs/core";
|
import {Vector3, WebXRInputSource} from "@babylonjs/core";
|
||||||
import {Bmenu} from "../menus/bmenu";
|
import {Bmenu, BmenuState} from "../menus/bmenu";
|
||||||
|
import {DiagramEvent, DiagramEventType, DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
export class Right extends Base {
|
export class Right extends Base {
|
||||||
private bmenu: Bmenu;
|
private bmenu: Bmenu;
|
||||||
private addMesh: Mesh;
|
private down: boolean = false;
|
||||||
|
|
||||||
constructor(controller:
|
constructor(controller:
|
||||||
WebXRInputSource) {
|
WebXRInputSource) {
|
||||||
super(controller);
|
super(controller);
|
||||||
|
|
||||||
this.controller.onMotionControllerInitObservable.add((init)=> {
|
this.controller.onMotionControllerInitObservable.add((init)=> {
|
||||||
|
const trigger = init.components['xr-standard-trigger'];
|
||||||
|
if (trigger) {
|
||||||
|
trigger
|
||||||
|
.onButtonStateChangedObservable
|
||||||
|
.add((value) => {
|
||||||
|
if (value.value > .4 && !this.down) {
|
||||||
|
this.down = true;
|
||||||
|
if (this.bmenu.getState() == BmenuState.ADDING) {
|
||||||
|
this.bmenu.setState(BmenuState.DROPPING);
|
||||||
|
const event: DiagramEvent = {
|
||||||
|
type: DiagramEventType.DROP,
|
||||||
|
entity: null
|
||||||
|
}
|
||||||
|
DiagramManager.onDiagramEventObservable.notifyObservers(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value.value < .05) {
|
||||||
|
this.down = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
if (init.components['b-button']) {
|
if (init.components['b-button']) {
|
||||||
init.components['b-button'].onButtonStateChangedObservable.add((value)=>{
|
init.components['b-button'].onButtonStateChangedObservable.add((value)=>{
|
||||||
if (value.pressed) {
|
if (value.pressed) {
|
||||||
@ -21,29 +43,29 @@ export class Right extends Base {
|
|||||||
if (init.components['xr-standard-thumbstick']) {
|
if (init.components['xr-standard-thumbstick']) {
|
||||||
init.components['xr-standard-thumbstick']
|
init.components['xr-standard-thumbstick']
|
||||||
.onAxisValueChangedObservable.add((value) => {
|
.onAxisValueChangedObservable.add((value) => {
|
||||||
const ray = this.camera.getForwardRay();
|
|
||||||
|
|
||||||
if (Math.abs(value.x) > .1) {
|
if (Math.abs(value.x) > .1) {
|
||||||
this.body.setAngularVelocity(Vector3.Up().scale(value.x));
|
this.rig.turn(value.x);
|
||||||
} else {
|
} else {
|
||||||
this.body.setAngularVelocity(Vector3.Zero());
|
this.rig.turn(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Math.abs(value.y) > .1) {
|
if (Math.abs(value.y) > .1) {
|
||||||
this.body.setLinearVelocity(ray.direction.scale(value.y*-1*this.speedFactor));
|
this.rig.forwardback(value.y*this.speedFactor);
|
||||||
this.stickVector.z = 1;
|
Base.stickVector.z = 1;
|
||||||
} else {
|
} else {
|
||||||
this.stickVector.z = 0;
|
Base.stickVector.z = 0;
|
||||||
}
|
}
|
||||||
if (this.stickVector.equals(Vector3.Zero())) {
|
if (Base.stickVector.equals(Vector3.Zero())) {
|
||||||
this.body.setLinearVelocity(Vector3.Zero());
|
this.rig.forwardback(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public setBMenu(menu: Bmenu) {
|
public setBMenu(menu: Bmenu) {
|
||||||
this.bmenu = menu;
|
this.bmenu = menu;
|
||||||
|
this.bmenu.setController(this.controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,30 +1,54 @@
|
|||||||
import {
|
import {
|
||||||
|
Camera,
|
||||||
Color3,
|
Color3,
|
||||||
Mesh,
|
Mesh,
|
||||||
MeshBuilder,
|
MeshBuilder,
|
||||||
PhysicsAggregate, PhysicsBody, PhysicsMotionType,
|
PhysicsAggregate,
|
||||||
PhysicsShapeType, Quaternion,
|
PhysicsBody,
|
||||||
|
PhysicsMotionType,
|
||||||
|
PhysicsShapeType,
|
||||||
|
Quaternion,
|
||||||
Scene,
|
Scene,
|
||||||
StandardMaterial,
|
StandardMaterial,
|
||||||
Vector3
|
Vector3,
|
||||||
|
WebXRDefaultExperience
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import {Right} from "./right";
|
import {Right} from "./right";
|
||||||
import {Left} from "./left";
|
import {Left} from "./left";
|
||||||
|
import {Bmenu} from "../menus/bmenu";
|
||||||
|
|
||||||
export class Rigplatform {
|
export class Rigplatform {
|
||||||
|
static LINEAR_VELOCITY = 4;
|
||||||
|
static ANGULAR_VELOCITY = 3;
|
||||||
|
public bMenu: Bmenu;
|
||||||
|
static x90 = Quaternion.RotationAxis(Vector3.Up(), 1.5708);
|
||||||
|
private camera: Camera;
|
||||||
private scene: Scene;
|
private scene: Scene;
|
||||||
|
private xr: WebXRDefaultExperience;
|
||||||
public right: Right;
|
public right: Right;
|
||||||
public left: Left;
|
public left: Left;
|
||||||
public body: PhysicsBody;
|
public body: PhysicsBody;
|
||||||
public rigMesh: Mesh;
|
public rigMesh: Mesh;
|
||||||
constructor(scene: Scene) {
|
private turning: boolean = false;
|
||||||
|
|
||||||
|
constructor(scene: Scene, xr: WebXRDefaultExperience) {
|
||||||
|
this.xr = xr;
|
||||||
|
this.bMenu = new Bmenu(scene, this.xr.baseExperience);
|
||||||
|
this.camera = scene.activeCamera;
|
||||||
|
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
|
||||||
this.rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: 1.5, height: .01}, scene);
|
this.rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: 1.5, height: .01}, scene);
|
||||||
|
|
||||||
|
for (const cam of this.scene.cameras) {
|
||||||
|
cam.parent = this.rigMesh;
|
||||||
|
}
|
||||||
|
|
||||||
const myMaterial = new StandardMaterial("myMaterial", scene);
|
const myMaterial = new StandardMaterial("myMaterial", scene);
|
||||||
myMaterial.diffuseColor = Color3.Blue();
|
myMaterial.diffuseColor = Color3.Blue();
|
||||||
this.rigMesh.material = myMaterial;
|
this.rigMesh.material = myMaterial;
|
||||||
this.rigMesh.setAbsolutePosition(new Vector3(0, .1, -3));
|
this.rigMesh.setAbsolutePosition(new Vector3(0, .1, -3));
|
||||||
this.rigMesh.visibility=0;
|
this.rigMesh.visibility = 1;
|
||||||
const rigAggregate =
|
const rigAggregate =
|
||||||
new PhysicsAggregate(
|
new PhysicsAggregate(
|
||||||
this.rigMesh,
|
this.rigMesh,
|
||||||
@ -35,6 +59,133 @@ export class Rigplatform {
|
|||||||
rigAggregate.body.setGravityFactor(0);
|
rigAggregate.body.setGravityFactor(0);
|
||||||
this.#fixRotation();
|
this.#fixRotation();
|
||||||
this.body = rigAggregate.body;
|
this.body = rigAggregate.body;
|
||||||
|
this.#setupKeyboard();
|
||||||
|
this.#initializeControllers();
|
||||||
|
this.scene.onActiveCameraChanged.add((s) => {
|
||||||
|
this.camera = s.activeCamera;
|
||||||
|
this.camera.parent = this.rigMesh;
|
||||||
|
console.log('camera changed');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#initializeControllers() {
|
||||||
|
this.xr.input.onControllerAddedObservable.add((source, state) => {
|
||||||
|
let controller;
|
||||||
|
switch (source.inputSource.handedness) {
|
||||||
|
case "right":
|
||||||
|
controller = new Right(source);
|
||||||
|
this.right = controller;
|
||||||
|
controller.setBMenu(this.bMenu);
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
controller = new Left(source);
|
||||||
|
this.left = controller;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
this.xr.baseExperience.camera.position = new Vector3(0, 1.6, 0);
|
||||||
|
if (controller) {
|
||||||
|
controller.setRig(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(source);
|
||||||
|
console.log(state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public forwardback(val: number) {
|
||||||
|
const ray = this.camera.getForwardRay();
|
||||||
|
|
||||||
|
this.body.setLinearVelocity(ray.direction.scale(val * -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public leftright(val: number) {
|
||||||
|
|
||||||
|
|
||||||
|
const ray = this.camera.getForwardRay();
|
||||||
|
const direction = ray.direction.applyRotationQuaternion(Rigplatform.x90).scale(val);
|
||||||
|
this.body.setLinearVelocity(direction);
|
||||||
|
console.log(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public stop() {
|
||||||
|
this.body.setLinearVelocity(Vector3.Zero());
|
||||||
|
this.body.setAngularVelocity(Vector3.Zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
public updown(val: number) {
|
||||||
|
let direction = Vector3.Zero();
|
||||||
|
this.body.getLinearVelocityToRef(direction);
|
||||||
|
direction.y = (val * -1);
|
||||||
|
this.body.setLinearVelocity(direction);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public turn(val: number) {
|
||||||
|
const snap = true;
|
||||||
|
if (snap) {
|
||||||
|
if (!this.turning) {
|
||||||
|
this.turning = true;
|
||||||
|
const q = this.rigMesh.rotation.y += Math.abs(val) * 22.5;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (val < .1) {
|
||||||
|
this.turning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Math.abs(val) > .1) {
|
||||||
|
this.body.setAngularVelocity(Vector3.Up().scale(val));
|
||||||
|
} else {
|
||||||
|
this.body.setAngularVelocity(Vector3.Zero());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//create a method to set the camera to the rig
|
||||||
|
|
||||||
|
#setupKeyboard() {
|
||||||
|
///simplify this with a map
|
||||||
|
|
||||||
|
window.addEventListener("keydown", (ev) => {
|
||||||
|
switch (ev.key) {
|
||||||
|
case "w":
|
||||||
|
this.forwardback(1 * Rigplatform.LINEAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case "s":
|
||||||
|
this.forwardback(-1 * Rigplatform.LINEAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case "a":
|
||||||
|
this.leftright(1 * Rigplatform.LINEAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case "d":
|
||||||
|
this.leftright(-1 * Rigplatform.LINEAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case "q":
|
||||||
|
this.turn(-1 * Rigplatform.ANGULAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case "e":
|
||||||
|
this.turn(1 * Rigplatform.ANGULAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case "W":
|
||||||
|
this.updown(-1 * Rigplatform.LINEAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case "S":
|
||||||
|
this.updown(1 * Rigplatform.LINEAR_VELOCITY);
|
||||||
|
break;
|
||||||
|
case " ":
|
||||||
|
this.bMenu.toggle()
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
window.addEventListener("keyup", (ev) => {
|
||||||
|
const keys = "wsadqeWS";
|
||||||
|
|
||||||
|
if (keys.indexOf(ev.key) > -1) {
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#fixRotation() {
|
#fixRotation() {
|
||||||
|
|||||||
2
src/diagram/diagramEntity.ts
Normal file
2
src/diagram/diagramEntity.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
||||||
140
src/diagram/diagramManager.ts
Normal file
140
src/diagram/diagramManager.ts
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import {AbstractMesh, Color3, Mesh, MeshBuilder, Observable, Scene, StandardMaterial, Vector3} from "@babylonjs/core";
|
||||||
|
import {v4 as uuidv4} from 'uuid';
|
||||||
|
import {BmenuState} from "../menus/bmenu";
|
||||||
|
|
||||||
|
|
||||||
|
export enum DiagramEventType {
|
||||||
|
ADD,
|
||||||
|
REMOVE,
|
||||||
|
MODIFY,
|
||||||
|
DROP,
|
||||||
|
DROPPED,
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
export type DiagramEvent = {
|
||||||
|
type: DiagramEventType;
|
||||||
|
menustate?: BmenuState;
|
||||||
|
entity?: DiagramEntity;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DiagramEntity = {
|
||||||
|
color?: string;
|
||||||
|
id?: string;
|
||||||
|
last_seen?: Date;
|
||||||
|
position?: Vector3;
|
||||||
|
rotation?: Vector3;
|
||||||
|
template?: string;
|
||||||
|
text?: string;
|
||||||
|
scale?: Vector3;
|
||||||
|
parent?: string;
|
||||||
|
}
|
||||||
|
export class DiagramManager {
|
||||||
|
static onDiagramEventObservable = new Observable();
|
||||||
|
static leftController: Mesh;
|
||||||
|
static currentMesh: AbstractMesh;
|
||||||
|
static rightController: Mesh;
|
||||||
|
static state: BmenuState;
|
||||||
|
private scene: Scene;
|
||||||
|
|
||||||
|
constructor(scene: Scene) {
|
||||||
|
this.scene = scene;
|
||||||
|
if (DiagramManager.onDiagramEventObservable.hasObservers()) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DiagramManager.onDiagramEventObservable.add(this.#onDiagramEvent, -1, true, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#onDiagramEvent(event: DiagramEvent) {
|
||||||
|
console.log(event);
|
||||||
|
const entity = event.entity;
|
||||||
|
|
||||||
|
let mesh;
|
||||||
|
|
||||||
|
let material
|
||||||
|
if (entity) {
|
||||||
|
mesh = this.scene.getMeshByName(entity.id);
|
||||||
|
material = this.scene.getMaterialByName("material-"+entity.id);
|
||||||
|
if (!material){
|
||||||
|
material = new StandardMaterial("material-"+event.entity.id, this.scene);
|
||||||
|
material.ambientColor = Color3.FromHexString(event.entity.color.replace("#",""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case DiagramEventType.DROPPED:
|
||||||
|
break;
|
||||||
|
case DiagramEventType.DROP:
|
||||||
|
if (DiagramManager.currentMesh) {
|
||||||
|
const newMesh = DiagramManager.currentMesh.clone(DiagramManager.currentMesh.name = "id" + uuidv4(), DiagramManager.currentMesh.parent);
|
||||||
|
DiagramManager.currentMesh.setParent(null);
|
||||||
|
DiagramManager.currentMesh = newMesh;
|
||||||
|
DiagramManager.onDiagramEventObservable.notifyObservers({type: DiagramEventType.DROPPED, entity: entity});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DiagramEventType.ADD:
|
||||||
|
if (mesh) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
mesh = this.#createMesh(entity);
|
||||||
|
if (!mesh) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case DiagramEventType.MODIFY:
|
||||||
|
if (!mesh) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const rotation = entity.rotation;
|
||||||
|
const scale = entity.scale;
|
||||||
|
const position = entity.position;
|
||||||
|
|
||||||
|
mesh.material = material;
|
||||||
|
mesh.position = new Vector3(position.x, position.y, position.z);
|
||||||
|
mesh.rotation = new Vector3(rotation.x, rotation.y, rotation.z);
|
||||||
|
|
||||||
|
if (entity.parent) {
|
||||||
|
mesh.parent = this.scene.getMeshByName(entity.parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DiagramManager.currentMesh = mesh;
|
||||||
|
break;
|
||||||
|
case DiagramEventType.REMOVE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#createMesh(entity: DiagramEntity) {
|
||||||
|
if (!entity.id) {
|
||||||
|
entity.id = "id" + uuidv4();
|
||||||
|
}
|
||||||
|
let mesh: Mesh;
|
||||||
|
switch (entity.template) {
|
||||||
|
case "#box-template":
|
||||||
|
mesh = MeshBuilder.CreateBox( entity.id,
|
||||||
|
{width: entity.scale.x,
|
||||||
|
height: entity.scale.y,
|
||||||
|
depth: entity.scale.z}, this.scene);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "#sphere-template":
|
||||||
|
|
||||||
|
mesh= MeshBuilder.CreateSphere(entity.id, {diameter: entity.scale.x}, this.scene);
|
||||||
|
break
|
||||||
|
case "#cylinder-template":
|
||||||
|
mesh= MeshBuilder.CreateCylinder(entity.id, {diameter: entity.scale.x, height: entity.scale.y}, this.scene);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mesh = null;
|
||||||
|
}
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1,28 +1,44 @@
|
|||||||
import {Angle, FadeInOutBehavior, Scene, TransformNode, Vector3, WebXRExperienceHelper} from "@babylonjs/core";
|
|
||||||
import {
|
import {
|
||||||
Container3D,
|
AbstractMesh,
|
||||||
CylinderPanel,
|
Angle,
|
||||||
GUI3DManager,
|
Color3, Mesh,
|
||||||
HandMenu,
|
MeshBuilder,
|
||||||
HolographicButton, HolographicSlate,
|
Scene, SceneSerializer,
|
||||||
NearMenu, PlanePanel,
|
StandardMaterial,
|
||||||
SpherePanel
|
TransformNode, Vector3,
|
||||||
} from "@babylonjs/gui";
|
WebXRExperienceHelper, WebXRInputSource
|
||||||
import {Rigplatform} from "../controllers/rigplatform";
|
} from "@babylonjs/core";
|
||||||
|
import {GUI3DManager, HolographicButton, PlanePanel} from "@babylonjs/gui";
|
||||||
|
import {DiagramEntity, DiagramEvent, DiagramEventType, DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
|
export enum BmenuState {
|
||||||
|
NONE,
|
||||||
|
ADDING, // Adding a new entity
|
||||||
|
DROPPING, // Dropping an entity
|
||||||
|
|
||||||
|
}
|
||||||
export class Bmenu {
|
export class Bmenu {
|
||||||
private scene;
|
private scene;
|
||||||
private rig;
|
private state: BmenuState = BmenuState.NONE;
|
||||||
|
|
||||||
private xr;
|
private xr;
|
||||||
private manager;
|
private manager;
|
||||||
private panel;
|
private panel;
|
||||||
constructor(scene: Scene, rig: Rigplatform, xr: WebXRExperienceHelper) {
|
private rightController: AbstractMesh;
|
||||||
|
|
||||||
|
constructor(scene: Scene, xr: WebXRExperienceHelper) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.rig = rig;
|
|
||||||
this.manager = new GUI3DManager(scene);
|
this.manager = new GUI3DManager(scene);
|
||||||
this.xr = xr;
|
this.xr = xr;
|
||||||
|
DiagramManager.onDiagramEventObservable.add((event: DiagramEvent) => {
|
||||||
|
if (event.type === DiagramEventType.DROPPED) {
|
||||||
|
this.state = BmenuState.ADDING;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setController(controller: WebXRInputSource) {
|
||||||
|
this.rightController = controller.grip;
|
||||||
}
|
}
|
||||||
|
|
||||||
makeButton(name: string, id: string) {
|
makeButton(name: string, id: string) {
|
||||||
const button = new HolographicButton(name);
|
const button = new HolographicButton(name);
|
||||||
button.text = name;
|
button.text = name;
|
||||||
@ -30,13 +46,62 @@ export class Bmenu {
|
|||||||
button.onPointerClickObservable.add(this.#clickhandler, -1, false, this);
|
button.onPointerClickObservable.add(this.#clickhandler, -1, false, this);
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
#clickhandler(_info, state) {
|
#clickhandler(_info, state) {
|
||||||
console.log(state.currentTarget.name);
|
console.log(state.currentTarget.name);
|
||||||
|
|
||||||
|
let entity: DiagramEntity = {
|
||||||
|
template: null,
|
||||||
|
position: new Vector3(0,-.040,.13),
|
||||||
|
rotation: new Vector3(),
|
||||||
|
scale: new Vector3(.1, .1, .1),
|
||||||
|
color: "#CEE",
|
||||||
|
text: "test",
|
||||||
|
last_seen: new Date(),
|
||||||
|
parent: this.rightController.id
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (state.currentTarget.name) {
|
||||||
|
case "addBox":
|
||||||
|
entity.template = "#box-template";
|
||||||
|
break;
|
||||||
|
case "addSphere":
|
||||||
|
entity.template = "#sphere-template";
|
||||||
|
break;
|
||||||
|
case "addCylinder":
|
||||||
|
entity.template = "#cylinder-template";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("Unknown button");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const event: DiagramEvent = {
|
||||||
|
type: DiagramEventType.ADD,
|
||||||
|
entity: entity
|
||||||
|
}
|
||||||
|
this.state = BmenuState.ADDING;
|
||||||
|
DiagramManager.onDiagramEventObservable.notifyObservers(event);
|
||||||
|
}
|
||||||
|
public getState() {
|
||||||
|
return this.state;
|
||||||
|
}
|
||||||
|
public setState(state: BmenuState) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createDefaultMaterial() {
|
||||||
|
|
||||||
|
const myMaterial = new StandardMaterial("myMaterial", this.scene);
|
||||||
|
myMaterial.diffuseColor = Color3.FromHexString("#CEE");
|
||||||
|
return myMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
toggle() {
|
toggle() {
|
||||||
if (this.panel) {
|
if (this.panel) {
|
||||||
this.panel.dispose();
|
this.panel.dispose();
|
||||||
this.panel = null;
|
this.panel = null;
|
||||||
|
this.setState(BmenuState.NONE);
|
||||||
} else {
|
} else {
|
||||||
const anchor = new TransformNode("bMenuAnchor");
|
const anchor = new TransformNode("bMenuAnchor");
|
||||||
anchor.rotation.y = Angle.FromDegrees(180).radians();
|
anchor.rotation.y = Angle.FromDegrees(180).radians();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user