Optimize WebXR performance and add procedural planet generation
Some checks failed
Build / build (push) Failing after 4m43s
Enable multiview rendering in WebXR for improved framerate, remove expensive PhotoDome per-frame updates, and add planet generation system with 76 unique textures across 12 planet types. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
58
package-lock.json
generated
@ -24,9 +24,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/addons": {
|
"node_modules/@babylonjs/addons": {
|
||||||
"version": "8.32.0",
|
"version": "8.32.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/addons/-/addons-8.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/addons/-/addons-8.32.1.tgz",
|
||||||
"integrity": "sha512-mv3rF6slOYcArpQbWJzVlN7Qb71/um4HpZRYIyA37wmmoX1behxk+1Of9J6PqdrwLQjng9e8gxfrIA1OUxIEpw==",
|
"integrity": "sha512-FAPhpiE7tZvmVX6DiKbRmM/koOUrvBItYGKDWyXikaV9ftkOfQNi82Oz9s08WdmIsItE6jUmNT3Kc7+T5JDeSg==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^8.0.0"
|
"@babylonjs/core": "^8.0.0"
|
||||||
@ -38,17 +38,17 @@
|
|||||||
"integrity": "sha512-Z83WIe2eZEAOo5bb9Tjd+lY4ru6N8qgtZJGjWcoXOiP3BrtbatPUXdVKqm7m60ItQABFaVdMGygvIXY+wNXU/Q=="
|
"integrity": "sha512-Z83WIe2eZEAOo5bb9Tjd+lY4ru6N8qgtZJGjWcoXOiP3BrtbatPUXdVKqm7m60ItQABFaVdMGygvIXY+wNXU/Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/gui": {
|
"node_modules/@babylonjs/gui": {
|
||||||
"version": "8.32.0",
|
"version": "8.32.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-8.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-8.32.1.tgz",
|
||||||
"integrity": "sha512-nR+E3u3hgGky+/6k1h8F5B4tS4OW6x3y63hf88kS3GgANd8as2iL54NC1Z74a25/8/nlaSRhodEYwx5O7lZKlQ==",
|
"integrity": "sha512-KTAtDYK4JUsqfgnLxQ1tVu5PU8nQr2VJupT5wlojQkLmsmP1pyiTMQ7r00BcJUiZQu+0MJBS4yQ+6WDBS8NWiA==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^8.0.0"
|
"@babylonjs/core": "^8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/gui-editor": {
|
"node_modules/@babylonjs/gui-editor": {
|
||||||
"version": "8.32.0",
|
"version": "8.32.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/gui-editor/-/gui-editor-8.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/gui-editor/-/gui-editor-8.32.1.tgz",
|
||||||
"integrity": "sha512-sRql2tCW+dUulQxWbzSOskGsgDUGYHJ5mM0eLbsKPFTCggURse3drNtynOw/24dO/OCaES0zO0Ob/nDH0qrFxA==",
|
"integrity": "sha512-cPm9bfBEksZXtZ3NgDYkvIcimEAaAOqDdhTZC2EWLUks6fVAZgheGa4IxV5zHQxpl9djhxqKDJPS4I1zFUw2IQ==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^8.0.0",
|
"@babylonjs/core": "^8.0.0",
|
||||||
@ -489,45 +489,41 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fortawesome/fontawesome-common-types": {
|
"node_modules/@fortawesome/fontawesome-common-types": {
|
||||||
"version": "6.5.2",
|
"version": "6.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz",
|
||||||
"integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==",
|
"integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==",
|
||||||
"hasInstallScript": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fortawesome/fontawesome-svg-core": {
|
"node_modules/@fortawesome/fontawesome-svg-core": {
|
||||||
"version": "6.5.2",
|
"version": "6.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz",
|
||||||
"integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==",
|
"integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==",
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
"@fortawesome/fontawesome-common-types": "6.7.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fortawesome/free-regular-svg-icons": {
|
"node_modules/@fortawesome/free-regular-svg-icons": {
|
||||||
"version": "6.5.2",
|
"version": "6.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.7.2.tgz",
|
||||||
"integrity": "sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw==",
|
"integrity": "sha512-7Z/ur0gvCMW8G93dXIQOkQqHo2M5HLhYrRVC0//fakJXxcF1VmMPsxnG6Ee8qEylA8b8Q3peQXWMNZ62lYF28g==",
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
"@fortawesome/fontawesome-common-types": "6.7.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fortawesome/free-solid-svg-icons": {
|
"node_modules/@fortawesome/free-solid-svg-icons": {
|
||||||
"version": "6.5.2",
|
"version": "6.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz",
|
||||||
"integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==",
|
"integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==",
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
"@fortawesome/fontawesome-common-types": "6.7.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@ -815,9 +811,9 @@
|
|||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
},
|
},
|
||||||
"node_modules/babylonjs-gltf2interface": {
|
"node_modules/babylonjs-gltf2interface": {
|
||||||
"version": "8.32.0",
|
"version": "8.32.1",
|
||||||
"resolved": "https://registry.npmjs.org/babylonjs-gltf2interface/-/babylonjs-gltf2interface-8.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/babylonjs-gltf2interface/-/babylonjs-gltf2interface-8.32.1.tgz",
|
||||||
"integrity": "sha512-OECfOlxbIXHp4kYzqZNj42e0I5MfVAmgAgBkQaFGJdojK+hc/iIg9LQfAhYbKjr+Rpb1v1HnQ8tWBjXLwgtyXg==",
|
"integrity": "sha512-GfpzooetdbFU22X75SvWzAMjzfkdypzB4WtG5Y+F2UGFf0CUa9PCftwTiH2wJFaE+OQDXF6+l4rgwZCIjOSUCw==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
|
|||||||
BIN
public/planetTextures/Arid/Arid_01-512x512.png
Normal file
|
After Width: | Height: | Size: 573 KiB |
BIN
public/planetTextures/Arid/Arid_02-512x512.png
Normal file
|
After Width: | Height: | Size: 565 KiB |
BIN
public/planetTextures/Arid/Arid_03-512x512.png
Normal file
|
After Width: | Height: | Size: 585 KiB |
BIN
public/planetTextures/Arid/Arid_04-512x512.png
Normal file
|
After Width: | Height: | Size: 560 KiB |
BIN
public/planetTextures/Arid/Arid_05-512x512.png
Normal file
|
After Width: | Height: | Size: 570 KiB |
BIN
public/planetTextures/Barren/Barren_01-512x512.png
Normal file
|
After Width: | Height: | Size: 352 KiB |
BIN
public/planetTextures/Barren/Barren_02-512x512.png
Normal file
|
After Width: | Height: | Size: 360 KiB |
BIN
public/planetTextures/Barren/Barren_03-512x512.png
Normal file
|
After Width: | Height: | Size: 347 KiB |
BIN
public/planetTextures/Barren/Barren_04-512x512.png
Normal file
|
After Width: | Height: | Size: 359 KiB |
BIN
public/planetTextures/Barren/Barren_05-512x512.png
Normal file
|
After Width: | Height: | Size: 374 KiB |
BIN
public/planetTextures/Dusty/Dusty_01-512x512.png
Normal file
|
After Width: | Height: | Size: 567 KiB |
BIN
public/planetTextures/Dusty/Dusty_02-512x512.png
Normal file
|
After Width: | Height: | Size: 564 KiB |
BIN
public/planetTextures/Dusty/Dusty_03-512x512.png
Normal file
|
After Width: | Height: | Size: 572 KiB |
BIN
public/planetTextures/Dusty/Dusty_04-512x512.png
Normal file
|
After Width: | Height: | Size: 573 KiB |
BIN
public/planetTextures/Dusty/Dusty_05-512x512.png
Normal file
|
After Width: | Height: | Size: 560 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_01-512x512.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_02-512x512.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_03-512x512.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_04-512x512.png
Normal file
|
After Width: | Height: | Size: 171 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_05-512x512.png
Normal file
|
After Width: | Height: | Size: 168 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_06-512x512.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_07-512x512.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_08-512x512.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_09-512x512.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_10-512x512.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_11-512x512.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_12-512x512.png
Normal file
|
After Width: | Height: | Size: 201 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_13-512x512.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_14-512x512.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_15-512x512.png
Normal file
|
After Width: | Height: | Size: 166 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_16-512x512.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_17-512x512.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_18-512x512.png
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_19-512x512.png
Normal file
|
After Width: | Height: | Size: 145 KiB |
BIN
public/planetTextures/Gaseous/Gaseous_20-512x512.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
public/planetTextures/Grassland/Grassland_01-512x512.png
Normal file
|
After Width: | Height: | Size: 678 KiB |
BIN
public/planetTextures/Grassland/Grassland_02-512x512.png
Normal file
|
After Width: | Height: | Size: 626 KiB |
BIN
public/planetTextures/Grassland/Grassland_03-512x512.png
Normal file
|
After Width: | Height: | Size: 670 KiB |
BIN
public/planetTextures/Grassland/Grassland_04-512x512.png
Normal file
|
After Width: | Height: | Size: 675 KiB |
BIN
public/planetTextures/Grassland/Grassland_05-512x512.png
Normal file
|
After Width: | Height: | Size: 666 KiB |
BIN
public/planetTextures/Jungle/Jungle_01-512x512.png
Normal file
|
After Width: | Height: | Size: 634 KiB |
BIN
public/planetTextures/Jungle/Jungle_02-512x512.png
Normal file
|
After Width: | Height: | Size: 602 KiB |
BIN
public/planetTextures/Jungle/Jungle_03-512x512.png
Normal file
|
After Width: | Height: | Size: 614 KiB |
BIN
public/planetTextures/Jungle/Jungle_04-512x512.png
Normal file
|
After Width: | Height: | Size: 600 KiB |
BIN
public/planetTextures/Jungle/Jungle_05-512x512.png
Normal file
|
After Width: | Height: | Size: 656 KiB |
BIN
public/planetTextures/Marshy/Marshy_01-512x512.png
Normal file
|
After Width: | Height: | Size: 710 KiB |
BIN
public/planetTextures/Marshy/Marshy_02-512x512.png
Normal file
|
After Width: | Height: | Size: 714 KiB |
BIN
public/planetTextures/Marshy/Marshy_03-512x512.png
Normal file
|
After Width: | Height: | Size: 713 KiB |
BIN
public/planetTextures/Marshy/Marshy_04-512x512.png
Normal file
|
After Width: | Height: | Size: 727 KiB |
BIN
public/planetTextures/Marshy/Marshy_05-512x512.png
Normal file
|
After Width: | Height: | Size: 713 KiB |
BIN
public/planetTextures/Martian/Martian_01-512x512.png
Normal file
|
After Width: | Height: | Size: 517 KiB |
BIN
public/planetTextures/Martian/Martian_02-512x512.png
Normal file
|
After Width: | Height: | Size: 515 KiB |
BIN
public/planetTextures/Martian/Martian_03-512x512.png
Normal file
|
After Width: | Height: | Size: 526 KiB |
BIN
public/planetTextures/Martian/Martian_04-512x512.png
Normal file
|
After Width: | Height: | Size: 517 KiB |
BIN
public/planetTextures/Martian/Martian_05-512x512.png
Normal file
|
After Width: | Height: | Size: 526 KiB |
BIN
public/planetTextures/Methane/Methane_01-512x512.png
Normal file
|
After Width: | Height: | Size: 656 KiB |
BIN
public/planetTextures/Methane/Methane_02-512x512.png
Normal file
|
After Width: | Height: | Size: 663 KiB |
BIN
public/planetTextures/Methane/Methane_03-512x512.png
Normal file
|
After Width: | Height: | Size: 648 KiB |
BIN
public/planetTextures/Methane/Methane_04-512x512.png
Normal file
|
After Width: | Height: | Size: 665 KiB |
BIN
public/planetTextures/Methane/Methane_05-512x512.png
Normal file
|
After Width: | Height: | Size: 670 KiB |
BIN
public/planetTextures/Sandy/Sandy_01-512x512.png
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
public/planetTextures/Sandy/Sandy_02-512x512.png
Normal file
|
After Width: | Height: | Size: 327 KiB |
BIN
public/planetTextures/Sandy/Sandy_03-512x512.png
Normal file
|
After Width: | Height: | Size: 336 KiB |
BIN
public/planetTextures/Sandy/Sandy_04-512x512.png
Normal file
|
After Width: | Height: | Size: 325 KiB |
BIN
public/planetTextures/Sandy/Sandy_05-512x512.png
Normal file
|
After Width: | Height: | Size: 421 KiB |
BIN
public/planetTextures/Snowy/Snowy_01-512x512.png
Normal file
|
After Width: | Height: | Size: 576 KiB |
BIN
public/planetTextures/Snowy/Snowy_02-512x512.png
Normal file
|
After Width: | Height: | Size: 589 KiB |
BIN
public/planetTextures/Snowy/Snowy_03-512x512.png
Normal file
|
After Width: | Height: | Size: 591 KiB |
BIN
public/planetTextures/Snowy/Snowy_04-512x512.png
Normal file
|
After Width: | Height: | Size: 605 KiB |
BIN
public/planetTextures/Snowy/Snowy_05-512x512.png
Normal file
|
After Width: | Height: | Size: 585 KiB |
BIN
public/planetTextures/Tundra/Tundra_01-512x512.png
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
public/planetTextures/Tundra/Tundra_02-512x512.png
Normal file
|
After Width: | Height: | Size: 374 KiB |
BIN
public/planetTextures/Tundra/Tundra_03-512x512.png
Normal file
|
After Width: | Height: | Size: 389 KiB |
BIN
public/planetTextures/Tundra/Tundra_04-512x512.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
|
After Width: | Height: | Size: 396 KiB |
159
src/controllerDebug.ts
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
import {
|
||||||
|
Engine,
|
||||||
|
Scene,
|
||||||
|
HemisphericLight,
|
||||||
|
Vector3,
|
||||||
|
MeshBuilder,
|
||||||
|
WebXRDefaultExperience,
|
||||||
|
Color3
|
||||||
|
} from "@babylonjs/core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal standalone class to debug WebXR controller detection
|
||||||
|
* Usage: import and instantiate in main.ts instead of normal flow
|
||||||
|
*/
|
||||||
|
export class ControllerDebug {
|
||||||
|
private engine: Engine;
|
||||||
|
private scene: Scene;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
console.log('🔍 ControllerDebug: Starting minimal test...');
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async init() {
|
||||||
|
// Get canvas
|
||||||
|
const canvas = document.querySelector('#gameCanvas') as HTMLCanvasElement;
|
||||||
|
|
||||||
|
// Create engine (no antialiasing for Quest compatibility)
|
||||||
|
console.log('🔍 Creating engine...');
|
||||||
|
this.engine = new Engine(canvas, false);
|
||||||
|
|
||||||
|
// Create scene
|
||||||
|
console.log('🔍 Creating scene...');
|
||||||
|
this.scene = new Scene(this.engine);
|
||||||
|
this.scene.clearColor = new Color3(0.1, 0.1, 0.2).toColor4();
|
||||||
|
|
||||||
|
// Add light
|
||||||
|
//const light = new HemisphericLight("light", new Vector3(0, 1, 0), this.scene);
|
||||||
|
|
||||||
|
// Add ground for reference
|
||||||
|
const ground = MeshBuilder.CreateGround("ground", { width: 10, height: 10 }, this.scene);
|
||||||
|
|
||||||
|
// Create WebXR
|
||||||
|
//consol e.log('🔍 Creating WebXR...');
|
||||||
|
//await navigator.xr.offerSession("immersive-vr");
|
||||||
|
const xr = await this.scene.createDefaultXRExperienceAsync( {
|
||||||
|
disablePointerSelection: true,
|
||||||
|
disableTeleportation: true,
|
||||||
|
disableDefaultUI: false, // Enable UI for this test
|
||||||
|
disableHandTracking: true
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('🔍 WebXR created successfully');
|
||||||
|
console.log('🔍 XR input exists:', !!xr.input);
|
||||||
|
console.log('🔍 XR input controllers:', xr.input.controllers.length);
|
||||||
|
|
||||||
|
// Set up controller observable
|
||||||
|
console.log('🔍 Setting up onControllerAddedObservable...');
|
||||||
|
|
||||||
|
|
||||||
|
xr.input.onControllerAddedObservable.add((controller) => {
|
||||||
|
console.log('✅ CONTROLLER ADDED! Handedness:', controller.inputSource.handedness);
|
||||||
|
console.log(' - Input source:', controller.inputSource);
|
||||||
|
console.log(' - Has motion controller:', !!controller.motionController);
|
||||||
|
|
||||||
|
// Wait for motion controller
|
||||||
|
controller.onMotionControllerInitObservable.add((motionController) => {
|
||||||
|
console.log('✅ MOTION CONTROLLER INITIALIZED:', motionController.handness);
|
||||||
|
console.log(' - Profile:', motionController.profileId);
|
||||||
|
console.log(' - Components:', Object.keys(motionController.components));
|
||||||
|
|
||||||
|
// Log when any component changes
|
||||||
|
Object.keys(motionController.components).forEach(componentId => {
|
||||||
|
const component = motionController.components[componentId];
|
||||||
|
|
||||||
|
if (component.onAxisValueChangedObservable) {
|
||||||
|
component.onAxisValueChangedObservable.add((axes) => {
|
||||||
|
console.log(`📍 ${motionController.handness} ${componentId} axes:`, axes);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.onButtonStateChangedObservable) {
|
||||||
|
component.onButtonStateChangedObservable.add((state) => {
|
||||||
|
console.log(`🔘 ${motionController.handness} ${componentId} button:`, {
|
||||||
|
pressed: state.pressed,
|
||||||
|
touched: state.touched,
|
||||||
|
value: state.value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('🔍 Observable registered. Waiting for controllers...');
|
||||||
|
|
||||||
|
// Render loop
|
||||||
|
this.engine.runRenderLoop(() => {
|
||||||
|
this.scene.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create button to enter VR (requires user gesture)
|
||||||
|
this.createEnterVRButton(xr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private createEnterVRButton(xr: WebXRDefaultExperience) {
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.textContent = 'Enter VR (Controller Debug)';
|
||||||
|
button.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
padding: 20px 40px;
|
||||||
|
font-size: 24px;
|
||||||
|
background: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 9999;
|
||||||
|
`;
|
||||||
|
|
||||||
|
button.onclick = async () => {
|
||||||
|
console.log('🔍 Button clicked - Entering VR mode...');
|
||||||
|
button.remove();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await xr.baseExperience.enterXRAsync('immersive-vr', 'local-floor', undefined, {
|
||||||
|
requiredFeatures: ['local-floor'],
|
||||||
|
|
||||||
|
});
|
||||||
|
console.log(xr.baseExperience.featuresManager.getEnabledFeatures());
|
||||||
|
//await xr.baseExperience.exitXRAsync();
|
||||||
|
//await xr.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
|
||||||
|
console.log('🔍 ✅ Entered VR mode successfully');
|
||||||
|
console.log('🔍 Controllers after entering VR:', xr.input.controllers.length);
|
||||||
|
|
||||||
|
// Check again after delays
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('🔍 [+1s after VR] Controller count:', xr.input.controllers.length);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('🔍 [+3s after VR] Controller count:', xr.input.controllers.length);
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('🔍 [+5s after VR] Controller count:', xr.input.controllers.length);
|
||||||
|
}, 5000);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🔍 ❌ Failed to enter VR:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.body.appendChild(button);
|
||||||
|
console.log('🔍 Click the button to enter VR mode');
|
||||||
|
}
|
||||||
|
}
|
||||||
133
src/createPlanets.ts
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import {
|
||||||
|
AbstractMesh, Color3,
|
||||||
|
MeshBuilder,
|
||||||
|
StandardMaterial,
|
||||||
|
Texture,
|
||||||
|
Vector3
|
||||||
|
} from "@babylonjs/core";
|
||||||
|
import { DefaultScene } from "./defaultScene";
|
||||||
|
import { getRandomPlanetTexture } from "./planetTextures";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates multiple planets with random textures, sizes, and positions
|
||||||
|
* @param count - Number of planets to create
|
||||||
|
* @param sunPosition - Position of the sun (center point for planet orbit distances)
|
||||||
|
* @param minDiameter - Minimum planet diameter (default: 50)
|
||||||
|
* @param maxDiameter - Maximum planet diameter (default: 100)
|
||||||
|
* @param minDistance - Minimum distance from sun (default: 400)
|
||||||
|
* @param maxDistance - Maximum distance from sun (default: 1000)
|
||||||
|
* @returns Array of created planet meshes
|
||||||
|
*/
|
||||||
|
export function createPlanets(
|
||||||
|
count: number,
|
||||||
|
sunPosition: Vector3 = Vector3.Zero(),
|
||||||
|
minDiameter: number = 100,
|
||||||
|
maxDiameter: number = 200,
|
||||||
|
minDistance: number = 500,
|
||||||
|
maxDistance: number = 1000
|
||||||
|
): AbstractMesh[] {
|
||||||
|
const planets: AbstractMesh[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
// Random diameter between min and max
|
||||||
|
const diameter = minDiameter + Math.random() * (maxDiameter - minDiameter);
|
||||||
|
|
||||||
|
// Create sphere
|
||||||
|
const planet = MeshBuilder.CreateSphere(
|
||||||
|
`planet-${i}`,
|
||||||
|
{ diameter: diameter, segments: 32 },
|
||||||
|
DefaultScene.MainScene
|
||||||
|
);
|
||||||
|
|
||||||
|
// Random distance from sun
|
||||||
|
const distance = minDistance + Math.random() * (maxDistance - minDistance);
|
||||||
|
|
||||||
|
// Random position on a sphere around the sun
|
||||||
|
const theta = Math.random() * Math.PI * 2; // Random angle around Y axis
|
||||||
|
const phi = Math.random() * Math.PI; // Random angle from Y axis
|
||||||
|
|
||||||
|
// Convert spherical coordinates to Cartesian
|
||||||
|
const x = distance * Math.sin(phi) * Math.cos(theta);
|
||||||
|
const y = distance * Math.sin(phi) * Math.sin(theta);
|
||||||
|
const z = distance * Math.cos(phi);
|
||||||
|
|
||||||
|
planet.position = new Vector3(
|
||||||
|
sunPosition.x + x,
|
||||||
|
sunPosition.y + y,
|
||||||
|
sunPosition.z + z
|
||||||
|
);
|
||||||
|
|
||||||
|
// Apply random planet texture
|
||||||
|
const material = new StandardMaterial(`planet-material-${i}`, DefaultScene.MainScene);
|
||||||
|
material.diffuseTexture = new Texture(getRandomPlanetTexture(), DefaultScene.MainScene);
|
||||||
|
planet.material = material;
|
||||||
|
material.specularColor = Color3.Black()
|
||||||
|
|
||||||
|
planets.push(planet);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Created ${count} planets with diameters ${minDiameter}-${maxDiameter} at distances ${minDistance}-${maxDistance}`);
|
||||||
|
return planets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates planets in a more organized orbital pattern (flat solar system style)
|
||||||
|
* @param count - Number of planets to create
|
||||||
|
* @param sunPosition - Position of the sun
|
||||||
|
* @param minDiameter - Minimum planet diameter (default: 50)
|
||||||
|
* @param maxDiameter - Maximum planet diameter (default: 100)
|
||||||
|
* @param minDistance - Minimum distance from sun (default: 400)
|
||||||
|
* @param maxDistance - Maximum distance from sun (default: 1000)
|
||||||
|
* @returns Array of created planet meshes
|
||||||
|
*/
|
||||||
|
export function createPlanetsOrbital(
|
||||||
|
count: number,
|
||||||
|
sunPosition: Vector3 = Vector3.Zero(),
|
||||||
|
minDiameter: number = 50,
|
||||||
|
maxDiameter: number = 100,
|
||||||
|
minDistance: number = 400,
|
||||||
|
maxDistance: number = 1000
|
||||||
|
): AbstractMesh[] {
|
||||||
|
const planets: AbstractMesh[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
// Random diameter between min and max
|
||||||
|
const diameter = minDiameter + Math.random() * (maxDiameter - minDiameter);
|
||||||
|
|
||||||
|
// Create sphere
|
||||||
|
const planet = MeshBuilder.CreateSphere(
|
||||||
|
`planet-${i}`,
|
||||||
|
{ diameter: diameter, segments: 32 },
|
||||||
|
DefaultScene.MainScene
|
||||||
|
);
|
||||||
|
|
||||||
|
// Random distance from sun
|
||||||
|
const distance = minDistance + Math.random() * (maxDistance - minDistance);
|
||||||
|
|
||||||
|
// Random angle around Y axis (orbital plane)
|
||||||
|
const angle = Math.random() * Math.PI * 2;
|
||||||
|
|
||||||
|
// Keep planets mostly in a plane (like a solar system)
|
||||||
|
const y = (Math.random() - 0.5) * 100; // Small vertical variation
|
||||||
|
|
||||||
|
planet.position = new Vector3(
|
||||||
|
sunPosition.x + distance * Math.cos(angle),
|
||||||
|
sunPosition.y + y,
|
||||||
|
sunPosition.z + distance * Math.sin(angle)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Apply random planet texture
|
||||||
|
const material = new StandardMaterial(`planet-material-${i}`, DefaultScene.MainScene);
|
||||||
|
const texture = new Texture(getRandomPlanetTexture(), DefaultScene.MainScene);
|
||||||
|
material.diffuseTexture = texture;
|
||||||
|
material.ambientTexture = texture;
|
||||||
|
|
||||||
|
planet.material = material;
|
||||||
|
material.specularColor = Color3.Black()
|
||||||
|
|
||||||
|
planets.push(planet);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Created ${count} planets in orbital pattern with diameters ${minDiameter}-${maxDiameter} at distances ${minDistance}-${maxDistance}`);
|
||||||
|
return planets;
|
||||||
|
}
|
||||||
@ -6,28 +6,42 @@ import {
|
|||||||
PhysicsMotionType,
|
PhysicsMotionType,
|
||||||
PhysicsShapeType,
|
PhysicsShapeType,
|
||||||
PointLight,
|
PointLight,
|
||||||
StandardMaterial,
|
StandardMaterial, Texture,
|
||||||
Vector3
|
Vector3
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import {DefaultScene} from "./defaultScene";
|
import {DefaultScene} from "./defaultScene";
|
||||||
import {FireProceduralTexture} from "@babylonjs/procedural-textures";
|
import {FireProceduralTexture} from "@babylonjs/procedural-textures";
|
||||||
|
|
||||||
export function createSun() : AbstractMesh {
|
export function createSun() : AbstractMesh {
|
||||||
const light = new PointLight("light", new Vector3(0, 0, 0), DefaultScene.MainScene);
|
const light = new PointLight("light", new Vector3(0, 0, 400), DefaultScene.MainScene);
|
||||||
|
light.intensity = 100;
|
||||||
const sun = MeshBuilder.CreateSphere("sun", {diameter: 50, segments: 32}, DefaultScene.MainScene);
|
const sun = MeshBuilder.CreateSphere("sun", {diameter: 50, segments: 32}, DefaultScene.MainScene);
|
||||||
|
|
||||||
const sunAggregate = new PhysicsAggregate(sun, PhysicsShapeType.SPHERE, {mass: 0}, DefaultScene.MainScene);
|
//const sunAggregate = new PhysicsAggregate(sun, PhysicsShapeType.SPHERE, {mass: 0}, DefaultScene.MainScene);
|
||||||
sunAggregate.body.setMotionType(PhysicsMotionType.STATIC);
|
//sunAggregate.body.setMotionType(PhysicsMotionType.STATIC);
|
||||||
const material = new StandardMaterial("material", DefaultScene.MainScene);
|
const material = new StandardMaterial("material", DefaultScene.MainScene);
|
||||||
material.emissiveTexture =new FireProceduralTexture("fire", 256, DefaultScene.MainScene);
|
material.emissiveTexture =new FireProceduralTexture("fire", 512, DefaultScene.MainScene);
|
||||||
material.emissiveColor = new Color3(.5, .5, .1);
|
material.emissiveColor = new Color3(.5, .5, .1);
|
||||||
material.disableLighting = true;
|
material.disableLighting = true;
|
||||||
sun.material = material;
|
sun.material = material;
|
||||||
const gl = new GlowLayer("glow", DefaultScene.MainScene);
|
const gl = new GlowLayer("glow", DefaultScene.MainScene);
|
||||||
//gl.addIncludedOnlyMesh(sun);
|
//gl.addIncludedOnlyMesh(sun);
|
||||||
gl.intensity = 5;
|
gl.intensity = 1;
|
||||||
|
|
||||||
|
sun.position = new Vector3(0, 0, 400);
|
||||||
sun.position = new Vector3(0, 0, 0);
|
|
||||||
return sun;
|
return sun;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createPlanet(position: Vector3, diameter: number, name: string) : AbstractMesh {
|
||||||
|
const planet = MeshBuilder.CreateSphere(name, {diameter: diameter, segments: 32}, DefaultScene.MainScene);
|
||||||
|
const material = new StandardMaterial(name + "-material", DefaultScene.MainScene);
|
||||||
|
const texture = new Texture("/planetTextures/Arid/Arid_01-512x512.png", DefaultScene.MainScene);
|
||||||
|
material.diffuseTexture = texture;
|
||||||
|
material.ambientTexture = texture;
|
||||||
|
material.roughness = 1;
|
||||||
|
material.specularColor = Color3.Black();
|
||||||
|
//material.diffuseColor = new Color3(Math.random(), Math.random(), Math.random());
|
||||||
|
planet.material = material;
|
||||||
|
planet.position = position;
|
||||||
|
return planet;
|
||||||
}
|
}
|
||||||
@ -18,6 +18,8 @@ import {RockFactory} from "./starfield";
|
|||||||
import Level from "./level";
|
import Level from "./level";
|
||||||
import {Scoreboard} from "./scoreboard";
|
import {Scoreboard} from "./scoreboard";
|
||||||
import setLoadingMessage from "./setLoadingMessage";
|
import setLoadingMessage from "./setLoadingMessage";
|
||||||
|
import {createPlanet, createSun} from "./createSun";
|
||||||
|
import {createPlanetsOrbital} from "./createPlanets";
|
||||||
|
|
||||||
export class Level1 implements Level {
|
export class Level1 implements Level {
|
||||||
private _ship: Ship;
|
private _ship: Ship;
|
||||||
@ -44,13 +46,22 @@ export class Level1 implements Level {
|
|||||||
this._ship = new Ship(undefined, audioEngine);
|
this._ship = new Ship(undefined, audioEngine);
|
||||||
this._scoreboard = new Scoreboard();
|
this._scoreboard = new Scoreboard();
|
||||||
const xr = DefaultScene.XR;
|
const xr = DefaultScene.XR;
|
||||||
|
|
||||||
|
console.log('Level1 constructor - Setting up XR observables');
|
||||||
|
console.log('XR input exists:', !!xr.input);
|
||||||
|
console.log('onControllerAddedObservable exists:', !!xr.input?.onControllerAddedObservable);
|
||||||
|
|
||||||
xr.baseExperience.onInitialXRPoseSetObservable.add(() => {
|
xr.baseExperience.onInitialXRPoseSetObservable.add(() => {
|
||||||
xr.baseExperience.camera.parent = this._ship.transformNode;
|
xr.baseExperience.camera.parent = this._ship.transformNode;
|
||||||
xr.baseExperience.camera.position = new Vector3(0, 0, 0);
|
xr.baseExperience.camera.position = new Vector3(0, 0, 0);
|
||||||
|
const observer = xr.input.onControllerAddedObservable.add((controller) => {
|
||||||
|
console.log('🎮 onControllerAddedObservable FIRED for:', controller.inputSource.handedness);
|
||||||
|
this._ship.addController(controller);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
xr.input.onControllerAddedObservable.add((controller) => {
|
|
||||||
this._ship.addController(controller);
|
|
||||||
});
|
//console.log('Controller observable registered, observer:', !!observer);
|
||||||
|
|
||||||
this.createStartBase();
|
this.createStartBase();
|
||||||
this.initialize();
|
this.initialize();
|
||||||
@ -63,10 +74,10 @@ export class Level1 implements Level {
|
|||||||
return {
|
return {
|
||||||
rockCount: 5,
|
rockCount: 5,
|
||||||
forceMultiplier: 1,
|
forceMultiplier: 1,
|
||||||
rockSizeMin: 4,
|
rockSizeMin: 5,
|
||||||
rockSizeMax: 10,
|
rockSizeMax: 10,
|
||||||
distanceMin: 150,
|
distanceMin: 150,
|
||||||
distanceMax: 180
|
distanceMax: 200
|
||||||
};
|
};
|
||||||
case 'pilot':
|
case 'pilot':
|
||||||
return {
|
return {
|
||||||
@ -125,17 +136,27 @@ export class Level1 implements Level {
|
|||||||
// Create background music using AudioEngineV2
|
// Create background music using AudioEngineV2
|
||||||
const background = await this._audioEngine.createSoundAsync("background", "/song1.mp3", {
|
const background = await this._audioEngine.createSoundAsync("background", "/song1.mp3", {
|
||||||
loop: true,
|
loop: true,
|
||||||
volume: 0.2
|
volume: 0.5
|
||||||
});
|
});
|
||||||
background.play();
|
background.play();
|
||||||
|
|
||||||
// Enter XR mode
|
// Enter XR mode
|
||||||
await DefaultScene.XR.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
|
const xr = await DefaultScene.XR.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
|
||||||
|
|
||||||
// Check for controllers that are already connected after entering XR
|
// Check for controllers that are already connected after entering XR
|
||||||
DefaultScene.XR.input.controllers.forEach((controller) => {
|
console.log('Checking for controllers after entering XR. Count:', DefaultScene.XR.input.controllers.length);
|
||||||
|
DefaultScene.XR.input.controllers.forEach((controller, index) => {
|
||||||
|
console.log(`Controller ${index} - handedness: ${controller.inputSource.handedness}`);
|
||||||
this._ship.addController(controller);
|
this._ship.addController(controller);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Wait and check again after a delay (controllers might connect later)
|
||||||
|
console.log('Waiting 2 seconds to check for controllers again...');
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('After 2 second delay - controller count:', DefaultScene.XR.input.controllers.length);
|
||||||
|
DefaultScene.XR.input.controllers.forEach((controller, index) => {
|
||||||
|
console.log(` Late controller ${index} - handedness: ${controller.inputSource.handedness}`);
|
||||||
|
});
|
||||||
|
}, 2000);
|
||||||
}
|
}
|
||||||
public dispose() {
|
public dispose() {
|
||||||
this._startBase.dispose();
|
this._startBase.dispose();
|
||||||
@ -149,7 +170,6 @@ export class Level1 implements Level {
|
|||||||
this.createBackgroundElements();
|
this.createBackgroundElements();
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
this._ship.position = new Vector3(0, 1, 0);
|
this._ship.position = new Vector3(0, 1, 0);
|
||||||
|
|
||||||
const config = this._difficultyConfig;
|
const config = this._difficultyConfig;
|
||||||
console.log(config);
|
console.log(config);
|
||||||
setLoadingMessage("Creating Asteroids...");
|
setLoadingMessage("Creating Asteroids...");
|
||||||
@ -159,7 +179,7 @@ export class Level1 implements Level {
|
|||||||
const sizeRange = config.rockSizeMax - config.rockSizeMin;
|
const sizeRange = config.rockSizeMax - config.rockSizeMin;
|
||||||
const size = Vector3.Random(1,1.3).scale(Math.random() * sizeRange + config.rockSizeMin)
|
const size = Vector3.Random(1,1.3).scale(Math.random() * sizeRange + config.rockSizeMin)
|
||||||
|
|
||||||
const rock = await RockFactory.createRock(i, new Vector3(Math.random() * 200 +50 * Math.sign(Math.random() -.5),200,200),
|
const rock = await RockFactory.createRock(i, new Vector3(0,1,dist),
|
||||||
size,
|
size,
|
||||||
this._scoreboard.onScoreObservable);
|
this._scoreboard.onScoreObservable);
|
||||||
const constraint = new DistanceConstraint(dist, DefaultScene.MainScene);
|
const constraint = new DistanceConstraint(dist, DefaultScene.MainScene);
|
||||||
@ -180,11 +200,12 @@ export class Level1 implements Level {
|
|||||||
*/
|
*/
|
||||||
this._scoreboard.onScoreObservable.notifyObservers({
|
this._scoreboard.onScoreObservable.notifyObservers({
|
||||||
score: 0,
|
score: 0,
|
||||||
remaining: 1,
|
remaining: i+1,
|
||||||
message: "Get Ready"
|
message: "Get Ready"
|
||||||
});
|
});
|
||||||
this._startBase.physicsBody.addConstraint(rock.physicsBody, constraint);
|
this._startBase.physicsBody.addConstraint(rock.physicsBody, constraint);
|
||||||
rock.physicsBody.applyForce(Vector3.Random(-1, 1).scale(5000000 * config.forceMultiplier), rock.position);
|
rock.physicsBody.applyForce(new Vector3(50000000 * config.forceMultiplier, 0, 0), rock.position);
|
||||||
|
//rock.physicsBody.applyForce(Vector3.Random(-1, 1).scale(5000000 * config.forceMultiplier), rock.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify that initialization is complete
|
// Notify that initialization is complete
|
||||||
@ -220,11 +241,25 @@ export class Level1 implements Level {
|
|||||||
this._endBase = mesh;
|
this._endBase = mesh;
|
||||||
}
|
}
|
||||||
private createBackgroundElements() {
|
private createBackgroundElements() {
|
||||||
const sun = MeshBuilder.CreateSphere("sun", {diameter: 200}, DefaultScene.MainScene);
|
//const sun = MeshBuilder.CreateSphere("sun", {diameter: 200}, DefaultScene.MainScene);
|
||||||
const sunMaterial = new StandardMaterial("sunMaterial", DefaultScene.MainScene);
|
//const sunMaterial = new StandardMaterial("sunMaterial", DefaultScene.MainScene);
|
||||||
sunMaterial.emissiveColor = new Color3(1, 1, 0);
|
//sunMaterial.emissiveColor = new Color3(1, 1, 0);
|
||||||
sun.material = sunMaterial;
|
//sun.material = sunMaterial;
|
||||||
sun.position = new Vector3(-200, 300, 500);
|
//sun.position = new Vector3(-200, 300, 500);
|
||||||
|
const sun = createSun();
|
||||||
|
|
||||||
|
// Create planets around the sun
|
||||||
|
const sunPosition = sun.position;
|
||||||
|
const planets = createPlanetsOrbital(
|
||||||
|
8, // 8 planets
|
||||||
|
sunPosition, // sun position
|
||||||
|
50, // min diameter
|
||||||
|
100, // max diameter
|
||||||
|
400, // min distance from sun
|
||||||
|
1000 // max distance from sun
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`Created ${planets.length} planets around sun at position`, sunPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
private createTarget(i: number) {
|
private createTarget(i: number) {
|
||||||
|
|||||||
64
src/main.ts
@ -1,28 +1,29 @@
|
|||||||
|
import type {AudioEngineV2} from "@babylonjs/core";
|
||||||
import {
|
import {
|
||||||
Color3,
|
Color3,
|
||||||
CreateAudioEngineAsync,
|
CreateAudioEngineAsync,
|
||||||
Engine,
|
Engine,
|
||||||
HavokPlugin,
|
HavokPlugin,
|
||||||
ParticleHelper,
|
ParticleHelper,
|
||||||
PhotoDome,
|
Scene,
|
||||||
Scene, StandardMaterial,
|
|
||||||
Vector3,
|
Vector3,
|
||||||
WebGPUEngine,
|
WebGPUEngine,
|
||||||
WebXRDefaultExperience
|
WebXRDefaultExperience,
|
||||||
|
WebXRFeatureName
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import type {AudioEngineV2} from "@babylonjs/core";
|
|
||||||
import '@babylonjs/loaders';
|
import '@babylonjs/loaders';
|
||||||
import HavokPhysics from "@babylonjs/havok";
|
import HavokPhysics from "@babylonjs/havok";
|
||||||
|
|
||||||
import {DefaultScene} from "./defaultScene";
|
import {DefaultScene} from "./defaultScene";
|
||||||
import {Ship} from "./ship";
|
|
||||||
import {Level1} from "./level1";
|
import {Level1} from "./level1";
|
||||||
import {Scoreboard} from "./scoreboard";
|
|
||||||
import Demo from "./demo";
|
import Demo from "./demo";
|
||||||
import Level from "./level";
|
import Level from "./level";
|
||||||
import setLoadingMessage from "./setLoadingMessage";
|
import setLoadingMessage from "./setLoadingMessage";
|
||||||
import {RockFactory} from "./starfield";
|
import {RockFactory} from "./starfield";
|
||||||
|
import {ControllerDebug} from "./controllerDebug";
|
||||||
|
|
||||||
|
// Set to true to run minimal controller debug test
|
||||||
|
const DEBUG_CONTROLLERS = false;
|
||||||
const webGpu = false;
|
const webGpu = false;
|
||||||
const canvas = (document.querySelector('#gameCanvas') as HTMLCanvasElement);
|
const canvas = (document.querySelector('#gameCanvas') as HTMLCanvasElement);
|
||||||
enum GameState {
|
enum GameState {
|
||||||
@ -94,20 +95,24 @@ export class Main {
|
|||||||
disableNearInteraction: true,
|
disableNearInteraction: true,
|
||||||
disableHandTracking: true,
|
disableHandTracking: true,
|
||||||
disableDefaultUI: true,
|
disableDefaultUI: true,
|
||||||
|
|
||||||
});
|
});
|
||||||
|
DefaultScene.XR.baseExperience.featuresManager.enableFeature(WebXRFeatureName.LAYERS, "stable",
|
||||||
|
{preferMultiviewOnInit: true});
|
||||||
|
|
||||||
|
|
||||||
setLoadingMessage("Get Ready!");
|
setLoadingMessage("Get Ready!");
|
||||||
|
|
||||||
const photoDome1 = new PhotoDome("testdome", '/8192.webp', {size: 1000}, DefaultScene.MainScene);
|
//const photoDome1 = new PhotoDome("testdome", '/8192.webp', {size: 1000}, DefaultScene.MainScene);
|
||||||
photoDome1.material.diffuseTexture.hasAlpha = true;
|
//photoDome1.material.diffuseTexture.hasAlpha = true;
|
||||||
photoDome1.material.alpha = .3;
|
//photoDome1.material.alpha = .3;
|
||||||
|
|
||||||
const photoDome2 = new PhotoDome("testdome", '/8192.webp', {size: 2000}, DefaultScene.MainScene);
|
//const photoDome2 = new PhotoDome("testdome", '/8192.webp', {size: 2000}, DefaultScene.MainScene);
|
||||||
photoDome2.rotation.y = Math.PI;
|
//photoDome2.rotation.y = Math.PI;
|
||||||
photoDome2.rotation.x = Math.PI/2;
|
//photoDome2.rotation.x = Math.PI/2;
|
||||||
DefaultScene.MainScene.onAfterRenderObservable.add(() => {
|
DefaultScene.MainScene.onAfterRenderObservable.add(() => {
|
||||||
photoDome1.position = DefaultScene.MainScene.activeCamera.globalPosition;
|
// photoDome1.position = DefaultScene.MainScene.activeCamera.globalPosition;
|
||||||
photoDome2.position = DefaultScene.MainScene.activeCamera.globalPosition;
|
// photoDome2.position = DefaultScene.MainScene.activeCamera.globalPosition;
|
||||||
});
|
});
|
||||||
setLoadingMessage("Select a difficulty to begin!");
|
setLoadingMessage("Select a difficulty to begin!");
|
||||||
}
|
}
|
||||||
@ -140,30 +145,33 @@ export class Main {
|
|||||||
// Initialize AudioEngineV2
|
// Initialize AudioEngineV2
|
||||||
setLoadingMessage("Initializing Audio Engine...");
|
setLoadingMessage("Initializing Audio Engine...");
|
||||||
this._audioEngine = await CreateAudioEngineAsync();
|
this._audioEngine = await CreateAudioEngineAsync();
|
||||||
setLoadingMessage("Ready!");
|
|
||||||
|
|
||||||
this.setupInspector();
|
this.setupInspector();
|
||||||
this._engine.runRenderLoop(() => {
|
window.setTimeout(()=>{
|
||||||
if (!this._started) {
|
if (!this._started) {
|
||||||
this._started = true;
|
this._started = true;
|
||||||
const levelSelect = document.querySelector('#levelSelect');
|
const levelSelect = document.querySelector('#levelSelect');
|
||||||
if (levelSelect) {
|
if (levelSelect) {
|
||||||
levelSelect.classList.add('ready');
|
levelSelect.classList.add('ready');
|
||||||
|
setLoadingMessage("Ready!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this._gameState == GameState.PLAY) {
|
})
|
||||||
|
|
||||||
|
this._engine.runRenderLoop(() => {
|
||||||
DefaultScene.MainScene.render();
|
DefaultScene.MainScene.render();
|
||||||
} else {
|
|
||||||
DefaultScene.DemoScene.render();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setupPhysics() {
|
private async setupPhysics() {
|
||||||
const havok = await HavokPhysics();
|
const havok = await HavokPhysics();
|
||||||
const havokPlugin = new HavokPlugin(true, havok);
|
const havokPlugin = new HavokPlugin(true, havok);
|
||||||
|
|
||||||
DefaultScene.MainScene.enablePhysics(new Vector3(0, 0, 0), havokPlugin);
|
DefaultScene.MainScene.enablePhysics(new Vector3(0, 0, 0), havokPlugin);
|
||||||
DefaultScene.MainScene.getPhysicsEngine().setSubTimeStep(5);
|
DefaultScene.MainScene.getPhysicsEngine().setTimeStep(1/90);
|
||||||
|
DefaultScene.MainScene.getPhysicsEngine().setSubTimeStep(9);
|
||||||
|
|
||||||
DefaultScene.MainScene.collisionsEnabled = true;
|
DefaultScene.MainScene.collisionsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,8 +190,18 @@ export class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const main = new Main();
|
if (DEBUG_CONTROLLERS) {
|
||||||
const demo = new Demo(main);
|
console.log('🔍 DEBUG MODE: Running minimal controller test');
|
||||||
|
// Hide the UI elements
|
||||||
|
const mainDiv = document.querySelector('#mainDiv');
|
||||||
|
if (mainDiv) {
|
||||||
|
(mainDiv as HTMLElement).style.display = 'none';
|
||||||
|
}
|
||||||
|
new ControllerDebug();
|
||||||
|
} else {
|
||||||
|
const main = new Main();
|
||||||
|
const demo = new Demo(main);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
225
src/planetTextures.ts
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/**
|
||||||
|
* Planet texture paths for randomly generating planets
|
||||||
|
* All textures are 512x512 PNG files
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const PLANET_TEXTURES = [
|
||||||
|
// Arid planets (5 textures)
|
||||||
|
"/planetTextures/Arid/Arid_01-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_02-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_03-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_04-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_05-512x512.png",
|
||||||
|
|
||||||
|
// Barren planets (5 textures)
|
||||||
|
"/planetTextures/Barren/Barren_01-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_02-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_03-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_04-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_05-512x512.png",
|
||||||
|
|
||||||
|
// Dusty planets (5 textures)
|
||||||
|
"/planetTextures/Dusty/Dusty_01-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_02-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_03-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_04-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_05-512x512.png",
|
||||||
|
|
||||||
|
// Gaseous planets (20 textures)
|
||||||
|
"/planetTextures/Gaseous/Gaseous_01-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_02-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_03-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_04-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_05-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_06-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_07-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_08-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_09-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_10-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_11-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_12-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_13-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_14-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_15-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_16-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_17-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_18-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_19-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_20-512x512.png",
|
||||||
|
|
||||||
|
// Grassland planets (5 textures)
|
||||||
|
"/planetTextures/Grassland/Grassland_01-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_02-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_03-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_04-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_05-512x512.png",
|
||||||
|
|
||||||
|
// Jungle planets (5 textures)
|
||||||
|
"/planetTextures/Jungle/Jungle_01-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_02-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_03-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_04-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_05-512x512.png",
|
||||||
|
|
||||||
|
// Marshy planets (5 textures)
|
||||||
|
"/planetTextures/Marshy/Marshy_01-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_02-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_03-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_04-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_05-512x512.png",
|
||||||
|
|
||||||
|
// Martian planets (5 textures)
|
||||||
|
"/planetTextures/Martian/Martian_01-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_02-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_03-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_04-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_05-512x512.png",
|
||||||
|
|
||||||
|
// Methane planets (5 textures)
|
||||||
|
"/planetTextures/Methane/Methane_01-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_02-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_03-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_04-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_05-512x512.png",
|
||||||
|
|
||||||
|
// Sandy planets (5 textures)
|
||||||
|
"/planetTextures/Sandy/Sandy_01-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_02-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_03-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_04-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_05-512x512.png",
|
||||||
|
|
||||||
|
// Snowy planets (5 textures)
|
||||||
|
"/planetTextures/Snowy/Snowy_01-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_02-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_03-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_04-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_05-512x512.png",
|
||||||
|
|
||||||
|
// Tundra planets (5 textures)
|
||||||
|
"/planetTextures/Tundra/Tundra_01-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundra_02-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundra_03-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundra_04-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundral-EQUIRECTANGULAR-5-512x512.png",
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a random planet texture path
|
||||||
|
*/
|
||||||
|
export function getRandomPlanetTexture(): string {
|
||||||
|
return PLANET_TEXTURES[Math.floor(Math.random() * PLANET_TEXTURES.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Planet texture categories organized by type
|
||||||
|
*/
|
||||||
|
export const PLANET_TEXTURES_BY_TYPE = {
|
||||||
|
arid: [
|
||||||
|
"/planetTextures/Arid/Arid_01-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_02-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_03-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_04-512x512.png",
|
||||||
|
"/planetTextures/Arid/Arid_05-512x512.png",
|
||||||
|
],
|
||||||
|
barren: [
|
||||||
|
"/planetTextures/Barren/Barren_01-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_02-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_03-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_04-512x512.png",
|
||||||
|
"/planetTextures/Barren/Barren_05-512x512.png",
|
||||||
|
],
|
||||||
|
dusty: [
|
||||||
|
"/planetTextures/Dusty/Dusty_01-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_02-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_03-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_04-512x512.png",
|
||||||
|
"/planetTextures/Dusty/Dusty_05-512x512.png",
|
||||||
|
],
|
||||||
|
gaseous: [
|
||||||
|
"/planetTextures/Gaseous/Gaseous_01-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_02-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_03-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_04-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_05-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_06-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_07-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_08-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_09-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_10-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_11-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_12-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_13-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_14-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_15-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_16-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_17-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_18-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_19-512x512.png",
|
||||||
|
"/planetTextures/Gaseous/Gaseous_20-512x512.png",
|
||||||
|
],
|
||||||
|
grassland: [
|
||||||
|
"/planetTextures/Grassland/Grassland_01-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_02-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_03-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_04-512x512.png",
|
||||||
|
"/planetTextures/Grassland/Grassland_05-512x512.png",
|
||||||
|
],
|
||||||
|
jungle: [
|
||||||
|
"/planetTextures/Jungle/Jungle_01-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_02-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_03-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_04-512x512.png",
|
||||||
|
"/planetTextures/Jungle/Jungle_05-512x512.png",
|
||||||
|
],
|
||||||
|
marshy: [
|
||||||
|
"/planetTextures/Marshy/Marshy_01-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_02-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_03-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_04-512x512.png",
|
||||||
|
"/planetTextures/Marshy/Marshy_05-512x512.png",
|
||||||
|
],
|
||||||
|
martian: [
|
||||||
|
"/planetTextures/Martian/Martian_01-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_02-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_03-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_04-512x512.png",
|
||||||
|
"/planetTextures/Martian/Martian_05-512x512.png",
|
||||||
|
],
|
||||||
|
methane: [
|
||||||
|
"/planetTextures/Methane/Methane_01-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_02-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_03-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_04-512x512.png",
|
||||||
|
"/planetTextures/Methane/Methane_05-512x512.png",
|
||||||
|
],
|
||||||
|
sandy: [
|
||||||
|
"/planetTextures/Sandy/Sandy_01-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_02-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_03-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_04-512x512.png",
|
||||||
|
"/planetTextures/Sandy/Sandy_05-512x512.png",
|
||||||
|
],
|
||||||
|
snowy: [
|
||||||
|
"/planetTextures/Snowy/Snowy_01-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_02-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_03-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_04-512x512.png",
|
||||||
|
"/planetTextures/Snowy/Snowy_05-512x512.png",
|
||||||
|
],
|
||||||
|
tundra: [
|
||||||
|
"/planetTextures/Tundra/Tundra_01-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundra_02-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundra_03-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundra_04-512x512.png",
|
||||||
|
"/planetTextures/Tundra/Tundral-EQUIRECTANGULAR-5-512x512.png",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a random texture from a specific planet type
|
||||||
|
*/
|
||||||
|
export function getRandomTextureByType(type: keyof typeof PLANET_TEXTURES_BY_TYPE): string {
|
||||||
|
const textures = PLANET_TEXTURES_BY_TYPE[type];
|
||||||
|
return textures[Math.floor(Math.random() * textures.length)];
|
||||||
|
}
|
||||||
42
src/ship.ts
@ -145,11 +145,11 @@ export class Ship {
|
|||||||
this._ammoBaseMesh.material = this._ammoMaterial;
|
this._ammoBaseMesh.material = this._ammoMaterial;
|
||||||
this._ammoBaseMesh.setEnabled(false);
|
this._ammoBaseMesh.setEnabled(false);
|
||||||
|
|
||||||
const light = new DirectionalLight("light", new Vector3(.1, -1, 0), DefaultScene.MainScene);
|
//const light = new DirectionalLight("light", new Vector3(.1, -1, 0), DefaultScene.MainScene);
|
||||||
|
|
||||||
const landingLight = new SpotLight("landingLight", new Vector3(0, 0, 0), new Vector3(0, -.5, .5), 1.5, .5, DefaultScene.MainScene);
|
//const landingLight = new SpotLight("landingLight", new Vector3(0, 0, 0), new Vector3(0, -.5, .5), 1.5, .5, DefaultScene.MainScene);
|
||||||
landingLight.parent = this._ship;
|
// landingLight.parent = this._ship;
|
||||||
landingLight.position.z = 5;
|
// landingLight.position.z = 5;
|
||||||
const agg = new PhysicsAggregate(this._ship, PhysicsShapeType.BOX, {
|
const agg = new PhysicsAggregate(this._ship, PhysicsShapeType.BOX, {
|
||||||
mass: 100,
|
mass: 100,
|
||||||
extents: new Vector3(4, 4, 7.4),
|
extents: new Vector3(4, 4, 7.4),
|
||||||
@ -180,6 +180,7 @@ export class Ship {
|
|||||||
sight.parent = this._ship
|
sight.parent = this._ship
|
||||||
const signtMaterial = new StandardMaterial("sightMaterial", DefaultScene.MainScene);
|
const signtMaterial = new StandardMaterial("sightMaterial", DefaultScene.MainScene);
|
||||||
signtMaterial.emissiveColor = Color3.Yellow();
|
signtMaterial.emissiveColor = Color3.Yellow();
|
||||||
|
signtMaterial.ambientColor = Color3.Yellow();
|
||||||
sight.material = signtMaterial;
|
sight.material = signtMaterial;
|
||||||
sight.position = new Vector3(0, 2, 125);
|
sight.position = new Vector3(0, 2, 125);
|
||||||
let i = Date.now();
|
let i = Date.now();
|
||||||
@ -283,6 +284,12 @@ export class Ship {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private controllerCallback = (controllerEvent: ControllerEvent) => {
|
private controllerCallback = (controllerEvent: ControllerEvent) => {
|
||||||
|
// Log first few events to verify they're firing
|
||||||
|
if (Math.random() < 0.01) { // Only log 1% to avoid spam
|
||||||
|
console.log('Controller event:', controllerEvent.type, controllerEvent.hand,
|
||||||
|
controllerEvent.type === 'thumbstick' ? controllerEvent.axisData : controllerEvent.value);
|
||||||
|
}
|
||||||
|
|
||||||
if (controllerEvent.type == 'thumbstick') {
|
if (controllerEvent.type == 'thumbstick') {
|
||||||
if (controllerEvent.hand == 'left') {
|
if (controllerEvent.hand == 'left') {
|
||||||
this._leftStickVector.x = controllerEvent.axisData.x;
|
this._leftStickVector.x = controllerEvent.axisData.x;
|
||||||
@ -388,23 +395,50 @@ export class Ship {
|
|||||||
private _rightInputSource: WebXRInputSource;
|
private _rightInputSource: WebXRInputSource;
|
||||||
|
|
||||||
public addController(controller: WebXRInputSource) {
|
public addController(controller: WebXRInputSource) {
|
||||||
|
console.log('Ship.addController called for:', controller.inputSource.handedness);
|
||||||
|
|
||||||
if (controller.inputSource.handedness == "left") {
|
if (controller.inputSource.handedness == "left") {
|
||||||
|
console.log('Adding left controller');
|
||||||
this._leftInputSource = controller;
|
this._leftInputSource = controller;
|
||||||
this._leftInputSource.onMotionControllerInitObservable.add((motionController) => {
|
this._leftInputSource.onMotionControllerInitObservable.add((motionController) => {
|
||||||
|
console.log('Left motion controller initialized:', motionController.handness);
|
||||||
this.mapMotionController(motionController);
|
this.mapMotionController(motionController);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check if motion controller is already initialized
|
||||||
|
if (controller.motionController) {
|
||||||
|
console.log('Left motion controller already initialized, mapping now');
|
||||||
|
this.mapMotionController(controller.motionController);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (controller.inputSource.handedness == "right") {
|
if (controller.inputSource.handedness == "right") {
|
||||||
|
console.log('Adding right controller');
|
||||||
this._rightInputSource = controller;
|
this._rightInputSource = controller;
|
||||||
this._rightInputSource.onMotionControllerInitObservable.add((motionController) => {
|
this._rightInputSource.onMotionControllerInitObservable.add((motionController) => {
|
||||||
|
console.log('Right motion controller initialized:', motionController.handness);
|
||||||
this.mapMotionController(motionController);
|
this.mapMotionController(motionController);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check if motion controller is already initialized
|
||||||
|
if (controller.motionController) {
|
||||||
|
console.log('Right motion controller already initialized, mapping now');
|
||||||
|
this.mapMotionController(controller.motionController);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private mapMotionController(controller: WebXRAbstractMotionController) {
|
private mapMotionController(controller: WebXRAbstractMotionController) {
|
||||||
|
console.log('Mapping motion controller:', controller.handness, 'Profile:', controller.profileId);
|
||||||
|
|
||||||
controllerComponents.forEach((component) => {
|
controllerComponents.forEach((component) => {
|
||||||
const comp = controller.components[component];
|
const comp = controller.components[component];
|
||||||
|
|
||||||
|
if (!comp) {
|
||||||
|
console.log(` Component ${component} not found on ${controller.handness} controller`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` Found component ${component} on ${controller.handness} controller`);
|
||||||
const observable = this._controllerObservable;
|
const observable = this._controllerObservable;
|
||||||
|
|
||||||
if (comp && comp.onAxisValueChangedObservable) {
|
if (comp && comp.onAxisValueChangedObservable) {
|
||||||
|
|||||||
@ -9,13 +9,15 @@ import {
|
|||||||
PBRMaterial,
|
PBRMaterial,
|
||||||
PhysicsAggregate, PhysicsBody,
|
PhysicsAggregate, PhysicsBody,
|
||||||
PhysicsMotionType,
|
PhysicsMotionType,
|
||||||
PhysicsShapeType,
|
PhysicsShapeType, PhysicsViewer,
|
||||||
SceneLoader,
|
SceneLoader,
|
||||||
Vector3
|
Vector3
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import {DefaultScene} from "./defaultScene";
|
import {DefaultScene} from "./defaultScene";
|
||||||
import {ScoreEvent} from "./scoreboard";
|
import {ScoreEvent} from "./scoreboard";
|
||||||
|
import {Debug} from "@babylonjs/core/Legacy/legacy";
|
||||||
let _particleData: any = null;
|
let _particleData: any = null;
|
||||||
|
|
||||||
export class Rock {
|
export class Rock {
|
||||||
private _rockMesh: AbstractMesh;
|
private _rockMesh: AbstractMesh;
|
||||||
constructor(mesh: AbstractMesh) {
|
constructor(mesh: AbstractMesh) {
|
||||||
@ -34,7 +36,7 @@ export class RockFactory {
|
|||||||
private static _rockMaterial: PBRMaterial;
|
private static _rockMaterial: PBRMaterial;
|
||||||
private static _explosionPool: ParticleSystemSet[] = [];
|
private static _explosionPool: ParticleSystemSet[] = [];
|
||||||
private static _poolSize: number = 10;
|
private static _poolSize: number = 10;
|
||||||
|
private static _viewer: PhysicsViewer = null;
|
||||||
public static async init() {
|
public static async init() {
|
||||||
// Pre-create explosion particle systems for pooling
|
// Pre-create explosion particle systems for pooling
|
||||||
console.log("Pre-creating explosion particle systems...");
|
console.log("Pre-creating explosion particle systems...");
|
||||||
@ -92,11 +94,18 @@ export class RockFactory {
|
|||||||
rock.id = "asteroid-" + i;
|
rock.id = "asteroid-" + i;
|
||||||
rock.metadata = {type: 'asteroid'};
|
rock.metadata = {type: 'asteroid'};
|
||||||
rock.setEnabled(true);
|
rock.setEnabled(true);
|
||||||
|
console.log(rock.getBoundingInfo());
|
||||||
const agg = new PhysicsAggregate(rock, PhysicsShapeType.CONVEX_HULL, {
|
const agg = new PhysicsAggregate(rock, PhysicsShapeType.CONVEX_HULL, {
|
||||||
mass: 10000,
|
mass: 10000,
|
||||||
restitution: .5,
|
restitution: .5,
|
||||||
}, DefaultScene.MainScene);
|
}, DefaultScene.MainScene);
|
||||||
const body =agg.body;
|
const body =agg.body;
|
||||||
|
|
||||||
|
if (!this._viewer) {
|
||||||
|
this._viewer = new PhysicsViewer(DefaultScene.MainScene);
|
||||||
|
}
|
||||||
|
|
||||||
|
//this._viewer.showBody(body);
|
||||||
body.setLinearDamping(0);
|
body.setLinearDamping(0);
|
||||||
body.setMotionType(PhysicsMotionType.DYNAMIC);
|
body.setMotionType(PhysicsMotionType.DYNAMIC);
|
||||||
body.setCollisionCallbackEnabled(true);
|
body.setCollisionCallbackEnabled(true);
|
||||||
|
|||||||