diff --git a/index.html b/index.html index 819aa4d..a6234fc 100644 --- a/index.html +++ b/index.html @@ -49,6 +49,7 @@
Launch On Quest
+ diff --git a/package-lock.json b/package-lock.json index 519a27b..bc1b0e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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 }, diff --git a/package.json b/package.json index 908409e..ed6d284 100644 --- a/package.json +++ b/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" } diff --git a/src/app.ts b/src/app.ts index 9bfd63d..af4fff8 100644 --- a/src/app.ts +++ b/src/app.ts @@ -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); diff --git a/src/controllers/base.ts b/src/controllers/base.ts index 4af70fd..17b25c9 100644 --- a/src/controllers/base.ts +++ b/src/controllers/base.ts @@ -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); - if (event.gripId == this?.controller?.grip?.id) { - this.controller?.motionController?.pulse(.25, 30) - .then(() => { - this.logger.debug("pulse done"); - }); - } + 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; diff --git a/src/controllers/controllers.ts b/src/controllers/controllers.ts index 5c9f359..efbaef4 100644 --- a/src/controllers/controllers.ts +++ b/src/controllers/controllers.ts @@ -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 = new Observable(); + public readonly controllerObserver: Observable = new Observable(); } \ No newline at end of file diff --git a/src/controllers/left.ts b/src/controllers/left.ts index 32fbbf6..383b258 100644 --- a/src/controllers/left.ts +++ b/src/controllers/left.ts @@ -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 { } diff --git a/src/controllers/right.ts b/src/controllers/right.ts index ec468b8..2a188e2 100644 --- a/src/controllers/right.ts +++ b/src/controllers/right.ts @@ -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}); } } } \ No newline at end of file diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index 5124a94..b952800 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -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; } diff --git a/src/diagram/diagramEntityActionManager.ts b/src/diagram/diagramEntityActionManager.ts index da26e20..50f397f 100644 --- a/src/diagram/diagramEntityActionManager.ts +++ b/src/diagram/diagramEntityActionManager.ts @@ -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); diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index 2ddd5e2..d3f836b 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -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"; diff --git a/src/information/inputTextView.ts b/src/information/inputTextView.ts index a59d1b6..37a88d3 100644 --- a/src/information/inputTextView.ts +++ b/src/information/inputTextView.ts @@ -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 = new Observable(); 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.addEventListener('blur', () => { + log.getLogger('bmenu').debug("blur"); + this.onTextObservable.notifyObservers({text: textInput.value}); + 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(); - 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.xr.input.controllers.forEach((controller) => { - controller.motionController.rootMesh.setEnabled(true); - controller.pointer.setEnabled(true); - }); - } - textInput.blur(); - textInput.remove(); - }); - } } } \ No newline at end of file diff --git a/src/menus/abstractMenu.ts b/src/menus/abstractMenu.ts index c2fdd97..a851e9b 100644 --- a/src/menus/abstractMenu.ts +++ b/src/menus/abstractMenu.ts @@ -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; diff --git a/src/menus/configMenu.ts b/src/menus/configMenu.ts index 561e9de..65f6b7c 100644 --- a/src/menus/configMenu.ts +++ b/src/menus/configMenu.ts @@ -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 { diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index f7a2c7d..7f72d51 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -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() { diff --git a/src/menus/integrationMenu.ts b/src/menus/integrationMenu.ts index 9cc172a..106945a 100644 --- a/src/menus/integrationMenu.ts +++ b/src/menus/integrationMenu.ts @@ -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); } diff --git a/src/toolbox/functions/buildColor.ts b/src/toolbox/functions/buildColor.ts new file mode 100644 index 0000000..5b070bf --- /dev/null +++ b/src/toolbox/functions/buildColor.ts @@ -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); +} \ No newline at end of file diff --git a/src/toolbox/functions/buildMesh.ts b/src/toolbox/functions/buildMesh.ts new file mode 100644 index 0000000..34e4498 --- /dev/null +++ b/src/toolbox/functions/buildMesh.ts @@ -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; + + } +} \ No newline at end of file diff --git a/src/toolbox/functions/buildTool.ts b/src/toolbox/functions/buildTool.ts new file mode 100644 index 0000000..c1e7d6c --- /dev/null +++ b/src/toolbox/functions/buildTool.ts @@ -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(); +} \ No newline at end of file diff --git a/src/toolbox/toolbox.ts b/src/toolbox/toolbox.ts index f90f342..dbf400f 100644 --- a/src/toolbox/toolbox.ts +++ b/src/toolbox/toolbox.ts @@ -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(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; } \ No newline at end of file diff --git a/src/toolbox/types/toolType.ts b/src/toolbox/types/toolType.ts new file mode 100644 index 0000000..43062ae --- /dev/null +++ b/src/toolbox/types/toolType.ts @@ -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", +} \ No newline at end of file diff --git a/src/util/appConfig.ts b/src/util/appConfig.ts index f1ce18d..01bc27e 100644 --- a/src/util/appConfig.ts +++ b/src/util/appConfig.ts @@ -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(); 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(); - } } \ No newline at end of file diff --git a/src/util/cameraHelper.ts b/src/util/cameraHelper.ts deleted file mode 100644 index 4271964..0000000 --- a/src/util/cameraHelper.ts +++ /dev/null @@ -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; - - } -} \ No newline at end of file diff --git a/src/util/customPhysics.ts b/src/util/customPhysics.ts index d26876e..5dedf8c 100644 --- a/src/util/customPhysics.ts +++ b/src/util/customPhysics.ts @@ -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( diff --git a/src/util/deepCopy.ts b/src/util/functions/deepCopy.ts similarity index 100% rename from src/util/deepCopy.ts rename to src/util/functions/deepCopy.ts diff --git a/src/util/functions/enumKeys.ts b/src/util/functions/enumKeys.ts new file mode 100644 index 0000000..cd633f7 --- /dev/null +++ b/src/util/functions/enumKeys.ts @@ -0,0 +1,3 @@ +export function enumKeys(obj: O): K[] { + return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[]; +} \ No newline at end of file diff --git a/src/util/functions/getFrontPosition.ts b/src/util/functions/getFrontPosition.ts new file mode 100644 index 0000000..bbd7b54 --- /dev/null +++ b/src/util/functions/getFrontPosition.ts @@ -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); +} diff --git a/src/util/functions/setMenuPosition.ts b/src/util/functions/setMenuPosition.ts new file mode 100644 index 0000000..2d56689 --- /dev/null +++ b/src/util/functions/setMenuPosition.ts @@ -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; + +} \ No newline at end of file diff --git a/src/util/functions/snapGridVal.ts b/src/util/functions/snapGridVal.ts new file mode 100644 index 0000000..077f871 --- /dev/null +++ b/src/util/functions/snapGridVal.ts @@ -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; +} \ No newline at end of file diff --git a/src/util/functions/snapRotateVal.ts b/src/util/functions/snapRotateVal.ts new file mode 100644 index 0000000..a76de36 --- /dev/null +++ b/src/util/functions/snapRotateVal.ts @@ -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(); +} \ No newline at end of file