@thunderclap-engine/engine 0.0.0-stage → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +390 -0
- package/LICENSE +21 -0
- package/README.md +333 -2
- package/dist/analytics/analytics.d.ts +80 -0
- package/dist/analytics/analytics.js +129 -0
- package/dist/analytics/index.d.ts +1 -0
- package/dist/analytics/index.js +1 -0
- package/dist/anim/aim.d.ts +43 -0
- package/dist/anim/aim.js +157 -0
- package/dist/anim/clip.d.ts +98 -0
- package/dist/anim/clip.js +282 -0
- package/dist/anim/compress.d.ts +65 -0
- package/dist/anim/compress.js +339 -0
- package/dist/anim/foot-ik.d.ts +74 -0
- package/dist/anim/foot-ik.js +241 -0
- package/dist/anim/graph.d.ts +153 -0
- package/dist/anim/graph.js +532 -0
- package/dist/anim/ik.d.ts +105 -0
- package/dist/anim/ik.js +435 -0
- package/dist/anim/index.d.ts +36 -0
- package/dist/anim/index.js +21 -0
- package/dist/anim/match.d.ts +66 -0
- package/dist/anim/match.js +153 -0
- package/dist/anim/mixer.d.ts +113 -0
- package/dist/anim/mixer.js +314 -0
- package/dist/anim/morph.d.ts +41 -0
- package/dist/anim/morph.js +94 -0
- package/dist/anim/pose.d.ts +74 -0
- package/dist/anim/pose.js +254 -0
- package/dist/anim/quat.d.ts +44 -0
- package/dist/anim/quat.js +187 -0
- package/dist/anim/retarget.d.ts +97 -0
- package/dist/anim/retarget.js +366 -0
- package/dist/anim/root-motion.d.ts +44 -0
- package/dist/anim/root-motion.js +224 -0
- package/dist/anim/skin-pose.d.ts +39 -0
- package/dist/anim/skin-pose.js +53 -0
- package/dist/anim/socket.d.ts +47 -0
- package/dist/anim/socket.js +84 -0
- package/dist/anim/spring-chain.d.ts +73 -0
- package/dist/anim/spring-chain.js +294 -0
- package/dist/assets/atlas.d.ts +90 -0
- package/dist/assets/atlas.js +212 -0
- package/dist/assets/baked.d.ts +33 -0
- package/dist/assets/baked.js +38 -0
- package/dist/assets/bundle.d.ts +88 -0
- package/dist/assets/bundle.js +464 -0
- package/dist/assets/cache.d.ts +56 -0
- package/dist/assets/cache.js +123 -0
- package/dist/assets/gltf-load.d.ts +252 -0
- package/dist/assets/gltf-load.js +661 -0
- package/dist/assets/gltf-skin.d.ts +36 -0
- package/dist/assets/gltf-skin.js +109 -0
- package/dist/assets/gltf.d.ts +706 -0
- package/dist/assets/gltf.js +1376 -0
- package/dist/assets/index.d.ts +20 -0
- package/dist/assets/index.js +10 -0
- package/dist/assets/ktx2.d.ts +71 -0
- package/dist/assets/ktx2.js +213 -0
- package/dist/assets/manifest.d.ts +79 -0
- package/dist/assets/manifest.js +7 -0
- package/dist/assets/meshopt.d.ts +23 -0
- package/dist/assets/meshopt.js +403 -0
- package/dist/audio/audio.d.ts +733 -0
- package/dist/audio/audio.js +2013 -0
- package/dist/audio/dsp.d.ts +61 -0
- package/dist/audio/dsp.js +159 -0
- package/dist/audio/duck.d.ts +44 -0
- package/dist/audio/duck.js +101 -0
- package/dist/audio/envelope.d.ts +53 -0
- package/dist/audio/envelope.js +106 -0
- package/dist/audio/index.d.ts +13 -0
- package/dist/audio/index.js +14 -0
- package/dist/audio/music.d.ts +113 -0
- package/dist/audio/music.js +548 -0
- package/dist/audio/occlusion.d.ts +55 -0
- package/dist/audio/occlusion.js +61 -0
- package/dist/audio/persist.d.ts +23 -0
- package/dist/audio/persist.js +27 -0
- package/dist/audio/recipes.d.ts +55 -0
- package/dist/audio/recipes.js +227 -0
- package/dist/audio/send.d.ts +41 -0
- package/dist/audio/send.js +118 -0
- package/dist/audio/sprites.d.ts +59 -0
- package/dist/audio/sprites.js +43 -0
- package/dist/audio/synth.d.ts +103 -0
- package/dist/audio/synth.js +197 -0
- package/dist/audio/variations.d.ts +25 -0
- package/dist/audio/variations.js +55 -0
- package/dist/audio/zones.d.ts +100 -0
- package/dist/audio/zones.js +167 -0
- package/dist/core/detached-surface.d.ts +44 -0
- package/dist/core/detached-surface.js +104 -0
- package/dist/core/events.d.ts +24 -0
- package/dist/core/events.js +43 -0
- package/dist/core/game.d.ts +409 -0
- package/dist/core/game.js +530 -0
- package/dist/core/hash.d.ts +24 -0
- package/dist/core/hash.js +49 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.js +9 -0
- package/dist/core/loop.d.ts +113 -0
- package/dist/core/loop.js +185 -0
- package/dist/core/math.d.ts +58 -0
- package/dist/core/math.js +210 -0
- package/dist/core/noise.d.ts +40 -0
- package/dist/core/noise.js +247 -0
- package/dist/core/pool.d.ts +42 -0
- package/dist/core/pool.js +85 -0
- package/dist/core/random.d.ts +61 -0
- package/dist/core/random.js +199 -0
- package/dist/core/scene.d.ts +79 -0
- package/dist/core/scene.js +195 -0
- package/dist/core/timer.d.ts +66 -0
- package/dist/core/timer.js +286 -0
- package/dist/fx/billboard-wgsl.d.ts +29 -0
- package/dist/fx/billboard-wgsl.js +158 -0
- package/dist/fx/billboard.d.ts +249 -0
- package/dist/fx/billboard.js +702 -0
- package/dist/fx/debug-draw.d.ts +127 -0
- package/dist/fx/debug-draw.js +523 -0
- package/dist/fx/debug-wgsl.d.ts +7 -0
- package/dist/fx/debug-wgsl.js +32 -0
- package/dist/fx/decals-wgsl.d.ts +15 -0
- package/dist/fx/decals-wgsl.js +173 -0
- package/dist/fx/decals.d.ts +216 -0
- package/dist/fx/decals.js +607 -0
- package/dist/fx/effect.d.ts +129 -0
- package/dist/fx/effect.js +349 -0
- package/dist/fx/effects/hit-spark.json +48 -0
- package/dist/fx/effects/index.d.ts +8 -0
- package/dist/fx/effects/index.js +9 -0
- package/dist/fx/effects/magic-aura.json +47 -0
- package/dist/fx/effects/smoke-puff.json +34 -0
- package/dist/fx/emit-surface.d.ts +40 -0
- package/dist/fx/emit-surface.js +124 -0
- package/dist/fx/flicker.d.ts +30 -0
- package/dist/fx/flicker.js +42 -0
- package/dist/fx/index.d.ts +31 -0
- package/dist/fx/index.js +20 -0
- package/dist/fx/particles-wgsl.d.ts +57 -0
- package/dist/fx/particles-wgsl.js +828 -0
- package/dist/fx/particles.d.ts +566 -0
- package/dist/fx/particles.js +1533 -0
- package/dist/fx/random.d.ts +15 -0
- package/dist/fx/random.js +20 -0
- package/dist/fx/sky-wgsl.d.ts +23 -0
- package/dist/fx/sky-wgsl.js +127 -0
- package/dist/fx/sky.d.ts +96 -0
- package/dist/fx/sky.js +175 -0
- package/dist/fx/text-atlas.d.ts +143 -0
- package/dist/fx/text-atlas.js +327 -0
- package/dist/fx/trail-wgsl.d.ts +11 -0
- package/dist/fx/trail-wgsl.js +42 -0
- package/dist/fx/trail.d.ts +194 -0
- package/dist/fx/trail.js +555 -0
- package/dist/fx/water-wgsl.d.ts +34 -0
- package/dist/fx/water-wgsl.js +197 -0
- package/dist/fx/water.d.ts +176 -0
- package/dist/fx/water.js +371 -0
- package/dist/geom/collide/bvh.d.ts +151 -0
- package/dist/geom/collide/bvh.js +493 -0
- package/dist/geom/collide/debug.d.ts +14 -0
- package/dist/geom/collide/debug.js +74 -0
- package/dist/geom/collide/grid.d.ts +26 -0
- package/dist/geom/collide/grid.js +91 -0
- package/dist/geom/collide/index.d.ts +8 -0
- package/dist/geom/collide/index.js +8 -0
- package/dist/geom/collide/queries.d.ts +70 -0
- package/dist/geom/collide/queries.js +583 -0
- package/dist/geom/collide/serialize.d.ts +14 -0
- package/dist/geom/collide/serialize.js +145 -0
- package/dist/geom/collide/shapes.d.ts +161 -0
- package/dist/geom/collide/shapes.js +686 -0
- package/dist/geom/collide/slide.d.ts +66 -0
- package/dist/geom/collide/slide.js +375 -0
- package/dist/geom/collide/tile-slide.d.ts +88 -0
- package/dist/geom/collide/tile-slide.js +255 -0
- package/dist/geom/geometry.d.ts +95 -0
- package/dist/geom/geometry.js +322 -0
- package/dist/geom/heightfield.d.ts +72 -0
- package/dist/geom/heightfield.js +295 -0
- package/dist/geom/hull.d.ts +27 -0
- package/dist/geom/hull.js +279 -0
- package/dist/geom/index.d.ts +35 -0
- package/dist/geom/index.js +23 -0
- package/dist/geom/iso.d.ts +74 -0
- package/dist/geom/iso.js +89 -0
- package/dist/geom/lod.d.ts +29 -0
- package/dist/geom/lod.js +27 -0
- package/dist/geom/ops.d.ts +47 -0
- package/dist/geom/ops.js +285 -0
- package/dist/geom/primitives.d.ts +97 -0
- package/dist/geom/primitives.js +359 -0
- package/dist/geom/shapes.d.ts +43 -0
- package/dist/geom/shapes.js +88 -0
- package/dist/geom/simplify.d.ts +38 -0
- package/dist/geom/simplify.js +519 -0
- package/dist/geom/split.d.ts +37 -0
- package/dist/geom/split.js +413 -0
- package/dist/geom/sweep.d.ts +83 -0
- package/dist/geom/sweep.js +534 -0
- package/dist/geom/tangents.d.ts +16 -0
- package/dist/geom/tangents.js +124 -0
- package/dist/geom/triangulate.d.ts +19 -0
- package/dist/geom/triangulate.js +147 -0
- package/dist/host/default.d.ts +10 -0
- package/dist/host/default.js +10 -0
- package/dist/host/index.d.ts +4 -0
- package/dist/host/index.js +3 -0
- package/dist/host/types.d.ts +144 -0
- package/dist/host/types.js +1 -0
- package/dist/host/web-links.d.ts +38 -0
- package/dist/host/web-links.js +110 -0
- package/dist/host/web.d.ts +30 -0
- package/dist/host/web.js +216 -0
- package/dist/host/xr.d.ts +24 -0
- package/dist/host/xr.js +59 -0
- package/dist/i18n/i18n.d.ts +59 -0
- package/dist/i18n/i18n.js +241 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/message.d.ts +72 -0
- package/dist/i18n/message.js +369 -0
- package/dist/i18n/negotiate.d.ts +17 -0
- package/dist/i18n/negotiate.js +58 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -0
- package/dist/input/bindings.d.ts +31 -0
- package/dist/input/bindings.js +141 -0
- package/dist/input/clock.d.ts +44 -0
- package/dist/input/clock.js +49 -0
- package/dist/input/follow.d.ts +133 -0
- package/dist/input/follow.js +218 -0
- package/dist/input/gestures.d.ts +281 -0
- package/dist/input/gestures.js +662 -0
- package/dist/input/glyphs.d.ts +35 -0
- package/dist/input/glyphs.js +216 -0
- package/dist/input/gyro.d.ts +85 -0
- package/dist/input/gyro.js +140 -0
- package/dist/input/index.d.ts +19 -0
- package/dist/input/index.js +16 -0
- package/dist/input/input.d.ts +543 -0
- package/dist/input/input.js +1492 -0
- package/dist/input/look.d.ts +327 -0
- package/dist/input/look.js +681 -0
- package/dist/input/magnify.d.ts +177 -0
- package/dist/input/magnify.js +131 -0
- package/dist/input/pointer-dispatch.d.ts +138 -0
- package/dist/input/pointer-dispatch.js +180 -0
- package/dist/input/pointer-router.d.ts +204 -0
- package/dist/input/pointer-router.js +533 -0
- package/dist/input/pointer-sources.d.ts +164 -0
- package/dist/input/pointer-sources.js +306 -0
- package/dist/input/rays.d.ts +138 -0
- package/dist/input/rays.js +615 -0
- package/dist/input/record.d.ts +209 -0
- package/dist/input/record.js +601 -0
- package/dist/input/touch-zones.d.ts +147 -0
- package/dist/input/touch-zones.js +300 -0
- package/dist/input/types.d.ts +158 -0
- package/dist/input/types.js +1 -0
- package/dist/input/xr-source.d.ts +53 -0
- package/dist/input/xr-source.js +164 -0
- package/dist/nav/astar.d.ts +45 -0
- package/dist/nav/astar.js +182 -0
- package/dist/nav/corridor.d.ts +40 -0
- package/dist/nav/corridor.js +95 -0
- package/dist/nav/crowd.d.ts +94 -0
- package/dist/nav/crowd.js +624 -0
- package/dist/nav/flow.d.ts +61 -0
- package/dist/nav/flow.js +193 -0
- package/dist/nav/grid.d.ts +108 -0
- package/dist/nav/grid.js +210 -0
- package/dist/nav/heap.d.ts +22 -0
- package/dist/nav/heap.js +92 -0
- package/dist/nav/index.d.ts +37 -0
- package/dist/nav/index.js +19 -0
- package/dist/nav/mesh/areas.d.ts +44 -0
- package/dist/nav/mesh/areas.js +98 -0
- package/dist/nav/mesh/bake-options.d.ts +33 -0
- package/dist/nav/mesh/bake-options.js +76 -0
- package/dist/nav/mesh/contour.d.ts +22 -0
- package/dist/nav/mesh/contour.js +323 -0
- package/dist/nav/mesh/flow3.d.ts +35 -0
- package/dist/nav/mesh/flow3.js +229 -0
- package/dist/nav/mesh/links.d.ts +38 -0
- package/dist/nav/mesh/links.js +72 -0
- package/dist/nav/mesh/mesh-path.d.ts +152 -0
- package/dist/nav/mesh/mesh-path.js +643 -0
- package/dist/nav/mesh/mesh-reach.d.ts +78 -0
- package/dist/nav/mesh/mesh-reach.js +450 -0
- package/dist/nav/mesh/navmesh.d.ts +117 -0
- package/dist/nav/mesh/navmesh.js +647 -0
- package/dist/nav/mesh/polymesh.d.ts +24 -0
- package/dist/nav/mesh/polymesh.js +384 -0
- package/dist/nav/mesh/regions.d.ts +12 -0
- package/dist/nav/mesh/regions.js +367 -0
- package/dist/nav/mesh/serialize.d.ts +13 -0
- package/dist/nav/mesh/serialize.js +197 -0
- package/dist/nav/mesh/voxelize.d.ts +111 -0
- package/dist/nav/mesh/voxelize.js +552 -0
- package/dist/nav/obstacles.d.ts +75 -0
- package/dist/nav/obstacles.js +294 -0
- package/dist/nav/path.d.ts +59 -0
- package/dist/nav/path.js +177 -0
- package/dist/nav/query-queue.d.ts +46 -0
- package/dist/nav/query-queue.js +308 -0
- package/dist/nav/reach.d.ts +53 -0
- package/dist/nav/reach.js +148 -0
- package/dist/nav/steer.d.ts +36 -0
- package/dist/nav/steer.js +78 -0
- package/dist/platform/boot.d.ts +28 -0
- package/dist/platform/boot.js +43 -0
- package/dist/platform/device-mode.d.ts +40 -0
- package/dist/platform/device-mode.js +104 -0
- package/dist/platform/device.d.ts +31 -0
- package/dist/platform/device.js +91 -0
- package/dist/platform/environment.d.ts +42 -0
- package/dist/platform/environment.js +82 -0
- package/dist/platform/gpu.d.ts +40 -0
- package/dist/platform/gpu.js +57 -0
- package/dist/platform/index.d.ts +18 -0
- package/dist/platform/index.js +10 -0
- package/dist/platform/letterbox.d.ts +43 -0
- package/dist/platform/letterbox.js +57 -0
- package/dist/platform/links.d.ts +20 -0
- package/dist/platform/links.js +43 -0
- package/dist/platform/screens.d.ts +36 -0
- package/dist/platform/screens.js +138 -0
- package/dist/platform/surface.d.ts +72 -0
- package/dist/platform/surface.js +157 -0
- package/dist/platform/xr-fake.d.ts +168 -0
- package/dist/platform/xr-fake.js +434 -0
- package/dist/platform/xr-surface.d.ts +120 -0
- package/dist/platform/xr-surface.js +214 -0
- package/dist/platform/xr-types.d.ts +262 -0
- package/dist/post/ao.d.ts +12 -0
- package/dist/post/ao.js +136 -0
- package/dist/post/blend.d.ts +27 -0
- package/dist/post/blend.js +129 -0
- package/dist/post/depth-pass.d.ts +43 -0
- package/dist/post/depth-pass.js +118 -0
- package/dist/post/dof.d.ts +1 -0
- package/dist/post/dof.js +66 -0
- package/dist/post/exposure.d.ts +80 -0
- package/dist/post/exposure.js +322 -0
- package/dist/post/index.d.ts +12 -0
- package/dist/post/index.js +11 -0
- package/dist/post/lens-dirt.d.ts +13 -0
- package/dist/post/lens-dirt.js +91 -0
- package/dist/post/lut.d.ts +19 -0
- package/dist/post/lut.js +50 -0
- package/dist/post/motion-blur.d.ts +9 -0
- package/dist/post/motion-blur.js +78 -0
- package/dist/post/post-stack.d.ts +302 -0
- package/dist/post/post-stack.js +1137 -0
- package/dist/post/settings.d.ts +485 -0
- package/dist/post/settings.js +416 -0
- package/dist/post/shaders.d.ts +25 -0
- package/dist/post/shaders.js +410 -0
- package/dist/post/ssr.d.ts +16 -0
- package/dist/post/ssr.js +155 -0
- package/dist/post/taa.d.ts +74 -0
- package/dist/post/taa.js +235 -0
- package/dist/post/white-balance.d.ts +25 -0
- package/dist/post/white-balance.js +98 -0
- package/dist/render/bindings.d.ts +98 -0
- package/dist/render/bindings.js +281 -0
- package/dist/render/blend.d.ts +13 -0
- package/dist/render/blend.js +26 -0
- package/dist/render/camera-2d.d.ts +72 -0
- package/dist/render/camera-2d.js +92 -0
- package/dist/render/camera.d.ts +302 -0
- package/dist/render/camera.js +671 -0
- package/dist/render/color.d.ts +16 -0
- package/dist/render/color.js +41 -0
- package/dist/render/compressed.d.ts +104 -0
- package/dist/render/compressed.js +248 -0
- package/dist/render/diagnostics.d.ts +15 -0
- package/dist/render/diagnostics.js +43 -0
- package/dist/render/dynamic-resolution.d.ts +70 -0
- package/dist/render/dynamic-resolution.js +126 -0
- package/dist/render/fake-gpu.d.ts +204 -0
- package/dist/render/fake-gpu.js +426 -0
- package/dist/render/flipbook.d.ts +56 -0
- package/dist/render/flipbook.js +87 -0
- package/dist/render/frame.d.ts +278 -0
- package/dist/render/frame.js +174 -0
- package/dist/render/fullscreen.d.ts +54 -0
- package/dist/render/fullscreen.js +91 -0
- package/dist/render/gpu-timer.d.ts +73 -0
- package/dist/render/gpu-timer.js +186 -0
- package/dist/render/index.d.ts +53 -0
- package/dist/render/index.js +29 -0
- package/dist/render/instance-list.d.ts +185 -0
- package/dist/render/instance-list.js +547 -0
- package/dist/render/lights.d.ts +181 -0
- package/dist/render/lights.js +233 -0
- package/dist/render/lod.d.ts +54 -0
- package/dist/render/lod.js +52 -0
- package/dist/render/material.d.ts +165 -0
- package/dist/render/material.js +292 -0
- package/dist/render/mesh.d.ts +284 -0
- package/dist/render/mesh.js +472 -0
- package/dist/render/mipmap.d.ts +16 -0
- package/dist/render/mipmap.js +121 -0
- package/dist/render/parallax.d.ts +50 -0
- package/dist/render/parallax.js +47 -0
- package/dist/render/pbr-wgsl.d.ts +31 -0
- package/dist/render/pbr-wgsl.js +119 -0
- package/dist/render/ping-pong.d.ts +42 -0
- package/dist/render/ping-pong.js +74 -0
- package/dist/render/renderer.d.ts +741 -0
- package/dist/render/renderer.js +2486 -0
- package/dist/render/scene-pipelines.d.ts +44 -0
- package/dist/render/scene-pipelines.js +92 -0
- package/dist/render/scene-target.d.ts +170 -0
- package/dist/render/scene-target.js +450 -0
- package/dist/render/shadow.d.ts +74 -0
- package/dist/render/shadow.js +208 -0
- package/dist/render/skin.d.ts +112 -0
- package/dist/render/skin.js +240 -0
- package/dist/render/snapshot.d.ts +36 -0
- package/dist/render/snapshot.js +34 -0
- package/dist/render/standard.d.ts +162 -0
- package/dist/render/standard.js +263 -0
- package/dist/render/texture.d.ts +142 -0
- package/dist/render/texture.js +228 -0
- package/dist/render/tile-layer.d.ts +110 -0
- package/dist/render/tile-layer.js +304 -0
- package/dist/render/transform.d.ts +115 -0
- package/dist/render/transform.js +318 -0
- package/dist/render/wgsl.d.ts +131 -0
- package/dist/render/wgsl.js +528 -0
- package/dist/save/codec.d.ts +49 -0
- package/dist/save/codec.js +169 -0
- package/dist/save/index.d.ts +8 -0
- package/dist/save/index.js +8 -0
- package/dist/save/journal.d.ts +24 -0
- package/dist/save/journal.js +102 -0
- package/dist/save/migrate.d.ts +15 -0
- package/dist/save/migrate.js +37 -0
- package/dist/save/schema.d.ts +72 -0
- package/dist/save/schema.js +154 -0
- package/dist/save/settings.d.ts +28 -0
- package/dist/save/settings.js +59 -0
- package/dist/save/slots.d.ts +56 -0
- package/dist/save/slots.js +200 -0
- package/dist/save/storage.d.ts +35 -0
- package/dist/save/storage.js +62 -0
- package/dist/save/store.d.ts +114 -0
- package/dist/save/store.js +269 -0
- package/dist/testing/fake-host.d.ts +103 -0
- package/dist/testing/fake-host.js +163 -0
- package/dist/testing/fixed-clock.d.ts +25 -0
- package/dist/testing/fixed-clock.js +30 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/test-game.d.ts +76 -0
- package/dist/testing/test-game.js +92 -0
- package/dist/tween/ease.d.ts +77 -0
- package/dist/tween/ease.js +192 -0
- package/dist/tween/index.d.ts +8 -0
- package/dist/tween/index.js +7 -0
- package/dist/tween/timeline.d.ts +78 -0
- package/dist/tween/timeline.js +269 -0
- package/dist/tween/tween.d.ts +168 -0
- package/dist/tween/tween.js +320 -0
- package/dist/ui/anchor.d.ts +206 -0
- package/dist/ui/anchor.js +307 -0
- package/dist/ui/caption.d.ts +122 -0
- package/dist/ui/caption.js +286 -0
- package/dist/ui/cursor.d.ts +105 -0
- package/dist/ui/cursor.js +261 -0
- package/dist/ui/dom.d.ts +30 -0
- package/dist/ui/dom.js +92 -0
- package/dist/ui/floats.d.ts +86 -0
- package/dist/ui/floats.js +260 -0
- package/dist/ui/hud.d.ts +198 -0
- package/dist/ui/hud.js +431 -0
- package/dist/ui/index.d.ts +37 -0
- package/dist/ui/index.js +34 -0
- package/dist/ui/inventory-card.d.ts +52 -0
- package/dist/ui/inventory-card.js +173 -0
- package/dist/ui/inventory-context.d.ts +29 -0
- package/dist/ui/inventory-context.js +125 -0
- package/dist/ui/inventory-drag.d.ts +63 -0
- package/dist/ui/inventory-drag.js +394 -0
- package/dist/ui/inventory-grid.d.ts +66 -0
- package/dist/ui/inventory-grid.js +625 -0
- package/dist/ui/inventory-radial.d.ts +39 -0
- package/dist/ui/inventory-radial.js +168 -0
- package/dist/ui/inventory.d.ts +128 -0
- package/dist/ui/inventory.js +154 -0
- package/dist/ui/layout.d.ts +356 -0
- package/dist/ui/layout.js +856 -0
- package/dist/ui/link.d.ts +64 -0
- package/dist/ui/link.js +155 -0
- package/dist/ui/loading.d.ts +40 -0
- package/dist/ui/loading.js +157 -0
- package/dist/ui/loupe.d.ts +74 -0
- package/dist/ui/loupe.js +164 -0
- package/dist/ui/menu-nav.d.ts +33 -0
- package/dist/ui/menu-nav.js +28 -0
- package/dist/ui/minimap-canvas.d.ts +145 -0
- package/dist/ui/minimap-canvas.js +460 -0
- package/dist/ui/notify.d.ts +40 -0
- package/dist/ui/notify.js +141 -0
- package/dist/ui/orb.d.ts +53 -0
- package/dist/ui/orb.js +304 -0
- package/dist/ui/overlay.d.ts +213 -0
- package/dist/ui/overlay.js +394 -0
- package/dist/ui/padnav.d.ts +53 -0
- package/dist/ui/padnav.js +146 -0
- package/dist/ui/perf.d.ts +130 -0
- package/dist/ui/perf.js +329 -0
- package/dist/ui/rotate-card.d.ts +54 -0
- package/dist/ui/rotate-card.js +97 -0
- package/dist/ui/stack.d.ts +128 -0
- package/dist/ui/stack.js +312 -0
- package/dist/ui/styles.d.ts +13 -0
- package/dist/ui/styles.js +200 -0
- package/dist/ui/text-scale.d.ts +67 -0
- package/dist/ui/text-scale.js +102 -0
- package/dist/ui/theme.d.ts +70 -0
- package/dist/ui/theme.js +98 -0
- package/dist/ui/toast.d.ts +23 -0
- package/dist/ui/toast.js +46 -0
- package/dist/ui/tooltip.d.ts +89 -0
- package/dist/ui/tooltip.js +333 -0
- package/dist/ui/widgets-2.d.ts +134 -0
- package/dist/ui/widgets-2.js +399 -0
- package/dist/ui/widgets-3.d.ts +91 -0
- package/dist/ui/widgets-3.js +212 -0
- package/dist/ui/widgets.d.ts +34 -0
- package/dist/ui/widgets.js +50 -0
- package/dist/ui/world-panel/index.d.ts +5 -0
- package/dist/ui/world-panel/index.js +5 -0
- package/dist/ui/world-panel/layout.d.ts +38 -0
- package/dist/ui/world-panel/layout.js +68 -0
- package/dist/ui/world-panel/paint.d.ts +96 -0
- package/dist/ui/world-panel/paint.js +136 -0
- package/dist/ui/world-panel/panel.d.ts +235 -0
- package/dist/ui/world-panel/panel.js +762 -0
- package/dist/ui/world-panel/wgsl.d.ts +10 -0
- package/dist/ui/world-panel/wgsl.js +52 -0
- package/dist/ui/world-panel/widgets.d.ts +207 -0
- package/dist/ui/world-panel/widgets.js +569 -0
- package/dist/voxel/chunks.d.ts +77 -0
- package/dist/voxel/chunks.js +149 -0
- package/dist/voxel/grid.d.ts +84 -0
- package/dist/voxel/grid.js +223 -0
- package/dist/voxel/index.d.ts +22 -0
- package/dist/voxel/index.js +7 -0
- package/dist/voxel/mesher-worker.d.ts +14 -0
- package/dist/voxel/mesher-worker.js +47 -0
- package/dist/voxel/mesher.d.ts +73 -0
- package/dist/voxel/mesher.js +306 -0
- package/dist/voxel/ray.d.ts +32 -0
- package/dist/voxel/ray.js +73 -0
- package/dist/voxel/wgsl.d.ts +16 -0
- package/dist/voxel/wgsl.js +28 -0
- package/dist/voxel/worker-client.d.ts +79 -0
- package/dist/voxel/worker-client.js +122 -0
- package/package.json +177 -3
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Morph targets (blend shapes) on the CPU: `base + Σ weight × delta` per vertex, written into
|
|
3
|
+
* the position and normal lanes of an interleaved vertex buffer the mesh then uploads
|
|
4
|
+
* (`Mesh.update`). The arithmetic is here; the parser (`assets/gltf.ts`) fills `MorphTarget`s
|
|
5
|
+
* and the loader (`assets/gltf-load.ts`) owns the buffers and the upload. Nothing allocates
|
|
6
|
+
* after `createMorphBlender`.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* A blender over `base` (the primitive's interleaved vertices in `layout`) and its `targets`.
|
|
10
|
+
* `weights` may be the array the blender should read (shared between the primitives of a mesh);
|
|
11
|
+
* it defaults to zeros, `targets.length` long. Throws when a target's deltas do not cover
|
|
12
|
+
* `base`'s vertices or `weights` is shorter than `targets`.
|
|
13
|
+
*/
|
|
14
|
+
export function createMorphBlender(base, targets, layout, weights = new Float32Array(targets.length)) {
|
|
15
|
+
const floats = layout.floats;
|
|
16
|
+
const vertexCount = Math.floor(base.length / floats);
|
|
17
|
+
const po = layout.positionOffset ?? 0;
|
|
18
|
+
const no = layout.normalOffset === undefined ? 3 : layout.normalOffset;
|
|
19
|
+
const targetCount = targets.length;
|
|
20
|
+
if (weights.length < targetCount) {
|
|
21
|
+
throw new RangeError(`morph: ${weights.length} weights for ${targetCount} targets`);
|
|
22
|
+
}
|
|
23
|
+
for (let i = 0; i < targetCount; i++) {
|
|
24
|
+
const t = targets[i];
|
|
25
|
+
for (const d of [t.position, t.normal]) {
|
|
26
|
+
if (d && d.length < vertexCount * 3) {
|
|
27
|
+
throw new RangeError(`morph: target ${i} has ${d.length / 3} deltas for ${vertexCount} vertices`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const applied = new Float32Array(targetCount);
|
|
32
|
+
let lastOut = null;
|
|
33
|
+
return {
|
|
34
|
+
weights,
|
|
35
|
+
targetCount,
|
|
36
|
+
vertexCount,
|
|
37
|
+
apply(out) {
|
|
38
|
+
let changed = out !== lastOut;
|
|
39
|
+
for (let i = 0; i < targetCount && !changed; i++)
|
|
40
|
+
changed = weights[i] !== applied[i];
|
|
41
|
+
if (!changed)
|
|
42
|
+
return false;
|
|
43
|
+
if (out !== lastOut) {
|
|
44
|
+
out.set(base);
|
|
45
|
+
lastOut = out;
|
|
46
|
+
}
|
|
47
|
+
for (let i = 0; i < targetCount; i++)
|
|
48
|
+
applied[i] = weights[i];
|
|
49
|
+
for (let v = 0; v < vertexCount; v++) {
|
|
50
|
+
const o = v * floats;
|
|
51
|
+
const d = v * 3;
|
|
52
|
+
let px = base[o + po];
|
|
53
|
+
let py = base[o + po + 1];
|
|
54
|
+
let pz = base[o + po + 2];
|
|
55
|
+
for (let i = 0; i < targetCount; i++) {
|
|
56
|
+
const w = applied[i];
|
|
57
|
+
const t = targets[i].position;
|
|
58
|
+
if (w === 0 || !t)
|
|
59
|
+
continue;
|
|
60
|
+
px += w * t[d];
|
|
61
|
+
py += w * t[d + 1];
|
|
62
|
+
pz += w * t[d + 2];
|
|
63
|
+
}
|
|
64
|
+
out[o + po] = px;
|
|
65
|
+
out[o + po + 1] = py;
|
|
66
|
+
out[o + po + 2] = pz;
|
|
67
|
+
if (no === null)
|
|
68
|
+
continue;
|
|
69
|
+
let nx = base[o + no];
|
|
70
|
+
let ny = base[o + no + 1];
|
|
71
|
+
let nz = base[o + no + 2];
|
|
72
|
+
for (let i = 0; i < targetCount; i++) {
|
|
73
|
+
const w = applied[i];
|
|
74
|
+
const t = targets[i].normal;
|
|
75
|
+
if (w === 0 || !t)
|
|
76
|
+
continue;
|
|
77
|
+
nx += w * t[d];
|
|
78
|
+
ny += w * t[d + 1];
|
|
79
|
+
nz += w * t[d + 2];
|
|
80
|
+
}
|
|
81
|
+
const len = Math.hypot(nx, ny, nz);
|
|
82
|
+
if (len > 1e-12) {
|
|
83
|
+
nx /= len;
|
|
84
|
+
ny /= len;
|
|
85
|
+
nz /= len;
|
|
86
|
+
}
|
|
87
|
+
out[o + no] = nx;
|
|
88
|
+
out[o + no + 1] = ny;
|
|
89
|
+
out[o + no + 2] = nz;
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/** Floats per node in a `Pose` and in `Skeleton.rest`: `tx ty tz qx qy qz qw sx sy sz`. */
|
|
2
|
+
export declare const POSE_NODE_FLOATS = 10;
|
|
3
|
+
/** Floats per node in a world array and per joint in a skin array (3×4 row-major). */
|
|
4
|
+
export declare const WORLD_NODE_FLOATS = 12;
|
|
5
|
+
/**
|
|
6
|
+
* A node hierarchy with a rest pose and, when it skins a mesh, the joint list and its inverse
|
|
7
|
+
* bind matrices. Nodes are in parent-before-child order: `parents[i] < i`, or `-1` for a root
|
|
8
|
+
* (`validateSkeleton` checks it; a glTF importer reorders nodes to satisfy it).
|
|
9
|
+
*/
|
|
10
|
+
export interface Skeleton {
|
|
11
|
+
/** Parent node index per node, `-1` for a root. `parents[i] < i`. */
|
|
12
|
+
parents: Int16Array;
|
|
13
|
+
/** Rest pose, `POSE_NODE_FLOATS` per node. */
|
|
14
|
+
rest: Float32Array;
|
|
15
|
+
/**
|
|
16
|
+
* Inverse bind matrix per joint: 12 floats (3×4 row-major, this module's layout) or 16 floats
|
|
17
|
+
* (4×4 column-major, as glTF stores them; the last column is read as the translation).
|
|
18
|
+
*/
|
|
19
|
+
inverseBind?: Float32Array;
|
|
20
|
+
/** Node index per joint. Absent: joint `j` is node `j`. */
|
|
21
|
+
joints?: Uint16Array;
|
|
22
|
+
/** Node name per node (glTF `node.name`), so `createSocket` can take a joint by name. */
|
|
23
|
+
names?: string[];
|
|
24
|
+
}
|
|
25
|
+
/** Local transforms per node, `POSE_NODE_FLOATS` floats each. */
|
|
26
|
+
export type Pose = Float32Array;
|
|
27
|
+
/** Number of nodes in a skeleton. */
|
|
28
|
+
export declare function nodeCount(skeleton: Skeleton): number;
|
|
29
|
+
/** Number of joints: `joints.length` when given, else every node is a joint. */
|
|
30
|
+
export declare function jointCount(skeleton: Skeleton): number;
|
|
31
|
+
/**
|
|
32
|
+
* Throw if the skeleton is inconsistent: `rest` length, parent order (`parents[i] < i`), joint
|
|
33
|
+
* indices in range, `inverseBind` length (12 or 16 per joint).
|
|
34
|
+
*/
|
|
35
|
+
export declare function validateSkeleton(skeleton: Skeleton): void;
|
|
36
|
+
/** A new pose holding a copy of the rest pose. */
|
|
37
|
+
export declare function createPose(skeleton: Skeleton): Pose;
|
|
38
|
+
/** Copy `src` into `dst` (same length). */
|
|
39
|
+
export declare function copyPose(src: Pose, dst: Pose): void;
|
|
40
|
+
/**
|
|
41
|
+
* `out = lerp(a, b, t)` per node: translation and scale linearly, rotation by slerp along the
|
|
42
|
+
* shorter arc. `out` may alias `a` or `b`. No allocation.
|
|
43
|
+
*/
|
|
44
|
+
export declare function blendPose(a: Pose, b: Pose, t: number, out: Pose): void;
|
|
45
|
+
/** Write the 3×4 row-major matrix `T · R · S` of the node at `pose[po..po+10)` to `out[o..o+12)`. */
|
|
46
|
+
export declare function writeNodeMatrix(out: Float32Array, o: number, pose: ArrayLike<number>, po: number): void;
|
|
47
|
+
/**
|
|
48
|
+
* `out[oo..] = a[ao..] · b[bo..]` for 3×4 affine matrices (implicit last row `0 0 0 1`).
|
|
49
|
+
* `out` may alias neither input.
|
|
50
|
+
*/
|
|
51
|
+
export declare function multiplyAffine(out: Float32Array, oo: number, a: ArrayLike<number>, ao: number, b: ArrayLike<number>, bo: number): void;
|
|
52
|
+
/**
|
|
53
|
+
* Invert the 3×4 affine matrix at `m[mo..]` into `out[oo..]` (general 3×3 inverse plus
|
|
54
|
+
* translation). A singular matrix (a zero scale) yields the identity. `out` may not alias `m`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function invertAffine(out: Float32Array, oo: number, m: ArrayLike<number>, mo: number): void;
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a pose into world matrices: `out[i]` (12 floats, 3×4 row-major) is
|
|
59
|
+
* `world[parent] · T·R·S(pose[i])`, in node order. `out` needs `WORLD_NODE_FLOATS × nodes`.
|
|
60
|
+
* No allocation.
|
|
61
|
+
*/
|
|
62
|
+
export declare function poseToWorld(skeleton: Skeleton, pose: Pose, out3x4: Float32Array): void;
|
|
63
|
+
/**
|
|
64
|
+
* Joint matrices for skinning: `out[j]` (12 floats, 3×4 row-major) is
|
|
65
|
+
* `world[joints[j]] · inverseBind[j]`, the layout `render/skin.ts` uploads. Without
|
|
66
|
+
* `inverseBind` the world matrix is copied. `out` needs `WORLD_NODE_FLOATS × joints`. No
|
|
67
|
+
* allocation.
|
|
68
|
+
*/
|
|
69
|
+
export declare function skinMatrices(skeleton: Skeleton, world3x4: Float32Array, out: Float32Array): void;
|
|
70
|
+
/**
|
|
71
|
+
* Inverse bind matrices (12 floats per joint, 3×4 row-major) from the skeleton's rest pose, for
|
|
72
|
+
* procedural rigs: with them `skinMatrices` of the rest pose is the identity. Allocates.
|
|
73
|
+
*/
|
|
74
|
+
export declare function inverseBindFromRest(skeleton: Skeleton): Float32Array;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skeletons, poses and the two resolutions a renderer needs: node world matrices and skin joint
|
|
3
|
+
* matrices. Pure arithmetic on flat `Float32Array`s; nothing here allocates after setup.
|
|
4
|
+
*
|
|
5
|
+
* Layouts:
|
|
6
|
+
* - A `Pose` is `POSE_NODE_FLOATS` (10) floats per node: translation `t3`, rotation `q4`
|
|
7
|
+
* (`x y z w`), scale `s3`. `Skeleton.rest` has the same layout.
|
|
8
|
+
* - World matrices are **3×4 row-major**, 12 floats per node (`render/transform.ts`):
|
|
9
|
+
* `[r0 | tx, r1 | ty, r2 | tz]`, local = `T · R · S`, world = `parent.world · local`.
|
|
10
|
+
* - Skin matrices are the same 3×4 layout, 12 floats per joint, `world[joint] · inverseBind[j]`:
|
|
11
|
+
* what `render/skin.ts` (`SkinPalette`) consumes.
|
|
12
|
+
*/
|
|
13
|
+
import { quatSlerp } from './quat.js';
|
|
14
|
+
/** Floats per node in a `Pose` and in `Skeleton.rest`: `tx ty tz qx qy qz qw sx sy sz`. */
|
|
15
|
+
export const POSE_NODE_FLOATS = 10;
|
|
16
|
+
/** Floats per node in a world array and per joint in a skin array (3×4 row-major). */
|
|
17
|
+
export const WORLD_NODE_FLOATS = 12;
|
|
18
|
+
/** Number of nodes in a skeleton. */
|
|
19
|
+
export function nodeCount(skeleton) {
|
|
20
|
+
return skeleton.parents.length;
|
|
21
|
+
}
|
|
22
|
+
/** Number of joints: `joints.length` when given, else every node is a joint. */
|
|
23
|
+
export function jointCount(skeleton) {
|
|
24
|
+
return skeleton.joints ? skeleton.joints.length : skeleton.parents.length;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Throw if the skeleton is inconsistent: `rest` length, parent order (`parents[i] < i`), joint
|
|
28
|
+
* indices in range, `inverseBind` length (12 or 16 per joint).
|
|
29
|
+
*/
|
|
30
|
+
export function validateSkeleton(skeleton) {
|
|
31
|
+
const n = skeleton.parents.length;
|
|
32
|
+
if (skeleton.rest.length !== n * POSE_NODE_FLOATS) {
|
|
33
|
+
throw new Error(`Skeleton: rest has ${skeleton.rest.length} floats, expected ${n * POSE_NODE_FLOATS} (${n} nodes × ${POSE_NODE_FLOATS})`);
|
|
34
|
+
}
|
|
35
|
+
for (let i = 0; i < n; i++) {
|
|
36
|
+
const p = skeleton.parents[i];
|
|
37
|
+
if (p >= i || p < -1) {
|
|
38
|
+
throw new Error(`Skeleton: parents[${i}] = ${p}; parents must come before children (-1 = root)`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const joints = jointCount(skeleton);
|
|
42
|
+
if (skeleton.joints) {
|
|
43
|
+
for (let j = 0; j < joints; j++) {
|
|
44
|
+
const node = skeleton.joints[j];
|
|
45
|
+
if (node >= n)
|
|
46
|
+
throw new Error(`Skeleton: joints[${j}] = ${node} is not a node (${n} nodes)`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (skeleton.names && skeleton.names.length !== n) {
|
|
50
|
+
throw new Error(`Skeleton: names has ${skeleton.names.length} entries, expected ${n} (one per node)`);
|
|
51
|
+
}
|
|
52
|
+
const ib = skeleton.inverseBind;
|
|
53
|
+
if (ib && ib.length !== joints * 12 && ib.length !== joints * 16) {
|
|
54
|
+
throw new Error(`Skeleton: inverseBind has ${ib.length} floats, expected ${joints * 12} or ${joints * 16} for ${joints} joints`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** A new pose holding a copy of the rest pose. */
|
|
58
|
+
export function createPose(skeleton) {
|
|
59
|
+
return new Float32Array(skeleton.rest);
|
|
60
|
+
}
|
|
61
|
+
/** Copy `src` into `dst` (same length). */
|
|
62
|
+
export function copyPose(src, dst) {
|
|
63
|
+
dst.set(src);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* `out = lerp(a, b, t)` per node: translation and scale linearly, rotation by slerp along the
|
|
67
|
+
* shorter arc. `out` may alias `a` or `b`. No allocation.
|
|
68
|
+
*/
|
|
69
|
+
export function blendPose(a, b, t, out) {
|
|
70
|
+
const s = 1 - t;
|
|
71
|
+
const n = a.length;
|
|
72
|
+
for (let o = 0; o + POSE_NODE_FLOATS <= n; o += POSE_NODE_FLOATS) {
|
|
73
|
+
out[o] = s * a[o] + t * b[o];
|
|
74
|
+
out[o + 1] = s * a[o + 1] + t * b[o + 1];
|
|
75
|
+
out[o + 2] = s * a[o + 2] + t * b[o + 2];
|
|
76
|
+
quatSlerp(out, o + 3, a, o + 3, b, o + 3, t);
|
|
77
|
+
out[o + 7] = s * a[o + 7] + t * b[o + 7];
|
|
78
|
+
out[o + 8] = s * a[o + 8] + t * b[o + 8];
|
|
79
|
+
out[o + 9] = s * a[o + 9] + t * b[o + 9];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Write the 3×4 row-major matrix `T · R · S` of the node at `pose[po..po+10)` to `out[o..o+12)`. */
|
|
83
|
+
export function writeNodeMatrix(out, o, pose, po) {
|
|
84
|
+
const x = pose[po + 3];
|
|
85
|
+
const y = pose[po + 4];
|
|
86
|
+
const z = pose[po + 5];
|
|
87
|
+
const w = pose[po + 6];
|
|
88
|
+
const sx = pose[po + 7];
|
|
89
|
+
const sy = pose[po + 8];
|
|
90
|
+
const sz = pose[po + 9];
|
|
91
|
+
const xx = x * x;
|
|
92
|
+
const yy = y * y;
|
|
93
|
+
const zz = z * z;
|
|
94
|
+
const xy = x * y;
|
|
95
|
+
const xz = x * z;
|
|
96
|
+
const yz = y * z;
|
|
97
|
+
const wx = w * x;
|
|
98
|
+
const wy = w * y;
|
|
99
|
+
const wz = w * z;
|
|
100
|
+
out[o] = (1 - 2 * (yy + zz)) * sx;
|
|
101
|
+
out[o + 1] = 2 * (xy - wz) * sy;
|
|
102
|
+
out[o + 2] = 2 * (xz + wy) * sz;
|
|
103
|
+
out[o + 3] = pose[po];
|
|
104
|
+
out[o + 4] = 2 * (xy + wz) * sx;
|
|
105
|
+
out[o + 5] = (1 - 2 * (xx + zz)) * sy;
|
|
106
|
+
out[o + 6] = 2 * (yz - wx) * sz;
|
|
107
|
+
out[o + 7] = pose[po + 1];
|
|
108
|
+
out[o + 8] = 2 * (xz - wy) * sx;
|
|
109
|
+
out[o + 9] = 2 * (yz + wx) * sy;
|
|
110
|
+
out[o + 10] = (1 - 2 * (xx + yy)) * sz;
|
|
111
|
+
out[o + 11] = pose[po + 2];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `out[oo..] = a[ao..] · b[bo..]` for 3×4 affine matrices (implicit last row `0 0 0 1`).
|
|
115
|
+
* `out` may alias neither input.
|
|
116
|
+
*/
|
|
117
|
+
export function multiplyAffine(out, oo, a, ao, b, bo) {
|
|
118
|
+
for (let r = 0; r < 3; r++) {
|
|
119
|
+
const a0 = a[ao + r * 4];
|
|
120
|
+
const a1 = a[ao + r * 4 + 1];
|
|
121
|
+
const a2 = a[ao + r * 4 + 2];
|
|
122
|
+
const a3 = a[ao + r * 4 + 3];
|
|
123
|
+
out[oo + r * 4] = a0 * b[bo] + a1 * b[bo + 4] + a2 * b[bo + 8];
|
|
124
|
+
out[oo + r * 4 + 1] = a0 * b[bo + 1] + a1 * b[bo + 5] + a2 * b[bo + 9];
|
|
125
|
+
out[oo + r * 4 + 2] = a0 * b[bo + 2] + a1 * b[bo + 6] + a2 * b[bo + 10];
|
|
126
|
+
out[oo + r * 4 + 3] = a0 * b[bo + 3] + a1 * b[bo + 7] + a2 * b[bo + 11] + a3;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Invert the 3×4 affine matrix at `m[mo..]` into `out[oo..]` (general 3×3 inverse plus
|
|
131
|
+
* translation). A singular matrix (a zero scale) yields the identity. `out` may not alias `m`.
|
|
132
|
+
*/
|
|
133
|
+
export function invertAffine(out, oo, m, mo) {
|
|
134
|
+
const a00 = m[mo];
|
|
135
|
+
const a01 = m[mo + 1];
|
|
136
|
+
const a02 = m[mo + 2];
|
|
137
|
+
const tx = m[mo + 3];
|
|
138
|
+
const a10 = m[mo + 4];
|
|
139
|
+
const a11 = m[mo + 5];
|
|
140
|
+
const a12 = m[mo + 6];
|
|
141
|
+
const ty = m[mo + 7];
|
|
142
|
+
const a20 = m[mo + 8];
|
|
143
|
+
const a21 = m[mo + 9];
|
|
144
|
+
const a22 = m[mo + 10];
|
|
145
|
+
const tz = m[mo + 11];
|
|
146
|
+
const c00 = a11 * a22 - a12 * a21;
|
|
147
|
+
const c01 = a02 * a21 - a01 * a22;
|
|
148
|
+
const c02 = a01 * a12 - a02 * a11;
|
|
149
|
+
const det = a00 * c00 + a10 * c01 + a20 * c02;
|
|
150
|
+
if (det === 0) {
|
|
151
|
+
out.fill(0, oo, oo + 12);
|
|
152
|
+
out[oo] = 1;
|
|
153
|
+
out[oo + 5] = 1;
|
|
154
|
+
out[oo + 10] = 1;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const inv = 1 / det;
|
|
158
|
+
const i00 = c00 * inv;
|
|
159
|
+
const i01 = c01 * inv;
|
|
160
|
+
const i02 = c02 * inv;
|
|
161
|
+
const i10 = (a12 * a20 - a10 * a22) * inv;
|
|
162
|
+
const i11 = (a00 * a22 - a02 * a20) * inv;
|
|
163
|
+
const i12 = (a02 * a10 - a00 * a12) * inv;
|
|
164
|
+
const i20 = (a10 * a21 - a11 * a20) * inv;
|
|
165
|
+
const i21 = (a01 * a20 - a00 * a21) * inv;
|
|
166
|
+
const i22 = (a00 * a11 - a01 * a10) * inv;
|
|
167
|
+
out[oo] = i00;
|
|
168
|
+
out[oo + 1] = i01;
|
|
169
|
+
out[oo + 2] = i02;
|
|
170
|
+
out[oo + 3] = -(i00 * tx + i01 * ty + i02 * tz);
|
|
171
|
+
out[oo + 4] = i10;
|
|
172
|
+
out[oo + 5] = i11;
|
|
173
|
+
out[oo + 6] = i12;
|
|
174
|
+
out[oo + 7] = -(i10 * tx + i11 * ty + i12 * tz);
|
|
175
|
+
out[oo + 8] = i20;
|
|
176
|
+
out[oo + 9] = i21;
|
|
177
|
+
out[oo + 10] = i22;
|
|
178
|
+
out[oo + 11] = -(i20 * tx + i21 * ty + i22 * tz);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Resolve a pose into world matrices: `out[i]` (12 floats, 3×4 row-major) is
|
|
182
|
+
* `world[parent] · T·R·S(pose[i])`, in node order. `out` needs `WORLD_NODE_FLOATS × nodes`.
|
|
183
|
+
* No allocation.
|
|
184
|
+
*/
|
|
185
|
+
export function poseToWorld(skeleton, pose, out3x4) {
|
|
186
|
+
const parents = skeleton.parents;
|
|
187
|
+
const n = parents.length;
|
|
188
|
+
for (let i = 0; i < n; i++) {
|
|
189
|
+
const o = i * WORLD_NODE_FLOATS;
|
|
190
|
+
const p = parents[i];
|
|
191
|
+
if (p < 0) {
|
|
192
|
+
writeNodeMatrix(out3x4, o, pose, i * POSE_NODE_FLOATS);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
writeNodeMatrix(scratchLocal, 0, pose, i * POSE_NODE_FLOATS);
|
|
196
|
+
multiplyAffine(out3x4, o, out3x4, p * WORLD_NODE_FLOATS, scratchLocal, 0);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const scratchLocal = new Float32Array(WORLD_NODE_FLOATS);
|
|
201
|
+
const scratchBind = new Float32Array(WORLD_NODE_FLOATS);
|
|
202
|
+
/**
|
|
203
|
+
* Joint matrices for skinning: `out[j]` (12 floats, 3×4 row-major) is
|
|
204
|
+
* `world[joints[j]] · inverseBind[j]`, the layout `render/skin.ts` uploads. Without
|
|
205
|
+
* `inverseBind` the world matrix is copied. `out` needs `WORLD_NODE_FLOATS × joints`. No
|
|
206
|
+
* allocation.
|
|
207
|
+
*/
|
|
208
|
+
export function skinMatrices(skeleton, world3x4, out) {
|
|
209
|
+
const joints = jointCount(skeleton);
|
|
210
|
+
const map = skeleton.joints;
|
|
211
|
+
const ib = skeleton.inverseBind;
|
|
212
|
+
const stride = ib ? ib.length / joints : 0;
|
|
213
|
+
for (let j = 0; j < joints; j++) {
|
|
214
|
+
const node = map ? map[j] : j;
|
|
215
|
+
const wo = node * WORLD_NODE_FLOATS;
|
|
216
|
+
const oo = j * WORLD_NODE_FLOATS;
|
|
217
|
+
if (!ib) {
|
|
218
|
+
// A plain copy, not `set(subarray(...))`: no view allocated per joint.
|
|
219
|
+
for (let k = 0; k < WORLD_NODE_FLOATS; k++)
|
|
220
|
+
out[oo + k] = world3x4[wo + k];
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (stride === 16) {
|
|
224
|
+
// glTF column-major 4×4 → our row-major 3×4.
|
|
225
|
+
const b = j * 16;
|
|
226
|
+
for (let r = 0; r < 3; r++) {
|
|
227
|
+
scratchBind[r * 4] = ib[b + r];
|
|
228
|
+
scratchBind[r * 4 + 1] = ib[b + 4 + r];
|
|
229
|
+
scratchBind[r * 4 + 2] = ib[b + 8 + r];
|
|
230
|
+
scratchBind[r * 4 + 3] = ib[b + 12 + r];
|
|
231
|
+
}
|
|
232
|
+
multiplyAffine(out, oo, world3x4, wo, scratchBind, 0);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
multiplyAffine(out, oo, world3x4, wo, ib, j * 12);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Inverse bind matrices (12 floats per joint, 3×4 row-major) from the skeleton's rest pose, for
|
|
241
|
+
* procedural rigs: with them `skinMatrices` of the rest pose is the identity. Allocates.
|
|
242
|
+
*/
|
|
243
|
+
export function inverseBindFromRest(skeleton) {
|
|
244
|
+
const n = skeleton.parents.length;
|
|
245
|
+
const world = new Float32Array(n * WORLD_NODE_FLOATS);
|
|
246
|
+
poseToWorld(skeleton, skeleton.rest, world);
|
|
247
|
+
const joints = skeleton.joints ? skeleton.joints.length : n;
|
|
248
|
+
const out = new Float32Array(joints * WORLD_NODE_FLOATS);
|
|
249
|
+
for (let j = 0; j < joints; j++) {
|
|
250
|
+
const node = skeleton.joints ? skeleton.joints[j] : j;
|
|
251
|
+
invertAffine(out, j * WORLD_NODE_FLOATS, world, node * WORLD_NODE_FLOATS);
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quaternion helpers on flat arrays: every function reads and writes `(x, y, z, w)` at an
|
|
3
|
+
* offset into a `Float32Array` (or any `ArrayLike`), so poses and keyframe buffers are handled in
|
|
4
|
+
* place and nothing allocates. No dependency on `render/`.
|
|
5
|
+
*
|
|
6
|
+
* Conventions match `render/transform.ts`: unit quaternions `(x, y, z, w)`, right-handed, and
|
|
7
|
+
* `quatMultiply(out, a, b)` is "apply `b`, then `a`" (the same order as matrix products).
|
|
8
|
+
*/
|
|
9
|
+
/** Write the identity rotation at `out[o..o+4)`. */
|
|
10
|
+
export declare function quatIdentity(out: Float32Array, o?: number): void;
|
|
11
|
+
/** Normalise the quaternion at `q[o..o+4)` in place. A zero quaternion becomes the identity. */
|
|
12
|
+
export declare function quatNormalize(q: Float32Array, o?: number): void;
|
|
13
|
+
/** Dot product of the quaternions at `a[ao..]` and `b[bo..]`. */
|
|
14
|
+
export declare function quatDot(a: ArrayLike<number>, ao: number, b: ArrayLike<number>, bo: number): number;
|
|
15
|
+
/**
|
|
16
|
+
* `out = a · b`: the rotation that applies `b` first, then `a`. `out` may alias either input.
|
|
17
|
+
*/
|
|
18
|
+
export declare function quatMultiply(out: Float32Array, oo: number, a: ArrayLike<number>, ao: number, b: ArrayLike<number>, bo: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Normalised linear interpolation from `a` to `b` by `t` along the shorter arc. Cheaper than
|
|
21
|
+
* `quatSlerp`, not constant speed; fine for blending nearby poses. `out` may alias an input.
|
|
22
|
+
*/
|
|
23
|
+
export declare function quatNlerp(out: Float32Array, oo: number, a: ArrayLike<number>, ao: number, b: ArrayLike<number>, bo: number, t: number): void;
|
|
24
|
+
/**
|
|
25
|
+
* Spherical linear interpolation from `a` to `b` by `t` along the shorter arc (glTF `LINEAR`
|
|
26
|
+
* rotation semantics). Falls back to a normalised lerp when the inputs are nearly parallel.
|
|
27
|
+
* `out` may alias an input.
|
|
28
|
+
*/
|
|
29
|
+
export declare function quatSlerp(out: Float32Array, oo: number, a: ArrayLike<number>, ao: number, b: ArrayLike<number>, bo: number, t: number): void;
|
|
30
|
+
/** Rotation about an axis (need not be unit length) by `radians`, written at `out[o..o+4)`. */
|
|
31
|
+
export declare function quatFromAxisAngle(out: Float32Array, o: number, ax: number, ay: number, az: number, radians: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* Rotation from Euler angles in radians: about X, then Y, then Z in the parent frame
|
|
34
|
+
* (`q = qz · qy · qx`). Written at `out[o..o+4)`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function quatFromEuler(out: Float32Array, o: number, x: number, y: number, z: number): void;
|
|
37
|
+
/**
|
|
38
|
+
* The rotation of a 3×3 matrix (or the 3×3 part of a 3×4 affine, with `stride` 4) read
|
|
39
|
+
* row-major at `m[mo..]` (rows `r0 r1 r2`, `stride` floats apart; default 3 for a packed
|
|
40
|
+
* mat3), written as a unit quaternion at `out[o..o+4)`. Shepperd's method: the largest
|
|
41
|
+
* diagonal term picks the stable branch. A scaled matrix is normalised first (uniform scale
|
|
42
|
+
* drops out; non-uniform scale gives the nearest rotation only approximately). Allocation-free.
|
|
43
|
+
*/
|
|
44
|
+
export declare function quatFromMat3(m: ArrayLike<number>, out: Float32Array, o?: number, mo?: number, stride?: number): void;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quaternion helpers on flat arrays: every function reads and writes `(x, y, z, w)` at an
|
|
3
|
+
* offset into a `Float32Array` (or any `ArrayLike`), so poses and keyframe buffers are handled in
|
|
4
|
+
* place and nothing allocates. No dependency on `render/`.
|
|
5
|
+
*
|
|
6
|
+
* Conventions match `render/transform.ts`: unit quaternions `(x, y, z, w)`, right-handed, and
|
|
7
|
+
* `quatMultiply(out, a, b)` is "apply `b`, then `a`" (the same order as matrix products).
|
|
8
|
+
*/
|
|
9
|
+
/** Write the identity rotation at `out[o..o+4)`. */
|
|
10
|
+
export function quatIdentity(out, o = 0) {
|
|
11
|
+
out[o] = 0;
|
|
12
|
+
out[o + 1] = 0;
|
|
13
|
+
out[o + 2] = 0;
|
|
14
|
+
out[o + 3] = 1;
|
|
15
|
+
}
|
|
16
|
+
/** Normalise the quaternion at `q[o..o+4)` in place. A zero quaternion becomes the identity. */
|
|
17
|
+
export function quatNormalize(q, o = 0) {
|
|
18
|
+
const x = q[o];
|
|
19
|
+
const y = q[o + 1];
|
|
20
|
+
const z = q[o + 2];
|
|
21
|
+
const w = q[o + 3];
|
|
22
|
+
const len = Math.hypot(x, y, z, w);
|
|
23
|
+
if (len === 0) {
|
|
24
|
+
quatIdentity(q, o);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const inv = 1 / len;
|
|
28
|
+
q[o] = x * inv;
|
|
29
|
+
q[o + 1] = y * inv;
|
|
30
|
+
q[o + 2] = z * inv;
|
|
31
|
+
q[o + 3] = w * inv;
|
|
32
|
+
}
|
|
33
|
+
/** Dot product of the quaternions at `a[ao..]` and `b[bo..]`. */
|
|
34
|
+
export function quatDot(a, ao, b, bo) {
|
|
35
|
+
return (a[ao] * b[bo] + a[ao + 1] * b[bo + 1] + a[ao + 2] * b[bo + 2] + a[ao + 3] * b[bo + 3]);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `out = a · b`: the rotation that applies `b` first, then `a`. `out` may alias either input.
|
|
39
|
+
*/
|
|
40
|
+
export function quatMultiply(out, oo, a, ao, b, bo) {
|
|
41
|
+
const ax = a[ao];
|
|
42
|
+
const ay = a[ao + 1];
|
|
43
|
+
const az = a[ao + 2];
|
|
44
|
+
const aw = a[ao + 3];
|
|
45
|
+
const bx = b[bo];
|
|
46
|
+
const by = b[bo + 1];
|
|
47
|
+
const bz = b[bo + 2];
|
|
48
|
+
const bw = b[bo + 3];
|
|
49
|
+
out[oo] = aw * bx + ax * bw + ay * bz - az * by;
|
|
50
|
+
out[oo + 1] = aw * by - ax * bz + ay * bw + az * bx;
|
|
51
|
+
out[oo + 2] = aw * bz + ax * by - ay * bx + az * bw;
|
|
52
|
+
out[oo + 3] = aw * bw - ax * bx - ay * by - az * bz;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Normalised linear interpolation from `a` to `b` by `t` along the shorter arc. Cheaper than
|
|
56
|
+
* `quatSlerp`, not constant speed; fine for blending nearby poses. `out` may alias an input.
|
|
57
|
+
*/
|
|
58
|
+
export function quatNlerp(out, oo, a, ao, b, bo, t) {
|
|
59
|
+
const sign = quatDot(a, ao, b, bo) < 0 ? -1 : 1;
|
|
60
|
+
const s = 1 - t;
|
|
61
|
+
const u = t * sign;
|
|
62
|
+
out[oo] = s * a[ao] + u * b[bo];
|
|
63
|
+
out[oo + 1] = s * a[ao + 1] + u * b[bo + 1];
|
|
64
|
+
out[oo + 2] = s * a[ao + 2] + u * b[bo + 2];
|
|
65
|
+
out[oo + 3] = s * a[ao + 3] + u * b[bo + 3];
|
|
66
|
+
quatNormalize(out, oo);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Spherical linear interpolation from `a` to `b` by `t` along the shorter arc (glTF `LINEAR`
|
|
70
|
+
* rotation semantics). Falls back to a normalised lerp when the inputs are nearly parallel.
|
|
71
|
+
* `out` may alias an input.
|
|
72
|
+
*/
|
|
73
|
+
export function quatSlerp(out, oo, a, ao, b, bo, t) {
|
|
74
|
+
let cos = quatDot(a, ao, b, bo);
|
|
75
|
+
let sign = 1;
|
|
76
|
+
if (cos < 0) {
|
|
77
|
+
cos = -cos;
|
|
78
|
+
sign = -1;
|
|
79
|
+
}
|
|
80
|
+
if (cos > 0.9995) {
|
|
81
|
+
quatNlerp(out, oo, a, ao, b, bo, t);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const theta = Math.acos(cos);
|
|
85
|
+
const sinTheta = Math.sin(theta);
|
|
86
|
+
const s = Math.sin((1 - t) * theta) / sinTheta;
|
|
87
|
+
const u = (Math.sin(t * theta) / sinTheta) * sign;
|
|
88
|
+
out[oo] = s * a[ao] + u * b[bo];
|
|
89
|
+
out[oo + 1] = s * a[ao + 1] + u * b[bo + 1];
|
|
90
|
+
out[oo + 2] = s * a[ao + 2] + u * b[bo + 2];
|
|
91
|
+
out[oo + 3] = s * a[ao + 3] + u * b[bo + 3];
|
|
92
|
+
}
|
|
93
|
+
/** Rotation about an axis (need not be unit length) by `radians`, written at `out[o..o+4)`. */
|
|
94
|
+
export function quatFromAxisAngle(out, o, ax, ay, az, radians) {
|
|
95
|
+
const len = Math.hypot(ax, ay, az) || 1;
|
|
96
|
+
const s = Math.sin(radians / 2) / len;
|
|
97
|
+
out[o] = ax * s;
|
|
98
|
+
out[o + 1] = ay * s;
|
|
99
|
+
out[o + 2] = az * s;
|
|
100
|
+
out[o + 3] = Math.cos(radians / 2);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Rotation from Euler angles in radians: about X, then Y, then Z in the parent frame
|
|
104
|
+
* (`q = qz · qy · qx`). Written at `out[o..o+4)`.
|
|
105
|
+
*/
|
|
106
|
+
export function quatFromEuler(out, o, x, y, z) {
|
|
107
|
+
const cx = Math.cos(x / 2);
|
|
108
|
+
const sx = Math.sin(x / 2);
|
|
109
|
+
const cy = Math.cos(y / 2);
|
|
110
|
+
const sy = Math.sin(y / 2);
|
|
111
|
+
const cz = Math.cos(z / 2);
|
|
112
|
+
const sz = Math.sin(z / 2);
|
|
113
|
+
out[o] = sx * cy * cz - cx * sy * sz;
|
|
114
|
+
out[o + 1] = cx * sy * cz + sx * cy * sz;
|
|
115
|
+
out[o + 2] = cx * cy * sz - sx * sy * cz;
|
|
116
|
+
out[o + 3] = cx * cy * cz + sx * sy * sz;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The rotation of a 3×3 matrix (or the 3×3 part of a 3×4 affine, with `stride` 4) read
|
|
120
|
+
* row-major at `m[mo..]` (rows `r0 r1 r2`, `stride` floats apart; default 3 for a packed
|
|
121
|
+
* mat3), written as a unit quaternion at `out[o..o+4)`. Shepperd's method: the largest
|
|
122
|
+
* diagonal term picks the stable branch. A scaled matrix is normalised first (uniform scale
|
|
123
|
+
* drops out; non-uniform scale gives the nearest rotation only approximately). Allocation-free.
|
|
124
|
+
*/
|
|
125
|
+
export function quatFromMat3(m, out, o = 0, mo = 0, stride = 3) {
|
|
126
|
+
// Normalise each row so a scaled matrix yields a unit quaternion.
|
|
127
|
+
let m00 = m[mo];
|
|
128
|
+
let m01 = m[mo + 1];
|
|
129
|
+
let m02 = m[mo + 2];
|
|
130
|
+
let m10 = m[mo + stride];
|
|
131
|
+
let m11 = m[mo + stride + 1];
|
|
132
|
+
let m12 = m[mo + stride + 2];
|
|
133
|
+
let m20 = m[mo + 2 * stride];
|
|
134
|
+
let m21 = m[mo + 2 * stride + 1];
|
|
135
|
+
let m22 = m[mo + 2 * stride + 2];
|
|
136
|
+
// Columns are the rotated basis vectors; their lengths are the scale.
|
|
137
|
+
const sx = Math.hypot(m00, m10, m20) || 1;
|
|
138
|
+
const sy = Math.hypot(m01, m11, m21) || 1;
|
|
139
|
+
const sz = Math.hypot(m02, m12, m22) || 1;
|
|
140
|
+
m00 /= sx;
|
|
141
|
+
m10 /= sx;
|
|
142
|
+
m20 /= sx;
|
|
143
|
+
m01 /= sy;
|
|
144
|
+
m11 /= sy;
|
|
145
|
+
m21 /= sy;
|
|
146
|
+
m02 /= sz;
|
|
147
|
+
m12 /= sz;
|
|
148
|
+
m22 /= sz;
|
|
149
|
+
const trace = m00 + m11 + m22;
|
|
150
|
+
let x;
|
|
151
|
+
let y;
|
|
152
|
+
let z;
|
|
153
|
+
let w;
|
|
154
|
+
if (trace > 0) {
|
|
155
|
+
const s = Math.sqrt(trace + 1) * 2;
|
|
156
|
+
w = s / 4;
|
|
157
|
+
x = (m21 - m12) / s;
|
|
158
|
+
y = (m02 - m20) / s;
|
|
159
|
+
z = (m10 - m01) / s;
|
|
160
|
+
}
|
|
161
|
+
else if (m00 > m11 && m00 > m22) {
|
|
162
|
+
const s = Math.sqrt(1 + m00 - m11 - m22) * 2;
|
|
163
|
+
w = (m21 - m12) / s;
|
|
164
|
+
x = s / 4;
|
|
165
|
+
y = (m01 + m10) / s;
|
|
166
|
+
z = (m02 + m20) / s;
|
|
167
|
+
}
|
|
168
|
+
else if (m11 > m22) {
|
|
169
|
+
const s = Math.sqrt(1 + m11 - m00 - m22) * 2;
|
|
170
|
+
w = (m02 - m20) / s;
|
|
171
|
+
x = (m01 + m10) / s;
|
|
172
|
+
y = s / 4;
|
|
173
|
+
z = (m12 + m21) / s;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const s = Math.sqrt(1 + m22 - m00 - m11) * 2;
|
|
177
|
+
w = (m10 - m01) / s;
|
|
178
|
+
x = (m02 + m20) / s;
|
|
179
|
+
y = (m12 + m21) / s;
|
|
180
|
+
z = s / 4;
|
|
181
|
+
}
|
|
182
|
+
out[o] = x;
|
|
183
|
+
out[o + 1] = y;
|
|
184
|
+
out[o + 2] = z;
|
|
185
|
+
out[o + 3] = w;
|
|
186
|
+
quatNormalize(out, o);
|
|
187
|
+
}
|