@nakednous/tree 0.0.20 → 0.0.21
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/README.md +61 -7
- package/dist/index.js +333 -297
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -170,23 +170,77 @@ For matrix-based capture use `track.add({ mat4Model: mat4Eye })` for full-fideli
|
|
|
170
170
|
|
|
171
171
|
The interpolated path of a track can be sampled without advancing the transport cursor or firing hooks. All samplers are zero-alloc — the caller owns the output buffers — and honour the track's interpolation mode (`hermite` / `linear` / `step`) and the same stored-tangent → auto-CR fallback chain used by `eval()`.
|
|
172
172
|
|
|
173
|
+
Two shapes of method, each playing a different role:
|
|
174
|
+
|
|
175
|
+
* **Continuous samplers** — evaluate a path-evolving quantity at any point along the path. Accept either a cursor form (reads `track.seg` / `track.f`) or an explicit `(seg, t)` form, with `seg ∈ [0, segments−1]` and `t ∈ [0, 1]` local to that segment.
|
|
176
|
+
* **Keyframe-indexed queries** — give a property of a specific keyframe. Tangents at a junction, or the per-keyframe projection matrix.
|
|
177
|
+
|
|
173
178
|
**`PoseTrack`:**
|
|
174
179
|
|
|
175
180
|
```js
|
|
176
|
-
track.samplePos(out
|
|
177
|
-
track.
|
|
181
|
+
track.samplePos(out) // cursor form
|
|
182
|
+
track.samplePos(out, seg, t) // explicit
|
|
183
|
+
|
|
184
|
+
track.mat4Model(out) // cursor form — TRS as model mat4
|
|
185
|
+
track.mat4Model(out, seg, t) // explicit
|
|
186
|
+
|
|
187
|
+
track.tangents(outIn, outOut, i) // effective in/out pos-tangents at keyframe i
|
|
178
188
|
```
|
|
179
189
|
|
|
180
190
|
**`CameraTrack`:**
|
|
181
191
|
|
|
182
192
|
```js
|
|
183
|
-
track.sampleEye(out, seg, t)
|
|
184
|
-
track.sampleCenter(out, seg, t)
|
|
185
|
-
|
|
186
|
-
track.
|
|
193
|
+
track.sampleEye(out) track.sampleEye(out, seg, t)
|
|
194
|
+
track.sampleCenter(out) track.sampleCenter(out, seg, t)
|
|
195
|
+
|
|
196
|
+
track.mat4Eye(out) // cursor form — lookat eye matrix
|
|
197
|
+
track.mat4Eye(out, seg, t) // explicit
|
|
198
|
+
|
|
199
|
+
track.eyeTangents(outIn, outOut, i)
|
|
200
|
+
track.centerTangents(outIn, outOut, i)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Tangent samplers mirror the missing side at boundary keyframes so the first and last keyframes produce visible tangent vectors.
|
|
204
|
+
|
|
205
|
+
**Projection matrices are not a track method.** Each `CameraTrack` keyframe stores `fov` (perspective) or `halfHeight` (orthographic) as a raw scalar on `track.keyframes[i]` — callers wanting a projection build one from those scalars using `mat4Persp` / `mat4Ortho` directly:
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
const kf = track.keyframes[i]
|
|
209
|
+
if (kf.fov != null) {
|
|
210
|
+
const hh = near * Math.tan(kf.fov * 0.5), hw = hh * aspect
|
|
211
|
+
mat4Persp(out, -hw, hw, -hh, hh, near, far, ndcZMin)
|
|
212
|
+
} else if (kf.halfHeight != null) {
|
|
213
|
+
const hh = kf.halfHeight, hw = hh * aspect
|
|
214
|
+
mat4Ortho(out, -hw, hw, -hh, hh, near, far, ndcZMin)
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Animated `fov` or `halfHeight` in sketches flows through the bridge's camera-binding: `p5.tree` reads `eval().fov` / `eval().halfHeight` each frame and calls `cam.perspective()` / `cam.ortho()` accordingly — none of this touches matrix construction.
|
|
219
|
+
|
|
220
|
+
Callers who want an interpolated projection matrix at mid-segment `(seg, t)` lerp the raw scalars from adjacent keyframes before building:
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
import { mat4Persp, mat4Ortho } from '@nakednous/tree'
|
|
224
|
+
|
|
225
|
+
function mat4ProjAt(out, track, seg, t, near, far, aspect, ndcZMin, ndcYSign = 1) {
|
|
226
|
+
const k0 = track.keyframes[seg]
|
|
227
|
+
const k1 = track.keyframes[seg + 1] ?? k0
|
|
228
|
+
|
|
229
|
+
if (k0.fov != null && k1.fov != null) {
|
|
230
|
+
const fov = k0.fov + t * (k1.fov - k0.fov)
|
|
231
|
+
const hh = near * Math.tan(fov * 0.5), hw = hh * aspect
|
|
232
|
+
return mat4Persp(out, -hw, hw, -hh, hh, near, far, ndcZMin, ndcYSign)
|
|
233
|
+
}
|
|
234
|
+
if (k0.halfHeight != null && k1.halfHeight != null) {
|
|
235
|
+
const hh = k0.halfHeight + t * (k1.halfHeight - k0.halfHeight)
|
|
236
|
+
const hw = hh * aspect
|
|
237
|
+
return mat4Ortho(out, -hw, hw, -hh, hh, near, far, ndcZMin, ndcYSign)
|
|
238
|
+
}
|
|
239
|
+
return null
|
|
240
|
+
}
|
|
187
241
|
```
|
|
188
242
|
|
|
189
|
-
|
|
243
|
+
Intended uses of the samplers: custom rendering of the path (polyline overlays, arclength-based placement), pedagogical visualisations of Hermite / Catmull-Rom, and gizmos — `p5.tree`'s `trackPath` is built on top of these.
|
|
190
244
|
|
|
191
245
|
---
|
|
192
246
|
|