lecodes-cli 0.18.2 → 0.19.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/dist/index.js +1240 -170
- package/package.json +3 -2
- package/runtime/scene-harness.json +1 -1
- package/runtime/sdk/compile/aspectMacro.ts +86 -0
- package/runtime/sdk/compile/assetIconMacro.ts +384 -0
- package/runtime/sdk/compile/assetMacro.ts +146 -0
- package/runtime/sdk/compile/assetName.ts +50 -0
- package/runtime/sdk/compile/bundler.ts +287 -0
- package/runtime/sdk/compile/compileProject.ts +129 -0
- package/runtime/sdk/compile/detectEntry.ts +128 -0
- package/runtime/sdk/compile/fontMacro.ts +459 -0
- package/runtime/sdk/compile/fontRegistry.ts +78 -0
- package/runtime/sdk/compile/header.ts +67 -0
- package/runtime/sdk/compile/index.ts +100 -0
- package/runtime/sdk/compile/libraryImports.ts +52 -0
- package/runtime/sdk/compile/liteMaterial.ts +247 -0
- package/runtime/sdk/compile/sceneEditor.ts +88 -0
- package/runtime/sdk/compile/serverSplit.ts +233 -0
- package/runtime/sdk/compile/serverTypes.ts +227 -0
- package/runtime/sdk/compile/sfnt.ts +98 -0
- package/runtime/sdk/compile/shaderSchema.ts +202 -0
- package/runtime/sdk/compile/shaderTargets.ts +81 -0
- package/runtime/sdk/compile/sourcemap.ts +25 -0
- package/runtime/sdk/core/Aspect.ts +65 -9
- package/runtime/sdk/core/StateMachine.ts +308 -0
- package/runtime/sdk/core/time.ts +3 -0
- package/runtime/sdk/gl/CameraPlace.ts +52 -52
- package/runtime/sdk/gl/Light.ts +12 -4
- package/runtime/sdk/gl/Lightmap.ts +87 -10
- package/runtime/sdk/gl/Material.ts +15 -0
- package/runtime/sdk/gl/Model.ts +68 -8
- package/runtime/sdk/gl/NavAgent.ts +337 -0
- package/runtime/sdk/gl/NavMesh.ts +397 -0
- package/runtime/sdk/gl/Ragdoll.ts +270 -0
- package/runtime/sdk/gl/Scene.ts +7 -0
- package/runtime/sdk/gl/Shape.ts +37 -5
- package/runtime/sdk/gl/Terrain.ts +1092 -0
- package/runtime/sdk/gl/Texture.ts +17 -0
- package/runtime/sdk/gl/Trigger.ts +45 -45
- package/runtime/sdk/gl/animation/Animator.ts +35 -2
- package/runtime/sdk/gl/animation/Layer.ts +3 -1
- package/runtime/sdk/gl/animation/Loop.ts +5 -0
- package/runtime/sdk/gl/animation/Playback.ts +4 -3
- package/runtime/sdk/gl/animation/core.ts +52 -10
- package/runtime/sdk/gl/scenarios.ts +291 -291
- package/runtime/sdk/gl/state.ts +6 -6
- package/runtime/sdk/gl/terrainMesh.ts +219 -0
- package/runtime/sdk/inject.ts +12 -1
- package/runtime/sdk/net/codec.ts +119 -0
- package/runtime/sdk/net/core.ts +384 -0
- package/runtime/sdk/net/index.ts +181 -0
- package/runtime/sdk/net/replication.ts +622 -0
- package/runtime/sdk/scene/defineScene.ts +140 -14
- package/runtime/sdk/scene/editorPlugins.ts +18 -0
- package/runtime/sdk/scene/gizmos.ts +148 -148
- package/runtime/sdk/ui/UINode.ts +4 -0
- package/runtime/sdk-types.json +1 -1
package/runtime/sdk/gl/Scene.ts
CHANGED
|
@@ -141,6 +141,13 @@ const installRenderSyncedFrames = (): void => {
|
|
|
141
141
|
_creator.setEarlyUpdate((dt: number) => { glState.frame++; early(dt) })
|
|
142
142
|
_creator.setLateUpdate(late)
|
|
143
143
|
return true
|
|
144
|
+
}, (fixed) => {
|
|
145
|
+
// The fixed phase runs INSIDE the engine's substep loop (physics/world.cpp) when the host has the
|
|
146
|
+
// hook; each substep moves bodies natively, so the frame stamp bumps per step too. Feature-detected:
|
|
147
|
+
// an older host returns false and the dispatcher steps its own 1/60 accumulator.
|
|
148
|
+
if (typeof _creator.setFixedUpdate !== "function") return false
|
|
149
|
+
_creator.setFixedUpdate((dt: number) => { glState.frame++; fixed(dt) })
|
|
150
|
+
return true
|
|
144
151
|
})
|
|
145
152
|
// Time.scale / Time.paused reach the engine's own clocks (physics, animators, particles) through
|
|
146
153
|
// setTimeScale; a host without it keeps running its sims at wall-clock speed (feature-detected).
|
package/runtime/sdk/gl/Shape.ts
CHANGED
|
@@ -22,7 +22,11 @@ import { cx, cy, cz, type Vec3Like } from "../math/vec"
|
|
|
22
22
|
import type { Node } from "./Node"
|
|
23
23
|
|
|
24
24
|
/** Which geometry a Shape uses — the one-of the fields below encode (see `_build`'s order). */
|
|
25
|
-
export type ShapeKind = "auto" | "box" | "sphere" | "cylinder" | "capsule" | "mesh" | "convex"
|
|
25
|
+
export type ShapeKind = "auto" | "box" | "sphere" | "cylinder" | "capsule" | "mesh" | "convex" | "heightfield"
|
|
26
|
+
|
|
27
|
+
/** What a terrain node carries for `Shape { heightfield: true }` (gl/Terrain.ts `_data`). */
|
|
28
|
+
type TerrainData = { sizeX: number, sizeZ: number, cellSize: number, heights: Float32Array, holes: Uint8Array | null }
|
|
29
|
+
const terrainOf = (node: Node): TerrainData | null => (node as unknown as { _terrain?: { _data: TerrainData } })._terrain?._data ?? null
|
|
26
30
|
|
|
27
31
|
/** A node-local AABB, in the node's OWN frame (its own transform excluded), before world scale. */
|
|
28
32
|
export type ShapeBounds = { min: [number, number, number], max: [number, number, number] }
|
|
@@ -60,6 +64,10 @@ export class Shape extends Aspect<"shape", Node> {
|
|
|
60
64
|
* only (a dynamic body can't be a triangle mesh; Physics throws). `'convex'` = convex hull of the
|
|
61
65
|
* vertices, works for dynamic bodies too. A Model uses its bind pose (skinned parts skipped). */
|
|
62
66
|
mesh?: boolean | "convex"
|
|
67
|
+
/** The node's terrain (`Terrain.create(...).node`) as a Jolt height field — the exact drawn grid,
|
|
68
|
+
* holes included (docs/terrain-plan.md). Static / kinematic / picking / character ground only,
|
|
69
|
+
* like `mesh: true`. `terrain.commit()` pushes edits into the live shape. */
|
|
70
|
+
heightfield?: boolean
|
|
63
71
|
/**
|
|
64
72
|
* The shape's centre, relative to the node's origin — world units in the node's ROTATED frame
|
|
65
73
|
* (the node's scale is ignored, exactly like the explicit dimensions above). Default [0, 0, 0].
|
|
@@ -140,6 +148,7 @@ export class Shape extends Aspect<"shape", Node> {
|
|
|
140
148
|
|
|
141
149
|
/** Which geometry this shape currently uses (the `_build` dispatch, as a name). */
|
|
142
150
|
get kind(): ShapeKind {
|
|
151
|
+
if (this.heightfield) return "heightfield"
|
|
143
152
|
if (this.mesh === "convex") return "convex"
|
|
144
153
|
if (this.mesh) return "mesh"
|
|
145
154
|
if (this.sphere !== undefined) return "sphere"
|
|
@@ -238,8 +247,14 @@ export class Shape extends Aspect<"shape", Node> {
|
|
|
238
247
|
if (!this.raycast && this._bodyId) _creator.physicsSetPickable(this._bodyId, false)
|
|
239
248
|
}
|
|
240
249
|
|
|
241
|
-
/** @internal true for an exact triangle mesh — Physics refuses a dynamic body on it. */
|
|
242
|
-
get _isTriangleMesh(): boolean { return this.mesh === true }
|
|
250
|
+
/** @internal true for an exact triangle mesh or a height field — Physics refuses a dynamic body on it. */
|
|
251
|
+
get _isTriangleMesh(): boolean { return this.mesh === true || this.heightfield === true }
|
|
252
|
+
|
|
253
|
+
/** @internal the height range a heightfield shape can encode (`Terrain.commit` rebuilds past it). */
|
|
254
|
+
_heightfieldRange: [number, number] | null = null
|
|
255
|
+
|
|
256
|
+
/** @internal rebuild the geometry in place (a terrain edit that left the encodable range). */
|
|
257
|
+
_rebuildShape(): void { this._rebuild() }
|
|
243
258
|
|
|
244
259
|
// Rebuild the geometry in place: the body keeps its id, velocity and world transform (Physics
|
|
245
260
|
// holds that id, so re-creating the body instead would strand it). A shape a CharacterController
|
|
@@ -290,7 +305,8 @@ export class Shape extends Aspect<"shape", Node> {
|
|
|
290
305
|
this._autoOrigin = null
|
|
291
306
|
this._sig = this._signature()
|
|
292
307
|
let id = 0
|
|
293
|
-
if (this.
|
|
308
|
+
if (this.heightfield) id = this._buildHeightField()
|
|
309
|
+
else if (this.mesh) id = this._buildMesh(this.mesh === "convex")
|
|
294
310
|
else if (this.sphere !== undefined) id = _creator.physicsBuildSphere(this.sphere)
|
|
295
311
|
else if (this.cylinder) id = _creator.physicsBuildCylinder(this.cylinder.halfHeight, this.cylinder.radius)
|
|
296
312
|
else if (this.capsule) id = _creator.physicsBuildCapsule(this.capsule.halfHeight, this.capsule.radius)
|
|
@@ -321,7 +337,23 @@ export class Shape extends Aspect<"shape", Node> {
|
|
|
321
337
|
private _signature(): string {
|
|
322
338
|
const v = (a: Vec3Like | undefined) => (a ? `${cx(a)},${cy(a)},${cz(a)}` : "")
|
|
323
339
|
const t = (o: { halfHeight: number, radius: number } | undefined) => (o ? `${o.halfHeight},${o.radius}` : "")
|
|
324
|
-
return `${v(this.box)}|${this.sphere ?? ""}|${t(this.cylinder)}|${t(this.capsule)}|${this.mesh ?? ""}|${v(this.origin)}`
|
|
340
|
+
return `${v(this.box)}|${this.sphere ?? ""}|${t(this.cylinder)}|${t(this.capsule)}|${this.mesh ?? ""}|${this.heightfield ? "hf" : ""}|${v(this.origin)}`
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// heightfield: the terrain on this node hands its grid over; the engine keeps its own copy and
|
|
344
|
+
// pads it to Jolt's block grid. No terrain / no host support = no collider (0), with a warning.
|
|
345
|
+
private _buildHeightField(): number {
|
|
346
|
+
const t = terrainOf(this.node)
|
|
347
|
+
if (!t) { console.warn(`Shape { heightfield }: "${this.node.name}" carries no Terrain — no collider`); return 0 }
|
|
348
|
+
if (!_creator.physicsBuildHeightField) { console.warn("Shape { heightfield } needs a newer host — the terrain has no collider"); return 0 }
|
|
349
|
+
const s = this.node.worldScale
|
|
350
|
+
let lo = Infinity, hi = -Infinity
|
|
351
|
+
for (let i = 0; i < t.heights.length; i++) { const h = t.heights[i]; if (h < lo) lo = h; if (h > hi) hi = h }
|
|
352
|
+
const range = Math.max(1, hi - lo), margin = Math.max(2, range * 0.25)
|
|
353
|
+
this._heightfieldRange = [ lo - margin, hi + margin ] // mirrors creator-gl physicsBuildHeightField's headroom
|
|
354
|
+
const id = _creator.physicsBuildHeightField(t.heights, t.sizeX, t.sizeZ, t.cellSize, t.holes, s.x, s.y, s.z)
|
|
355
|
+
if (!id) console.warn(`Shape { heightfield }: the engine refused "${this.node.name}"'s grid (all holes?)`)
|
|
356
|
+
return id
|
|
325
357
|
}
|
|
326
358
|
|
|
327
359
|
// mesh: a Mesh node hands its CPU geometry over; anything else is tried as a GLB root (the host
|