@driftengine/capture 4.0.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/LICENSE +202 -0
- package/NOTICE +29 -0
- package/README.md +68 -0
- package/dist/browserFrames.d.ts +31 -0
- package/dist/browserFrames.js +105 -0
- package/dist/collide.d.ts +59 -0
- package/dist/collide.js +92 -0
- package/dist/decimate.d.ts +42 -0
- package/dist/decimate.js +439 -0
- package/dist/delight.d.ts +42 -0
- package/dist/delight.js +351 -0
- package/dist/delightScene.d.ts +37 -0
- package/dist/delightScene.js +183 -0
- package/dist/depth.d.ts +44 -0
- package/dist/depth.js +53 -0
- package/dist/features.d.ts +33 -0
- package/dist/features.js +260 -0
- package/dist/frames.d.ts +47 -0
- package/dist/frames.js +87 -0
- package/dist/fusion.d.ts +77 -0
- package/dist/fusion.js +152 -0
- package/dist/gaussians/adam.d.ts +57 -0
- package/dist/gaussians/adam.js +88 -0
- package/dist/gaussians/depth.d.ts +8 -0
- package/dist/gaussians/depth.js +73 -0
- package/dist/gaussians/gradients.d.ts +36 -0
- package/dist/gaussians/gradients.js +228 -0
- package/dist/gaussians/harmonics.d.ts +46 -0
- package/dist/gaussians/harmonics.js +99 -0
- package/dist/gaussians/optimise.d.ts +50 -0
- package/dist/gaussians/optimise.js +125 -0
- package/dist/gaussians/parameters.d.ts +35 -0
- package/dist/gaussians/parameters.js +165 -0
- package/dist/gaussians/project.d.ts +72 -0
- package/dist/gaussians/project.js +137 -0
- package/dist/gaussians/projectGradient.d.ts +15 -0
- package/dist/gaussians/projectGradient.js +213 -0
- package/dist/gaussians/rasterise.d.ts +13 -0
- package/dist/gaussians/rasterise.js +65 -0
- package/dist/gaussians/refine.d.ts +36 -0
- package/dist/gaussians/refine.js +136 -0
- package/dist/gaussians/similarity.d.ts +25 -0
- package/dist/gaussians/similarity.js +80 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +96 -0
- package/dist/marching.d.ts +38 -0
- package/dist/marching.js +258 -0
- package/dist/masks.d.ts +59 -0
- package/dist/masks.js +165 -0
- package/dist/math/dense.d.ts +68 -0
- package/dist/math/dense.js +294 -0
- package/dist/math/schur.d.ts +23 -0
- package/dist/math/schur.js +140 -0
- package/dist/models/batchNorm.d.ts +17 -0
- package/dist/models/batchNorm.js +24 -0
- package/dist/models/clipTokenizer.d.ts +40 -0
- package/dist/models/clipTokenizer.js +122 -0
- package/dist/models/clipTower.d.ts +27 -0
- package/dist/models/clipTower.js +45 -0
- package/dist/models/depthAnything2.d.ts +38 -0
- package/dist/models/depthAnything2.js +163 -0
- package/dist/models/depthAnything3.d.ts +26 -0
- package/dist/models/depthAnything3.js +171 -0
- package/dist/models/dualDpt.d.ts +19 -0
- package/dist/models/dualDpt.js +138 -0
- package/dist/models/hiera.d.ts +49 -0
- package/dist/models/hiera.js +120 -0
- package/dist/models/hieraAttention.d.ts +16 -0
- package/dist/models/hieraAttention.js +68 -0
- package/dist/models/miniature.d.ts +36 -0
- package/dist/models/miniature.js +216 -0
- package/dist/models/mobileSam.d.ts +41 -0
- package/dist/models/mobileSam.js +88 -0
- package/dist/models/owlv2.d.ts +49 -0
- package/dist/models/owlv2.js +131 -0
- package/dist/models/owlv2Detect.d.ts +25 -0
- package/dist/models/owlv2Detect.js +80 -0
- package/dist/models/owlv2Miniature.d.ts +27 -0
- package/dist/models/owlv2Miniature.js +87 -0
- package/dist/models/rope.d.ts +23 -0
- package/dist/models/rope.js +84 -0
- package/dist/models/sam21.d.ts +45 -0
- package/dist/models/sam21.js +126 -0
- package/dist/models/sam21Miniature.d.ts +37 -0
- package/dist/models/sam21Miniature.js +194 -0
- package/dist/models/sam21Video.d.ts +30 -0
- package/dist/models/sam21Video.js +101 -0
- package/dist/models/sam2Choice.d.ts +19 -0
- package/dist/models/sam2Choice.js +55 -0
- package/dist/models/sam2Decoder.d.ts +36 -0
- package/dist/models/sam2Decoder.js +108 -0
- package/dist/models/sam2Memories.d.ts +54 -0
- package/dist/models/sam2Memories.js +93 -0
- package/dist/models/sam2Memory.d.ts +30 -0
- package/dist/models/sam2Memory.js +136 -0
- package/dist/models/sam2Positions.d.ts +24 -0
- package/dist/models/sam2Positions.js +94 -0
- package/dist/models/sam2Tracker.d.ts +69 -0
- package/dist/models/sam2Tracker.js +172 -0
- package/dist/models/samDecoder.d.ts +45 -0
- package/dist/models/samDecoder.js +96 -0
- package/dist/models/samMiniature.d.ts +43 -0
- package/dist/models/samMiniature.js +161 -0
- package/dist/models/samPrompt.d.ts +57 -0
- package/dist/models/samPrompt.js +160 -0
- package/dist/models/seeded.d.ts +16 -0
- package/dist/models/seeded.js +48 -0
- package/dist/models/tinyVit.d.ts +38 -0
- package/dist/models/tinyVit.js +82 -0
- package/dist/models/twoWay.d.ts +46 -0
- package/dist/models/twoWay.js +67 -0
- package/dist/models/vit.d.ts +45 -0
- package/dist/models/vit.js +157 -0
- package/dist/models/windowAttention.d.ts +25 -0
- package/dist/models/windowAttention.js +104 -0
- package/dist/poses.d.ts +31 -0
- package/dist/poses.js +750 -0
- package/dist/prepare.d.ts +30 -0
- package/dist/prepare.js +238 -0
- package/dist/propose.d.ts +36 -0
- package/dist/propose.js +63 -0
- package/dist/resample.d.ts +39 -0
- package/dist/resample.js +165 -0
- package/dist/run.d.ts +3 -0
- package/dist/run.js +1 -0
- package/dist/scene.d.ts +104 -0
- package/dist/scene.js +109 -0
- package/dist/segment.d.ts +40 -0
- package/dist/segment.js +184 -0
- package/dist/testScene.d.ts +55 -0
- package/dist/testScene.js +214 -0
- package/dist/twoView.d.ts +22 -0
- package/dist/twoView.js +435 -0
- package/package.json +63 -0
- package/src/browserFrames.ts +145 -0
- package/src/collide.ts +128 -0
- package/src/decimate.ts +510 -0
- package/src/delight.ts +427 -0
- package/src/delightScene.ts +249 -0
- package/src/depth.ts +100 -0
- package/src/features.ts +302 -0
- package/src/frames.ts +111 -0
- package/src/fusion.ts +229 -0
- package/src/gaussians/adam.ts +131 -0
- package/src/gaussians/depth.ts +87 -0
- package/src/gaussians/gradients.ts +285 -0
- package/src/gaussians/harmonics.ts +122 -0
- package/src/gaussians/optimise.ts +191 -0
- package/src/gaussians/parameters.ts +186 -0
- package/src/gaussians/project.ts +207 -0
- package/src/gaussians/projectGradient.ts +234 -0
- package/src/gaussians/rasterise.ts +81 -0
- package/src/gaussians/refine.ts +176 -0
- package/src/gaussians/similarity.ts +87 -0
- package/src/index.ts +225 -0
- package/src/marching.ts +358 -0
- package/src/masks.ts +201 -0
- package/src/math/dense.ts +317 -0
- package/src/math/schur.ts +167 -0
- package/src/models/batchNorm.ts +57 -0
- package/src/models/clipTokenizer.ts +129 -0
- package/src/models/clipTower.ts +87 -0
- package/src/models/depthAnything2.ts +276 -0
- package/src/models/depthAnything3.ts +229 -0
- package/src/models/dualDpt.ts +233 -0
- package/src/models/hiera.ts +231 -0
- package/src/models/hieraAttention.ts +121 -0
- package/src/models/miniature.ts +241 -0
- package/src/models/mobileSam.ts +135 -0
- package/src/models/owlv2.ts +190 -0
- package/src/models/owlv2Detect.ts +116 -0
- package/src/models/owlv2Miniature.ts +108 -0
- package/src/models/rope.ts +111 -0
- package/src/models/sam21.ts +182 -0
- package/src/models/sam21Miniature.ts +225 -0
- package/src/models/sam21Video.ts +154 -0
- package/src/models/sam2Choice.ts +62 -0
- package/src/models/sam2Decoder.ts +218 -0
- package/src/models/sam2Memories.ts +165 -0
- package/src/models/sam2Memory.ts +247 -0
- package/src/models/sam2Positions.ts +106 -0
- package/src/models/sam2Tracker.ts +300 -0
- package/src/models/samDecoder.ts +225 -0
- package/src/models/samMiniature.ts +190 -0
- package/src/models/samPrompt.ts +227 -0
- package/src/models/seeded.ts +50 -0
- package/src/models/tinyVit.ts +178 -0
- package/src/models/twoWay.ts +122 -0
- package/src/models/vit.ts +265 -0
- package/src/models/windowAttention.ts +155 -0
- package/src/poses.ts +894 -0
- package/src/prepare.ts +306 -0
- package/src/propose.ts +96 -0
- package/src/resample.ts +197 -0
- package/src/run.ts +7 -0
- package/src/scene.ts +141 -0
- package/src/segment.ts +220 -0
- package/src/testScene.ts +283 -0
- package/src/twoView.ts +536 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*! DriftEngine | Copyright 2026 Drift Technologies | Apache-2.0 | https://github.com/drftrun/driftengine */
|
|
2
|
+
/**
|
|
3
|
+
* `@driftengine/capture` — a video to a playable scene, on the player's own device.
|
|
4
|
+
*
|
|
5
|
+
* **What is here so far is the models a capture runs**, each written as a definition the engine's
|
|
6
|
+
* one neural runtime builds a graph from: `@driftengine/texture` holds the operators and the rule
|
|
7
|
+
* that every weight is read or set aside by name, and this package says which weights a model reads
|
|
8
|
+
* and how. A definition is run over a checkpoint once, when it is converted, and over the converted
|
|
9
|
+
* file afterwards whenever a clip needs the graph at a new size — every device kernel bakes its
|
|
10
|
+
* shapes, and a clip's aspect ratio decides the patch grid.
|
|
11
|
+
*
|
|
12
|
+
* **Depth Anything 3**: depth, its confidence and a camera per view, from one view or several at
|
|
13
|
+
* once. **Depth Anything V2 Small**, the lighter fallback: relative depth from one view.
|
|
14
|
+
* **MobileSAM**: masks from a point or a box, an encoder run once an image and a decoder once a
|
|
15
|
+
* prompt. **SAM 2.1**: the same, and objects tracked through a video by a memory of the frames before.
|
|
16
|
+
* **OWLv2**: boxes for things named in words, an image graph and a text graph joined on the host,
|
|
17
|
+
* with CLIP's tokenizer. Each answers as its upstream's own code does on a seeded miniature of its
|
|
18
|
+
* layout, the fixtures shipped beside them.
|
|
19
|
+
*/
|
|
20
|
+
export { eachFrame, selectFrames } from './frames.ts';
|
|
21
|
+
export type { FrameChoice, FrameSize, FrameSource } from './frames.ts';
|
|
22
|
+
export { cholesky, choleskySolve, levenbergMarquardt, svd3, svdN, symmetricEigen, } from './math/dense.ts';
|
|
23
|
+
export type { FitOptions, LeastSquares } from './math/dense.ts';
|
|
24
|
+
export { schurSolve } from './math/schur.ts';
|
|
25
|
+
export type { BlockNormals } from './math/schur.ts';
|
|
26
|
+
export { DESCRIPTOR_BYTES, createFeatureSet, describeFeatures, detectFeatures, matchFeatures, } from './features.ts';
|
|
27
|
+
export type { Descriptors, FeatureSet } from './features.ts';
|
|
28
|
+
export { estimatePoses } from './poses.ts';
|
|
29
|
+
export type { CaptureFrame, PoseOptions, PoseResult } from './poses.ts';
|
|
30
|
+
export { relativePose, triangulate } from './twoView.ts';
|
|
31
|
+
export type { RelativePoseOut, RelativePoseResult } from './twoView.ts';
|
|
32
|
+
export { lookAt, renderTestScene } from './testScene.ts';
|
|
33
|
+
export type { TestBox, TestCamera, TestPlane, TestScene } from './testScene.ts';
|
|
34
|
+
export { createDepthEstimator } from './depth.ts';
|
|
35
|
+
export type { DepthEstimate, DepthEstimator, DepthView, RawFrame } from './depth.ts';
|
|
36
|
+
export type { GraphRun } from './run.ts';
|
|
37
|
+
export { DEPTH_PIXEL_MEAN, DEPTH_PIXEL_STD, longestSideSize, prepareDepthFrame, prepareOwlv2Frame, prepareSam2Frame, prepareSamFrame, } from './prepare.ts';
|
|
38
|
+
export type { PreparedFrame } from './prepare.ts';
|
|
39
|
+
export { areaResize, triangleResize, PILLOW_PRECISION, TORCHVISION_PRECISION } from './resample.ts';
|
|
40
|
+
export { browserFrameSource } from './browserFrames.ts';
|
|
41
|
+
export type { BrowserClip } from './browserFrames.ts';
|
|
42
|
+
export { DEPTH_ANYTHING_3, decodeCamera, decodeDepth, depthAnything3, } from './models/depthAnything3.ts';
|
|
43
|
+
export type { DepthAnything3Config } from './models/depthAnything3.ts';
|
|
44
|
+
export { DEPTH_ANYTHING_2_SMALL, depthAnything2 } from './models/depthAnything2.ts';
|
|
45
|
+
export type { DepthAnything2Config } from './models/depthAnything2.ts';
|
|
46
|
+
export type { HeadConfig } from './models/dualDpt.ts';
|
|
47
|
+
export type { VitConfig } from './models/vit.ts';
|
|
48
|
+
export { MINIATURE_CASES, MINIATURE_DEPTH_ANYTHING_2, MINIATURE_DEPTH_ANYTHING_3, MINIATURE_SEED, miniatureCheckpoint, miniatureCheckpoint2, miniatureImages, } from './models/miniature.ts';
|
|
49
|
+
export { MOBILE_SAM, SAM_PIXEL_MEAN, SAM_PIXEL_STD, mobileSamDecoder, mobileSamEncoder, samMasksToImage, } from './models/mobileSam.ts';
|
|
50
|
+
export type { MobileSamConfig } from './models/mobileSam.ts';
|
|
51
|
+
export type { SamDecoderConfig } from './models/samDecoder.ts';
|
|
52
|
+
export { SAM2_PROMPT, SAM2_VIDEO_PROMPT, SAM_PROMPT, samGridPositions, samInputSize, samPromptTokens, samTokenCount, stabilityScore, } from './models/samPrompt.ts';
|
|
53
|
+
export type { SamPrompt, SamPromptLayout } from './models/samPrompt.ts';
|
|
54
|
+
export { MINIATURE_MOBILE_SAM, MINIATURE_SAM_IMAGE, MINIATURE_SAM_PROMPTS, miniatureSamCheckpoint, } from './models/samMiniature.ts';
|
|
55
|
+
export type { TinyVitConfig } from './models/tinyVit.ts';
|
|
56
|
+
export { SAM_21_TINY, sam21Decoder, sam21Encoder } from './models/sam21.ts';
|
|
57
|
+
export type { Sam21Config, Sam21MemoryConfig } from './models/sam21.ts';
|
|
58
|
+
export { sam21MasksToImage, sam21MemoryAttention, sam21MemoryEncoder, sam21Upscale, } from './models/sam21Video.ts';
|
|
59
|
+
export { Sam21Tracker } from './models/sam2Tracker.ts';
|
|
60
|
+
export type { Sam21Frame, Sam21Video, Sam21Weights } from './models/sam2Tracker.ts';
|
|
61
|
+
export type { HieraConfig } from './models/hiera.ts';
|
|
62
|
+
export { MINIATURE_SAM_21, MINIATURE_SAM_21_IMAGE, MINIATURE_SAM_21_PROMPTS, miniatureSam21Checkpoint, } from './models/sam21Miniature.ts';
|
|
63
|
+
export { OWLV2_BASE, OWLV2_PIXEL_MEAN, OWLV2_PIXEL_STD, owlv2BoxBias, owlv2Image, owlv2Text, } from './models/owlv2.ts';
|
|
64
|
+
export type { Owlv2Config } from './models/owlv2.ts';
|
|
65
|
+
export type { ClipTowerConfig } from './models/clipTower.ts';
|
|
66
|
+
export { owlv2Detections, owlv2Logits } from './models/owlv2Detect.ts';
|
|
67
|
+
export type { Owlv2Detection, Owlv2Patches } from './models/owlv2Detect.ts';
|
|
68
|
+
export { clipTokenizer, owlv2Tokens } from './models/clipTokenizer.ts';
|
|
69
|
+
export type { ClipTokenizer } from './models/clipTokenizer.ts';
|
|
70
|
+
export { MINIATURE_OWLV2, MINIATURE_OWLV2_IMAGE, MINIATURE_OWLV2_MERGES, MINIATURE_OWLV2_QUERIES, miniatureOwlv2Checkpoint, } from './models/owlv2Miniature.ts';
|
|
71
|
+
export { optimiseGaussians } from './gaussians/optimise.ts';
|
|
72
|
+
export type { OptimiseOptions } from './gaussians/optimise.ts';
|
|
73
|
+
export { projectGaussian, visibleGaussians, LOW_PASS, REACH } from './gaussians/project.ts';
|
|
74
|
+
export type { GaussianSet, Projected, RasterCamera } from './gaussians/project.ts';
|
|
75
|
+
export { rasteriseGaussians } from './gaussians/rasterise.ts';
|
|
76
|
+
export type { Frame } from './gaussians/rasterise.ts';
|
|
77
|
+
export { accumulateGradients, createGradients, imageLoss } from './gaussians/gradients.ts';
|
|
78
|
+
export type { GaussianGradients } from './gaussians/gradients.ts';
|
|
79
|
+
export { sh1Basis, splatColour, SH1_COEFFICIENTS, SH_C1 } from './gaussians/harmonics.ts';
|
|
80
|
+
export { structuralSimilarity, SIMILARITY_WINDOW } from './gaussians/similarity.ts';
|
|
81
|
+
export { renderDepth } from './gaussians/depth.ts';
|
|
82
|
+
export { createVolume, fuseDepth } from './fusion.ts';
|
|
83
|
+
export type { FuseOptions, SurfaceView, Volume } from './fusion.ts';
|
|
84
|
+
export { marchVolume } from './marching.ts';
|
|
85
|
+
export type { MarchOptions } from './marching.ts';
|
|
86
|
+
export { decimate } from './decimate.ts';
|
|
87
|
+
export type { DecimateOptions } from './decimate.ts';
|
|
88
|
+
export { collisionMesh, propHulls } from './collide.ts';
|
|
89
|
+
export type { CollisionOptions, CollisionSource, PropHulls } from './collide.ts';
|
|
90
|
+
export { createDelightOut, delight } from './delight.ts';
|
|
91
|
+
export type { DelightOptions, DelightOut, DelightView } from './delight.ts';
|
|
92
|
+
export { interpolate, nearestHit, renderLit } from './delightScene.ts';
|
|
93
|
+
export type { Light, LitScene, MeshHit } from './delightScene.ts';
|
|
94
|
+
export { segmentGeometry } from './segment.ts';
|
|
95
|
+
export type { Region, SegmentOptions } from './segment.ts';
|
|
96
|
+
export { labelMasks, liftMasks, promptGrid } from './masks.ts';
|
|
97
|
+
export type { MaskView } from './masks.ts';
|
|
98
|
+
export { MOVABLE_COMPONENTS, SCENERY_COMPONENTS, WALKABLE_COMPONENTS, proposeEntities, } from './propose.ts';
|
|
99
|
+
export type { EntityProposal, ProposeOptions } from './propose.ts';
|
|
100
|
+
export { PROPOSAL_COMPONENT, PROPOSAL_SCHEMA, captureFile, proposalScene, readProposals, } from './scene.ts';
|
|
101
|
+
export type { CaptureScene } from './scene.ts';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*! DriftEngine | Copyright 2026 Drift Technologies | Apache-2.0 | https://github.com/drftrun/driftengine */
|
|
2
|
+
/**
|
|
3
|
+
* `@driftengine/capture` — a video to a playable scene, on the player's own device.
|
|
4
|
+
*
|
|
5
|
+
* **What is here so far is the models a capture runs**, each written as a definition the engine's
|
|
6
|
+
* one neural runtime builds a graph from: `@driftengine/texture` holds the operators and the rule
|
|
7
|
+
* that every weight is read or set aside by name, and this package says which weights a model reads
|
|
8
|
+
* and how. A definition is run over a checkpoint once, when it is converted, and over the converted
|
|
9
|
+
* file afterwards whenever a clip needs the graph at a new size — every device kernel bakes its
|
|
10
|
+
* shapes, and a clip's aspect ratio decides the patch grid.
|
|
11
|
+
*
|
|
12
|
+
* **Depth Anything 3**: depth, its confidence and a camera per view, from one view or several at
|
|
13
|
+
* once. **Depth Anything V2 Small**, the lighter fallback: relative depth from one view.
|
|
14
|
+
* **MobileSAM**: masks from a point or a box, an encoder run once an image and a decoder once a
|
|
15
|
+
* prompt. **SAM 2.1**: the same, and objects tracked through a video by a memory of the frames before.
|
|
16
|
+
* **OWLv2**: boxes for things named in words, an image graph and a text graph joined on the host,
|
|
17
|
+
* with CLIP's tokenizer. Each answers as its upstream's own code does on a seeded miniature of its
|
|
18
|
+
* layout, the fixtures shipped beside them.
|
|
19
|
+
*/
|
|
20
|
+
export { eachFrame, selectFrames } from './frames.js';
|
|
21
|
+
export { cholesky, choleskySolve, levenbergMarquardt, svd3, svdN, symmetricEigen, } from './math/dense.js';
|
|
22
|
+
export { schurSolve } from './math/schur.js';
|
|
23
|
+
export { DESCRIPTOR_BYTES, createFeatureSet, describeFeatures, detectFeatures, matchFeatures, } from './features.js';
|
|
24
|
+
export { estimatePoses } from './poses.js';
|
|
25
|
+
export { relativePose, triangulate } from './twoView.js';
|
|
26
|
+
export { lookAt, renderTestScene } from './testScene.js';
|
|
27
|
+
export { createDepthEstimator } from './depth.js';
|
|
28
|
+
export { DEPTH_PIXEL_MEAN, DEPTH_PIXEL_STD, longestSideSize, prepareDepthFrame, prepareOwlv2Frame, prepareSam2Frame, prepareSamFrame, } from './prepare.js';
|
|
29
|
+
export { areaResize, triangleResize, PILLOW_PRECISION, TORCHVISION_PRECISION } from './resample.js';
|
|
30
|
+
export { browserFrameSource } from './browserFrames.js';
|
|
31
|
+
export { DEPTH_ANYTHING_3, decodeCamera, decodeDepth, depthAnything3, } from './models/depthAnything3.js';
|
|
32
|
+
export { DEPTH_ANYTHING_2_SMALL, depthAnything2 } from './models/depthAnything2.js';
|
|
33
|
+
export { MINIATURE_CASES, MINIATURE_DEPTH_ANYTHING_2, MINIATURE_DEPTH_ANYTHING_3, MINIATURE_SEED, miniatureCheckpoint, miniatureCheckpoint2, miniatureImages, } from './models/miniature.js';
|
|
34
|
+
export { MOBILE_SAM, SAM_PIXEL_MEAN, SAM_PIXEL_STD, mobileSamDecoder, mobileSamEncoder, samMasksToImage, } from './models/mobileSam.js';
|
|
35
|
+
export { SAM2_PROMPT, SAM2_VIDEO_PROMPT, SAM_PROMPT, samGridPositions, samInputSize, samPromptTokens, samTokenCount, stabilityScore, } from './models/samPrompt.js';
|
|
36
|
+
export { MINIATURE_MOBILE_SAM, MINIATURE_SAM_IMAGE, MINIATURE_SAM_PROMPTS, miniatureSamCheckpoint, } from './models/samMiniature.js';
|
|
37
|
+
export { SAM_21_TINY, sam21Decoder, sam21Encoder } from './models/sam21.js';
|
|
38
|
+
export { sam21MasksToImage, sam21MemoryAttention, sam21MemoryEncoder, sam21Upscale, } from './models/sam21Video.js';
|
|
39
|
+
export { Sam21Tracker } from './models/sam2Tracker.js';
|
|
40
|
+
export { MINIATURE_SAM_21, MINIATURE_SAM_21_IMAGE, MINIATURE_SAM_21_PROMPTS, miniatureSam21Checkpoint, } from './models/sam21Miniature.js';
|
|
41
|
+
export { OWLV2_BASE, OWLV2_PIXEL_MEAN, OWLV2_PIXEL_STD, owlv2BoxBias, owlv2Image, owlv2Text, } from './models/owlv2.js';
|
|
42
|
+
export { owlv2Detections, owlv2Logits } from './models/owlv2Detect.js';
|
|
43
|
+
export { clipTokenizer, owlv2Tokens } from './models/clipTokenizer.js';
|
|
44
|
+
export { MINIATURE_OWLV2, MINIATURE_OWLV2_IMAGE, MINIATURE_OWLV2_MERGES, MINIATURE_OWLV2_QUERIES, miniatureOwlv2Checkpoint, } from './models/owlv2Miniature.js';
|
|
45
|
+
/*
|
|
46
|
+
* **Gaussians.** A reference rasteriser that projects the way `@driftengine/splats`' shader does,
|
|
47
|
+
* its analytic gradients, and the fit that descends them into a `SplatSource` the engine draws.
|
|
48
|
+
* `optimiseGaussians` is what a caller wants; the rest is exported because a caller measuring or
|
|
49
|
+
* extending a fit needs the same pieces the fit is built from.
|
|
50
|
+
*/
|
|
51
|
+
export { optimiseGaussians } from './gaussians/optimise.js';
|
|
52
|
+
export { projectGaussian, visibleGaussians, LOW_PASS, REACH } from './gaussians/project.js';
|
|
53
|
+
export { rasteriseGaussians } from './gaussians/rasterise.js';
|
|
54
|
+
export { accumulateGradients, createGradients, imageLoss } from './gaussians/gradients.js';
|
|
55
|
+
export { sh1Basis, splatColour, SH1_COEFFICIENTS, SH_C1 } from './gaussians/harmonics.js';
|
|
56
|
+
export { structuralSimilarity, SIMILARITY_WINDOW } from './gaussians/similarity.js';
|
|
57
|
+
/*
|
|
58
|
+
* **Splats to a surface.** A cloud's depth, many views of it fused into one volume, that volume's
|
|
59
|
+
* crossing as a mesh facing outwards, and the mesh brought down to a budget — which is what a game
|
|
60
|
+
* stands on, rather than the cloud, which only draws.
|
|
61
|
+
*/
|
|
62
|
+
export { renderDepth } from './gaussians/depth.js';
|
|
63
|
+
export { createVolume, fuseDepth } from './fusion.js';
|
|
64
|
+
export { marchVolume } from './marching.js';
|
|
65
|
+
export { decimate } from './decimate.js';
|
|
66
|
+
/*
|
|
67
|
+
* **A surface to stand on.** The drawn mesh cleaned for collision, and a prop's convex hulls inside
|
|
68
|
+
* the container's own caps — which is where a capture stops being a picture.
|
|
69
|
+
*/
|
|
70
|
+
export { collisionMesh, propHulls } from './collide.js';
|
|
71
|
+
/*
|
|
72
|
+
* **A surface's material, separated from the light it was photographed under.** Multi-view inverse
|
|
73
|
+
* rendering with a classical separation: what stays the same across views is the material, what
|
|
74
|
+
* moves is the light, and a chromaticity that holds across an intensity jump is a shadow. Every
|
|
75
|
+
* surface gets a confidence, and `delight.ts` states plainly what that confidence does and does not
|
|
76
|
+
* grade. `renderLit` is the lit fixture the measurements are made against.
|
|
77
|
+
*/
|
|
78
|
+
export { createDelightOut, delight } from './delight.js';
|
|
79
|
+
export { interpolate, nearestHit, renderLit } from './delightScene.js';
|
|
80
|
+
/*
|
|
81
|
+
* **A mesh cut into regions, and each region proposed as something a scene could hold.** Stage four
|
|
82
|
+
* and labelled as such: with a model loaded the masks are voted onto the mesh, and with none the
|
|
83
|
+
* geometry answers on its own. Nothing here decides what an object *is* — a region nobody labelled
|
|
84
|
+
* comes back as scenery, which is drawn, solid, and doing nothing.
|
|
85
|
+
*/
|
|
86
|
+
export { segmentGeometry } from './segment.js';
|
|
87
|
+
export { labelMasks, liftMasks, promptGrid } from './masks.js';
|
|
88
|
+
export { MOVABLE_COMPONENTS, SCENERY_COMPONENTS, WALKABLE_COMPONENTS, proposeEntities, } from './propose.js';
|
|
89
|
+
/*
|
|
90
|
+
* **Every stage in one file.** A capture that arrives as six files is a capture somebody has to
|
|
91
|
+
* reassemble; this writes the mesh, its materials and decode program, the cloud, a prop's hulls,
|
|
92
|
+
* the way across the scene and the proposals into one `.drft`. The proposals travel under a
|
|
93
|
+
* component this package declares — a capture proposes in its own words, and what a scene ends up
|
|
94
|
+
* holding is the consumer's decision.
|
|
95
|
+
*/
|
|
96
|
+
export { PROPOSAL_COMPONENT, PROPOSAL_SCHEMA, captureFile, proposalScene, readProposals, } from './scene.js';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A volume's zero crossing as a mesh, facing outwards.
|
|
3
|
+
*
|
|
4
|
+
* **Tetrahedra rather than cubes, and the reason is watertightness rather than taste.** Marching
|
|
5
|
+
* cubes classifies a cube's eight corners into 256 cases, and a handful of those are *ambiguous*:
|
|
6
|
+
* the same corner signs admit two different surfaces, and two neighbouring cubes that resolve one
|
|
7
|
+
* the two different ways leave a hole between them. Every implementation patches this, and the
|
|
8
|
+
* patches are the part that gets subtly wrong. A tetrahedron has four corners and sixteen cases,
|
|
9
|
+
* **none of them ambiguous** — a plane through a tetrahedron cuts it one way — so a mesh built this
|
|
10
|
+
* way is closed wherever the volume is known, by construction rather than by a table of exceptions.
|
|
11
|
+
*
|
|
12
|
+
* What it costs is triangles: roughly twice what marching cubes emits for the same surface, because
|
|
13
|
+
* a cube is cut six ways rather than once. `decimate` is the answer to that, and it is a better
|
|
14
|
+
* answer than an ambiguity table because it is driven by the error it introduces.
|
|
15
|
+
*
|
|
16
|
+
* **A cube with an unknown corner is not marched at all.** A sample no view ever saw has no
|
|
17
|
+
* distance, and a surface built through it is one the capture invented — which is exactly the
|
|
18
|
+
* spurious closing surface an open scene must not grow. The boundary of what was seen is left open,
|
|
19
|
+
* and that is the honest shape of a clip that walked through a room rather than around an object.
|
|
20
|
+
*
|
|
21
|
+
* **Normals come from the volume's gradient, and their sign is checked against it.** An inverted
|
|
22
|
+
* mesh collides inside-out: a character walks through the floor and falls out of the world, which
|
|
23
|
+
* reads as a physics fault and is a meshing one.
|
|
24
|
+
*/
|
|
25
|
+
import type { MeshData } from '@driftengine/drft';
|
|
26
|
+
import type { Volume } from './fusion.ts';
|
|
27
|
+
export interface MarchOptions {
|
|
28
|
+
/** A sample with less evidence than this is treated as unknown, and its cube is not marched. */
|
|
29
|
+
readonly minimumWeight?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* `volume`'s surface, welded so that neighbours share vertices exactly.
|
|
33
|
+
*
|
|
34
|
+
* A vertex belongs to the *edge* it was found on, so two tetrahedra meeting along an edge find the
|
|
35
|
+
* same one — which is what closes the mesh. Answers the mesh; a volume with no crossing answers an
|
|
36
|
+
* empty one rather than throwing, because a capture of nothing is a real thing to have.
|
|
37
|
+
*/
|
|
38
|
+
export declare function marchVolume(volume: Volume, options?: MarchOptions): MeshData;
|
package/dist/marching.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The six tetrahedra a cube is cut into, by corner index.
|
|
3
|
+
*
|
|
4
|
+
* Corner `n` is the one at `(n & 1, (n >> 1) & 1, (n >> 2) & 1)`. Every tetrahedron holds corners
|
|
5
|
+
* 0 and 7 — the cube's main diagonal — which is what makes the cut the same for every cube and so
|
|
6
|
+
* agrees across their shared faces. A cut chosen per cube would leave the faces between them
|
|
7
|
+
* triangulated two different ways, which is the hole this arrangement exists to avoid.
|
|
8
|
+
*/
|
|
9
|
+
const TETRAHEDRA = [
|
|
10
|
+
[0, 7, 1, 3],
|
|
11
|
+
[0, 7, 3, 2],
|
|
12
|
+
[0, 7, 2, 6],
|
|
13
|
+
[0, 7, 6, 4],
|
|
14
|
+
[0, 7, 4, 5],
|
|
15
|
+
[0, 7, 5, 1],
|
|
16
|
+
];
|
|
17
|
+
/** The six edges of a tetrahedron, as pairs of its own corner slots. */
|
|
18
|
+
const TETRA_EDGES = [
|
|
19
|
+
[0, 1],
|
|
20
|
+
[0, 2],
|
|
21
|
+
[0, 3],
|
|
22
|
+
[1, 2],
|
|
23
|
+
[1, 3],
|
|
24
|
+
[2, 3],
|
|
25
|
+
];
|
|
26
|
+
const DEFAULT_WEIGHT = 1e-6;
|
|
27
|
+
/**
|
|
28
|
+
* How far a crossing is kept from either end of the edge it is on, as a fraction of that edge.
|
|
29
|
+
*
|
|
30
|
+
* **A surface passing exactly through a sample is the one degenerate case tetrahedra do not save
|
|
31
|
+
* you from.** Every edge out of that sample crosses at its very end, so several crossings land on
|
|
32
|
+
* the same point and the triangles between them have no area at all — measured on a sphere whose
|
|
33
|
+
* radius is a whole number of samples: **280 faces of 3,960 with zero area**, and 256 of those with
|
|
34
|
+
* no direction to wind by, because a degenerate triangle has no normal. They cannot simply be
|
|
35
|
+
* dropped: their edges are shared with real faces, and dropping them opens the mesh.
|
|
36
|
+
*
|
|
37
|
+
* So the crossing is held a thousandth of an edge away from each end instead. At a tenth-metre
|
|
38
|
+
* spacing that is a tenth of a millimetre of geometry given up, and it makes the case stop
|
|
39
|
+
* existing rather than handling it.
|
|
40
|
+
*/
|
|
41
|
+
const MARGIN = 1e-3;
|
|
42
|
+
/**
|
|
43
|
+
* `volume`'s surface, welded so that neighbours share vertices exactly.
|
|
44
|
+
*
|
|
45
|
+
* A vertex belongs to the *edge* it was found on, so two tetrahedra meeting along an edge find the
|
|
46
|
+
* same one — which is what closes the mesh. Answers the mesh; a volume with no crossing answers an
|
|
47
|
+
* empty one rather than throwing, because a capture of nothing is a real thing to have.
|
|
48
|
+
*/
|
|
49
|
+
export function marchVolume(volume, options = {}) {
|
|
50
|
+
const [nx, ny, nz] = volume.dims;
|
|
51
|
+
const minimumWeight = options.minimumWeight ?? DEFAULT_WEIGHT;
|
|
52
|
+
const positions = [];
|
|
53
|
+
const normals = [];
|
|
54
|
+
const indices = [];
|
|
55
|
+
/* Which vertex each crossed edge already has, keyed by its two sample indices. */
|
|
56
|
+
const vertexOf = new Map();
|
|
57
|
+
const corner = new Int32Array(8);
|
|
58
|
+
const value = new Float64Array(8);
|
|
59
|
+
for (let k = 0; k + 1 < nz; k += 1) {
|
|
60
|
+
for (let j = 0; j + 1 < ny; j += 1) {
|
|
61
|
+
for (let i = 0; i + 1 < nx; i += 1) {
|
|
62
|
+
let known = true;
|
|
63
|
+
for (let n = 0; n < 8; n += 1) {
|
|
64
|
+
const at = (((k + ((n >> 2) & 1)) * ny + (j + ((n >> 1) & 1))) * nx +
|
|
65
|
+
(i + (n & 1)));
|
|
66
|
+
corner[n] = at;
|
|
67
|
+
value[n] = volume.distance[at];
|
|
68
|
+
if (volume.weight[at] < minimumWeight)
|
|
69
|
+
known = false;
|
|
70
|
+
}
|
|
71
|
+
if (!known)
|
|
72
|
+
continue;
|
|
73
|
+
for (const tetra of TETRAHEDRA) {
|
|
74
|
+
marchTetrahedron(volume, corner, value, tetra, vertexOf, positions, normals, indices);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const colors = new Float32Array(positions.length).fill(1);
|
|
80
|
+
return {
|
|
81
|
+
positions: Float32Array.from(positions),
|
|
82
|
+
normals: Float32Array.from(normals),
|
|
83
|
+
colors,
|
|
84
|
+
/*
|
|
85
|
+
* **One float a vertex, which is what `MeshData` means by emissive** — how much of the
|
|
86
|
+
* surface's own colour it emits — rather than a colour of its own. It was three, and nothing
|
|
87
|
+
* noticed until a captured mesh was written to a file: every consumer of it so far measured
|
|
88
|
+
* geometry, and the container is the first thing that checks an attribute's length against
|
|
89
|
+
* the vertex count. A short attribute buffer is the failure `writeDrft` refuses by name,
|
|
90
|
+
* because a driver handed one may draw zeroes or drop the draw.
|
|
91
|
+
*/
|
|
92
|
+
emissive: new Float32Array(positions.length / 3),
|
|
93
|
+
indices: Uint32Array.from(indices),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function marchTetrahedron(volume, corner, value, tetra, vertexOf, positions, normals, indices) {
|
|
97
|
+
/* Which of the four corners are inside, as a four-bit pattern. */
|
|
98
|
+
let pattern = 0;
|
|
99
|
+
for (let slot = 0; slot < 4; slot += 1) {
|
|
100
|
+
if (value[tetra[slot]] < 0)
|
|
101
|
+
pattern |= 1 << slot;
|
|
102
|
+
}
|
|
103
|
+
if (pattern === 0 || pattern === 15)
|
|
104
|
+
return;
|
|
105
|
+
/* The edges this pattern crosses: one end inside, the other out. */
|
|
106
|
+
const crossings = [];
|
|
107
|
+
for (const [a, b] of TETRA_EDGES) {
|
|
108
|
+
const insideA = (pattern & (1 << a)) !== 0;
|
|
109
|
+
const insideB = (pattern & (1 << b)) !== 0;
|
|
110
|
+
if (insideA === insideB)
|
|
111
|
+
continue;
|
|
112
|
+
crossings.push(vertexOn(volume, corner[tetra[a]], corner[tetra[b]], value[tetra[a]], value[tetra[b]], vertexOf, positions, normals));
|
|
113
|
+
}
|
|
114
|
+
/*
|
|
115
|
+
* Three crossings where one corner is alone on its side of the surface, four where they are two
|
|
116
|
+
* against two — a quadrilateral, which becomes two triangles. There is no other case: this is the
|
|
117
|
+
* whole of the ambiguity marching cubes has and tetrahedra do not.
|
|
118
|
+
*/
|
|
119
|
+
if (crossings.length === 3) {
|
|
120
|
+
emit(volume, positions, normals, indices, crossings[0], crossings[1], crossings[2]);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (crossings.length !== 4)
|
|
124
|
+
return;
|
|
125
|
+
/*
|
|
126
|
+
* The four are in edge order, which walks the quadrilateral as 0–1–3–2 rather than 0–1–2–3: the
|
|
127
|
+
* edges opposite each other in the list share no corner. Taking them in the listed order would
|
|
128
|
+
* fold the quad into a bowtie, which is a pair of triangles that overlap and leave a hole.
|
|
129
|
+
*/
|
|
130
|
+
emit(volume, positions, normals, indices, crossings[0], crossings[1], crossings[3]);
|
|
131
|
+
emit(volume, positions, normals, indices, crossings[0], crossings[3], crossings[2]);
|
|
132
|
+
}
|
|
133
|
+
/** The crossing on the edge between two samples, made once and shared by everything that meets it. */
|
|
134
|
+
function vertexOn(volume, a, b, valueA, valueB, vertexOf, positions, normals) {
|
|
135
|
+
/* Keyed by the pair, smaller first, so the two tetrahedra either side agree on the key. */
|
|
136
|
+
const low = a < b ? a : b;
|
|
137
|
+
const high = a < b ? b : a;
|
|
138
|
+
const key = low * volume.distance.length + high;
|
|
139
|
+
const held = vertexOf.get(key);
|
|
140
|
+
if (held !== undefined)
|
|
141
|
+
return held;
|
|
142
|
+
const first = low === a ? valueA : valueB;
|
|
143
|
+
const second = low === a ? valueB : valueA;
|
|
144
|
+
/* Where the line between the two samples is zero; a pair that does not straddle takes the middle. */
|
|
145
|
+
const span = second - first;
|
|
146
|
+
const found = span === 0 ? 0.5 : first / -span;
|
|
147
|
+
const t = found < MARGIN ? MARGIN : found > 1 - MARGIN ? 1 - MARGIN : found;
|
|
148
|
+
const index = positions.length / 3;
|
|
149
|
+
const [nx, ny] = volume.dims;
|
|
150
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
151
|
+
const from = sampleAxis(low, axis, nx, ny);
|
|
152
|
+
const to = sampleAxis(high, axis, nx, ny);
|
|
153
|
+
positions.push(volume.origin[axis] + (from + (to - from) * t) * volume.spacing);
|
|
154
|
+
}
|
|
155
|
+
const normal = gradientAt(volume, low, high, t);
|
|
156
|
+
normals.push(normal[0], normal[1], normal[2]);
|
|
157
|
+
vertexOf.set(key, index);
|
|
158
|
+
return index;
|
|
159
|
+
}
|
|
160
|
+
function sampleAxis(at, axis, nx, ny) {
|
|
161
|
+
if (axis === 0)
|
|
162
|
+
return at % nx;
|
|
163
|
+
if (axis === 1)
|
|
164
|
+
return Math.floor(at / nx) % ny;
|
|
165
|
+
return Math.floor(at / (nx * ny));
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The volume's gradient partway along an edge, normalised: which way is out.
|
|
169
|
+
*
|
|
170
|
+
* Taken at each end and blended, rather than at the point, because the gradient is only defined at
|
|
171
|
+
* samples. A gradient of nothing — a flat patch of volume — answers the edge's own direction, which
|
|
172
|
+
* is the one thing that is certainly not tangent to the surface there.
|
|
173
|
+
*/
|
|
174
|
+
function gradientAt(volume, low, high, t) {
|
|
175
|
+
const first = gradientAtSample(volume, low);
|
|
176
|
+
const second = gradientAtSample(volume, high);
|
|
177
|
+
const out = [0, 0, 0];
|
|
178
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
179
|
+
out[axis] = first[axis] * (1 - t) + second[axis] * t;
|
|
180
|
+
}
|
|
181
|
+
const length = Math.sqrt(out[0] * out[0] +
|
|
182
|
+
out[1] * out[1] +
|
|
183
|
+
out[2] * out[2]);
|
|
184
|
+
if (length > 1e-12) {
|
|
185
|
+
for (let axis = 0; axis < 3; axis += 1)
|
|
186
|
+
out[axis] = out[axis] / length;
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
const [nx, ny] = volume.dims;
|
|
190
|
+
const fallback = [0, 0, 0];
|
|
191
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
192
|
+
fallback[axis] = sampleAxis(high, axis, nx, ny) - sampleAxis(low, axis, nx, ny);
|
|
193
|
+
}
|
|
194
|
+
const span = Math.sqrt(fallback[0] * fallback[0] +
|
|
195
|
+
fallback[1] * fallback[1] +
|
|
196
|
+
fallback[2] * fallback[2]);
|
|
197
|
+
return span > 0 ? fallback.map((value) => value / span) : [0, 0, 1];
|
|
198
|
+
}
|
|
199
|
+
/** A central difference where both neighbours exist, and a one-sided one at the volume's edge. */
|
|
200
|
+
function gradientAtSample(volume, at) {
|
|
201
|
+
const [nx, ny, nz] = volume.dims;
|
|
202
|
+
const x = at % nx;
|
|
203
|
+
const y = Math.floor(at / nx) % ny;
|
|
204
|
+
const z = Math.floor(at / (nx * ny));
|
|
205
|
+
const here = volume.distance[at];
|
|
206
|
+
const out = [0, 0, 0];
|
|
207
|
+
const steps = [1, nx, nx * ny];
|
|
208
|
+
const limits = [
|
|
209
|
+
[x, nx],
|
|
210
|
+
[y, ny],
|
|
211
|
+
[z, nz],
|
|
212
|
+
];
|
|
213
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
214
|
+
const [position, size] = limits[axis];
|
|
215
|
+
const step = steps[axis];
|
|
216
|
+
const low = position > 0 ? volume.distance[at - step] : here;
|
|
217
|
+
const high = position + 1 < size ? volume.distance[at + step] : here;
|
|
218
|
+
const span = (position > 0 ? 1 : 0) + (position + 1 < size ? 1 : 0);
|
|
219
|
+
out[axis] = span === 0 ? 0 : (high - low) / (span * volume.spacing);
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* One triangle, wound so that its own normal agrees with the volume's gradient.
|
|
225
|
+
*
|
|
226
|
+
* **This is the check the whole module exists to pass.** A mesh whose faces point inwards collides
|
|
227
|
+
* inside-out — a character walks through the floor and out of the world — and it looks entirely
|
|
228
|
+
* correct until something stands on it.
|
|
229
|
+
*/
|
|
230
|
+
function emit(volume, positions, normals, indices, a, b, c) {
|
|
231
|
+
if (a === b || b === c || a === c)
|
|
232
|
+
return;
|
|
233
|
+
const ax = positions[a * 3];
|
|
234
|
+
const ay = positions[a * 3 + 1];
|
|
235
|
+
const az = positions[a * 3 + 2];
|
|
236
|
+
const ux = positions[b * 3] - ax;
|
|
237
|
+
const uy = positions[b * 3 + 1] - ay;
|
|
238
|
+
const uz = positions[b * 3 + 2] - az;
|
|
239
|
+
const vx = positions[c * 3] - ax;
|
|
240
|
+
const vy = positions[c * 3 + 1] - ay;
|
|
241
|
+
const vz = positions[c * 3 + 2] - az;
|
|
242
|
+
const fx = uy * vz - uz * vy;
|
|
243
|
+
const fy = uz * vx - ux * vz;
|
|
244
|
+
const fz = ux * vy - uy * vx;
|
|
245
|
+
/* The three vertices' own normals, which came from the gradient, say which way out is. */
|
|
246
|
+
let outward = 0;
|
|
247
|
+
for (const vertex of [a, b, c]) {
|
|
248
|
+
outward +=
|
|
249
|
+
fx * normals[vertex * 3] +
|
|
250
|
+
fy * normals[vertex * 3 + 1] +
|
|
251
|
+
fz * normals[vertex * 3 + 2];
|
|
252
|
+
}
|
|
253
|
+
if (outward >= 0)
|
|
254
|
+
indices.push(a, b, c);
|
|
255
|
+
else
|
|
256
|
+
indices.push(a, c, b);
|
|
257
|
+
void volume;
|
|
258
|
+
}
|
package/dist/masks.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A segmentation model's masks brought onto the mesh, and a detector's names brought onto the masks.
|
|
3
|
+
*
|
|
4
|
+
* **Where a region comes from when weights are loaded.** A prompt lattice asks the model what is in
|
|
5
|
+
* the frame, the masks that come back are voted onto the mesh across every view that saw a
|
|
6
|
+
* triangle, and a detector's boxes put names to the mask indices. Nothing here runs a model: masks
|
|
7
|
+
* and detections arrive as data, so this module is the same code whether they were produced on a
|
|
8
|
+
* device, on a native host, or by hand in a test.
|
|
9
|
+
*
|
|
10
|
+
* **Voting rather than taking the best view**, because a mask boundary is where a model is least
|
|
11
|
+
* sure and every view puts it somewhere slightly different — and **a triangle no view claimed is
|
|
12
|
+
* left unassigned**, which is what keeps an unlabelled region unlabelled rather than absorbed.
|
|
13
|
+
*/
|
|
14
|
+
import type { MeshData } from '@driftengine/drft';
|
|
15
|
+
import type { Owlv2Detection } from './models/owlv2Detect.ts';
|
|
16
|
+
import { type Region } from './segment.ts';
|
|
17
|
+
/** Where a model is prompted, and what came back for each prompt. */
|
|
18
|
+
export interface MaskView {
|
|
19
|
+
/** One mask index per pixel, or −1 where the model claimed nothing. */
|
|
20
|
+
readonly mask: Int32Array;
|
|
21
|
+
readonly width: number;
|
|
22
|
+
readonly height: number;
|
|
23
|
+
/** 3 × 4 row-major world-to-camera. */
|
|
24
|
+
readonly worldToCamera: Float64Array;
|
|
25
|
+
/** `fx`, `fy`, `cx`, `cy`. */
|
|
26
|
+
readonly intrinsics: readonly [number, number, number, number];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A lattice of prompt points over an image, seeded.
|
|
30
|
+
*
|
|
31
|
+
* **A lattice rather than a scatter**, because a scatter leaves gaps a small object falls into and
|
|
32
|
+
* a lattice does not; the seeded jitter is there so that a repeated object does not land on the
|
|
33
|
+
* same part of every instance, which is how a grid misses the same feature twice. Two per pixel
|
|
34
|
+
* pair — `x` then `y` — in reading order, which is the order a model's masks come back in.
|
|
35
|
+
*/
|
|
36
|
+
export declare function promptGrid(width: number, height: number, across: number, down: number, random: () => number): Float32Array;
|
|
37
|
+
/**
|
|
38
|
+
* Masks from several views lifted onto the mesh, by what most of the views that saw a triangle say.
|
|
39
|
+
*
|
|
40
|
+
* **Voting rather than taking the best view**, because a mask boundary is where a model is least
|
|
41
|
+
* sure and every view puts it somewhere slightly different. A triangle no view claimed is left
|
|
42
|
+
* unassigned rather than given to its neighbour, which is what keeps an unlabelled region
|
|
43
|
+
* unlabelled.
|
|
44
|
+
*/
|
|
45
|
+
export declare function liftMasks(views: readonly MaskView[], mesh: MeshData, labels: readonly string[]): Region[];
|
|
46
|
+
/**
|
|
47
|
+
* A name for each mask index, from a detector's boxes.
|
|
48
|
+
*
|
|
49
|
+
* **The join between the two models a capture runs**: one says *where the things are* and the other
|
|
50
|
+
* says *what they are called*, and neither can do the other's half. A mask takes the name of the
|
|
51
|
+
* detection it agrees with most, measured as intersection over union between the mask's own pixels
|
|
52
|
+
* and the box — the mask's pixels rather than the box around them, because the box around an
|
|
53
|
+
* L-shaped mask is mostly not the mask.
|
|
54
|
+
*
|
|
55
|
+
* **A mask that agrees with nothing gets no name, and that is a result.** `null` here reaches
|
|
56
|
+
* `proposeEntities` as scenery, which is the safe answer; a name taken from the nearest box
|
|
57
|
+
* whatever the overlap is how a chair becomes a table. `overlap` is where a caller draws that line.
|
|
58
|
+
*/
|
|
59
|
+
export declare function labelMasks(view: MaskView, detections: readonly Owlv2Detection[], queries: readonly string[], overlap?: number): (string | null)[];
|