@driftengine/core 4.4.2 → 4.6.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.json +97 -0
- package/README.md +1 -1
- package/dist/geometry/boxCsg.d.ts +28 -0
- package/dist/geometry/boxCsg.js +139 -0
- package/dist/geometry/csg.d.ts +36 -0
- package/dist/geometry/csg.js +329 -0
- package/dist/geometry/meshBuilder.js +13 -0
- package/dist/geometry/meshConcat.js +1 -0
- package/dist/geometry/pixelFont.js +2 -0
- package/dist/geometry/solid.d.ts +61 -0
- package/dist/geometry/solid.js +152 -0
- package/dist/geometry/solidFlat.d.ts +35 -0
- package/dist/geometry/solidFlat.js +428 -0
- package/dist/geometry/solidHarness.d.ts +19 -0
- package/dist/geometry/solidHarness.js +66 -0
- package/dist/geometry/solidNormals.d.ts +17 -0
- package/dist/geometry/solidNormals.js +86 -0
- package/dist/geometry/solidRound.d.ts +41 -0
- package/dist/geometry/solidRound.js +323 -0
- package/dist/geometry/solidWriter.d.ts +16 -0
- package/dist/geometry/solidWriter.js +42 -0
- package/dist/index.d.ts +28 -3
- package/dist/index.js +20 -1
- package/dist/render/backend/api.d.ts +34 -14
- package/dist/render/backend/drawFog.d.ts +26 -0
- package/dist/render/backend/drawFog.js +30 -0
- package/dist/render/backend/materialChanges.d.ts +2 -1
- package/dist/render/backend/materialChanges.js +6 -1
- package/dist/render/backend/webgl2/glassTintPrograms.d.ts +13 -0
- package/dist/render/backend/webgl2/glassTintPrograms.js +38 -0
- package/dist/render/backend/webgl2/instanced.d.ts +24 -5
- package/dist/render/backend/webgl2/instanced.js +72 -15
- package/dist/render/backend/webgl2/renderer.d.ts +201 -16
- package/dist/render/backend/webgl2/renderer.js +596 -224
- package/dist/render/backend/webgpu/buffers.d.ts +29 -1
- package/dist/render/backend/webgpu/buffers.js +61 -4
- package/dist/render/backend/webgpu/depthPass.d.ts +1 -1
- package/dist/render/backend/webgpu/depthPass.js +7 -2
- package/dist/render/backend/webgpu/drawCommand.d.ts +5 -0
- package/dist/render/backend/webgpu/drawCommand.js +1 -0
- package/dist/render/backend/webgpu/flatPass.d.ts +6 -1
- package/dist/render/backend/webgpu/flatPass.js +57 -9
- package/dist/render/backend/webgpu/glassTintPass.d.ts +28 -0
- package/dist/render/backend/webgpu/glassTintPass.js +206 -0
- package/dist/render/backend/webgpu/gpuDrivenPass.d.ts +60 -1
- package/dist/render/backend/webgpu/gpuDrivenPass.js +305 -5
- package/dist/render/backend/webgpu/instanceCullPass.d.ts +34 -0
- package/dist/render/backend/webgpu/instanceCullPass.js +144 -0
- package/dist/render/backend/webgpu/instanced.d.ts +23 -2
- package/dist/render/backend/webgpu/instanced.js +41 -4
- package/dist/render/backend/webgpu/latePass.d.ts +30 -0
- package/dist/render/backend/webgpu/latePass.js +140 -0
- package/dist/render/backend/webgpu/lightVolumePass.js +5 -1
- package/dist/render/backend/webgpu/motionPass.d.ts +95 -0
- package/dist/render/backend/webgpu/motionPass.js +491 -0
- package/dist/render/backend/webgpu/pipelineCache.d.ts +10 -1
- package/dist/render/backend/webgpu/pipelineCache.js +11 -1
- package/dist/render/backend/webgpu/pointGlassTintPass.d.ts +32 -0
- package/dist/render/backend/webgpu/pointGlassTintPass.js +193 -0
- package/dist/render/backend/webgpu/pointShadowPass.d.ts +35 -6
- package/dist/render/backend/webgpu/pointShadowPass.js +105 -20
- package/dist/render/backend/webgpu/postPass.d.ts +3 -13
- package/dist/render/backend/webgpu/renderer.d.ts +271 -64
- package/dist/render/backend/webgpu/renderer.js +1395 -580
- package/dist/render/backend/webgpu/scatterPass.js +2 -1
- package/dist/render/backend/webgpu/sdfTextPass.js +6 -1
- package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.d.ts +18 -0
- package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.js +59 -0
- package/dist/render/backend/webgpu/skinPaletteRing.d.ts +4 -0
- package/dist/render/backend/webgpu/skinPaletteRing.js +4 -0
- package/dist/render/backend/webgpu/snapshotMips.d.ts +29 -0
- package/dist/render/backend/webgpu/snapshotMips.js +52 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +22 -3
- package/dist/render/backend/webgpu/surfaceTexturePass.js +78 -39
- package/dist/render/driftLight/bake.d.ts +7 -0
- package/dist/render/driftLight/bake.js +61 -56
- package/dist/render/driftLight/denseField.d.ts +46 -0
- package/dist/render/driftLight/denseField.js +109 -0
- package/dist/render/driftLight/lightField.d.ts +10 -5
- package/dist/render/driftLight/lightField.js +25 -19
- package/dist/render/driftLight/presence.d.ts +50 -0
- package/dist/render/driftLight/presence.js +43 -0
- package/dist/render/driftLight/uniforms.d.ts +3 -3
- package/dist/render/driftLight/uniforms.js +5 -6
- package/dist/render/driftLight/worldLightField.d.ts +41 -0
- package/dist/render/driftLight/worldLightField.js +66 -0
- package/dist/render/fixtureAtlas.d.ts +20 -0
- package/dist/render/fixtureAtlas.js +49 -0
- package/dist/render/glass.d.ts +45 -0
- package/dist/render/glass.js +39 -0
- package/dist/render/glassCasters.d.ts +40 -0
- package/dist/render/glassCasters.js +84 -0
- package/dist/render/glassShadow.d.ts +78 -0
- package/dist/render/glassShadow.js +125 -0
- package/dist/render/globalMediumPass.d.ts +2 -3
- package/dist/render/globalMediumPass.js +2 -8
- package/dist/render/gpudriven/lit.d.ts +12 -0
- package/dist/render/gpudriven/lit.js +23 -0
- package/dist/render/gpudriven/materialTable.d.ts +15 -5
- package/dist/render/gpudriven/materialTable.js +26 -6
- package/dist/render/gpudriven/pipeline.d.ts +1 -1
- package/dist/render/gpudriven/pipeline.js +4 -3
- package/dist/render/gpudriven/sunGlass.d.ts +35 -0
- package/dist/render/gpudriven/sunGlass.js +89 -0
- package/dist/render/instanceCull.d.ts +63 -0
- package/dist/render/instanceCull.js +160 -0
- package/dist/render/instances.d.ts +15 -0
- package/dist/render/lightBudget.d.ts +36 -35
- package/dist/render/lightBudget.js +38 -37
- package/dist/render/lightGrid.d.ts +42 -0
- package/dist/render/lightGrid.js +87 -0
- package/dist/render/mesh.d.ts +18 -24
- package/dist/render/mesh.js +51 -68
- package/dist/render/occlusion.d.ts +10 -0
- package/dist/render/occlusion.js +36 -7
- package/dist/render/pointGlassTint.d.ts +59 -0
- package/dist/render/pointGlassTint.js +198 -0
- package/dist/render/pointLightSelection.d.ts +7 -0
- package/dist/render/pointLightSelection.js +29 -4
- package/dist/render/pointShadowArray.d.ts +56 -3
- package/dist/render/pointShadowArray.js +127 -16
- package/dist/render/pointShadowMap.d.ts +23 -1
- package/dist/render/pointShadowMap.js +27 -1
- package/dist/render/rainField.d.ts +13 -0
- package/dist/render/rainField.js +27 -5
- package/dist/render/recon/changeFrames.d.ts +15 -0
- package/dist/render/recon/changeFrames.js +21 -0
- package/dist/render/recon/lateDepth.d.ts +11 -0
- package/dist/render/recon/lateDepth.js +70 -0
- package/dist/render/recon/lateRouting.d.ts +14 -0
- package/dist/render/recon/lateRouting.js +18 -0
- package/dist/render/recon/mover.d.ts +57 -0
- package/dist/render/recon/mover.js +86 -0
- package/dist/render/recon/resolve.d.ts +34 -4
- package/dist/render/recon/resolve.js +161 -20
- package/dist/render/renderQuality.d.ts +35 -0
- package/dist/render/renderQuality.js +7 -0
- package/dist/render/rendererHarness.js +16 -0
- package/dist/render/sceneTarget.d.ts +9 -1
- package/dist/render/sceneTarget.js +60 -12
- package/dist/render/shaders/depth.d.ts +16 -1
- package/dist/render/shaders/depth.js +94 -15
- package/dist/render/shaders/flat/directionalShadow.js +91 -6
- package/dist/render/shaders/flat/driftLight.d.ts +1 -1
- package/dist/render/shaders/flat/driftLight.js +32 -7
- package/dist/render/shaders/flat/glassTint.d.ts +6 -0
- package/dist/render/shaders/flat/glassTint.js +25 -0
- package/dist/render/shaders/flat/index.d.ts +13 -0
- package/dist/render/shaders/flat/index.js +9 -3
- package/dist/render/shaders/flat/lampGlass.d.ts +1 -0
- package/dist/render/shaders/flat/lampGlass.js +183 -0
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +190 -38
- package/dist/render/shaders/flat/pointShadow.d.ts +1 -1
- package/dist/render/shaders/flat/pointShadow.js +2 -0
- package/dist/render/shaders/flat/preamble.js +96 -26
- package/dist/render/shaders/flat/surfaceEffects.d.ts +29 -0
- package/dist/render/shaders/flat/surfaceEffects.js +152 -0
- package/dist/render/shaders/generated/depth.wgsl.d.ts +230 -7
- package/dist/render/shaders/generated/depth.wgsl.js +230 -7
- package/dist/render/shaders/generated/flat.wgsl.d.ts +1644 -1596
- package/dist/render/shaders/generated/flat.wgsl.js +1683 -1621
- package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +3 -13
- package/dist/render/shaders/generated/globalMedium.wgsl.js +3 -13
- package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +3 -13
- package/dist/render/shaders/generated/lightVolume.wgsl.js +21 -17
- package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +29 -0
- package/dist/render/shaders/generated/octahedralResolve.wgsl.js +29 -0
- package/dist/render/shaders/generated/rush.wgsl.d.ts +21 -16
- package/dist/render/shaders/generated/rush.wgsl.js +21 -16
- package/dist/render/shaders/generated/sdfText.wgsl.d.ts +2 -2
- package/dist/render/shaders/generated/sdfText.wgsl.js +2 -2
- package/dist/render/shaders/generated/text.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/text.wgsl.js +1 -1
- package/dist/render/shaders/gi/driftLight.wgsl.d.ts +1 -1
- package/dist/render/shaders/gi/driftLight.wgsl.js +27 -4
- package/dist/render/shaders/globalMedium.js +6 -6
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.d.ts +7 -0
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +86 -1
- package/dist/render/shaders/gpudriven/cull.wgsl.d.ts +1 -1
- package/dist/render/shaders/gpudriven/cull.wgsl.js +11 -2
- package/dist/render/shaders/gpudriven/materialTable.wgsl.d.ts +1 -1
- package/dist/render/shaders/gpudriven/materialTable.wgsl.js +3 -1
- package/dist/render/shaders/gpudriven/shade.wgsl.js +50 -1
- package/dist/render/shaders/gpudriven/sunGlass.wgsl.d.ts +9 -0
- package/dist/render/shaders/gpudriven/sunGlass.wgsl.js +133 -0
- package/dist/render/shaders/lightVolume.js +6 -6
- package/dist/render/shaders/octahedralResolve.d.ts +8 -0
- package/dist/render/shaders/octahedralResolve.js +48 -17
- package/dist/render/shaders/recon/lateDepth.wgsl.d.ts +1 -0
- package/dist/render/shaders/recon/lateDepth.wgsl.js +69 -0
- package/dist/render/shaders/recon/motion.wgsl.d.ts +1 -1
- package/dist/render/shaders/recon/motion.wgsl.js +84 -0
- package/dist/render/shaders/recon/resolve.wgsl.d.ts +8 -7
- package/dist/render/shaders/recon/resolve.wgsl.js +161 -27
- package/dist/render/shaders/rush.js +11 -1
- package/dist/render/shaders/sdfText.d.ts +1 -1
- package/dist/render/shaders/sdfText.js +3 -2
- package/dist/render/shaders/text.d.ts +1 -1
- package/dist/render/shaders/text.js +18 -9
- package/dist/render/shadowCasters.d.ts +20 -1
- package/dist/render/shadowCasters.js +15 -1
- package/dist/render/shadowMap.d.ts +54 -5
- package/dist/render/shadowMap.js +190 -36
- package/dist/render/sunGlassTint.d.ts +25 -0
- package/dist/render/sunGlassTint.js +79 -0
- package/dist/render/surfaceEffects.d.ts +83 -0
- package/dist/render/surfaceEffects.js +75 -0
- package/dist/render/surfaceScene.d.ts +8 -0
- package/dist/render/surfaceScene.js +8 -0
- package/dist/render/surfaceTexture.d.ts +18 -2
- package/dist/render/surfaceTexture.js +68 -15
- package/dist/render/temporalAa.d.ts +25 -6
- package/dist/render/temporalAa.js +45 -15
- package/dist/render/textureSource.d.ts +30 -0
- package/dist/render/textureSource.js +53 -0
- package/dist/render/translucentQueue.d.ts +6 -0
- package/dist/render/translucentQueue.js +15 -1
- package/dist/render/vertexDefaults.js +2 -0
- package/dist/world/hlod.d.ts +104 -0
- package/dist/world/hlod.js +214 -0
- package/package.json +6 -6
- package/src/geometry/boxCsg.ts +186 -0
- package/src/geometry/csg.ts +384 -0
- package/src/geometry/meshBuilder.ts +15 -0
- package/src/geometry/meshConcat.ts +1 -0
- package/src/geometry/pixelFont.ts +2 -0
- package/src/geometry/solid.ts +189 -0
- package/src/geometry/solidFlat.ts +522 -0
- package/src/geometry/solidHarness.ts +83 -0
- package/src/geometry/solidNormals.ts +103 -0
- package/src/geometry/solidRound.ts +443 -0
- package/src/geometry/solidWriter.ts +58 -0
- package/src/index.ts +61 -1
- package/src/render/backend/api.ts +36 -11
- package/src/render/backend/drawFog.ts +31 -0
- package/src/render/backend/materialChanges.ts +9 -2
- package/src/render/backend/webgl2/glassTintPrograms.ts +58 -0
- package/src/render/backend/webgl2/instanced.ts +80 -14
- package/src/render/backend/webgl2/renderer.ts +700 -250
- package/src/render/backend/webgpu/buffers.ts +92 -5
- package/src/render/backend/webgpu/depthPass.ts +7 -2
- package/src/render/backend/webgpu/drawCommand.ts +6 -0
- package/src/render/backend/webgpu/flatPass.ts +62 -11
- package/src/render/backend/webgpu/glassTintPass.ts +245 -0
- package/src/render/backend/webgpu/gpuDrivenPass.ts +349 -5
- package/src/render/backend/webgpu/instanceCullPass.ts +165 -0
- package/src/render/backend/webgpu/instanced.ts +42 -4
- package/src/render/backend/webgpu/latePass.ts +161 -0
- package/src/render/backend/webgpu/lightVolumePass.ts +5 -1
- package/src/render/backend/webgpu/motionPass.ts +535 -0
- package/src/render/backend/webgpu/pipelineCache.ts +12 -1
- package/src/render/backend/webgpu/pointGlassTintPass.ts +233 -0
- package/src/render/backend/webgpu/pointShadowPass.ts +158 -26
- package/src/render/backend/webgpu/renderer.ts +1671 -670
- package/src/render/backend/webgpu/scatterPass.ts +2 -1
- package/src/render/backend/webgpu/sdfTextPass.ts +6 -1
- package/src/render/backend/webgpu/shaders/instanceCull.wgsl.ts +61 -0
- package/src/render/backend/webgpu/skinPaletteRing.ts +4 -0
- package/src/render/backend/webgpu/snapshotMips.ts +80 -0
- package/src/render/backend/webgpu/surfaceTexturePass.ts +91 -51
- package/src/render/driftLight/bake.ts +85 -62
- package/src/render/driftLight/denseField.ts +149 -0
- package/src/render/driftLight/lightField.ts +33 -18
- package/src/render/driftLight/presence.ts +69 -0
- package/src/render/driftLight/uniforms.ts +8 -9
- package/src/render/driftLight/worldLightField.ts +83 -0
- package/src/render/fixtureAtlas.ts +63 -0
- package/src/render/glass.ts +74 -0
- package/src/render/glassCasters.ts +164 -0
- package/src/render/glassShadow.ts +153 -0
- package/src/render/globalMediumPass.ts +4 -11
- package/src/render/gpudriven/lit.ts +31 -0
- package/src/render/gpudriven/materialTable.ts +28 -6
- package/src/render/gpudriven/pipeline.ts +4 -3
- package/src/render/gpudriven/sunGlass.ts +117 -0
- package/src/render/instanceCull.ts +205 -0
- package/src/render/instances.ts +16 -0
- package/src/render/lightBudget.ts +41 -38
- package/src/render/lightGrid.ts +130 -0
- package/src/render/mesh.ts +59 -72
- package/src/render/occlusion.ts +51 -7
- package/src/render/pointGlassTint.ts +250 -0
- package/src/render/pointLightSelection.ts +72 -4
- package/src/render/pointShadowArray.ts +188 -22
- package/src/render/pointShadowMap.ts +41 -0
- package/src/render/rainField.ts +39 -5
- package/src/render/recon/changeFrames.ts +24 -0
- package/src/render/recon/lateDepth.ts +83 -0
- package/src/render/recon/lateRouting.ts +29 -0
- package/src/render/recon/mover.ts +118 -0
- package/src/render/recon/resolve.ts +206 -20
- package/src/render/renderQuality.ts +47 -0
- package/src/render/rendererHarness.ts +16 -0
- package/src/render/sceneTarget.ts +62 -11
- package/src/render/shaders/depth.ts +118 -15
- package/src/render/shaders/flat/directionalShadow.ts +97 -6
- package/src/render/shaders/flat/driftLight.ts +32 -7
- package/src/render/shaders/flat/glassTint.ts +25 -0
- package/src/render/shaders/flat/index.ts +22 -3
- package/src/render/shaders/flat/lampGlass.ts +185 -0
- package/src/render/shaders/flat/main.ts +190 -38
- package/src/render/shaders/flat/pointShadow.ts +2 -0
- package/src/render/shaders/flat/preamble.ts +96 -26
- package/src/render/shaders/flat/surfaceEffects.ts +152 -0
- package/src/render/shaders/generated/depth.wgsl.ts +237 -7
- package/src/render/shaders/generated/flat.wgsl.ts +1685 -1621
- package/src/render/shaders/generated/globalMedium.wgsl.ts +3 -13
- package/src/render/shaders/generated/lightVolume.wgsl.ts +23 -17
- package/src/render/shaders/generated/octahedralResolve.wgsl.ts +30 -0
- package/src/render/shaders/generated/rush.wgsl.ts +21 -16
- package/src/render/shaders/generated/sdfText.wgsl.ts +2 -2
- package/src/render/shaders/generated/text.wgsl.ts +1 -1
- package/src/render/shaders/gi/driftLight.wgsl.ts +27 -4
- package/src/render/shaders/globalMedium.ts +6 -6
- package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +88 -1
- package/src/render/shaders/gpudriven/cull.wgsl.ts +11 -2
- package/src/render/shaders/gpudriven/materialTable.wgsl.ts +3 -1
- package/src/render/shaders/gpudriven/shade.wgsl.ts +50 -1
- package/src/render/shaders/gpudriven/sunGlass.wgsl.ts +139 -0
- package/src/render/shaders/lightVolume.ts +6 -6
- package/src/render/shaders/octahedralResolve.ts +50 -17
- package/src/render/shaders/recon/lateDepth.wgsl.ts +72 -0
- package/src/render/shaders/recon/motion.wgsl.ts +84 -0
- package/src/render/shaders/recon/resolve.wgsl.ts +161 -27
- package/src/render/shaders/rush.ts +11 -1
- package/src/render/shaders/sdfText.ts +3 -2
- package/src/render/shaders/text.ts +18 -9
- package/src/render/shadowCasters.ts +28 -1
- package/src/render/shadowMap.ts +231 -37
- package/src/render/sunGlassTint.ts +86 -0
- package/src/render/surfaceEffects.ts +132 -0
- package/src/render/surfaceScene.ts +16 -0
- package/src/render/surfaceTexture.ts +110 -19
- package/src/render/temporalAa.ts +78 -14
- package/src/render/textureSource.ts +72 -0
- package/src/render/translucentQueue.ts +20 -1
- package/src/render/vertexDefaults.ts +2 -0
- package/src/world/hlod.ts +290 -0
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The round solids: cylinder, cone, frustum, tube, sphere, hemisphere, icosphere, capsule, torus
|
|
3
|
+
* and lathe — all but the icosphere one revolve of a profile around +Y.
|
|
4
|
+
*
|
|
5
|
+
* A profile is `(r, y)` points. Revolving it, the vertex at angle θ sits at (r·cos θ, y, r·sin θ),
|
|
6
|
+
* and a quad is wound so that the profile's direction crossed with the direction of increasing θ
|
|
7
|
+
* points outward: a profile climbing on its outer side, or running outward along a bottom cap,
|
|
8
|
+
* faces out. Where the profile touches the axis a quad collapses to a triangle and only the
|
|
9
|
+
* triangle is written, so no edge is counted twice.
|
|
10
|
+
*
|
|
11
|
+
* `smooth` shares vertices around the axis with normals that vary around it; the default,
|
|
12
|
+
* faceted, gives every quad its own four vertices and its own normal. Texture u runs around (0..1,
|
|
13
|
+
* the seam duplicated) and v along the profile (0..1 by length).
|
|
14
|
+
*/
|
|
15
|
+
import type { Solid } from './solid.ts';
|
|
16
|
+
import { SolidWriter } from './solidWriter.ts';
|
|
17
|
+
|
|
18
|
+
/** A profile point with the in-plane normal it wants when smooth: (nr, ny) across the profile. */
|
|
19
|
+
interface ProfilePoint {
|
|
20
|
+
readonly r: number;
|
|
21
|
+
readonly y: number;
|
|
22
|
+
readonly nr: number;
|
|
23
|
+
readonly ny: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Revolve one or more strips — runs of profile points whose normals are continuous — around +Y.
|
|
28
|
+
* A strip's normals are used when smooth; faceted quads take the normal their corners imply.
|
|
29
|
+
*/
|
|
30
|
+
function revolve(
|
|
31
|
+
strips: readonly (readonly ProfilePoint[])[],
|
|
32
|
+
segments: number,
|
|
33
|
+
smooth: boolean,
|
|
34
|
+
): Solid {
|
|
35
|
+
const n = Math.max(3, Math.floor(segments));
|
|
36
|
+
const out = new SolidWriter();
|
|
37
|
+
let total = 0;
|
|
38
|
+
for (const strip of strips) {
|
|
39
|
+
for (let i = 0; i + 1 < strip.length; i++) total += span(strip[i], strip[i + 1]);
|
|
40
|
+
}
|
|
41
|
+
let walked = 0;
|
|
42
|
+
for (const strip of strips) {
|
|
43
|
+
const v: number[] = [];
|
|
44
|
+
for (let i = 0; i < strip.length; i++) {
|
|
45
|
+
if (i > 0) walked += span(strip[i - 1], strip[i]);
|
|
46
|
+
v.push(total > 0 ? walked / total : 0);
|
|
47
|
+
}
|
|
48
|
+
if (smooth) revolveSmooth(out, strip, v, n);
|
|
49
|
+
else revolveFaceted(out, strip, v, n);
|
|
50
|
+
}
|
|
51
|
+
return out.finish();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function span(a: ProfilePoint | undefined, b: ProfilePoint | undefined): number {
|
|
55
|
+
return a && b ? Math.hypot(b.r - a.r, b.y - a.y) : 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function revolveSmooth(
|
|
59
|
+
out: SolidWriter,
|
|
60
|
+
strip: readonly ProfilePoint[],
|
|
61
|
+
v: number[],
|
|
62
|
+
n: number,
|
|
63
|
+
): void {
|
|
64
|
+
const base = out.vertexCount;
|
|
65
|
+
const row = n + 1;
|
|
66
|
+
for (let i = 0; i < strip.length; i++) {
|
|
67
|
+
const p = strip[i];
|
|
68
|
+
if (!p) continue;
|
|
69
|
+
for (let j = 0; j <= n; j++) {
|
|
70
|
+
const t = (2 * Math.PI * (j % n)) / n;
|
|
71
|
+
const c = Math.cos(t);
|
|
72
|
+
const s = Math.sin(t);
|
|
73
|
+
out.vertex(p.r * c, p.y, p.r * s, p.nr * c, p.ny, p.nr * s, j / n, v[i] ?? 0);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
for (let i = 0; i + 1 < strip.length; i++) {
|
|
77
|
+
const r0 = strip[i]?.r ?? 0;
|
|
78
|
+
const r1 = strip[i + 1]?.r ?? 0;
|
|
79
|
+
for (let j = 0; j < n; j++) {
|
|
80
|
+
const a = base + i * row + j;
|
|
81
|
+
const b = a + row;
|
|
82
|
+
const c = b + 1;
|
|
83
|
+
const d = a + 1;
|
|
84
|
+
emit(out, a, b, c, d, r0, r1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function revolveFaceted(
|
|
90
|
+
out: SolidWriter,
|
|
91
|
+
strip: readonly ProfilePoint[],
|
|
92
|
+
v: number[],
|
|
93
|
+
n: number,
|
|
94
|
+
): void {
|
|
95
|
+
for (let i = 0; i + 1 < strip.length; i++) {
|
|
96
|
+
const p = strip[i];
|
|
97
|
+
const q = strip[i + 1];
|
|
98
|
+
if (!p || !q) continue;
|
|
99
|
+
for (let j = 0; j < n; j++) {
|
|
100
|
+
const t0 = (2 * Math.PI * j) / n;
|
|
101
|
+
const t1 = (2 * Math.PI * ((j + 1) % n)) / n;
|
|
102
|
+
const c0 = Math.cos(t0);
|
|
103
|
+
const s0 = Math.sin(t0);
|
|
104
|
+
const c1 = Math.cos(t1);
|
|
105
|
+
const s1 = Math.sin(t1);
|
|
106
|
+
const ax = p.r * c0;
|
|
107
|
+
const az = p.r * s0;
|
|
108
|
+
const bx = q.r * c0;
|
|
109
|
+
const bz = q.r * s0;
|
|
110
|
+
const cx = q.r * c1;
|
|
111
|
+
const cz = q.r * s1;
|
|
112
|
+
const dx = p.r * c1;
|
|
113
|
+
const dz = p.r * s1;
|
|
114
|
+
/* The normal from the diagonals, (c − a) × (d − b): right for a quad and for the triangle a
|
|
115
|
+
quad collapses to at the axis, where the edge-based cross product is zero. */
|
|
116
|
+
const ex = cx - ax;
|
|
117
|
+
const ey = q.y - p.y;
|
|
118
|
+
const ez = cz - az;
|
|
119
|
+
const fx = dx - bx;
|
|
120
|
+
const fy = p.y - q.y;
|
|
121
|
+
const fz = dz - bz;
|
|
122
|
+
let nx = ey * fz - ez * fy;
|
|
123
|
+
let ny = ez * fx - ex * fz;
|
|
124
|
+
let nz = ex * fy - ey * fx;
|
|
125
|
+
const len = Math.hypot(nx, ny, nz) || 1;
|
|
126
|
+
nx /= len;
|
|
127
|
+
ny /= len;
|
|
128
|
+
nz /= len;
|
|
129
|
+
const u0 = j / n;
|
|
130
|
+
const u1 = (j + 1) / n;
|
|
131
|
+
const a = out.vertex(ax, p.y, az, nx, ny, nz, u0, v[i] ?? 0);
|
|
132
|
+
const b = out.vertex(bx, q.y, bz, nx, ny, nz, u0, v[i + 1] ?? 0);
|
|
133
|
+
const c = out.vertex(cx, q.y, cz, nx, ny, nz, u1, v[i + 1] ?? 0);
|
|
134
|
+
const d = out.vertex(dx, p.y, dz, nx, ny, nz, u1, v[i] ?? 0);
|
|
135
|
+
emit(out, a, b, c, d, p.r, q.r);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Quad `a b c d`, or the one triangle left of it where either end of the profile step is on the axis. */
|
|
141
|
+
function emit(
|
|
142
|
+
out: SolidWriter,
|
|
143
|
+
a: number,
|
|
144
|
+
b: number,
|
|
145
|
+
c: number,
|
|
146
|
+
d: number,
|
|
147
|
+
r0: number,
|
|
148
|
+
r1: number,
|
|
149
|
+
): void {
|
|
150
|
+
if (r0 <= 1e-12 && r1 <= 1e-12) return;
|
|
151
|
+
if (r0 <= 1e-12) out.triangle(a, b, c);
|
|
152
|
+
else if (r1 <= 1e-12) out.triangle(a, b, d);
|
|
153
|
+
else out.quad(a, b, c, d);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Points along a polyline profile, each segment its own strip so every corner creases. */
|
|
157
|
+
function creasedStrips(points: readonly (readonly [number, number])[]): ProfilePoint[][] {
|
|
158
|
+
const strips: ProfilePoint[][] = [];
|
|
159
|
+
for (let i = 0; i + 1 < points.length; i++) {
|
|
160
|
+
const [r0, y0] = points[i] ?? [0, 0];
|
|
161
|
+
const [r1, y1] = points[i + 1] ?? [0, 0];
|
|
162
|
+
const len = Math.hypot(r1 - r0, y1 - y0) || 1;
|
|
163
|
+
const nr = (y1 - y0) / len;
|
|
164
|
+
const ny = -(r1 - r0) / len;
|
|
165
|
+
strips.push([
|
|
166
|
+
{ r: r0, y: y0, nr, ny },
|
|
167
|
+
{ r: r1, y: y1, nr, ny },
|
|
168
|
+
]);
|
|
169
|
+
}
|
|
170
|
+
return strips;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** An arc of the circle centred (cr, cy), radius `radius`, from angle `a0` to `a1` in `steps`. */
|
|
174
|
+
function arc(
|
|
175
|
+
cr: number,
|
|
176
|
+
cy: number,
|
|
177
|
+
radius: number,
|
|
178
|
+
a0: number,
|
|
179
|
+
a1: number,
|
|
180
|
+
steps: number,
|
|
181
|
+
): ProfilePoint[] {
|
|
182
|
+
const points: ProfilePoint[] = [];
|
|
183
|
+
for (let s = 0; s <= steps; s++) {
|
|
184
|
+
const a = a0 + ((a1 - a0) * s) / steps;
|
|
185
|
+
const c = Math.cos(a);
|
|
186
|
+
const sn = Math.sin(a);
|
|
187
|
+
points.push({ r: Math.max(0, cr + radius * c), y: cy + radius * sn, nr: c, ny: sn });
|
|
188
|
+
}
|
|
189
|
+
return points;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** A cylinder of `radius` and `length` along Y, centred, capped. */
|
|
193
|
+
export function solidCylinder(
|
|
194
|
+
radius: number,
|
|
195
|
+
length: number,
|
|
196
|
+
segments: number,
|
|
197
|
+
smooth = false,
|
|
198
|
+
): Solid {
|
|
199
|
+
return solidFrustum(radius, radius, length, segments, smooth);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** A cone: base `radius` at −length/2, apex at +length/2. */
|
|
203
|
+
export function solidCone(radius: number, length: number, segments: number, smooth = false): Solid {
|
|
204
|
+
return solidFrustum(radius, 0, length, segments, smooth);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** A frustum with explicit radii at its bottom (−length/2) and top (+length/2), capped. */
|
|
208
|
+
export function solidFrustum(
|
|
209
|
+
radiusBottom: number,
|
|
210
|
+
radiusTop: number,
|
|
211
|
+
length: number,
|
|
212
|
+
segments: number,
|
|
213
|
+
smooth = false,
|
|
214
|
+
): Solid {
|
|
215
|
+
const h = length / 2;
|
|
216
|
+
return revolve(
|
|
217
|
+
creasedStrips([
|
|
218
|
+
[0, -h],
|
|
219
|
+
[radiusBottom, -h],
|
|
220
|
+
[radiusTop, h],
|
|
221
|
+
[0, h],
|
|
222
|
+
]),
|
|
223
|
+
segments,
|
|
224
|
+
smooth,
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** A hollow cylinder: outer `radius`, wall `thickness`, `length` along Y, centred. Four segments make a square frame. */
|
|
229
|
+
export function solidTube(
|
|
230
|
+
radius: number,
|
|
231
|
+
thickness: number,
|
|
232
|
+
length: number,
|
|
233
|
+
segments: number,
|
|
234
|
+
smooth = false,
|
|
235
|
+
): Solid {
|
|
236
|
+
const h = length / 2;
|
|
237
|
+
const inner = Math.max(0, radius - thickness);
|
|
238
|
+
return revolve(
|
|
239
|
+
creasedStrips([
|
|
240
|
+
[inner, -h],
|
|
241
|
+
[radius, -h],
|
|
242
|
+
[radius, h],
|
|
243
|
+
[inner, h],
|
|
244
|
+
[inner, -h],
|
|
245
|
+
]),
|
|
246
|
+
segments,
|
|
247
|
+
smooth,
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** A sphere of `radius`: `segments` around, half as many from pole to pole. */
|
|
252
|
+
export function solidSphere(radius: number, segments: number, smooth = false): Solid {
|
|
253
|
+
const rings = Math.max(2, Math.floor(segments / 2));
|
|
254
|
+
return revolve([arc(0, 0, radius, -Math.PI / 2, Math.PI / 2, rings)], segments, smooth);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** A dome toward +Y on a flat base at the origin. */
|
|
258
|
+
export function solidHemisphere(radius: number, segments: number, smooth = false): Solid {
|
|
259
|
+
const rings = Math.max(1, Math.floor(segments / 4));
|
|
260
|
+
const base: ProfilePoint[] = [
|
|
261
|
+
{ r: 0, y: 0, nr: 0, ny: -1 },
|
|
262
|
+
{ r: radius, y: 0, nr: 0, ny: -1 },
|
|
263
|
+
];
|
|
264
|
+
return revolve([base, arc(0, 0, radius, 0, Math.PI / 2, rings)], segments, smooth);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** A capsule: a cylinder of `length` (excluding the caps) with hemispherical ends, along Y. */
|
|
268
|
+
export function solidCapsule(
|
|
269
|
+
radius: number,
|
|
270
|
+
length: number,
|
|
271
|
+
segments: number,
|
|
272
|
+
smooth = false,
|
|
273
|
+
): Solid {
|
|
274
|
+
const rings = Math.max(1, Math.floor(segments / 4));
|
|
275
|
+
const h = length / 2;
|
|
276
|
+
return revolve(
|
|
277
|
+
[
|
|
278
|
+
arc(0, -h, radius, -Math.PI / 2, 0, rings),
|
|
279
|
+
[
|
|
280
|
+
{ r: radius, y: -h, nr: 1, ny: 0 },
|
|
281
|
+
{ r: radius, y: h, nr: 1, ny: 0 },
|
|
282
|
+
],
|
|
283
|
+
arc(0, h, radius, 0, Math.PI / 2, rings),
|
|
284
|
+
],
|
|
285
|
+
segments,
|
|
286
|
+
smooth,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** A torus around +Y: ring radius `major`, tube radius `minor`, `segments` around and `sides` across. */
|
|
291
|
+
export function solidTorus(
|
|
292
|
+
major: number,
|
|
293
|
+
minor: number,
|
|
294
|
+
segments: number,
|
|
295
|
+
sides: number,
|
|
296
|
+
smooth = false,
|
|
297
|
+
): Solid {
|
|
298
|
+
return revolve(
|
|
299
|
+
[arc(major, 0, minor, 0, 2 * Math.PI, Math.max(3, Math.floor(sides)))],
|
|
300
|
+
segments,
|
|
301
|
+
smooth,
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* A profile (`r, y` pairs, bottom to top) revolved around +Y. An end off the axis is closed with a
|
|
307
|
+
* flat cap, so any profile makes a solid. Every profile corner creases, faceted or smooth.
|
|
308
|
+
*/
|
|
309
|
+
export function solidLathe(profile: ArrayLike<number>, segments: number, smooth = false): Solid {
|
|
310
|
+
const points: [number, number][] = [];
|
|
311
|
+
for (let i = 0; i + 1 < profile.length; i += 2)
|
|
312
|
+
points.push([profile[i] ?? 0, profile[i + 1] ?? 0]);
|
|
313
|
+
const first = points[0];
|
|
314
|
+
const last = points[points.length - 1];
|
|
315
|
+
if (first && first[0] > 1e-12) points.unshift([0, first[1]]);
|
|
316
|
+
if (last && last[0] > 1e-12) points.push([0, last[1]]);
|
|
317
|
+
return revolve(creasedStrips(points), segments, smooth);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* An icosahedron subdivided `level` times onto a sphere of `radius`. Faceted by default — every
|
|
322
|
+
* triangle its own vertices and face normal — or smooth, sharing vertices with radial normals.
|
|
323
|
+
*/
|
|
324
|
+
export function solidIcosphere(radius: number, level: number, smooth = false): Solid {
|
|
325
|
+
const t = (1 + Math.sqrt(5)) / 2;
|
|
326
|
+
const verts: number[][] = [
|
|
327
|
+
[-1, t, 0],
|
|
328
|
+
[1, t, 0],
|
|
329
|
+
[-1, -t, 0],
|
|
330
|
+
[1, -t, 0],
|
|
331
|
+
[0, -1, t],
|
|
332
|
+
[0, 1, t],
|
|
333
|
+
[0, -1, -t],
|
|
334
|
+
[0, 1, -t],
|
|
335
|
+
[t, 0, -1],
|
|
336
|
+
[t, 0, 1],
|
|
337
|
+
[-t, 0, -1],
|
|
338
|
+
[-t, 0, 1],
|
|
339
|
+
].map(unit);
|
|
340
|
+
let faces: number[][] = [
|
|
341
|
+
[0, 11, 5],
|
|
342
|
+
[0, 5, 1],
|
|
343
|
+
[0, 1, 7],
|
|
344
|
+
[0, 7, 10],
|
|
345
|
+
[0, 10, 11],
|
|
346
|
+
[1, 5, 9],
|
|
347
|
+
[5, 11, 4],
|
|
348
|
+
[11, 10, 2],
|
|
349
|
+
[10, 7, 6],
|
|
350
|
+
[7, 1, 8],
|
|
351
|
+
[3, 9, 4],
|
|
352
|
+
[3, 4, 2],
|
|
353
|
+
[3, 2, 6],
|
|
354
|
+
[3, 6, 8],
|
|
355
|
+
[3, 8, 9],
|
|
356
|
+
[4, 9, 5],
|
|
357
|
+
[2, 4, 11],
|
|
358
|
+
[6, 2, 10],
|
|
359
|
+
[8, 6, 7],
|
|
360
|
+
[9, 8, 1],
|
|
361
|
+
];
|
|
362
|
+
for (let l = 0; l < Math.floor(level); l++) {
|
|
363
|
+
const cache = new Map<string, number>();
|
|
364
|
+
const mid = (a: number, b: number): number => {
|
|
365
|
+
const key = a < b ? `${a},${b}` : `${b},${a}`;
|
|
366
|
+
const hit = cache.get(key);
|
|
367
|
+
if (hit !== undefined) return hit;
|
|
368
|
+
const va = verts[a] ?? [0, 0, 0];
|
|
369
|
+
const vb = verts[b] ?? [0, 0, 0];
|
|
370
|
+
verts.push(
|
|
371
|
+
unit([
|
|
372
|
+
(va[0] ?? 0) + (vb[0] ?? 0),
|
|
373
|
+
(va[1] ?? 0) + (vb[1] ?? 0),
|
|
374
|
+
(va[2] ?? 0) + (vb[2] ?? 0),
|
|
375
|
+
]),
|
|
376
|
+
);
|
|
377
|
+
cache.set(key, verts.length - 1);
|
|
378
|
+
return verts.length - 1;
|
|
379
|
+
};
|
|
380
|
+
const next: number[][] = [];
|
|
381
|
+
for (const [a = 0, b = 0, c = 0] of faces) {
|
|
382
|
+
const ab = mid(a, b);
|
|
383
|
+
const bc = mid(b, c);
|
|
384
|
+
const ca = mid(c, a);
|
|
385
|
+
next.push([a, ab, ca], [b, bc, ab], [c, ca, bc], [ab, bc, ca]);
|
|
386
|
+
}
|
|
387
|
+
faces = next;
|
|
388
|
+
}
|
|
389
|
+
const out = new SolidWriter();
|
|
390
|
+
const uv = (p: number[]): [number, number] => [
|
|
391
|
+
0.5 + Math.atan2(p[2] ?? 0, p[0] ?? 0) / (2 * Math.PI),
|
|
392
|
+
0.5 + Math.asin(Math.max(-1, Math.min(1, p[1] ?? 0))) / Math.PI,
|
|
393
|
+
];
|
|
394
|
+
if (smooth) {
|
|
395
|
+
for (const p of verts) {
|
|
396
|
+
const [u, v] = uv(p);
|
|
397
|
+
out.vertex(
|
|
398
|
+
(p[0] ?? 0) * radius,
|
|
399
|
+
(p[1] ?? 0) * radius,
|
|
400
|
+
(p[2] ?? 0) * radius,
|
|
401
|
+
p[0] ?? 0,
|
|
402
|
+
p[1] ?? 0,
|
|
403
|
+
p[2] ?? 0,
|
|
404
|
+
u,
|
|
405
|
+
v,
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
/* The table's faces run counter-clockwise seen from outside, as every face here does. */
|
|
409
|
+
for (const [a = 0, b = 0, c = 0] of faces) out.triangle(a, b, c);
|
|
410
|
+
return out.finish();
|
|
411
|
+
}
|
|
412
|
+
for (const [a = 0, b = 0, c = 0] of faces) {
|
|
413
|
+
const pa = verts[a] ?? [0, 0, 0];
|
|
414
|
+
const pb = verts[b] ?? [0, 0, 0];
|
|
415
|
+
const pc = verts[c] ?? [0, 0, 0];
|
|
416
|
+
const n = unit([
|
|
417
|
+
((pa[0] ?? 0) + (pb[0] ?? 0) + (pc[0] ?? 0)) / 3,
|
|
418
|
+
((pa[1] ?? 0) + (pb[1] ?? 0) + (pc[1] ?? 0)) / 3,
|
|
419
|
+
((pa[2] ?? 0) + (pb[2] ?? 0) + (pc[2] ?? 0)) / 3,
|
|
420
|
+
]);
|
|
421
|
+
const base = out.vertexCount;
|
|
422
|
+
for (const p of [pa, pb, pc]) {
|
|
423
|
+
const [u, v] = uv(p);
|
|
424
|
+
out.vertex(
|
|
425
|
+
(p[0] ?? 0) * radius,
|
|
426
|
+
(p[1] ?? 0) * radius,
|
|
427
|
+
(p[2] ?? 0) * radius,
|
|
428
|
+
n[0] ?? 0,
|
|
429
|
+
n[1] ?? 0,
|
|
430
|
+
n[2] ?? 0,
|
|
431
|
+
u,
|
|
432
|
+
v,
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
out.triangle(base, base + 1, base + 2);
|
|
436
|
+
}
|
|
437
|
+
return out.finish();
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function unit(p: number[]): number[] {
|
|
441
|
+
const len = Math.hypot(p[0] ?? 0, p[1] ?? 0, p[2] ?? 0) || 1;
|
|
442
|
+
return [(p[0] ?? 0) / len, (p[1] ?? 0) / len, (p[2] ?? 0) / len];
|
|
443
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The accumulator every solid primitive writes through: a vertex at a time, a triangle or a quad at
|
|
3
|
+
* a time, finished into a `Solid`.
|
|
4
|
+
*
|
|
5
|
+
* Internal to the geometry modules and not in the barrel — a caller building geometry of its own
|
|
6
|
+
* wants `MeshBuilder` or typed arrays, and this exists so the primitives share one place that
|
|
7
|
+
* decides how a vertex is laid out.
|
|
8
|
+
*/
|
|
9
|
+
import { GrowableF32, GrowableU32 } from './growable.ts';
|
|
10
|
+
import type { Solid } from './solid.ts';
|
|
11
|
+
|
|
12
|
+
export class SolidWriter {
|
|
13
|
+
private readonly positions = new GrowableF32();
|
|
14
|
+
private readonly normals = new GrowableF32();
|
|
15
|
+
private readonly uvs = new GrowableF32();
|
|
16
|
+
private readonly indices = new GrowableU32();
|
|
17
|
+
private count = 0;
|
|
18
|
+
|
|
19
|
+
/** Add one vertex and return its index. The normal is taken as given; pass it unit length. */
|
|
20
|
+
vertex(
|
|
21
|
+
px: number,
|
|
22
|
+
py: number,
|
|
23
|
+
pz: number,
|
|
24
|
+
nx: number,
|
|
25
|
+
ny: number,
|
|
26
|
+
nz: number,
|
|
27
|
+
u: number,
|
|
28
|
+
v: number,
|
|
29
|
+
): number {
|
|
30
|
+
this.positions.push(px, py, pz);
|
|
31
|
+
this.normals.push(nx, ny, nz);
|
|
32
|
+
this.uvs.push(u, v);
|
|
33
|
+
return this.count++;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
triangle(a: number, b: number, c: number): void {
|
|
37
|
+
this.indices.push(a, b, c);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Two triangles over a counter-clockwise quad `a b c d`. */
|
|
41
|
+
quad(a: number, b: number, c: number, d: number): void {
|
|
42
|
+
this.indices.push(a, b, c, a, c, d);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** How many vertices so far, which is the index the next `vertex` returns. */
|
|
46
|
+
get vertexCount(): number {
|
|
47
|
+
return this.count;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
finish(): Solid {
|
|
51
|
+
return {
|
|
52
|
+
positions: this.positions.toTyped(),
|
|
53
|
+
normals: this.normals.toTyped(),
|
|
54
|
+
uvs: this.uvs.toTyped(),
|
|
55
|
+
indices: this.indices.toTyped(),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -202,6 +202,15 @@ export { createPassAttachment } from './render/passTarget.ts';
|
|
|
202
202
|
* resolve finds its geometry where the renderer's own verbs put theirs.
|
|
203
203
|
*/
|
|
204
204
|
export { jitterClip } from './render/recon/jitter.ts';
|
|
205
|
+
/*
|
|
206
|
+
* Which object a draw is, for a reconstruction that has to find where it was last frame. See
|
|
207
|
+
* `RendererApi.drawMesh`.
|
|
208
|
+
*/
|
|
209
|
+
/* Glass: a pane that shows what is behind it, clear or frosted. See `TranslucentMeshOptions.glass`. */
|
|
210
|
+
export { resolveGlass } from './render/glass.ts';
|
|
211
|
+
export type { GlassOptions, ResolvedGlass } from './render/glass.ts';
|
|
212
|
+
export { createMover } from './render/recon/mover.ts';
|
|
213
|
+
export type { Mover } from './render/recon/mover.ts';
|
|
205
214
|
export type { FrameResource } from './render/frame/index.ts';
|
|
206
215
|
/*
|
|
207
216
|
* Occlusion culling, which is arithmetic rather than a GPU feature — so the class is public and a
|
|
@@ -382,6 +391,17 @@ export type {
|
|
|
382
391
|
} from './render/gi/globalField.ts';
|
|
383
392
|
export { FIELD_FADE_SEC, LightField } from './render/driftLight/lightField.ts';
|
|
384
393
|
export type { LightFieldOptions, LightFieldSource } from './render/driftLight/lightField.ts';
|
|
394
|
+
export {
|
|
395
|
+
DENSE_MAX_AXIS,
|
|
396
|
+
DENSE_MAX_HEIGHT,
|
|
397
|
+
bakeDenseField,
|
|
398
|
+
} from './render/driftLight/denseField.ts';
|
|
399
|
+
export type { DenseLightVolume } from './render/driftLight/denseField.ts';
|
|
400
|
+
export { WorldLightField } from './render/driftLight/worldLightField.ts';
|
|
401
|
+
export type { WorldLightFieldOptions } from './render/driftLight/worldLightField.ts';
|
|
402
|
+
export { SURFACE_EFFECT_TEXELS, packSurfaceEffects } from './render/surfaceEffects.ts';
|
|
403
|
+
export type { SurfaceLayerEffect } from './render/surfaceEffects.ts';
|
|
404
|
+
export type { FieldLight } from './render/driftLight/bake.ts';
|
|
385
405
|
export {
|
|
386
406
|
GI_SCREEN_MARCH,
|
|
387
407
|
SCREEN_TRACE_BIAS_M,
|
|
@@ -568,6 +588,7 @@ export type { PrefilterQuality } from './render/prefilterEnvMap.ts';
|
|
|
568
588
|
export type { ProbeBakeOptions } from './render/reflectionProbe.ts';
|
|
569
589
|
export type {
|
|
570
590
|
DirectionalShadowDepthLayers,
|
|
591
|
+
GlassShadows,
|
|
571
592
|
OutputTransform,
|
|
572
593
|
RenderQuality,
|
|
573
594
|
RenderQualityOptions,
|
|
@@ -593,8 +614,11 @@ export type { GpuIdentity, DescribeGpuOptions } from './render/gpuCapability.ts'
|
|
|
593
614
|
export {
|
|
594
615
|
DEFAULT_POINT_LIGHT_VIEW_RANGE,
|
|
595
616
|
createPointLightBuffer,
|
|
617
|
+
selectGridLights,
|
|
596
618
|
selectPointLights,
|
|
597
619
|
} from './render/pointLightSelection.ts';
|
|
620
|
+
export { LIGHT_GRID_MAX_CELLS, createLightGrid, gatherLights } from './render/lightGrid.ts';
|
|
621
|
+
export type { LightGrid } from './render/lightGrid.ts';
|
|
598
622
|
export type { PointLightBuffer, PointLightSource } from './render/pointLightSelection.ts';
|
|
599
623
|
export { createFlame, flameFrequencyHz, updateFlame } from './render/flameLight.ts';
|
|
600
624
|
export type { Flame, FlameOptions } from './render/flameLight.ts';
|
|
@@ -648,6 +672,38 @@ export { WaterRenderer } from './render/waterRenderer.ts';
|
|
|
648
672
|
export type { WaterBody, WaterBounds, WaterSettings } from './render/waterRenderer.ts';
|
|
649
673
|
export { MeshBuilder } from './geometry/meshBuilder.ts';
|
|
650
674
|
export { concatMeshes, placeMesh } from './geometry/meshConcat.ts';
|
|
675
|
+
export {
|
|
676
|
+
emptySolid,
|
|
677
|
+
mergeSolids,
|
|
678
|
+
solidToMesh,
|
|
679
|
+
solidVolume,
|
|
680
|
+
transformSolid,
|
|
681
|
+
} from './geometry/solid.ts';
|
|
682
|
+
export type { Solid } from './geometry/solid.ts';
|
|
683
|
+
export {
|
|
684
|
+
solidBox,
|
|
685
|
+
solidExtrude,
|
|
686
|
+
solidPrism,
|
|
687
|
+
solidQuad,
|
|
688
|
+
solidRoundedBox,
|
|
689
|
+
solidSweep,
|
|
690
|
+
} from './geometry/solidFlat.ts';
|
|
691
|
+
export {
|
|
692
|
+
solidCapsule,
|
|
693
|
+
solidCone,
|
|
694
|
+
solidCylinder,
|
|
695
|
+
solidFrustum,
|
|
696
|
+
solidHemisphere,
|
|
697
|
+
solidIcosphere,
|
|
698
|
+
solidLathe,
|
|
699
|
+
solidSphere,
|
|
700
|
+
solidTorus,
|
|
701
|
+
solidTube,
|
|
702
|
+
} from './geometry/solidRound.ts';
|
|
703
|
+
export { solidIntersect, solidSubtract, solidUnion } from './geometry/csg.ts';
|
|
704
|
+
export { boxBooleanCells, solidBoxBoolean } from './geometry/boxCsg.ts';
|
|
705
|
+
export type { BoxOperation } from './geometry/boxCsg.ts';
|
|
706
|
+
export { smoothSolidNormals } from './geometry/solidNormals.ts';
|
|
651
707
|
/* A tangent frame, which every map in the material track reads. */
|
|
652
708
|
export { generateTangents } from './geometry/tangents.ts';
|
|
653
709
|
export type { MeshBuildOptions } from './geometry/meshBuilder.ts';
|
|
@@ -1007,7 +1063,9 @@ export type { FlockParams } from './render/flockRenderer.ts';
|
|
|
1007
1063
|
export { buildTree } from './geometry/treeBuilder.ts';
|
|
1008
1064
|
export type { TreeParams, TreeGeometry } from './geometry/treeBuilder.ts';
|
|
1009
1065
|
export type { InstanceData } from './render/instancedMesh.ts';
|
|
1010
|
-
export type { MeshInstances } from './render/instances.ts';
|
|
1066
|
+
export type { InstancedOptions, MeshInstances } from './render/instances.ts';
|
|
1067
|
+
export { batchBoxVisible, cullInstances, instancesBox } from './render/instanceCull.ts';
|
|
1068
|
+
export type { BoxOccluder } from './render/instanceCull.ts';
|
|
1011
1069
|
export type { WindProfile, WindState } from './render/wind.ts';
|
|
1012
1070
|
|
|
1013
1071
|
/*
|
|
@@ -1045,3 +1103,5 @@ export {
|
|
|
1045
1103
|
thawCell,
|
|
1046
1104
|
} from './world/freeze.ts';
|
|
1047
1105
|
export type { FreezableWorld, FrozenCell, FrozenCells } from './world/freeze.ts';
|
|
1106
|
+
export { HLOD_NONE, HlodSet, createHlodDraws, projectionScaleOf } from './world/hlod.ts';
|
|
1107
|
+
export type { HlodDraws, HlodOptions } from './world/hlod.ts';
|
|
@@ -4,12 +4,13 @@ import type { ReadonlyMat4 } from 'gl-matrix';
|
|
|
4
4
|
import type { MeshData } from '../mesh.ts';
|
|
5
5
|
import type { ProbeBakeOptions } from '../reflectionProbe.ts';
|
|
6
6
|
import type { Renderer, TranslucentMeshOptions } from './webgl2/renderer.ts';
|
|
7
|
-
import type { MeshInstances } from '../instances.ts';
|
|
7
|
+
import type { InstancedOptions, MeshInstances } from '../instances.ts';
|
|
8
8
|
import type { SurfaceMaterial } from '../surfaceTexture.ts';
|
|
9
9
|
import type { TextStyle } from '../textLayout.ts';
|
|
10
10
|
import type { SdfFont } from '../sdfFont.ts';
|
|
11
11
|
import type { SdfTextStyle } from '../sdfTextLayout.ts';
|
|
12
12
|
import type { FrameTimer } from './timer.ts';
|
|
13
|
+
import type { Mover } from '../recon/mover.ts';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Geometry on the device, as something a consumer holds and hands back.
|
|
@@ -281,6 +282,7 @@ export type RendererApi = Omit<
|
|
|
281
282
|
| 'drawSdfText'
|
|
282
283
|
| 'disposeSdfText'
|
|
283
284
|
| 'createSurfaceTexture'
|
|
285
|
+
| 'createSurfaceTextureArray'
|
|
284
286
|
| 'updateSurfaceTexture'
|
|
285
287
|
| 'disposeSurfaceTexture'
|
|
286
288
|
| 'setSurfaceTexture'
|
|
@@ -292,6 +294,24 @@ export type RendererApi = Omit<
|
|
|
292
294
|
options?: Parameters<Renderer['createSurfaceTexture']>[1],
|
|
293
295
|
): SurfaceTextureHandle;
|
|
294
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Upload several images of one size as the layers of one array texture.
|
|
299
|
+
*
|
|
300
|
+
* The same handle a single image returns — every surface texture is an array, and a plain image
|
|
301
|
+
* is an array of one — so it goes wherever a texture goes: any map of `setMaterial`. A mesh picks
|
|
302
|
+
* its image per vertex with `MeshData.layers`, and every map of the material is read at that
|
|
303
|
+
* layer, so an albedo array and an emissive array built in one order pair image with glow by
|
|
304
|
+
* index. **A merged mesh wearing many images is then one draw and one material change.**
|
|
305
|
+
*
|
|
306
|
+
* Every image must be the same size: the device allocates one size for every layer, and the
|
|
307
|
+
* refusal names the first image that differs. A layer past the end reads the last one.
|
|
308
|
+
* `updateSurfaceTexture` refuses an array.
|
|
309
|
+
*/
|
|
310
|
+
createSurfaceTextureArray(
|
|
311
|
+
sources: readonly TexImageSource[],
|
|
312
|
+
options?: Parameters<Renderer['createSurfaceTexture']>[1],
|
|
313
|
+
): SurfaceTextureHandle;
|
|
314
|
+
|
|
295
315
|
/**
|
|
296
316
|
* Replace a texture's pixels, keeping the GPU object and its sampler state.
|
|
297
317
|
*
|
|
@@ -547,7 +567,7 @@ export type RendererApi = Omit<
|
|
|
547
567
|
* would wear one expression. Both are refused where the variant is built rather than dropped
|
|
548
568
|
* quietly.
|
|
549
569
|
*/
|
|
550
|
-
createInstanced(mesh: MeshHandle, capacity: number): InstancedHandle;
|
|
570
|
+
createInstanced(mesh: MeshHandle, capacity: number, options?: InstancedOptions): InstancedHandle;
|
|
551
571
|
|
|
552
572
|
/**
|
|
553
573
|
* Push placement and colour to the device. Only `data.count` instances are written.
|
|
@@ -767,18 +787,23 @@ export type RendererApi = Omit<
|
|
|
767
787
|
depthLayer?: number,
|
|
768
788
|
tint?: Vec3 | null,
|
|
769
789
|
/**
|
|
770
|
-
* Where this mesh's surface was last frame, for a reconstruction's motion target
|
|
790
|
+
* Where this mesh's surface was last frame, for a reconstruction's motion target: a `Mover`,
|
|
791
|
+
* or last frame's model matrix.
|
|
771
792
|
*
|
|
772
|
-
* **
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
*
|
|
793
|
+
* **A `Mover` is the ordinary answer.** Make one per moving object with `createMover()` and pass
|
|
794
|
+
* it with every draw of that object; the renderer keeps last frame's model and, for a skinned
|
|
795
|
+
* draw, last frame's palette. A matrix still works exactly as it always has: the *model* matrix
|
|
796
|
+
* this mesh was drawn with last frame, not a velocity, so a rotation and a scale are as correct
|
|
797
|
+
* as a translation. Null and omitted mean the same thing: the camera's motion, derived from the
|
|
798
|
+
* depth, which is exactly right for anything that did not move and wrong in proportion to how
|
|
799
|
+
* far a mover moved.
|
|
776
800
|
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
801
|
+
* **Only a reconstruction reads it**, and only on WebGPU. A mover drawn twice in one frame is
|
|
802
|
+
* two objects wearing one identity: the second draw is warned about once and records no motion.
|
|
803
|
+
* Instanced batches and meshes rewritten with `updateMesh` need none — the batch and the mesh
|
|
804
|
+
* are their own identity.
|
|
780
805
|
*/
|
|
781
|
-
previousModel?: ReadonlyMat4 | null,
|
|
806
|
+
previousModel?: ReadonlyMat4 | Mover | null,
|
|
782
807
|
): void;
|
|
783
808
|
|
|
784
809
|
/** Release the geometry behind a handle. */
|