From ed9bf360070ad60b3336b043b88bbcbd3d682d07 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Fri, 23 Jun 2023 05:51:28 -0500 Subject: [PATCH] Initial Menu System Commit. --- package-lock.json | 8 ++-- package.json | 1 + src/app.ts | 74 +++++++++++++--------------------- src/controllers/base.ts | 3 +- src/controllers/left.ts | 1 - src/controllers/right.ts | 21 ++++++---- src/controllers/rigplatform.ts | 41 +++++++++++++++++++ src/menus/bmenu.ts | 36 +++++++++++++++++ 8 files changed, 123 insertions(+), 62 deletions(-) create mode 100644 src/controllers/rigplatform.ts create mode 100644 src/menus/bmenu.ts diff --git a/package-lock.json b/package-lock.json index 0f67f06..c20c7e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@auth0/auth0-spa-js": "^2.0.8", "@babylonjs/core": "^6.8.0", + "@babylonjs/gui": "^6.9.0", "@babylonjs/havok": "^1.0.1", "@babylonjs/inspector": "^6.8.0", "express": "^4.18.2" @@ -31,10 +32,9 @@ "integrity": "sha512-wTWj9TsnVGqfXt+tXKi7+SIWi4MzBMwIq+jcylRR1qzHTHFfMuKrRRLZJ5jQtpAhcDPI2TOuJ3/NOccPyawlgQ==" }, "node_modules/@babylonjs/gui": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-6.8.0.tgz", - "integrity": "sha512-zp1Kidc0RIZ0z8yiC4bdzYtNtqzbQQzOroYeHClJOQHSxl1ksRGWaCOOph89NgRatP5dJIZFw4jlqbPU6Avj8w==", - "peer": true, + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-6.9.0.tgz", + "integrity": "sha512-RcVorxsj6n2EbwkBJYPBqF88Rybd3OHbx55runbMSehb9rKhc6d2QIiXTi7yI2oBNyuQBsDxx+ky58Rur2UXww==", "peerDependencies": { "@babylonjs/core": "^6.0.0" } diff --git a/package.json b/package.json index 2f4226b..17603eb 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@babylonjs/core": "^6.8.0", + "@babylonjs/gui": "^6.9.0", "@babylonjs/havok": "^1.0.1", "@babylonjs/inspector": "^6.8.0", "express": "^4.18.2", diff --git a/src/app.ts b/src/app.ts index b196b4a..174ef0f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -7,7 +7,7 @@ import { HavokPlugin, HemisphericLight, Mesh, - MeshBuilder, PBRMaterial, PBRMetallicRoughnessMaterial, + MeshBuilder, PBRMetallicRoughnessMaterial, PhotoDome, PhysicsAggregate, PhysicsShapeType, Quaternion, @@ -18,79 +18,43 @@ import { import {Right} from "./controllers/right"; import {Left} from "./controllers/left"; import {havokModule} from "./util/havok"; +import {Bmenu} from "./menus/bmenu"; +import {Rigplatform} from "./controllers/rigplatform"; class App { preTasks = [havokModule]; constructor() { - this.initialize(); - } - - async initialize() { - // create the canvas html element and attach it to the webpage const canvas = document.createElement("canvas"); canvas.style.width = "100%"; canvas.style.height = "100%"; canvas.id = "gameCanvas"; document.body.appendChild(canvas); + this.initialize(canvas); + } - // initialize babylon scene and engine + async initialize(canvas) { const engine = new Engine(canvas, true); const scene = new Scene(engine); const hk = new HavokPlugin(true, await havokModule); scene.enablePhysics(new Vector3(0 , -9.8, 0), hk); - const camera: ArcRotateCamera = new ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new Vector3(0, 1.6, 0), scene); camera.attachControl(canvas, true); - const light1: HemisphericLight = new HemisphericLight("light1", new Vector3(1, 1, 0), scene); - const sphere: Mesh = MeshBuilder.CreateCylinder("sphere", {diameter: 1}, scene); - sphere.setAbsolutePosition(new Vector3(0, 2, -5)); + new HemisphericLight("light1", new Vector3(1, 1, 0), scene); - const cylinder: Mesh = MeshBuilder.CreateCylinder("platform", {diameter: 1.5, height: .01}, scene); - const myMaterial = new StandardMaterial("myMaterial", scene); - myMaterial.diffuseColor = Color3.Blue(); - cylinder.material = myMaterial; - cylinder.setAbsolutePosition(new Vector3(0, .1, -3)); - const sphereAggregate = - new PhysicsAggregate( - cylinder, - PhysicsShapeType.CYLINDER, - { friction: 1, center: Vector3.Zero(), radius: .5, mass: .1, restitution: .1}, - scene); + const rig = new Rigplatform(scene); - sphereAggregate.body.setGravityFactor(0); - - //sphereAggregate.body.applyForce(new Vector3(0, 0,-1), cylinder.position); const photoDome = new PhotoDome('sky', './outdoor_field.jpeg', {}, scene); - const groundMaterial = new PBRMetallicRoughnessMaterial("groundMaterial", scene); - const gText = new Texture("./grass1.jpeg", scene); - gText.uScale =40; - gText.vScale=40; - scene.registerBeforeRender(() => { - const q = cylinder.rotationQuaternion; - const e = q.toEulerAngles(); - q.copyFrom(Quaternion.FromEulerAngles(0, e.y, 0)); - }); - - groundMaterial.baseTexture = gText; - groundMaterial.metallic =0; - groundMaterial.roughness=1; - const ground = MeshBuilder.CreateGround("ground", {width: 100, height: 100, subdivisions: 1}, scene); - - ground.material = groundMaterial; - const groundAggregate = new PhysicsAggregate(ground, PhysicsShapeType.BOX, {mass: 0}, scene); - - const xr = await WebXRDefaultExperience.CreateAsync(scene, {floorMeshes: [ground], + const xr = await WebXRDefaultExperience.CreateAsync(scene, {floorMeshes: [this.createGround(scene)], optionalFeatures: true}); - xr.baseExperience.camera.parent = cylinder; + xr.baseExperience.camera.parent = rig.rigMesh; const stickVector = Vector3.Zero(); - xr.input.onControllerAddedObservable.add((source, state) => { let controller; switch (source.inputSource.handedness) { @@ -106,7 +70,7 @@ class App { if (controller) { controller.setStickVector(stickVector); controller.setCamera(xr.baseExperience.camera); - controller.setRig(sphereAggregate.body); + controller.setRig(rig.body); } console.log(source); @@ -125,12 +89,28 @@ class App { } } }); + const b = new Bmenu(scene, rig); // run the main render loop engine.runRenderLoop(() => { scene.render(); }); } + createGround(scene) { + const groundMaterial = new PBRMetallicRoughnessMaterial("groundMaterial", scene); + const gText = new Texture("./grass1.jpeg", scene); + gText.uScale =40; + gText.vScale=40; + groundMaterial.baseTexture = gText; + groundMaterial.metallic =0; + groundMaterial.roughness=1; + const ground = MeshBuilder.CreateGround("ground", {width: 100, height: 100, subdivisions: 1}, scene); + + ground.material = groundMaterial; + const groundAggregate = new PhysicsAggregate(ground, PhysicsShapeType.BOX, {mass: 0}, scene); + return ground; + + } } new App(); \ No newline at end of file diff --git a/src/controllers/base.ts b/src/controllers/base.ts index 946e608..c931578 100644 --- a/src/controllers/base.ts +++ b/src/controllers/base.ts @@ -1,4 +1,4 @@ -import {Observable, PhysicsBody, Scene, Vector3, WebXRCamera, WebXRInputSource} from "@babylonjs/core"; +import {PhysicsBody, Vector3, WebXRCamera, WebXRInputSource} from "@babylonjs/core"; export class Base { protected controller: WebXRInputSource; @@ -19,5 +19,4 @@ export class Base { setStickVector(vector: Vector3) { this.stickVector = vector; } - } \ No newline at end of file diff --git a/src/controllers/left.ts b/src/controllers/left.ts index 71ba0e1..dc8fcf4 100644 --- a/src/controllers/left.ts +++ b/src/controllers/left.ts @@ -2,7 +2,6 @@ import {Quaternion, Vector3, WebXRInputSource} from "@babylonjs/core"; import {Base} from "./base"; export class Left extends Base { - private y90 = Quaternion.RotationAxis(Vector3.Right(), 1.5708); private x90 = Quaternion.RotationAxis(Vector3.Up(), 1.5708); constructor(controller: diff --git a/src/controllers/right.ts b/src/controllers/right.ts index df58d82..86d259b 100644 --- a/src/controllers/right.ts +++ b/src/controllers/right.ts @@ -1,15 +1,20 @@ import {Base} from "./base"; -import {Observer, Quaternion, Vector3, WebXRInputSource} from "@babylonjs/core"; -import {Logger} from "../util/logger"; +import {Vector3, WebXRInputSource} from "@babylonjs/core"; export class Right extends Base { - public stickY; - public stickX; - + private bmenu: any; constructor(controller: WebXRInputSource) { super(controller); + this.controller.onMotionControllerInitObservable.add((init)=> { + if (init.components['b-button']) { + init.components['b-button'].onButtonStateChangedObservable.add((value)=>{ + if (value.pressed) { + + } + }); + } if (init.components['xr-standard-thumbstick']) { init.components['xr-standard-thumbstick'] .onAxisValueChangedObservable.add((value) => { @@ -24,17 +29,17 @@ export class Right extends Base { this.stickVector.z = 1; } else { this.stickVector.z = 0; - } if (this.stickVector.equals(Vector3.Zero())) { this.body.setLinearVelocity(Vector3.Zero()); } - - }); } }); } + public setBMenu(menu: any) { + this.bmenu = menu; + } } \ No newline at end of file diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts new file mode 100644 index 0000000..3718320 --- /dev/null +++ b/src/controllers/rigplatform.ts @@ -0,0 +1,41 @@ +import { + Color3, + Mesh, + MeshBuilder, + PhysicsAggregate, PhysicsBody, + PhysicsShapeType, Quaternion, + Scene, + StandardMaterial, + Vector3 +} from "@babylonjs/core"; + +export class Rigplatform { + private scene: Scene; + public body: PhysicsBody; + public rigMesh: Mesh; + constructor(scene: Scene) { + this.scene = scene; + this.rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: 1.5, height: .01}, scene); + const myMaterial = new StandardMaterial("myMaterial", scene); + myMaterial.diffuseColor = Color3.Blue(); + this.rigMesh.material = myMaterial; + this.rigMesh.setAbsolutePosition(new Vector3(0, .1, -3)); + const rigAggregate = + new PhysicsAggregate( + this.rigMesh, + PhysicsShapeType.CYLINDER, + { friction: 1, center: Vector3.Zero(), radius: .5, mass: .1, restitution: .1}, + scene); + + rigAggregate.body.setGravityFactor(0); + this.#fixRotation(); + this.body = rigAggregate.body; + } + #fixRotation() { + this.scene.registerBeforeRender(() => { + const q = this.rigMesh.rotationQuaternion; + const e = q.toEulerAngles(); + q.copyFrom(Quaternion.FromEulerAngles(0, e.y, 0)); + }); + } +} \ No newline at end of file diff --git a/src/menus/bmenu.ts b/src/menus/bmenu.ts new file mode 100644 index 0000000..1c37bf8 --- /dev/null +++ b/src/menus/bmenu.ts @@ -0,0 +1,36 @@ +import {Angle, Scene, TransformNode, Vector3} from "@babylonjs/core"; +import {Container3D, CylinderPanel, GUI3DManager, HolographicButton, SpherePanel} from "@babylonjs/gui"; +import {Rigplatform} from "../controllers/rigplatform"; + +export class Bmenu { + private scene; + constructor(scene: Scene, rig: Rigplatform) { + const anchor = new TransformNode("bMenuAnchor"); + anchor.rotation.y = Angle.FromDegrees(180).radians(); + //anchor.position = rig.rigMesh.position; + //anchor.rotation = new Vector3(0 , Angle.FromDegrees(180).radians(), 0); + this.scene = scene; + const manager = new GUI3DManager(scene); + const panel = new CylinderPanel(); + panel.margin=.6; + panel.scaling.y=.5; + //panel.orientation = Container3D.FACEFORWARDREVERSED_ORIENTATION; + panel.radius = 2; + panel.columns = 8; + manager.addControl(panel); + panel.linkToTransformNode(anchor); + panel.position.z = 2; + panel.position.y = 4; + for (var i = 0; i < 10; i++) { + panel.addControl(this.makeButton("Button " + i)); + } + + + + } + makeButton(name: string) { + const button = new HolographicButton(name); + button.text = name; + return button; + } +} \ No newline at end of file