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