decomposed functions.
This commit is contained in:
parent
d59e75ddc9
commit
f44b2129c8
@ -49,6 +49,7 @@
|
|||||||
<div id="graphContainer"></div>
|
<div id="graphContainer"></div>
|
||||||
<div id="questLaunch"><a href="https://www.oculus.com/open_url/?url=https://www.deepdiagram.com/">Launch On Quest</a>
|
<div id="questLaunch"><a href="https://www.oculus.com/open_url/?url=https://www.deepdiagram.com/">Launch On Quest</a>
|
||||||
</div>
|
</div>
|
||||||
|
<input id="textInput" type="text"/>
|
||||||
<script type="module" src="./src/app.ts"></script>
|
<script type="module" src="./src/app.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
279
package-lock.json
generated
279
package-lock.json
generated
@ -8,16 +8,16 @@
|
|||||||
"name": "immersive",
|
"name": "immersive",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babylonjs/core": "^6.15.0",
|
"@babylonjs/core": "^6.17.1",
|
||||||
"@babylonjs/gui": "^6.15.0",
|
"@babylonjs/gui": "^6.17.1",
|
||||||
"@babylonjs/havok": "1.1.1",
|
"@babylonjs/havok": "1.1.4",
|
||||||
"@babylonjs/inspector": "^6.15.0",
|
"@babylonjs/inspector": "^6.17.1",
|
||||||
"@babylonjs/loaders": "^6.15.0",
|
"@babylonjs/loaders": "^6.17.1",
|
||||||
"@babylonjs/serializers": "^6.15.0",
|
"@babylonjs/serializers": "^6.17.1",
|
||||||
"@cloudflare/workers-types": "^4.20230807.0",
|
"@cloudflare/workers-types": "^4.20230821.0",
|
||||||
"@netlify/functions": "^1.6.0",
|
"@netlify/functions": "^1.6.0",
|
||||||
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
||||||
"@types/node": "^14.18.54",
|
"@types/node": "^18.14.0",
|
||||||
"dexie": "^3.2.4",
|
"dexie": "^3.2.4",
|
||||||
"dexie-observable": "^4.0.1-beta.13",
|
"dexie-observable": "^4.0.1-beta.13",
|
||||||
"earcut": "^2.2.4",
|
"earcut": "^2.2.4",
|
||||||
@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.4.9",
|
||||||
"vite-plugin-api": "^0.1.11",
|
"vite-plugin-api": "^0.1.11",
|
||||||
"vite-plugin-cp": "^1.0.0"
|
"vite-plugin-cp": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -51,14 +51,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/core": {
|
"node_modules/@babylonjs/core": {
|
||||||
"version": "6.15.0",
|
"version": "6.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-6.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/core/-/core-6.17.1.tgz",
|
||||||
"integrity": "sha512-eoeJ3RB6xYC63ZuGGuceF7rrVA1OFIlO3cvBvAxsoBIzxTSLxyhmG4wwktEvCAePxZ7W7CDYNtA061edGWhxUw=="
|
"integrity": "sha512-CMhbyA7FEjYJC1JMetfRVH955lDwpKASufjeYw0UTB92+tlwwOsonN8eYr2r9DAHb+7UcQegGopx/nj+THAcIQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/gui": {
|
"node_modules/@babylonjs/gui": {
|
||||||
"version": "6.15.0",
|
"version": "6.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-6.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/gui/-/gui-6.17.1.tgz",
|
||||||
"integrity": "sha512-WkR/r8wLbKyzUuXUgcWVaTZO5drxQ8YjkstDRz/ZrhfOTIEFDpidd7onDhaQ9wmekQEpFHcKJejJ1/MLXYLwAg==",
|
"integrity": "sha512-AQUE+r71X889I8hHg58Gpou7eeksIY878hrROnBbV2W8UpAAwL9p4A4kQ+EG8gTWwmn+NnahSRblmHfYnsT2KA==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0"
|
"@babylonjs/core": "^6.0.0"
|
||||||
}
|
}
|
||||||
@ -76,17 +76,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/havok": {
|
"node_modules/@babylonjs/havok": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/havok/-/havok-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/havok/-/havok-1.1.4.tgz",
|
||||||
"integrity": "sha512-QIygEnKPYYPCE8QuJDxDLYPMj+W5Yha6NOdUfpvcVfZwtjVDE+eOa2Y5el7muQD563OdeJS+Kzmhyg+5qAZHBA==",
|
"integrity": "sha512-mK/sgqv4LaI4BjoQgWYGxOBX45hVauZ8PopPkIUIB42DiVPgWkiCZbBQ9pL7r1tbLhThvV1RTokj4z5bVGBayw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/emscripten": "^1.39.6"
|
"@types/emscripten": "^1.39.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/inspector": {
|
"node_modules/@babylonjs/inspector": {
|
||||||
"version": "6.15.0",
|
"version": "6.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-6.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-6.17.1.tgz",
|
||||||
"integrity": "sha512-wN1jVC+gxQDcLL/dyuIMbedPZpxTHNW9gto82jvgyjXLIUKOWiQUVJS7moaLhTM27BMWBrHMfG+K4RnsnKEW9A==",
|
"integrity": "sha512-WrztLKLQpbt4mFFR4xYDfsFrYORFfDH4pG7LjoeeOIANZhGspZ4Sk1HdNdQ2OoDDLZQpABdyZ9RLHKo/XycAjA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.0.0",
|
"@fortawesome/free-regular-svg-icons": "^6.0.0",
|
||||||
@ -104,9 +104,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/loaders": {
|
"node_modules/@babylonjs/loaders": {
|
||||||
"version": "6.15.0",
|
"version": "6.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-6.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/loaders/-/loaders-6.17.1.tgz",
|
||||||
"integrity": "sha512-pE22KVLEWcsWPmiL+TFsNyqLTMGhnt/6oPDy3nWpMwHTfjeaoW9qTV7hFDwhXopzU1Ddp6c/DhzFZalgSvCvbg==",
|
"integrity": "sha512-k4g2rnqKnzoq+8AYO4IQL3aLAJDCCJrpL8Qj/CoVFjt3fDsPzC3ncnmu45VaTwpiXI5St/qfX3s9Bwncn6aI+A==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^6.0.0",
|
||||||
"babylonjs-gltf2interface": "^6.0.0"
|
"babylonjs-gltf2interface": "^6.0.0"
|
||||||
@ -122,18 +122,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babylonjs/serializers": {
|
"node_modules/@babylonjs/serializers": {
|
||||||
"version": "6.15.0",
|
"version": "6.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-6.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-6.17.1.tgz",
|
||||||
"integrity": "sha512-qUKqMe18wlEQpyh5cAa/u/B4xMZ2tKh5K1CurnN9TXaM6i8wImRL4mmXqlwy/Tq18zUGmfmPyU1p1qPuD1ytcg==",
|
"integrity": "sha512-+wSKhOPKu9wsAB4cmRARyYMgB7uGjr0axnFwZUBp8zaJ2beW9YxFvSqFcRVe2cgrwRel5FkVlM0xDxgak3dPVg==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babylonjs/core": "^6.0.0",
|
"@babylonjs/core": "^6.0.0",
|
||||||
"babylonjs-gltf2interface": "^6.0.0"
|
"babylonjs-gltf2interface": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@cloudflare/workers-types": {
|
"node_modules/@cloudflare/workers-types": {
|
||||||
"version": "4.20230807.0",
|
"version": "4.20230821.0",
|
||||||
"resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20230807.0.tgz",
|
"resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20230821.0.tgz",
|
||||||
"integrity": "sha512-gQczWuGE2rxmpzOCNn0zLbx8Xz0gqspdE9S7tu4Xax39q1csgO/E9flcS+KG3GHB522ugOh84inmABDhpeJnvQ=="
|
"integrity": "sha512-lVQSyr5E4CEkQw7WIdsrMTj+kHjsm28mJ0B5AhNFByKR+16KTFsU/RW/nGLKHHW2jxT5lvYI+HjNQMzC9QR8Ng=="
|
||||||
},
|
},
|
||||||
"node_modules/@eneris/push-receiver": {
|
"node_modules/@eneris/push-receiver": {
|
||||||
"version": "3.1.4",
|
"version": "3.1.4",
|
||||||
@ -150,9 +150,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/android-arm": {
|
"node_modules/@esbuild/android-arm": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
|
||||||
"integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
|
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -166,9 +166,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/android-arm64": {
|
"node_modules/@esbuild/android-arm64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
|
||||||
"integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
|
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -182,9 +182,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/android-x64": {
|
"node_modules/@esbuild/android-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
|
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -198,9 +198,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/darwin-arm64": {
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
|
||||||
"integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
|
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -214,9 +214,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/darwin-x64": {
|
"node_modules/@esbuild/darwin-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
|
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -230,9 +230,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/freebsd-arm64": {
|
"node_modules/@esbuild/freebsd-arm64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
|
||||||
"integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
|
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -246,9 +246,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/freebsd-x64": {
|
"node_modules/@esbuild/freebsd-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
|
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -262,9 +262,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-arm": {
|
"node_modules/@esbuild/linux-arm": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
|
||||||
"integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
|
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -278,9 +278,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-arm64": {
|
"node_modules/@esbuild/linux-arm64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
|
||||||
"integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
|
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -294,9 +294,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-ia32": {
|
"node_modules/@esbuild/linux-ia32": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
|
||||||
"integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
|
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@ -310,9 +310,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-loong64": {
|
"node_modules/@esbuild/linux-loong64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
|
||||||
"integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
|
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@ -326,9 +326,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-mips64el": {
|
"node_modules/@esbuild/linux-mips64el": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
|
||||||
"integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
|
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"mips64el"
|
"mips64el"
|
||||||
],
|
],
|
||||||
@ -342,9 +342,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-ppc64": {
|
"node_modules/@esbuild/linux-ppc64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
|
||||||
"integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
|
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@ -358,9 +358,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-riscv64": {
|
"node_modules/@esbuild/linux-riscv64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
|
||||||
"integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
|
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@ -374,9 +374,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-s390x": {
|
"node_modules/@esbuild/linux-s390x": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
|
||||||
"integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
|
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@ -390,9 +390,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/linux-x64": {
|
"node_modules/@esbuild/linux-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
|
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -406,9 +406,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/netbsd-x64": {
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
|
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -422,9 +422,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/openbsd-x64": {
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
|
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -438,9 +438,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/sunos-x64": {
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
|
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -454,9 +454,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/win32-arm64": {
|
"node_modules/@esbuild/win32-arm64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
|
||||||
"integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
|
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -470,9 +470,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/win32-ia32": {
|
"node_modules/@esbuild/win32-ia32": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
|
||||||
"integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
|
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@ -486,9 +486,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/win32-x64": {
|
"node_modules/@esbuild/win32-x64": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
|
||||||
"integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
|
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -983,9 +983,9 @@
|
|||||||
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
|
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "14.18.54",
|
"version": "18.17.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.8.tgz",
|
||||||
"integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw=="
|
"integrity": "sha512-Av/7MqX/iNKwT9Tr60V85NqMnsmh8ilfJoBlIVibkXfitk9Q22D9Y5mSpm+FvG5DET7EbVfB40bOiLzKgYFgPw=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
@ -1810,9 +1810,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.17.19",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
||||||
"integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
|
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -1822,28 +1822,28 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@esbuild/android-arm": "0.17.19",
|
"@esbuild/android-arm": "0.18.20",
|
||||||
"@esbuild/android-arm64": "0.17.19",
|
"@esbuild/android-arm64": "0.18.20",
|
||||||
"@esbuild/android-x64": "0.17.19",
|
"@esbuild/android-x64": "0.18.20",
|
||||||
"@esbuild/darwin-arm64": "0.17.19",
|
"@esbuild/darwin-arm64": "0.18.20",
|
||||||
"@esbuild/darwin-x64": "0.17.19",
|
"@esbuild/darwin-x64": "0.18.20",
|
||||||
"@esbuild/freebsd-arm64": "0.17.19",
|
"@esbuild/freebsd-arm64": "0.18.20",
|
||||||
"@esbuild/freebsd-x64": "0.17.19",
|
"@esbuild/freebsd-x64": "0.18.20",
|
||||||
"@esbuild/linux-arm": "0.17.19",
|
"@esbuild/linux-arm": "0.18.20",
|
||||||
"@esbuild/linux-arm64": "0.17.19",
|
"@esbuild/linux-arm64": "0.18.20",
|
||||||
"@esbuild/linux-ia32": "0.17.19",
|
"@esbuild/linux-ia32": "0.18.20",
|
||||||
"@esbuild/linux-loong64": "0.17.19",
|
"@esbuild/linux-loong64": "0.18.20",
|
||||||
"@esbuild/linux-mips64el": "0.17.19",
|
"@esbuild/linux-mips64el": "0.18.20",
|
||||||
"@esbuild/linux-ppc64": "0.17.19",
|
"@esbuild/linux-ppc64": "0.18.20",
|
||||||
"@esbuild/linux-riscv64": "0.17.19",
|
"@esbuild/linux-riscv64": "0.18.20",
|
||||||
"@esbuild/linux-s390x": "0.17.19",
|
"@esbuild/linux-s390x": "0.18.20",
|
||||||
"@esbuild/linux-x64": "0.17.19",
|
"@esbuild/linux-x64": "0.18.20",
|
||||||
"@esbuild/netbsd-x64": "0.17.19",
|
"@esbuild/netbsd-x64": "0.18.20",
|
||||||
"@esbuild/openbsd-x64": "0.17.19",
|
"@esbuild/openbsd-x64": "0.18.20",
|
||||||
"@esbuild/sunos-x64": "0.17.19",
|
"@esbuild/sunos-x64": "0.18.20",
|
||||||
"@esbuild/win32-arm64": "0.17.19",
|
"@esbuild/win32-arm64": "0.18.20",
|
||||||
"@esbuild/win32-ia32": "0.17.19",
|
"@esbuild/win32-ia32": "0.18.20",
|
||||||
"@esbuild/win32-x64": "0.17.19"
|
"@esbuild/win32-x64": "0.18.20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
@ -3141,9 +3141,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.24",
|
"version": "8.4.28",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz",
|
||||||
"integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
|
"integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -3424,9 +3424,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "3.25.1",
|
"version": "3.28.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz",
|
||||||
"integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==",
|
"integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
@ -3929,14 +3929,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "4.3.9",
|
"version": "4.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
|
||||||
"integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==",
|
"integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.17.5",
|
"esbuild": "^0.18.10",
|
||||||
"postcss": "^8.4.23",
|
"postcss": "^8.4.27",
|
||||||
"rollup": "^3.21.0"
|
"rollup": "^3.27.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite": "bin/vite.js"
|
"vite": "bin/vite.js"
|
||||||
@ -3944,12 +3944,16 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.18.0 || >=16.0.0"
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
},
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/vitejs/vite?sponsor=1"
|
||||||
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/node": ">= 14",
|
"@types/node": ">= 14",
|
||||||
"less": "*",
|
"less": "*",
|
||||||
|
"lightningcss": "^1.21.0",
|
||||||
"sass": "*",
|
"sass": "*",
|
||||||
"stylus": "*",
|
"stylus": "*",
|
||||||
"sugarss": "*",
|
"sugarss": "*",
|
||||||
@ -3962,6 +3966,9 @@
|
|||||||
"less": {
|
"less": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"lightningcss": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"sass": {
|
"sass": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
|||||||
21
package.json
21
package.json
@ -3,6 +3,9 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
@ -12,16 +15,16 @@
|
|||||||
"havok": "cp ./node_modules/@babylonjs/havok/lib/esm/HavokPhysics.wasm ./node_modules/.vite/deps"
|
"havok": "cp ./node_modules/@babylonjs/havok/lib/esm/HavokPhysics.wasm ./node_modules/.vite/deps"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babylonjs/core": "^6.15.0",
|
"@babylonjs/core": "^6.17.1",
|
||||||
"@babylonjs/gui": "^6.15.0",
|
"@babylonjs/gui": "^6.17.1",
|
||||||
"@babylonjs/havok": "1.1.1",
|
"@babylonjs/havok": "1.1.4",
|
||||||
"@babylonjs/inspector": "^6.15.0",
|
"@babylonjs/inspector": "^6.17.1",
|
||||||
"@babylonjs/loaders": "^6.15.0",
|
"@babylonjs/loaders": "^6.17.1",
|
||||||
"@babylonjs/serializers": "^6.15.0",
|
"@babylonjs/serializers": "^6.17.1",
|
||||||
"@cloudflare/workers-types": "^4.20230807.0",
|
"@cloudflare/workers-types": "^4.20230821.0",
|
||||||
"@netlify/functions": "^1.6.0",
|
"@netlify/functions": "^1.6.0",
|
||||||
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
|
||||||
"@types/node": "^14.18.54",
|
"@types/node": "^18.14.0",
|
||||||
"dexie": "^3.2.4",
|
"dexie": "^3.2.4",
|
||||||
"dexie-observable": "^4.0.1-beta.13",
|
"dexie-observable": "^4.0.1-beta.13",
|
||||||
"earcut": "^2.2.4",
|
"earcut": "^2.2.4",
|
||||||
@ -38,7 +41,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.4.9",
|
||||||
"vite-plugin-api": "^0.1.11",
|
"vite-plugin-api": "^0.1.11",
|
||||||
"vite-plugin-cp": "^1.0.0"
|
"vite-plugin-cp": "^1.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,7 +82,14 @@ export class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
xr.baseExperience.sessionManager.onXRSessionInit.add((session) => {
|
||||||
|
session.addEventListener('visibilitychange', (ev) => {
|
||||||
|
console.log(ev);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
xr.baseExperience.onStateChangedObservable.add((state) => {
|
xr.baseExperience.onStateChangedObservable.add((state) => {
|
||||||
|
console.log(state);
|
||||||
if (state == WebXRState.IN_XR) {
|
if (state == WebXRState.IN_XR) {
|
||||||
scene.audioEnabled = true;
|
scene.audioEnabled = true;
|
||||||
xr.baseExperience.camera.position = new Vector3(0, 1.6, 0);
|
xr.baseExperience.camera.position = new Vector3(0, 1.6, 0);
|
||||||
@ -93,8 +100,10 @@ export class App {
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const rig = new Rigplatform(scene, xr, diagramManager, controllers);
|
const rig = new Rigplatform(scene, xr, diagramManager, controllers);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -12,10 +12,12 @@ import {
|
|||||||
import {DiagramManager} from "../diagram/diagramManager";
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {Controllers} from "./controllers";
|
import {ControllerEventType, Controllers} from "./controllers";
|
||||||
import {toDiagramEntity} from "../diagram/functions/toDiagramEntity";
|
import {toDiagramEntity} from "../diagram/functions/toDiagramEntity";
|
||||||
import {setupTransformNode} from "./functions/setupTransformNode";
|
import {setupTransformNode} from "./functions/setupTransformNode";
|
||||||
import {reparent} from "./functions/reparent";
|
import {reparent} from "./functions/reparent";
|
||||||
|
import {snapGridVal} from "../util/functions/snapGridVal";
|
||||||
|
import {snapRotateVal} from "../util/functions/snapRotateVal";
|
||||||
|
|
||||||
export class Base {
|
export class Base {
|
||||||
static stickVector = Vector3.Zero();
|
static stickVector = Vector3.Zero();
|
||||||
@ -72,26 +74,35 @@ export class Base {
|
|||||||
}
|
}
|
||||||
}, -1, false, this);
|
}, -1, false, this);
|
||||||
this.controllers.controllerObserver.add((event) => {
|
this.controllers.controllerObserver.add((event) => {
|
||||||
if (event.type == 'pulse') {
|
|
||||||
this.logger.debug(event);
|
this.logger.debug(event);
|
||||||
|
switch (event.type) {
|
||||||
|
case ControllerEventType.PULSE:
|
||||||
if (event.gripId == this?.controller?.grip?.id) {
|
if (event.gripId == this?.controller?.grip?.id) {
|
||||||
this.controller?.motionController?.pulse(.25, 30)
|
this.controller?.motionController?.pulse(.25, 30)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.logger.debug("pulse done");
|
this.logger.debug("pulse done");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
case ControllerEventType.HIDE:
|
||||||
|
this.disable();
|
||||||
|
break;
|
||||||
|
case ControllerEventType.SHOW:
|
||||||
|
this.enable();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public disable() {
|
public disable() {
|
||||||
this.controller.motionController.rootMesh.setEnabled(false);
|
this.controller.motionController.rootMesh.setEnabled(false)
|
||||||
this.controller.pointer.setEnabled(false);
|
this.controller.pointer.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enable() {
|
public enable() {
|
||||||
this.controller.motionController.rootMesh.setEnabled(true);
|
this.controller.motionController.rootMesh.setEnabled(true);
|
||||||
this.controller.pointer.setEnabled(true);
|
this.controller.pointer.setEnabled(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private grab() {
|
private grab() {
|
||||||
@ -174,8 +185,8 @@ export class Base {
|
|||||||
this.grabbedMeshParentId = null;
|
this.grabbedMeshParentId = null;
|
||||||
|
|
||||||
if (!mesh.physicsBody) {
|
if (!mesh.physicsBody) {
|
||||||
mesh.position = this.diagramManager.config.snapGridVal(mesh.position, this.diagramManager.config.current.gridSnap);
|
mesh.position = snapGridVal(mesh.position, this.diagramManager.config.current.gridSnap);
|
||||||
mesh.rotation = this.diagramManager.config.snapRotateVal(mesh.rotation, this.diagramManager.config.current.rotateSnap);
|
mesh.rotation = snapRotateVal(mesh.rotation, this.diagramManager.config.current.rotateSnap);
|
||||||
}
|
}
|
||||||
this.previousParentId = null;
|
this.previousParentId = null;
|
||||||
this.previousScaling = null;
|
this.previousScaling = null;
|
||||||
|
|||||||
@ -1,11 +1,34 @@
|
|||||||
import {AbstractMesh, Observable, TransformNode} from "@babylonjs/core";
|
import {AbstractMesh, Observable, TransformNode} from "@babylonjs/core";
|
||||||
|
|
||||||
export type ControllerEventType = {
|
export type ControllerEvent = {
|
||||||
type: string,
|
type: ControllerEventType,
|
||||||
value?: number,
|
value?: number,
|
||||||
gripId?: string;
|
gripId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ControllerEventType {
|
||||||
|
GRIP = 'grip',
|
||||||
|
HIDE = 'hide',
|
||||||
|
SHOW = 'show',
|
||||||
|
PULSE = 'pulse',
|
||||||
|
SQUEEZE = 'squeeze',
|
||||||
|
Y_BUTTON = 'y-button',
|
||||||
|
X_BUTTON = 'x-button',
|
||||||
|
A_BUTTON = 'a-button',
|
||||||
|
B_BUTTON = 'b-button',
|
||||||
|
THUMBSTICK = 'thumbstick',
|
||||||
|
THUMBSTICK_CHANGED = 'thumbstickChanged',
|
||||||
|
DECREASE_VELOCITY = 'decreaseVelocity',
|
||||||
|
INCREASE_VELOCITY = 'decreaseVelocity',
|
||||||
|
LEFT_RIGHT = 'leftright',
|
||||||
|
FORWARD_BACK = 'forwardback',
|
||||||
|
TURN = 'turn',
|
||||||
|
UP_DOWN = 'updown',
|
||||||
|
TRIGGER = 'trigger',
|
||||||
|
MENU = 'menu'
|
||||||
|
}
|
||||||
|
|
||||||
export class Controllers {
|
export class Controllers {
|
||||||
public movable: TransformNode | AbstractMesh;
|
public movable: TransformNode | AbstractMesh;
|
||||||
public readonly controllerObserver: Observable<ControllerEventType> = new Observable();
|
public readonly controllerObserver: Observable<ControllerEvent> = new Observable();
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
||||||
import {Base} from "./base";
|
import {Base} from "./base";
|
||||||
import {Controllers} from "./controllers";
|
import {ControllerEventType, Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {ConfigMenu} from "../menus/configMenu";
|
import {ConfigMenu} from "../menus/configMenu";
|
||||||
import {DiagramManager} from "../diagram/diagramManager";
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
@ -13,7 +13,7 @@ export class Left extends Base {
|
|||||||
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) {
|
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) {
|
||||||
|
|
||||||
super(controller, scene, xr, controllers, diagramManager);
|
super(controller, scene, xr, controllers, diagramManager);
|
||||||
this.configMenu = new ConfigMenu(this.scene, xr.baseExperience, this.controllers, this.diagramManager.config);
|
this.configMenu = new ConfigMenu(this.scene, xr, this.controllers, this.diagramManager.config);
|
||||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||||
if (init.components['xr-standard-thumbstick']) {
|
if (init.components['xr-standard-thumbstick']) {
|
||||||
init.components['xr-standard-thumbstick']
|
init.components['xr-standard-thumbstick']
|
||||||
@ -31,7 +31,7 @@ export class Left extends Base {
|
|||||||
if (value.pressed) {
|
if (value.pressed) {
|
||||||
log.trace('Left', 'thumbstick changed');
|
log.trace('Left', 'thumbstick changed');
|
||||||
this.controllers.controllerObserver.notifyObservers({
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
type: 'decreaseVelocity',
|
type: ControllerEventType.DECREASE_VELOCITY,
|
||||||
value: value.value
|
value: value.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -44,7 +44,10 @@ export class Left extends Base {
|
|||||||
if (xbutton) {
|
if (xbutton) {
|
||||||
xbutton.onButtonStateChangedObservable.add((button) => {
|
xbutton.onButtonStateChangedObservable.add((button) => {
|
||||||
if (button.pressed) {
|
if (button.pressed) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'x-button', value: button.value});
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
|
type: ControllerEventType.X_BUTTON,
|
||||||
|
value: button.value
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -54,7 +57,10 @@ export class Left extends Base {
|
|||||||
if (ybutton) {
|
if (ybutton) {
|
||||||
ybutton.onButtonStateChangedObservable.add((button) => {
|
ybutton.onButtonStateChangedObservable.add((button) => {
|
||||||
if (button.pressed) {
|
if (button.pressed) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'y-button', value: button.value});
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
|
type: ControllerEventType.Y_BUTTON,
|
||||||
|
value: button.value
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -75,14 +81,17 @@ export class Left extends Base {
|
|||||||
|
|
||||||
private moveRig(value: { x: number, y: number }) {
|
private moveRig(value: { x: number, y: number }) {
|
||||||
if (Math.abs(value.x) > .1) {
|
if (Math.abs(value.x) > .1) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'leftright', value: value.x * this.speedFactor});
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
|
type: ControllerEventType.LEFT_RIGHT,
|
||||||
|
value: value.x * this.speedFactor
|
||||||
|
});
|
||||||
Base.stickVector.x = 1;
|
Base.stickVector.x = 1;
|
||||||
} else {
|
} else {
|
||||||
Base.stickVector.x = 0;
|
Base.stickVector.x = 0;
|
||||||
}
|
}
|
||||||
if (Math.abs(value.y) > .1) {
|
if (Math.abs(value.y) > .1) {
|
||||||
this.controllers.controllerObserver.notifyObservers({
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
type: 'forwardback',
|
type: ControllerEventType.FORWARD_BACK,
|
||||||
value: value.y * this.speedFactor
|
value: value.y * this.speedFactor
|
||||||
});
|
});
|
||||||
Base.stickVector.y = 1;
|
Base.stickVector.y = 1;
|
||||||
@ -91,8 +100,8 @@ export class Left extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Base.stickVector.equals(Vector3.Zero())) {
|
if (Base.stickVector.equals(Vector3.Zero())) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'leftright', value: 0});
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.LEFT_RIGHT, value: 0});
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'forwardback', value: 0});
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.FORWARD_BACK, value: 0});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import {Base} from "./base";
|
import {Base} from "./base";
|
||||||
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
||||||
import {Controllers} from "./controllers";
|
import {ControllerEventType, Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {DiagramManager} from "../diagram/diagramManager";
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
@ -21,7 +21,10 @@ export class Right extends Base {
|
|||||||
if (bbutton) {
|
if (bbutton) {
|
||||||
bbutton.onButtonStateChangedObservable.add((button) => {
|
bbutton.onButtonStateChangedObservable.add((button) => {
|
||||||
if (button.pressed) {
|
if (button.pressed) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'b-button', value: button.value});
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
|
type: ControllerEventType.B_BUTTON,
|
||||||
|
value: button.value
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -33,7 +36,10 @@ export class Right extends Base {
|
|||||||
.onButtonStateChangedObservable
|
.onButtonStateChangedObservable
|
||||||
.add((button) => {
|
.add((button) => {
|
||||||
if (button.pressed) {
|
if (button.pressed) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'trigger', value: button.value});
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
|
type: ControllerEventType.TRIGGER,
|
||||||
|
value: button.value
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -44,7 +50,7 @@ export class Right extends Base {
|
|||||||
abutton.onButtonStateChangedObservable.add((value) => {
|
abutton.onButtonStateChangedObservable.add((value) => {
|
||||||
if (value.pressed) {
|
if (value.pressed) {
|
||||||
log.getLogger("right").debug("a-button pressed");
|
log.getLogger("right").debug("a-button pressed");
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'menu'});
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.MENU});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -59,7 +65,10 @@ export class Right extends Base {
|
|||||||
thumbstick.onButtonStateChangedObservable.add((value) => {
|
thumbstick.onButtonStateChangedObservable.add((value) => {
|
||||||
if (value.pressed) {
|
if (value.pressed) {
|
||||||
log.trace('Right', `thumbstick changed ${value.value}`);
|
log.trace('Right', `thumbstick changed ${value.value}`);
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'increaseVelocity', value: value.value});
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
|
type: ControllerEventType.INCREASE_VELOCITY,
|
||||||
|
value: value.value
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -67,19 +76,22 @@ export class Right extends Base {
|
|||||||
|
|
||||||
private moveRig(value) {
|
private moveRig(value) {
|
||||||
if (Math.abs(value.x) > .1) {
|
if (Math.abs(value.x) > .1) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'turn', value: value.x});
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.TURN, value: value.x});
|
||||||
} else {
|
} else {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'turn', value: 0});
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.TURN, value: 0});
|
||||||
}
|
}
|
||||||
if (Math.abs(value.y) > .1) {
|
if (Math.abs(value.y) > .1) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'updown', value: value.y * this.speedFactor});
|
this.controllers.controllerObserver.notifyObservers({
|
||||||
|
type: ControllerEventType.UP_DOWN,
|
||||||
|
value: value.y * this.speedFactor
|
||||||
|
});
|
||||||
Base.stickVector.z = 1;
|
Base.stickVector.z = 1;
|
||||||
} else {
|
} else {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'updown', value: 0});
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.UP_DOWN, value: 0});
|
||||||
Base.stickVector.z = 0;
|
Base.stickVector.z = 0;
|
||||||
}
|
}
|
||||||
if (Base.stickVector.equals(Vector3.Zero())) {
|
if (Base.stickVector.equals(Vector3.Zero())) {
|
||||||
this.controllers.controllerObserver.notifyObservers({type: 'updown', value: 0});
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.UP_DOWN, value: 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,7 +17,7 @@ import {
|
|||||||
import {Right} from "./right";
|
import {Right} from "./right";
|
||||||
import {Left} from "./left";
|
import {Left} from "./left";
|
||||||
import {EditMenu} from "../menus/editMenu";
|
import {EditMenu} from "../menus/editMenu";
|
||||||
import {Controllers} from "./controllers";
|
import {ControllerEvent, ControllerEventType, Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {DiagramManager} from "../diagram/diagramManager";
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ export class Rigplatform {
|
|||||||
this.controllers = controllers;
|
this.controllers = controllers;
|
||||||
Rigplatform.xr = xr;
|
Rigplatform.xr = xr;
|
||||||
Rigplatform.instance = this;
|
Rigplatform.instance = this;
|
||||||
this.bMenu = new EditMenu(scene, xr, this.diagramManager);
|
this.bMenu = new EditMenu(scene, xr, this.diagramManager, controllers);
|
||||||
this.camera = scene.activeCamera;
|
this.camera = scene.activeCamera;
|
||||||
|
|
||||||
this.rigMesh = MeshBuilder.CreateBox("platform", {width: 2, height: .02, depth: 2}, scene);
|
this.rigMesh = MeshBuilder.CreateBox("platform", {width: 2, height: .02, depth: 2}, scene);
|
||||||
@ -125,38 +125,35 @@ export class Rigplatform {
|
|||||||
private registerObserver() {
|
private registerObserver() {
|
||||||
if (!this.registered) {
|
if (!this.registered) {
|
||||||
this.registered = true;
|
this.registered = true;
|
||||||
this.controllers.controllerObserver.add((event: { type: string, value: number }) => {
|
this.controllers.controllerObserver.add((event: ControllerEvent) => {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case "increaseVelocity":
|
case ControllerEventType.INCREASE_VELOCITY:
|
||||||
if (this.velocityIndex < this.velocityArray.length - 1) {
|
if (this.velocityIndex < this.velocityArray.length - 1) {
|
||||||
this.velocityIndex++;
|
this.velocityIndex++;
|
||||||
} else {
|
} else {
|
||||||
this.velocityIndex = 0;
|
this.velocityIndex = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "decreaseVelocity":
|
case ControllerEventType.DECREASE_VELOCITY:
|
||||||
if (this.velocityIndex > 0) {
|
if (this.velocityIndex > 0) {
|
||||||
this.velocityIndex--;
|
this.velocityIndex--;
|
||||||
} else {
|
} else {
|
||||||
this.velocityIndex = this.velocityArray.length - 1;
|
this.velocityIndex = this.velocityArray.length - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "turn":
|
case ControllerEventType.TURN:
|
||||||
this.turn(event.value);
|
this.turn(event.value);
|
||||||
break;
|
break;
|
||||||
case "forwardback":
|
case ControllerEventType.FORWARD_BACK:
|
||||||
this.forwardback(event.value);
|
this.forwardback(event.value);
|
||||||
break;
|
break;
|
||||||
case "leftright":
|
case ControllerEventType.LEFT_RIGHT:
|
||||||
this.leftright(event.value);
|
this.leftright(event.value);
|
||||||
break;
|
break;
|
||||||
case "updown":
|
case ControllerEventType.UP_DOWN:
|
||||||
this.updown(event.value);
|
this.updown(event.value);
|
||||||
break;
|
break;
|
||||||
case "stop":
|
case ControllerEventType.MENU:
|
||||||
log.warn("Rigplatform", "stop is no longer implemented");
|
|
||||||
break;
|
|
||||||
case "menu":
|
|
||||||
this.bMenu.toggle();
|
this.bMenu.toggle();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import {ActionManager, ExecuteCodeAction, PlaySoundAction, Scene} from "@babylonjs/core";
|
import {ActionManager, ExecuteCodeAction, PlaySoundAction, Scene} from "@babylonjs/core";
|
||||||
import {DiaSounds} from "../util/diaSounds";
|
import {DiaSounds} from "../util/diaSounds";
|
||||||
import {Controllers} from "../controllers/controllers";
|
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
export class DiagramEntityActionManager {
|
export class DiagramEntityActionManager {
|
||||||
@ -14,7 +14,7 @@ export class DiagramEntityActionManager {
|
|||||||
this._actionManager.registerAction(
|
this._actionManager.registerAction(
|
||||||
new ExecuteCodeAction(ActionManager.OnPointerOverTrigger, (evt) => {
|
new ExecuteCodeAction(ActionManager.OnPointerOverTrigger, (evt) => {
|
||||||
controllers.controllerObserver.notifyObservers({
|
controllers.controllerObserver.notifyObservers({
|
||||||
type: 'pulse',
|
type: ControllerEventType.PULSE,
|
||||||
gripId: evt?.additionalData?.pickResult?.gripTransform?.id
|
gripId: evt?.additionalData?.pickResult?.gripTransform?.id
|
||||||
})
|
})
|
||||||
this.logger.debug(evt);
|
this.logger.debug(evt);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {Toolbox} from "../toolbox/toolbox";
|
|||||||
import {PresentationManager} from "./presentationManager";
|
import {PresentationManager} from "./presentationManager";
|
||||||
import {DiagramEntityActionManager} from "./diagramEntityActionManager";
|
import {DiagramEntityActionManager} from "./diagramEntityActionManager";
|
||||||
import {diagramEventHandler} from "./diagramEventHandler";
|
import {diagramEventHandler} from "./diagramEventHandler";
|
||||||
import {deepCopy} from "../util/deepCopy";
|
import {deepCopy} from "../util/functions/deepCopy";
|
||||||
import {applyPhysics} from "./functions/diagramShapePhysics";
|
import {applyPhysics} from "./functions/diagramShapePhysics";
|
||||||
import {applyScaling} from "./functions/applyScaling";
|
import {applyScaling} from "./functions/applyScaling";
|
||||||
import {toDiagramEntity} from "./functions/toDiagramEntity";
|
import {toDiagramEntity} from "./functions/toDiagramEntity";
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import {Observable, Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
import {Observable, Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {AdvancedDynamicTexture, InputText} from "@babylonjs/gui";
|
import {AdvancedDynamicTexture, InputText} from "@babylonjs/gui";
|
||||||
|
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||||
|
|
||||||
export type TextEvent = {
|
export type TextEvent = {
|
||||||
text: string;
|
text: string;
|
||||||
@ -9,12 +10,14 @@ export type InputTextViewOptions = {
|
|||||||
scene?: Scene;
|
scene?: Scene;
|
||||||
xr?: WebXRDefaultExperience;
|
xr?: WebXRDefaultExperience;
|
||||||
text?: string;
|
text?: string;
|
||||||
|
controllers?: Controllers;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InputTextView {
|
export class InputTextView {
|
||||||
public readonly onTextObservable: Observable<TextEvent> = new Observable<TextEvent>();
|
public readonly onTextObservable: Observable<TextEvent> = new Observable<TextEvent>();
|
||||||
private readonly text: string;
|
private readonly text: string;
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
|
private readonly controllers: Controllers;
|
||||||
private readonly xr: WebXRDefaultExperience;
|
private readonly xr: WebXRDefaultExperience;
|
||||||
|
|
||||||
constructor(options: InputTextViewOptions) {
|
constructor(options: InputTextViewOptions) {
|
||||||
@ -27,10 +30,14 @@ export class InputTextView {
|
|||||||
if (options.scene) {
|
if (options.scene) {
|
||||||
this.scene = options.scene;
|
this.scene = options.scene;
|
||||||
}
|
}
|
||||||
|
if (options.controllers) {
|
||||||
|
this.controllers = options.controllers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public show() {
|
public show() {
|
||||||
if (this?.xr?.baseExperience?.sessionManager?.inXRSession) {
|
|
||||||
|
if ((this.xr as WebXRDefaultExperience).baseExperience?.sessionManager?.inXRSession) {
|
||||||
this.showXr();
|
this.showXr();
|
||||||
} else {
|
} else {
|
||||||
this.showWeb();
|
this.showWeb();
|
||||||
@ -62,33 +69,31 @@ export class InputTextView {
|
|||||||
textInput.type = "text";
|
textInput.type = "text";
|
||||||
document.body.appendChild(textInput);
|
document.body.appendChild(textInput);
|
||||||
textInput.value = this.text;
|
textInput.value = this.text;
|
||||||
if (this.xr?.baseExperience?.sessionManager?.inXRSession) {
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.HIDE});
|
||||||
|
|
||||||
|
/*if (this.xr?.baseExperience?.sessionManager?.inXRSession) {
|
||||||
this.xr.input.controllers.forEach((controller) => {
|
this.xr.input.controllers.forEach((controller) => {
|
||||||
controller.motionController.rootMesh.setEnabled(false);
|
controller.motionController.rootMesh.setEnabled(false);
|
||||||
controller.pointer.setEnabled(false);
|
controller.pointer.setEnabled(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
textInput.focus();
|
|
||||||
if (navigator.userAgent.indexOf('Macintosh') > -1) {
|
|
||||||
textInput.addEventListener('input', (event) => {
|
|
||||||
log.debug(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
textInput.addEventListener('blur', () => {
|
textInput.addEventListener('blur', () => {
|
||||||
log.getLogger('bmenu').debug("blur");
|
log.getLogger('bmenu').debug("blur");
|
||||||
this.onTextObservable.notifyObservers({text: textInput.value});
|
this.onTextObservable.notifyObservers({text: textInput.value});
|
||||||
if (this.xr?.baseExperience?.sessionManager?.inXRSession) {
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.SHOW});
|
||||||
|
|
||||||
|
/*if (this.xr?.baseExperience?.sessionManager?.inXRSession) {
|
||||||
this.xr.input.controllers.forEach((controller) => {
|
this.xr.input.controllers.forEach((controller) => {
|
||||||
controller.motionController.rootMesh.setEnabled(true);
|
controller.motionController.rootMesh.setEnabled(true);
|
||||||
controller.pointer.setEnabled(true);
|
controller.pointer.setEnabled(true);
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
textInput.blur();
|
textInput.blur();
|
||||||
textInput.remove();
|
textInput.remove();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
textInput.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,12 @@
|
|||||||
import {Scene, WebXRExperienceHelper} from "@babylonjs/core";
|
import {Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import {Controllers} from "../controllers/controllers";
|
import {Controllers} from "../controllers/controllers";
|
||||||
|
|
||||||
export class AbstractMenu {
|
export class AbstractMenu {
|
||||||
protected scene: Scene;
|
protected scene: Scene;
|
||||||
protected xr: WebXRExperienceHelper;
|
protected xr: WebXRDefaultExperience;
|
||||||
protected controllers: Controllers;
|
protected controllers: Controllers;
|
||||||
|
|
||||||
constructor(scene: Scene, xr: WebXRExperienceHelper, controllers: Controllers) {
|
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.xr = xr;
|
this.xr = xr;
|
||||||
this.controllers = controllers;
|
this.controllers = controllers;
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import {AdvancedDynamicTexture, RadioGroup, SelectionPanel} from "@babylonjs/gui";
|
import {AdvancedDynamicTexture, RadioGroup, SelectionPanel} from "@babylonjs/gui";
|
||||||
import {AbstractMesh, MeshBuilder, Scene, WebXRExperienceHelper} from "@babylonjs/core";
|
import {AbstractMesh, MeshBuilder, Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import {CameraHelper} from "../util/cameraHelper";
|
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {AppConfig} from "../util/appConfig";
|
import {AppConfig} from "../util/appConfig";
|
||||||
import {Controllers} from "../controllers/controllers";
|
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||||
import {DiaSounds} from "../util/diaSounds";
|
import {DiaSounds} from "../util/diaSounds";
|
||||||
import {AbstractMenu} from "./abstractMenu";
|
import {AbstractMenu} from "./abstractMenu";
|
||||||
|
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
||||||
|
|
||||||
export class ConfigMenu extends AbstractMenu {
|
export class ConfigMenu extends AbstractMenu {
|
||||||
private sounds: DiaSounds;
|
private sounds: DiaSounds;
|
||||||
@ -21,6 +21,28 @@ export class ConfigMenu extends AbstractMenu {
|
|||||||
{label: "1", value: 1},
|
{label: "1", value: 1},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
private rotationSnaps: Array<{ label: string, value: number }> = [
|
||||||
|
{label: "Off", value: 0},
|
||||||
|
{label: "22.5", value: 22.5},
|
||||||
|
{label: "45", value: 45},
|
||||||
|
{label: "90", value: 90},
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers, config: AppConfig) {
|
||||||
|
super(scene, xr, controllers);
|
||||||
|
this.config = config;
|
||||||
|
this.sounds = new DiaSounds(scene);
|
||||||
|
if (!this.yObserver) {
|
||||||
|
this.controllers.controllerObserver.add((event) => {
|
||||||
|
if (event.type == ControllerEventType.Y_BUTTON) {
|
||||||
|
this.toggle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public toggle() {
|
public toggle() {
|
||||||
if (this.configPlane) {
|
if (this.configPlane) {
|
||||||
this.sounds.exit.play();
|
this.sounds.exit.play();
|
||||||
@ -48,28 +70,7 @@ export class ConfigMenu extends AbstractMenu {
|
|||||||
this.buildRotationSnapControl(selectionPanel);
|
this.buildRotationSnapControl(selectionPanel);
|
||||||
this.buildTurnSnapControl(selectionPanel);
|
this.buildTurnSnapControl(selectionPanel);
|
||||||
|
|
||||||
CameraHelper.setMenuPosition(this.configPlane, this.scene);
|
setMenuPosition(this.configPlane, this.scene);
|
||||||
}
|
|
||||||
private rotationSnaps: Array<{ label: string, value: number }> = [
|
|
||||||
{label: "Off", value: 0},
|
|
||||||
{label: "22.5", value: 22.5},
|
|
||||||
{label: "45", value: 45},
|
|
||||||
{label: "90", value: 90},
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
constructor(scene: Scene, xr: WebXRExperienceHelper, controllers: Controllers, config: AppConfig) {
|
|
||||||
super(scene, xr, controllers);
|
|
||||||
this.config = config;
|
|
||||||
this.sounds = new DiaSounds(scene);
|
|
||||||
if (!this.yObserver) {
|
|
||||||
this.controllers.controllerObserver.add((event) => {
|
|
||||||
if (event.type == 'y-button') {
|
|
||||||
this.toggle();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildCreateScaleControl(selectionPanel: SelectionPanel): RadioGroup {
|
private buildCreateScaleControl(selectionPanel: SelectionPanel): RadioGroup {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
Scene,
|
Scene,
|
||||||
StandardMaterial,
|
StandardMaterial,
|
||||||
Vector3,
|
Vector3,
|
||||||
WebXRDefaultExperience
|
WebXRDefaultExperience,
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import {Button3D, GUI3DManager, PlanePanel, TextBlock} from "@babylonjs/gui";
|
import {Button3D, GUI3DManager, PlanePanel, TextBlock} from "@babylonjs/gui";
|
||||||
import {DiagramManager} from "../diagram/diagramManager";
|
import {DiagramManager} from "../diagram/diagramManager";
|
||||||
@ -18,20 +18,20 @@ import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
|||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {InputTextView} from "../information/inputTextView";
|
import {InputTextView} from "../information/inputTextView";
|
||||||
import {DiaSounds} from "../util/diaSounds";
|
import {DiaSounds} from "../util/diaSounds";
|
||||||
import {CameraHelper} from "../util/cameraHelper";
|
|
||||||
import {TextLabel} from "../diagram/textLabel";
|
import {TextLabel} from "../diagram/textLabel";
|
||||||
import {DiagramConnection} from "../diagram/diagramConnection";
|
import {DiagramConnection} from "../diagram/diagramConnection";
|
||||||
import {GLTF2Export} from "@babylonjs/serializers";
|
import {GLTF2Export} from "@babylonjs/serializers";
|
||||||
import {toDiagramEntity} from "../diagram/functions/toDiagramEntity";
|
import {toDiagramEntity} from "../diagram/functions/toDiagramEntity";
|
||||||
|
import {AbstractMenu} from "./abstractMenu";
|
||||||
|
import {Controllers} from "../controllers/controllers";
|
||||||
|
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
||||||
|
|
||||||
export class EditMenu {
|
export class EditMenu extends AbstractMenu {
|
||||||
private state: EditMenuState = EditMenuState.NONE;
|
private state: EditMenuState = EditMenuState.NONE;
|
||||||
private manager: GUI3DManager;
|
private manager: GUI3DManager;
|
||||||
private readonly scene: Scene;
|
|
||||||
private paintColor: string = null;
|
private paintColor: string = null;
|
||||||
private readonly logger: log.Logger = log.getLogger('EditMenu');
|
private readonly logger: log.Logger = log.getLogger('EditMenu');
|
||||||
private gizmoManager: GizmoManager;
|
private gizmoManager: GizmoManager;
|
||||||
private readonly xr: WebXRDefaultExperience;
|
|
||||||
private readonly diagramManager: DiagramManager;
|
private readonly diagramManager: DiagramManager;
|
||||||
private connection: DiagramConnection = null;
|
private connection: DiagramConnection = null;
|
||||||
private panel: PlanePanel;
|
private panel: PlanePanel;
|
||||||
@ -49,9 +49,9 @@ export class EditMenu {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager) {
|
constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) {
|
||||||
|
super(scene, xr, controllers);
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.xr = xr;
|
|
||||||
this.sounds = new DiaSounds(scene);
|
this.sounds = new DiaSounds(scene);
|
||||||
this.diagramManager = diagramManager;
|
this.diagramManager = diagramManager;
|
||||||
this.gizmoManager = new GizmoManager(scene);
|
this.gizmoManager = new GizmoManager(scene);
|
||||||
@ -129,7 +129,7 @@ export class EditMenu {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.sounds.enter.play();
|
this.sounds.enter.play();
|
||||||
CameraHelper.setMenuPosition(this.manager.rootContainer.children[0].node, this.scene);
|
setMenuPosition(this.manager.rootContainer.children[0].node, this.scene);
|
||||||
this.isVisible = true;
|
this.isVisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,13 +251,15 @@ export class EditMenu {
|
|||||||
if (mesh?.metadata?.text) {
|
if (mesh?.metadata?.text) {
|
||||||
text = mesh.metadata.text;
|
text = mesh.metadata.text;
|
||||||
}
|
}
|
||||||
const textInput = new InputTextView({xr: this.xr, text: text});
|
const textInput = new InputTextView({xr: this.xr, text: text, controllers: this.controllers});
|
||||||
|
|
||||||
textInput.show();
|
textInput.show();
|
||||||
textInput.onTextObservable.addOnce((value) => {
|
textInput.onTextObservable.addOnce((value) => {
|
||||||
this.persist(mesh, value.text);
|
this.persist(mesh, value.text);
|
||||||
TextLabel.updateTextNode(mesh, value.text);
|
TextLabel.updateTextNode(mesh, value.text);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private showNewRelic() {
|
private showNewRelic() {
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import {AbstractMesh, MeshBuilder, Scene, WebXRExperienceHelper} from "@babylonjs/core";
|
import {AbstractMesh, MeshBuilder, Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import {Controllers} from "../controllers/controllers";
|
import {Controllers} from "../controllers/controllers";
|
||||||
import {AbstractMenu} from "./abstractMenu";
|
import {AbstractMenu} from "./abstractMenu";
|
||||||
import {AdvancedDynamicTexture, Grid, TextBlock} from "@babylonjs/gui";
|
import {AdvancedDynamicTexture, Grid, TextBlock} from "@babylonjs/gui";
|
||||||
import {CameraHelper} from "../util/cameraHelper";
|
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
||||||
|
|
||||||
export class IntegrationMenu extends AbstractMenu {
|
export class IntegrationMenu extends AbstractMenu {
|
||||||
private plane: AbstractMesh = null;
|
private plane: AbstractMesh = null;
|
||||||
|
|
||||||
constructor(scene: Scene, xr: WebXRExperienceHelper, controllers: Controllers) {
|
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) {
|
||||||
super(scene, xr, controllers);
|
super(scene, xr, controllers);
|
||||||
this.buildMenu();
|
this.buildMenu();
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ export class IntegrationMenu extends AbstractMenu {
|
|||||||
grid.addControl(labelText1, 0, 0);
|
grid.addControl(labelText1, 0, 0);
|
||||||
const labelText2 = new TextBlock("labelText1", "New Relic Account");
|
const labelText2 = new TextBlock("labelText1", "New Relic Account");
|
||||||
grid.addControl(labelText2, 1, 0);
|
grid.addControl(labelText2, 1, 0);
|
||||||
CameraHelper.setMenuPosition(this.plane, this.scene);
|
setMenuPosition(this.plane, this.scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
67
src/toolbox/functions/buildColor.ts
Normal file
67
src/toolbox/functions/buildColor.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import {Color3, MeshBuilder, Observable, Scene, StandardMaterial, TransformNode, Vector3} from "@babylonjs/core";
|
||||||
|
import {enumKeys} from "../../util/functions/enumKeys";
|
||||||
|
import {ToolType} from "../types/toolType";
|
||||||
|
import {buildTool} from "./buildTool";
|
||||||
|
import {AdvancedDynamicTexture, ColorPicker} from "@babylonjs/gui";
|
||||||
|
|
||||||
|
export function buildColor(color: Color3, scene: Scene, parent: TransformNode, index: number,
|
||||||
|
colorChangeObservable: Observable<{ oldColor: string, newColor: string }>) {
|
||||||
|
const width = 1;
|
||||||
|
const depth = .2;
|
||||||
|
const material = new StandardMaterial("material-" + color.toHexString(), scene);
|
||||||
|
material.diffuseColor = color;
|
||||||
|
const mesh = MeshBuilder.CreateBox("toolbox-color-" + color.toHexString(), {
|
||||||
|
width: width,
|
||||||
|
height: .01,
|
||||||
|
depth: depth
|
||||||
|
}, this.scene);
|
||||||
|
mesh.material = material;
|
||||||
|
mesh.position.z = index / 4;
|
||||||
|
mesh.parent = parent;
|
||||||
|
mesh.metadata = {tool: 'color'};
|
||||||
|
let i = 0;
|
||||||
|
for (const tool of enumKeys(ToolType)) {
|
||||||
|
const newItem = buildTool(ToolType[tool], mesh);
|
||||||
|
if (newItem) {
|
||||||
|
newItem.position = new Vector3(calculatePosition(++i), .1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const colorPickerPlane = MeshBuilder
|
||||||
|
.CreatePlane("colorPickerPlane",
|
||||||
|
{
|
||||||
|
width: .1,
|
||||||
|
height: .1
|
||||||
|
}, scene);
|
||||||
|
const colorPickerTexture = AdvancedDynamicTexture.CreateForMesh(colorPickerPlane, 1024, 1024);
|
||||||
|
colorPickerPlane.parent = mesh;
|
||||||
|
colorPickerPlane.position = new Vector3(calculatePosition(++i), .1, 0);
|
||||||
|
|
||||||
|
|
||||||
|
const colorPicker = new ColorPicker("color-picker");
|
||||||
|
colorPicker.scaleY = 5;
|
||||||
|
colorPicker.scaleX = 5;
|
||||||
|
colorPicker.value = color;
|
||||||
|
colorPicker.onValueChangedObservable.add((value) => {
|
||||||
|
const oldColor = material.diffuseColor.clone();
|
||||||
|
const newColor = value.clone();
|
||||||
|
material.diffuseColor = newColor;
|
||||||
|
const newColorHex = newColor.toHexString();
|
||||||
|
material.id = "material-" + newColorHex;
|
||||||
|
material.name = "material-" + newColorHex;
|
||||||
|
mesh.id = "toolbox-color-" + newColorHex;
|
||||||
|
mesh.name = "toolbox-color-" + newColorHex;
|
||||||
|
colorChangeObservable.notifyObservers({
|
||||||
|
oldColor: oldColor.toHexString(),
|
||||||
|
newColor: newColor.toHexString()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
colorPickerTexture.addControl(colorPicker);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const GRID_SIZE = 5;
|
||||||
|
|
||||||
|
function calculatePosition(i: number) {
|
||||||
|
return (i / GRID_SIZE) - .5 - (1 / GRID_SIZE / 2);
|
||||||
|
}
|
||||||
29
src/toolbox/functions/buildMesh.ts
Normal file
29
src/toolbox/functions/buildMesh.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import {ToolType} from "../types/toolType";
|
||||||
|
import {Mesh, MeshBuilder} from "@babylonjs/core";
|
||||||
|
|
||||||
|
export function buildMesh(type: ToolType, toolname: string): Mesh {
|
||||||
|
switch (type) {
|
||||||
|
case ToolType.BOX:
|
||||||
|
return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, this.scene);
|
||||||
|
|
||||||
|
case ToolType.SPHERE:
|
||||||
|
return MeshBuilder.CreateSphere(toolname, {diameter: 1}, this.scene);
|
||||||
|
|
||||||
|
case ToolType.CYLINDER:
|
||||||
|
return MeshBuilder.CreateCylinder(toolname, {height: 1, diameter: 1}, this.scene);
|
||||||
|
|
||||||
|
case ToolType.CONE:
|
||||||
|
return MeshBuilder.CreateCylinder(toolname, {
|
||||||
|
diameterTop: 0,
|
||||||
|
height: 1,
|
||||||
|
diameterBottom: 1
|
||||||
|
}, this.scene);
|
||||||
|
|
||||||
|
case ToolType.PLANE:
|
||||||
|
return MeshBuilder.CreatePlane(toolname, {width: 1, height: 1}, this.scene);
|
||||||
|
|
||||||
|
case ToolType.OBJECT:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/toolbox/functions/buildTool.ts
Normal file
36
src/toolbox/functions/buildTool.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import {AbstractMesh, Color3, InstancedMesh, StandardMaterial, Vector3} from "@babylonjs/core";
|
||||||
|
import {ToolType} from "../types/toolType";
|
||||||
|
import {buildMesh} from "./buildMesh";
|
||||||
|
|
||||||
|
const WIDGET_SIZE = .1;
|
||||||
|
|
||||||
|
export function buildTool(tool: ToolType, parent: AbstractMesh) {
|
||||||
|
const id = this.toolId(tool, (parent.material as StandardMaterial).diffuseColor);
|
||||||
|
|
||||||
|
const newItem = buildMesh(tool, `tool-${id}`);
|
||||||
|
if (!newItem) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
newItem.material = parent.material;
|
||||||
|
if (tool === ToolType.PLANE) {
|
||||||
|
newItem.material.backFaceCulling = false;
|
||||||
|
}
|
||||||
|
newItem.scaling = new Vector3(WIDGET_SIZE,
|
||||||
|
WIDGET_SIZE,
|
||||||
|
WIDGET_SIZE);
|
||||||
|
newItem.parent = parent;
|
||||||
|
newItem.metadata = {template: tool};
|
||||||
|
const instance = new InstancedMesh("instance-" + id, newItem);
|
||||||
|
instance.metadata = {template: tool};
|
||||||
|
instance.parent = parent;
|
||||||
|
newItem.setEnabled(false);
|
||||||
|
newItem.onEnabledStateChangedObservable.add(() => {
|
||||||
|
instance.setEnabled(false);
|
||||||
|
});
|
||||||
|
return instance;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function toolId(tool: ToolType, color: Color3) {
|
||||||
|
return tool + "-" + color.toHexString();
|
||||||
|
}
|
||||||
@ -1,35 +1,15 @@
|
|||||||
import {
|
import {Color3, Mesh, MeshBuilder, Observable, Scene, StandardMaterial, TransformNode, Vector3} from "@babylonjs/core";
|
||||||
AbstractMesh,
|
|
||||||
Color3,
|
|
||||||
InstancedMesh,
|
|
||||||
Mesh,
|
|
||||||
MeshBuilder,
|
|
||||||
Observable,
|
|
||||||
Scene,
|
|
||||||
StandardMaterial,
|
|
||||||
TransformNode,
|
|
||||||
Vector3
|
|
||||||
} from "@babylonjs/core";
|
|
||||||
|
|
||||||
import {CameraHelper} from "../util/cameraHelper";
|
import {Button3D, GUI3DManager, StackPanel3D, TextBlock} from "@babylonjs/gui";
|
||||||
import {AdvancedDynamicTexture, Button3D, ColorPicker, GUI3DManager, StackPanel3D, TextBlock} from "@babylonjs/gui";
|
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||||
import {Controllers} from "../controllers/controllers";
|
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
||||||
|
import {buildColor} from "./functions/buildColor";
|
||||||
export enum ToolType {
|
|
||||||
BOX = "#box-template",
|
|
||||||
SPHERE = "#sphere-template",
|
|
||||||
CYLINDER = "#cylinder-template",
|
|
||||||
CONE = "#cone-template",
|
|
||||||
PLANE = "#plane-template",
|
|
||||||
OBJECT = "#object-template",
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Toolbox {
|
export class Toolbox {
|
||||||
private index = 0;
|
private index = 0;
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
public readonly node: TransformNode;
|
public readonly node: TransformNode;
|
||||||
private readonly manager: GUI3DManager;
|
private readonly manager: GUI3DManager;
|
||||||
private readonly gridsize = 5;
|
|
||||||
private readonly addPanel: StackPanel3D;
|
private readonly addPanel: StackPanel3D;
|
||||||
private readonly controllers: Controllers;
|
private readonly controllers: Controllers;
|
||||||
private readonly xObserver;
|
private readonly xObserver;
|
||||||
@ -51,179 +31,61 @@ export class Toolbox {
|
|||||||
handle.id = "handle";
|
handle.id = "handle";
|
||||||
const handleMaterial = new StandardMaterial("handle-material", this.scene);
|
const handleMaterial = new StandardMaterial("handle-material", this.scene);
|
||||||
handleMaterial.diffuseColor = Color3.FromHexString("#EEEEFF");
|
handleMaterial.diffuseColor = Color3.FromHexString("#EEEEFF");
|
||||||
handleMaterial.alpha = .5;
|
handleMaterial.alpha = .8;
|
||||||
handle.material = handleMaterial;
|
handle.material = handleMaterial;
|
||||||
handle.position = Vector3.Zero();
|
handle.position = Vector3.Zero();
|
||||||
|
|
||||||
this.node.parent = handle;
|
this.node.parent = handle;
|
||||||
|
this.node.position.y = .1;
|
||||||
|
this.node.scaling = new Vector3(0.6, 0.6, 0.6);
|
||||||
this.buildToolbox();
|
this.buildToolbox();
|
||||||
|
|
||||||
if (!this.xObserver) {
|
if (!this.xObserver) {
|
||||||
this.xObserver = this.controllers.controllerObserver.add((evt) => {
|
this.xObserver = this.controllers.controllerObserver.add((evt) => {
|
||||||
if (evt.type == 'x-button') {
|
if (evt.type == ControllerEventType.X_BUTTON) {
|
||||||
if (evt.value == 1) {
|
if (evt.value == 1) {
|
||||||
this.node.parent.setEnabled(!this.node.parent.isEnabled(false));
|
this.node.parent.setEnabled(!this.node.parent.isEnabled(false));
|
||||||
CameraHelper.setMenuPosition(this.node.parent as Mesh, this.scene,
|
setMenuPosition(this.node.parent as Mesh, this.scene,
|
||||||
new Vector3(0, 0, 0));
|
Vector3.Zero());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public buildTool(tool: ToolType, parent: AbstractMesh) {
|
|
||||||
const id = this.toolId(tool, (parent.material as StandardMaterial).diffuseColor);
|
|
||||||
|
|
||||||
const newItem = this.buildMesh(tool, `tool-${id}`);
|
|
||||||
if (!newItem) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
newItem.material = parent.material;
|
|
||||||
if (tool === ToolType.PLANE) {
|
|
||||||
newItem.material.backFaceCulling = false;
|
|
||||||
}
|
|
||||||
newItem.scaling = new Vector3(Toolbox.WIDGET_SIZE,
|
|
||||||
Toolbox.WIDGET_SIZE,
|
|
||||||
Toolbox.WIDGET_SIZE);
|
|
||||||
newItem.parent = parent;
|
|
||||||
newItem.metadata = {template: tool};
|
|
||||||
const instance = new InstancedMesh("instance-" + id, newItem);
|
|
||||||
instance.metadata = {template: tool};
|
|
||||||
instance.parent = parent;
|
|
||||||
newItem.setEnabled(false);
|
|
||||||
newItem.onEnabledStateChangedObservable.add(() => {
|
|
||||||
instance.setEnabled(false);
|
|
||||||
});
|
|
||||||
return instance;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildMesh(type: ToolType, toolname: string): Mesh {
|
|
||||||
switch (type) {
|
|
||||||
case ToolType.BOX:
|
|
||||||
return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, this.scene);
|
|
||||||
|
|
||||||
case ToolType.SPHERE:
|
|
||||||
return MeshBuilder.CreateSphere(toolname, {diameter: 1}, this.scene);
|
|
||||||
|
|
||||||
case ToolType.CYLINDER:
|
|
||||||
return MeshBuilder.CreateCylinder(toolname, {height: 1, diameter: 1}, this.scene);
|
|
||||||
|
|
||||||
case ToolType.CONE:
|
|
||||||
return MeshBuilder.CreateCylinder(toolname, {
|
|
||||||
diameterTop: 0,
|
|
||||||
height: 1,
|
|
||||||
diameterBottom: 1
|
|
||||||
}, this.scene);
|
|
||||||
|
|
||||||
case ToolType.PLANE:
|
|
||||||
return MeshBuilder.CreatePlane(toolname, {width: 1, height: 1}, this.scene);
|
|
||||||
|
|
||||||
case ToolType.OBJECT:
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private toolId(tool: ToolType, color: Color3) {
|
|
||||||
return tool + "-" + color.toHexString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private calculatePosition(i: number) {
|
|
||||||
return (i / this.gridsize) - .5 - (1 / this.gridsize / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static WIDGET_SIZE = .1;
|
|
||||||
|
|
||||||
private buildToolbox() {
|
|
||||||
this.node.position.y = .1;
|
|
||||||
this.node.scaling = new Vector3(0.6, 0.6, 0.6);
|
|
||||||
const color = "#7777FF";
|
|
||||||
this.buildColor(Color3.FromHexString(color));
|
|
||||||
|
|
||||||
const addButton = new Button3D("add-button");
|
|
||||||
const text = new TextBlock("add-button-text", "Add Color");
|
|
||||||
text.color = "white";
|
|
||||||
text.fontSize = "48px";
|
|
||||||
text.text = "Add Color";
|
|
||||||
addButton.content = text;
|
|
||||||
this.addPanel.node.parent = this.node.parent;
|
|
||||||
this.addPanel.addControl(addButton);
|
|
||||||
this.addPanel.node.scaling = new Vector3(.1, .1, .1);
|
|
||||||
this.addPanel.position = new Vector3(-.25, 0, 0);
|
|
||||||
addButton.onPointerClickObservable.add(() => {
|
|
||||||
this.buildColor(Color3.Random());
|
|
||||||
});
|
|
||||||
this.node.parent.setEnabled(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public updateToolbox(color: string) {
|
public updateToolbox(color: string) {
|
||||||
if (this.scene.getMeshById("toolbox-color-" + color)) {
|
if (this.scene.getMeshById("toolbox-color-" + color)) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this.buildColor(Color3.FromHexString(color));
|
buildColor(Color3.FromHexString(color), this.scene, this.node, this.index++, this.colorChangeObservable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildColor(color: Color3) {
|
private buildToolbox() {
|
||||||
|
|
||||||
const width = 1;
|
const color = "#7777FF";
|
||||||
const depth = .2;
|
buildColor(Color3.FromHexString(color), this.scene, this.node, this.index++, this.colorChangeObservable);
|
||||||
const material = new StandardMaterial("material-" + color.toHexString(), this.scene);
|
const addButton = createButton();
|
||||||
material.diffuseColor = color;
|
|
||||||
const mesh = MeshBuilder.CreateBox("toolbox-color-" + color.toHexString(), {
|
|
||||||
width: width,
|
|
||||||
height: .01,
|
|
||||||
depth: depth
|
|
||||||
}, this.scene);
|
|
||||||
mesh.material = material;
|
|
||||||
mesh.position.z = this.index++ / 4;
|
|
||||||
mesh.parent = this.node;
|
|
||||||
mesh.metadata = {tool: 'color'};
|
|
||||||
let i = 0;
|
|
||||||
for (const tool of enumKeys(ToolType)) {
|
|
||||||
const newItem = this.buildTool(ToolType[tool], mesh);
|
|
||||||
if (newItem) {
|
|
||||||
newItem.position = new Vector3(this.calculatePosition(++i), .1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const colorPickerPlane = MeshBuilder
|
|
||||||
.CreatePlane("colorPickerPlane",
|
|
||||||
{
|
|
||||||
width: Toolbox.WIDGET_SIZE,
|
|
||||||
height: Toolbox.WIDGET_SIZE
|
|
||||||
}, this.scene);
|
|
||||||
const colorPickerTexture = AdvancedDynamicTexture.CreateForMesh(colorPickerPlane, 1024, 1024);
|
|
||||||
colorPickerPlane.parent = mesh;
|
|
||||||
colorPickerPlane.position = new Vector3(this.calculatePosition(++i), .1, 0);
|
|
||||||
|
|
||||||
|
this.addPanel.node.parent = this.node.parent;
|
||||||
|
this.addPanel.addControl(addButton);
|
||||||
|
this.addPanel.node.scaling = new Vector3(.1, .1, .1);
|
||||||
|
this.addPanel.position = new Vector3(-.25, 0, 0);
|
||||||
|
|
||||||
const colorPicker = new ColorPicker("color-picker");
|
addButton.onPointerClickObservable.add(() => {
|
||||||
colorPicker.scaleY = 5;
|
buildColor(Color3.Random(), this.scene, this.node, this.index++, this.colorChangeObservable);
|
||||||
colorPicker.scaleX = 5;
|
|
||||||
colorPicker.value = color;
|
|
||||||
colorPicker.onValueChangedObservable.add((value) => {
|
|
||||||
const oldColor = material.diffuseColor.clone();
|
|
||||||
const newColor = value.clone();
|
|
||||||
material.diffuseColor = newColor;
|
|
||||||
const newColorHex = newColor.toHexString();
|
|
||||||
material.id = "material-" + newColorHex;
|
|
||||||
material.name = "material-" + newColorHex;
|
|
||||||
mesh.id = "toolbox-color-" + newColorHex;
|
|
||||||
mesh.name = "toolbox-color-" + newColorHex;
|
|
||||||
this.colorChangeObservable.notifyObservers({
|
|
||||||
oldColor: oldColor.toHexString(),
|
|
||||||
newColor: newColor.toHexString()
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
colorPickerTexture.addControl(colorPicker);
|
this.node.parent.setEnabled(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
|
function createButton(): Button3D {
|
||||||
return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[];
|
const addButton = new Button3D("add-button");
|
||||||
|
const text = new TextBlock("add-button-text", "Add Color");
|
||||||
|
text.color = "white";
|
||||||
|
text.fontSize = "48px";
|
||||||
|
text.text = "Add Color";
|
||||||
|
addButton.content = text;
|
||||||
|
return addButton;
|
||||||
}
|
}
|
||||||
8
src/toolbox/types/toolType.ts
Normal file
8
src/toolbox/types/toolType.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export enum ToolType {
|
||||||
|
BOX = "#box-template",
|
||||||
|
SPHERE = "#sphere-template",
|
||||||
|
CYLINDER = "#cylinder-template",
|
||||||
|
CONE = "#cone-template",
|
||||||
|
PLANE = "#plane-template",
|
||||||
|
OBJECT = "#object-template",
|
||||||
|
}
|
||||||
@ -1,11 +1,9 @@
|
|||||||
import {Angle, Observable, Vector3} from "@babylonjs/core";
|
import {Observable} from "@babylonjs/core";
|
||||||
import log from "loglevel";
|
|
||||||
import round from "round";
|
|
||||||
import {IPersistenceManager} from "../integration/iPersistenceManager";
|
import {IPersistenceManager} from "../integration/iPersistenceManager";
|
||||||
import {AppConfigType} from "./appConfigType";
|
import {AppConfigType} from "./appConfigType";
|
||||||
|
|
||||||
export class AppConfig {
|
export class AppConfig {
|
||||||
private readonly logger = log.getLogger('AppConfig');
|
|
||||||
public readonly onConfigChangedObservable = new Observable<AppConfigType>();
|
public readonly onConfigChangedObservable = new Observable<AppConfigType>();
|
||||||
private _currentConfig: AppConfigType;
|
private _currentConfig: AppConfigType;
|
||||||
private persistenceManager: IPersistenceManager;
|
private persistenceManager: IPersistenceManager;
|
||||||
@ -34,7 +32,6 @@ export class AppConfig {
|
|||||||
} else {
|
} else {
|
||||||
this._currentConfig = config;
|
this._currentConfig = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return this._currentConfig;
|
return this._currentConfig;
|
||||||
@ -53,34 +50,4 @@ export class AppConfig {
|
|||||||
this._currentConfig = config;
|
this._currentConfig = config;
|
||||||
this.onConfigChangedObservable.notifyObservers(this._currentConfig);
|
this.onConfigChangedObservable.notifyObservers(this._currentConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public snapGridVal(value: Vector3, snap: number): Vector3 {
|
|
||||||
if (!snap) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
const position = value.clone();
|
|
||||||
position.x = round(value.x, snap);
|
|
||||||
position.y = round(value.y, snap);
|
|
||||||
position.z = round(value.z, snap);
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public snapRotateVal(value: Vector3, snap: number): Vector3 {
|
|
||||||
if (!snap) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
const rotation = new Vector3();
|
|
||||||
rotation.x = this.snapAngle(value.x, snap);
|
|
||||||
rotation.y = this.snapAngle(value.y, snap);
|
|
||||||
rotation.z = this.snapAngle(value.z, snap);
|
|
||||||
return rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private snapAngle(val: number, snap: number): number {
|
|
||||||
const angle = snap;
|
|
||||||
const deg = Angle.FromRadians(val).degrees();
|
|
||||||
const snappedDegrees = round(deg, angle);
|
|
||||||
this.logger.debug("deg", val, deg, snappedDegrees, angle);
|
|
||||||
return Angle.FromDegrees(snappedDegrees).radians();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,21 +0,0 @@
|
|||||||
import {Scene, TransformNode, Vector3} from "@babylonjs/core";
|
|
||||||
|
|
||||||
export class CameraHelper {
|
|
||||||
public static getFrontPosition(distance: number, scene: Scene): Vector3 {
|
|
||||||
const offset = new Vector3(0, 0, distance);
|
|
||||||
offset.applyRotationQuaternionInPlace(scene.activeCamera.absoluteRotation);
|
|
||||||
return scene.activeCamera.globalPosition.add(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static setMenuPosition(node: TransformNode, scene: Scene, offset: Vector3 = Vector3.Zero()) {
|
|
||||||
const front = CameraHelper.getFrontPosition(.8, scene);
|
|
||||||
front.y = scene.activeCamera.globalPosition.y;
|
|
||||||
|
|
||||||
node.position = front;
|
|
||||||
node.position.addInPlace(offset);
|
|
||||||
node.lookAt(scene.activeCamera.globalPosition);
|
|
||||||
node.rotation.y = node.rotation.y + Math.PI;
|
|
||||||
node.position.y -= .5;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import {HavokPlugin, Quaternion, Scene, Vector3} from "@babylonjs/core";
|
import {HavokPlugin, Quaternion, Scene, Vector3} from "@babylonjs/core";
|
||||||
import HavokPhysics from "@babylonjs/havok";
|
import HavokPhysics from "@babylonjs/havok";
|
||||||
import {AppConfig} from "./appConfig";
|
import {AppConfig} from "./appConfig";
|
||||||
|
import {snapGridVal} from "./functions/snapGridVal";
|
||||||
|
import {snapRotateVal} from "./functions/snapRotateVal";
|
||||||
|
|
||||||
export class CustomPhysics {
|
export class CustomPhysics {
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
@ -27,12 +29,12 @@ export class CustomPhysics {
|
|||||||
|
|
||||||
body.disablePreStep = false;
|
body.disablePreStep = false;
|
||||||
const pos: Vector3 = body.getObjectCenterWorld();
|
const pos: Vector3 = body.getObjectCenterWorld();
|
||||||
const val: Vector3 = this.config.snapGridVal(pos,
|
const val: Vector3 = snapGridVal(pos,
|
||||||
this.config.current.gridSnap);
|
this.config.current.gridSnap);
|
||||||
body.transformNode.position.set(val.x, val.y, val.z);
|
body.transformNode.position.set(val.x, val.y, val.z);
|
||||||
const rot: Quaternion =
|
const rot: Quaternion =
|
||||||
Quaternion.FromEulerVector(
|
Quaternion.FromEulerVector(
|
||||||
this.config.snapRotateVal(body.transformNode.rotationQuaternion.toEulerAngles(),
|
snapRotateVal(body.transformNode.rotationQuaternion.toEulerAngles(),
|
||||||
this.config.current.rotateSnap))
|
this.config.current.rotateSnap))
|
||||||
|
|
||||||
body.transformNode.rotationQuaternion.set(
|
body.transformNode.rotationQuaternion.set(
|
||||||
|
|||||||
3
src/util/functions/enumKeys.ts
Normal file
3
src/util/functions/enumKeys.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
|
||||||
|
return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[];
|
||||||
|
}
|
||||||
7
src/util/functions/getFrontPosition.ts
Normal file
7
src/util/functions/getFrontPosition.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import {Scene, Vector3} from "@babylonjs/core";
|
||||||
|
|
||||||
|
export function getFrontPosition(distance: number, scene: Scene): Vector3 {
|
||||||
|
const offset = new Vector3(0, 0, distance);
|
||||||
|
offset.applyRotationQuaternionInPlace(scene.activeCamera.absoluteRotation);
|
||||||
|
return scene.activeCamera.globalPosition.add(offset);
|
||||||
|
}
|
||||||
13
src/util/functions/setMenuPosition.ts
Normal file
13
src/util/functions/setMenuPosition.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import {Scene, TransformNode, Vector3} from "@babylonjs/core";
|
||||||
|
import {getFrontPosition} from "./getFrontPosition";
|
||||||
|
|
||||||
|
export function setMenuPosition(node: TransformNode, scene: Scene, offset: Vector3 = Vector3.Zero()) {
|
||||||
|
const front = getFrontPosition(.8, scene);
|
||||||
|
front.y = scene.activeCamera.globalPosition.y;
|
||||||
|
node.position = front;
|
||||||
|
node.position.addInPlace(offset);
|
||||||
|
node.lookAt(scene.activeCamera.globalPosition);
|
||||||
|
node.rotation.y = node.rotation.y + Math.PI;
|
||||||
|
node.position.y -= .5;
|
||||||
|
|
||||||
|
}
|
||||||
13
src/util/functions/snapGridVal.ts
Normal file
13
src/util/functions/snapGridVal.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import {Vector3} from "@babylonjs/core";
|
||||||
|
import round from "round";
|
||||||
|
|
||||||
|
export function snapGridVal(value: Vector3, snap: number): Vector3 {
|
||||||
|
if (!snap) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
const position =
|
||||||
|
new Vector3(round(value.x, snap),
|
||||||
|
round(value.y, snap),
|
||||||
|
round(value.z, snap))
|
||||||
|
return position;
|
||||||
|
}
|
||||||
24
src/util/functions/snapRotateVal.ts
Normal file
24
src/util/functions/snapRotateVal.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {Angle, Vector3} from "@babylonjs/core";
|
||||||
|
import round from "round";
|
||||||
|
import log from "loglevel";
|
||||||
|
|
||||||
|
const logger = log.getLogger('snapRotateVal');
|
||||||
|
|
||||||
|
export function snapRotateVal(value: Vector3, snap: number): Vector3 {
|
||||||
|
if (!snap) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
const rotation = new Vector3(
|
||||||
|
snapAngle(value.x, snap),
|
||||||
|
snapAngle(value.y, snap),
|
||||||
|
snapAngle(value.z, snap));
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
function snapAngle(val: number, snap: number): number {
|
||||||
|
const angle = snap;
|
||||||
|
const deg = Angle.FromRadians(val).degrees();
|
||||||
|
const snappedDegrees = round(deg, angle);
|
||||||
|
logger.debug("deg", val, deg, snappedDegrees, angle);
|
||||||
|
return Angle.FromDegrees(snappedDegrees).radians();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user