@phalanx-engine/physics 0.1.1 → 0.1.2
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
CHANGED
|
@@ -125,7 +125,7 @@ import {
|
|
|
125
125
|
TRANSFORM_COMPONENT_TYPE,
|
|
126
126
|
INTERPOLATION_COMPONENT_TYPE,
|
|
127
127
|
} from '@phalanx-engine/physics';
|
|
128
|
-
import { FP, FPVector3 } from '@phalanx-engine/math';
|
|
128
|
+
import { FP, FPVector3, FPQuaternion } from '@phalanx-engine/math';
|
|
129
129
|
|
|
130
130
|
// Register canonical component type symbols from phalanx-physics
|
|
131
131
|
export const ComponentType = createComponentTypeRegistry({
|
|
@@ -144,7 +144,11 @@ class MovementSystem extends GameSystem {
|
|
|
144
144
|
class RenderSystem extends GameSystem {
|
|
145
145
|
public override update(_dt: number): void {
|
|
146
146
|
const sample = this.physics?.getInterpolatedTransform(entityId);
|
|
147
|
-
if (sample)
|
|
147
|
+
if (sample) {
|
|
148
|
+
mesh.position.set(sample.position.x, sample.position.y, sample.position.z);
|
|
149
|
+
// sample.rotation is a float quaternion { x, y, z, w } — apply it as-is.
|
|
150
|
+
mesh.quaternion.set(sample.rotation.x, sample.rotation.y, sample.rotation.z, sample.rotation.w);
|
|
151
|
+
}
|
|
148
152
|
}
|
|
149
153
|
}
|
|
150
154
|
const movementSystem = new MovementSystem();
|
|
@@ -176,8 +180,9 @@ world.start();
|
|
|
176
180
|
// 4. Add transform, interpolation, and physics body to entities
|
|
177
181
|
declare const entity: { id: number; addComponent(c: unknown): void };
|
|
178
182
|
const fpPosition = FPVector3.FromFloat(0, 0, 0);
|
|
179
|
-
|
|
180
|
-
entity.addComponent(new
|
|
183
|
+
const fpRotation = FPQuaternion.Identity();
|
|
184
|
+
entity.addComponent(new TransformComponent(entity.id, fpPosition, fpRotation));
|
|
185
|
+
entity.addComponent(new InterpolationComponent(fpPosition, fpRotation));
|
|
181
186
|
entity.addComponent(new PhysicsBodyComponent(entity.id, { radius: FP.FromFloat(1.0) }));
|
|
182
187
|
world.entityManager.addEntity(entity as any);
|
|
183
188
|
|
|
@@ -282,7 +287,7 @@ class PhysicsWorld {
|
|
|
282
287
|
|
|
283
288
|
- **`getSystems()`** — Returns both `physicsSystem` (register as tick system) and `interpolationSystem` (register as frame system).
|
|
284
289
|
- **`getEntityPosition(entityId)`** — Fixed-point position for gameplay queries (e.g. ability targeting).
|
|
285
|
-
- **`getInterpolatedTransform(entityId)`** — Interpolated float
|
|
290
|
+
- **`getInterpolatedTransform(entityId)`** — Interpolated float transform for rendering, populated after `InterpolationSystem` runs. Returns an `InterpolatedTransformSample` with `position: { x, y, z }` and `rotation: { x, y, z, w }` — rotation is a float quaternion (slerped between tick samples), apply it directly to a mesh quaternion.
|
|
286
291
|
|
|
287
292
|
- **`applyImpulse(entityId, vx, vz)`** — Set body velocity (replaces, does not accumulate). Re-enables previously ejected bodies.
|
|
288
293
|
- **`isSettled(threshold?)`** — Pure query: `true` when all non-static, non-ignored bodies are below velocity threshold (default from config, falling back to `FP.FromFloat(0.01)`).
|
|
@@ -314,15 +319,18 @@ class TransformComponent extends SoAComponent<typeof TransformSoASchema.definiti
|
|
|
314
319
|
static readonly soaSchema: typeof TransformSoASchema;
|
|
315
320
|
readonly type: symbol; // TRANSFORM_COMPONENT_TYPE
|
|
316
321
|
|
|
317
|
-
constructor(entityId: number, initialPosition?: FPVector3, initialRotation?:
|
|
322
|
+
constructor(entityId: number, initialPosition?: FPVector3, initialRotation?: FPQuaternion);
|
|
318
323
|
|
|
319
|
-
fpPosition: FPVector3;
|
|
320
|
-
fpRotation:
|
|
321
|
-
|
|
324
|
+
fpPosition: FPVector3; // get/set — authoritative fixed-point position
|
|
325
|
+
fpRotation: FPQuaternion; // get/set — authoritative rotation quaternion
|
|
326
|
+
fpRotationEuler: FPVector3; // get/set — computed Euler view (radians, XYZ order)
|
|
327
|
+
fpRotationY: FixedPoint; // get/set — convenience Y-yaw (radians)
|
|
322
328
|
}
|
|
323
329
|
```
|
|
324
330
|
|
|
325
|
-
`
|
|
331
|
+
Rotation is authoritatively a quaternion (`fpRotation`). `fpRotationEuler` (XYZ Euler radians) and `fpRotationY` (yaw) are computed views over it — recomputed on each access, mirroring Unity's `Transform.rotation` / `Transform.eulerAngles`. Setting `fpRotationEuler` calls `FPQuaternion.FromEulerXYZ`; setting `fpRotationY` builds a yaw rotation around `FPVector3.Up`.
|
|
332
|
+
|
|
333
|
+
`TransformSoASchema` fields: `fpPositionX/Y/Z`, `fpRotationX/Y/Z/W` (all `i64`). Rotation defaults to the identity quaternion (`w = 1`).
|
|
326
334
|
|
|
327
335
|
### `InterpolationComponent`
|
|
328
336
|
|
|
@@ -330,10 +338,10 @@ class TransformComponent extends SoAComponent<typeof TransformSoASchema.definiti
|
|
|
330
338
|
class InterpolationComponent implements IComponent {
|
|
331
339
|
readonly type: symbol; // INTERPOLATION_COMPONENT_TYPE
|
|
332
340
|
|
|
333
|
-
constructor(initialPosition?: FPVector3, initialRotation?:
|
|
341
|
+
constructor(initialPosition?: FPVector3, initialRotation?: FPQuaternion);
|
|
334
342
|
|
|
335
343
|
snapshot(): void; // copy current → previous (called by InterpolationSystem before tick)
|
|
336
|
-
capture(fpPosition: FPVector3, fpRotation:
|
|
344
|
+
capture(fpPosition: FPVector3, fpRotation: FPQuaternion): void; // capture authoritative state after tick
|
|
337
345
|
}
|
|
338
346
|
```
|
|
339
347
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransformComponent.d.ts","sourceRoot":"","sources":["../../src/components/TransformComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,SAAS,IAAI,aAAa,EAC/B,KAAK,YAAY,IAAI,gBAAgB,EACtC,MAAM,sBAAsB,CAAC;AAU9B,eAAO,MAAM,kBAAkB;;;;;;;;EAW9B,CAAC;AAMF,eAAO,MAAM,wBAAwB,EAAE,MAA4B,CAAC;AAiBpE,qBAAa,kBAAmB,SAAQ,YAAY,CAAC,OAAO,kBAAkB,CAAC,UAAU,CAAC;IACxF,SAAgB,IAAI,SAA4B;IAChD,gBAAuB,SAAS;;;;;;;;OAAsB;IAEtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmD;IAC/E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgE;gBAG1F,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,aAAa,EAC/B,eAAe,CAAC,EAAE,gBAAgB;IAgBpC,IAAW,UAAU,IAAI,aAAa,CASrC;IAED,IAAW,UAAU,CAAC,KAAK,EAAE,aAAa,EAQzC;IAGD,IAAW,UAAU,IAAI,gBAAgB,CASxC;IAED,IAAW,UAAU,CAAC,KAAK,EAAE,gBAAgB,EAQ5C;IAOD,IAAW,eAAe,IAAI,aAAa,CAE1C;IAED,IAAW,eAAe,CAAC,KAAK,EAAE,aAAa,EAE9C;IAGD,IAAW,WAAW,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"TransformComponent.d.ts","sourceRoot":"","sources":["../../src/components/TransformComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,SAAS,IAAI,aAAa,EAC/B,KAAK,YAAY,IAAI,gBAAgB,EACtC,MAAM,sBAAsB,CAAC;AAU9B,eAAO,MAAM,kBAAkB;;;;;;;;EAW9B,CAAC;AAMF,eAAO,MAAM,wBAAwB,EAAE,MAA4B,CAAC;AAiBpE,qBAAa,kBAAmB,SAAQ,YAAY,CAAC,OAAO,kBAAkB,CAAC,UAAU,CAAC;IACxF,SAAgB,IAAI,SAA4B;IAChD,gBAAuB,SAAS;;;;;;;;OAAsB;IAEtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmD;IAC/E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgE;gBAG1F,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,aAAa,EAC/B,eAAe,CAAC,EAAE,gBAAgB;IAgBpC,IAAW,UAAU,IAAI,aAAa,CASrC;IAED,IAAW,UAAU,CAAC,KAAK,EAAE,aAAa,EAQzC;IAGD,IAAW,UAAU,IAAI,gBAAgB,CASxC;IAED,IAAW,UAAU,CAAC,KAAK,EAAE,gBAAgB,EAQ5C;IAOD,IAAW,eAAe,IAAI,aAAa,CAE1C;IAED,IAAW,eAAe,CAAC,KAAK,EAAE,aAAa,EAE9C;IAGD,IAAW,WAAW,IAAI,UAAU,CAMnC;IAED,IAAW,WAAW,CAAC,KAAK,EAAE,UAAU,EAEvC;CACF"}
|
|
@@ -71,9 +71,13 @@ export class TransformComponent extends SoAComponent {
|
|
|
71
71
|
this.fpRotation = FPQuaternion.FromEulerXYZ(value);
|
|
72
72
|
}
|
|
73
73
|
get fpRotationY() {
|
|
74
|
-
|
|
74
|
+
const q = this.fpRotation;
|
|
75
|
+
const two = FP.FromInt(2);
|
|
76
|
+
const sinY = FP.Mul(two, FP.Add(FP.Mul(q.w, q.y), FP.Mul(q.x, q.z)));
|
|
77
|
+
const cosY = FP.Sub(FP._1, FP.Mul(two, FP.Add(FP.Mul(q.y, q.y), FP.Mul(q.z, q.z))));
|
|
78
|
+
return FP.Atan2(sinY, cosY);
|
|
75
79
|
}
|
|
76
80
|
set fpRotationY(value) {
|
|
77
|
-
this.fpRotation = FPQuaternion.
|
|
81
|
+
this.fpRotation = FPQuaternion.FromYaw(value);
|
|
78
82
|
}
|
|
79
83
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phalanx-engine/physics",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Deterministic fixed-point physics engine for Phalanx Engine - spatial hashing, collision detection, and resolution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"typescript": "~5.9.3",
|
|
20
20
|
"vitest": "^1.0.0",
|
|
21
|
-
"@phalanx-engine/ecs": "0.1.
|
|
22
|
-
"@phalanx-engine/math": "0.1.
|
|
21
|
+
"@phalanx-engine/ecs": "0.1.2",
|
|
22
|
+
"@phalanx-engine/math": "0.1.2"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"physics",
|