lecodes-cli 0.17.1 → 0.18.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 +1340 -648
- package/package.json +3 -3
- package/runtime/scene-harness.json +1 -1
- package/runtime/sdk/compile/bundler.ts +1 -1
- package/runtime/sdk/compile/compileProject.ts +16 -1
- package/runtime/sdk/compile/header.ts +6 -1
- package/runtime/sdk/compile/index.ts +16 -0
- package/runtime/sdk/compile/liteMaterial.ts +247 -0
- package/runtime/sdk/compile/shaderTargets.ts +42 -0
- package/runtime/sdk/core/Aspect.ts +255 -244
- package/runtime/sdk/g2/CharacterController2D.ts +2 -2
- package/runtime/sdk/gl/Camera.ts +41 -0
- package/runtime/sdk/gl/CameraPlace.ts +51 -0
- package/runtime/sdk/gl/CharacterController.ts +6 -2
- package/runtime/sdk/gl/IK.ts +193 -174
- package/runtime/sdk/gl/Material.ts +23 -0
- package/runtime/sdk/gl/Model.ts +7 -6
- package/runtime/sdk/gl/Node.ts +270 -285
- package/runtime/sdk/gl/Particles.ts +676 -625
- package/runtime/sdk/gl/Physics.ts +53 -1
- package/runtime/sdk/gl/Scene.ts +323 -291
- package/runtime/sdk/gl/Shape.ts +248 -8
- package/runtime/sdk/gl/Trigger.ts +50 -46
- package/runtime/sdk/gl/Vehicle.ts +519 -0
- package/runtime/sdk/gl/{AnimationClip.ts → animation/AnimationClip.ts} +37 -7
- package/runtime/sdk/gl/animation/Animator.ts +87 -0
- package/runtime/sdk/gl/animation/Layer.ts +29 -0
- package/runtime/sdk/gl/animation/Loop.ts +25 -0
- package/runtime/sdk/gl/animation/Playback.ts +43 -0
- package/runtime/sdk/gl/animation/core.ts +294 -0
- package/runtime/sdk/gl/scenarios.ts +26 -58
- package/runtime/sdk/inject.ts +18 -9
- package/runtime/sdk/runtime/app.ts +13 -0
- package/runtime/sdk/runtime/input.ts +169 -6
- package/runtime/sdk/scene/defineScene.ts +182 -26
- package/runtime/sdk/scene/gizmos.ts +128 -0
- package/runtime/sdk-types.json +1 -1
- package/runtime/sdk/gl/Animator.ts +0 -642
- package/runtime/sdk/gl/ModelAnimation.ts +0 -95
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// are driven with moveTo.
|
|
13
13
|
|
|
14
14
|
import { Aspect } from "../core/Aspect"
|
|
15
|
+
import type { FieldMeta } from "../core/fields"
|
|
15
16
|
import { Vec3, cx, cy, cz, type Vec3Like } from "../math/vec"
|
|
16
17
|
import { nodeRegistry, type Node } from "./Node"
|
|
17
18
|
import { Shape } from "./Shape"
|
|
@@ -48,6 +49,29 @@ export class Physics extends Aspect<"physics", Node> {
|
|
|
48
49
|
motion: MotionType = "dynamic"
|
|
49
50
|
/** Mass in kg for dynamic bodies (default 1). Ignored for static/kinematic. */
|
|
50
51
|
mass = 1
|
|
52
|
+
/**
|
|
53
|
+
* Surface friction: 0 = ice, ~1 = grippy asphalt, and values above 1 are allowed (rubber on
|
|
54
|
+
* tarmac).
|
|
55
|
+
*
|
|
56
|
+
* The engine COMBINES the two touching bodies as `sqrt(a * b)`, so the LOWER value dominates and
|
|
57
|
+
* the floor caps everything standing on it. The default **0.6** is a neutral solid surface (the
|
|
58
|
+
* raw Jolt default of 0.2 is ice by game standards); dry tarmac a car should corner on wants a
|
|
59
|
+
* `1`, ice `0.02`. A Vehicle's tires read the GROUND body's value, so this is the single number
|
|
60
|
+
* that decides how well a car corners.
|
|
61
|
+
*
|
|
62
|
+
* Change it at runtime by re-configuring — `floor.aspect(Physics, { friction: 0.02 })` (an ice
|
|
63
|
+
* patch). It is a PLAIN FIELD on purpose: an accessor pair would be tree-shaken out of the
|
|
64
|
+
* bundle, because passing `{ friction }` in a config object is not a member reference the
|
|
65
|
+
* bundler can see, and the write would then silently land on a dead property.
|
|
66
|
+
*/
|
|
67
|
+
friction = 0.6
|
|
68
|
+
|
|
69
|
+
/** Scene-editor inspector: `motion` as a dropdown (a string default alone infers a text box). */
|
|
70
|
+
static fields: FieldMeta<Physics> = {
|
|
71
|
+
motion: { options: [ "static", "kinematic", "dynamic" ] },
|
|
72
|
+
mass: { min: 0, step: 0.1 },
|
|
73
|
+
friction: { min: 0, max: 2, step: 0.05 },
|
|
74
|
+
}
|
|
51
75
|
|
|
52
76
|
private _bodyId = 0
|
|
53
77
|
|
|
@@ -57,14 +81,29 @@ export class Physics extends Aspect<"physics", Node> {
|
|
|
57
81
|
if (!shape) {
|
|
58
82
|
throw new Error("Physics requires a Shape aspect — add it first: node.aspect(Shape, {…}).aspect(Physics, {…})")
|
|
59
83
|
}
|
|
84
|
+
if (this.motion === "dynamic" && shape._isTriangleMesh) {
|
|
85
|
+
throw new Error("Physics: a dynamic body cannot use Shape { mesh: true } (triangle meshes are static/kinematic only) — use { mesh: 'convex' } or a primitive shape")
|
|
86
|
+
}
|
|
60
87
|
const shapeId = shape._claim() // drop the pick-only body; reuse its shape
|
|
61
88
|
this._bodyId = _creator.physicsCreateBody(this.node.id, shapeId, MOTION[this.motion], this.mass, false, false)
|
|
89
|
+
this._applyFriction()
|
|
62
90
|
shape._ownBody(this._bodyId)
|
|
63
91
|
}
|
|
64
92
|
|
|
65
93
|
onDetach(): void {
|
|
66
94
|
if (this._bodyId) { _creator.physicsRemoveBody(this._bodyId); this._bodyId = 0 }
|
|
67
|
-
this.node.get(Shape)
|
|
95
|
+
const shape = this.node.get(Shape)
|
|
96
|
+
if (shape) {
|
|
97
|
+
shape._ownBody(0) // the Shape held OUR body id — forget it, or its own detach removes it twice (native crash)
|
|
98
|
+
shape._recreatePickBody() // keep the node pickable if the Shape stays
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Re-configuring (`node.aspect(Physics, { friction })`) pushes the new surface to the live body. */
|
|
103
|
+
onReconfigure(): void { this._applyFriction() }
|
|
104
|
+
|
|
105
|
+
private _applyFriction(): void {
|
|
106
|
+
if (this._bodyId) _creator.physicsSetFriction?.(this._bodyId, this.friction)
|
|
68
107
|
}
|
|
69
108
|
|
|
70
109
|
/** Native Jolt body id. 0 until attached, or if the build has no physics support. */
|
|
@@ -86,6 +125,19 @@ export class Physics extends Aspect<"physics", Node> {
|
|
|
86
125
|
return this
|
|
87
126
|
}
|
|
88
127
|
|
|
128
|
+
/** The same impulse applied at a WORLD-SPACE point instead of the centre of mass: the lever arm
|
|
129
|
+
* becomes angular impulse, so the body spins as well as moves (a bullet hitting a crate off
|
|
130
|
+
* centre, a blast lifting it by its base). Falls back to the central impulse on an older host. */
|
|
131
|
+
applyImpulseAt(v: Vec3Like, point: Vec3Like): this {
|
|
132
|
+
if (!this._bodyId) return this
|
|
133
|
+
if (_creator.physicsApplyImpulseAt) {
|
|
134
|
+
_creator.physicsApplyImpulseAt(this._bodyId, cx(v), cy(v), cz(v), cx(point), cy(point), cz(point))
|
|
135
|
+
} else {
|
|
136
|
+
_creator.physicsApplyImpulse(this._bodyId, cx(v), cy(v), cz(v))
|
|
137
|
+
}
|
|
138
|
+
return this
|
|
139
|
+
}
|
|
140
|
+
|
|
89
141
|
/** Teleport / drive a kinematic (or dynamic) body to a world position. */
|
|
90
142
|
moveTo(p: Vec3Like): this {
|
|
91
143
|
if (this._bodyId) _creator.physicsSetBodyPosition(this._bodyId, cx(p), cy(p), cz(p))
|