reze-engine 0.14.0 → 0.15.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.
Files changed (93) hide show
  1. package/README.md +81 -108
  2. package/dist/engine.d.ts +1 -7
  3. package/dist/engine.d.ts.map +1 -1
  4. package/dist/engine.js +4 -7
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -1
  8. package/dist/physics/body.d.ts +30 -0
  9. package/dist/physics/body.d.ts.map +1 -0
  10. package/dist/physics/body.js +215 -0
  11. package/dist/physics/constraint.d.ts +17 -0
  12. package/dist/physics/constraint.d.ts.map +1 -0
  13. package/dist/physics/constraint.js +102 -0
  14. package/dist/physics/contact.d.ts +32 -0
  15. package/dist/physics/contact.d.ts.map +1 -0
  16. package/dist/physics/contact.js +728 -0
  17. package/dist/physics/index.d.ts +4 -0
  18. package/dist/physics/index.d.ts.map +1 -0
  19. package/dist/physics/index.js +3 -0
  20. package/dist/physics/physics.d.ts +31 -0
  21. package/dist/physics/physics.d.ts.map +1 -0
  22. package/dist/physics/physics.js +211 -0
  23. package/dist/physics/solver.d.ts +5 -0
  24. package/dist/physics/solver.d.ts.map +1 -0
  25. package/dist/physics/solver.js +416 -0
  26. package/dist/physics/types.d.ts +46 -0
  27. package/dist/physics/types.d.ts.map +1 -0
  28. package/dist/physics/types.js +12 -0
  29. package/dist/physics/world.d.ts +12 -0
  30. package/dist/physics/world.d.ts.map +1 -0
  31. package/dist/physics/world.js +146 -0
  32. package/dist/physics-debug.d.ts +30 -0
  33. package/dist/physics-debug.d.ts.map +1 -0
  34. package/dist/physics-debug.js +526 -0
  35. package/dist/shaders/materials/hair.d.ts +1 -1
  36. package/dist/shaders/materials/hair.d.ts.map +1 -1
  37. package/dist/shaders/materials/hair.js +2 -2
  38. package/dist/shaders/passes/physics-debug.d.ts +2 -0
  39. package/dist/shaders/passes/physics-debug.d.ts.map +1 -0
  40. package/dist/shaders/passes/physics-debug.js +69 -0
  41. package/package.json +3 -6
  42. package/src/engine.ts +5 -9
  43. package/src/index.ts +1 -1
  44. package/src/physics/body.ts +305 -0
  45. package/src/physics/constraint.ts +151 -0
  46. package/src/physics/contact.ts +983 -0
  47. package/src/physics/index.ts +8 -0
  48. package/src/physics/physics.ts +255 -0
  49. package/src/physics/solver.ts +430 -0
  50. package/src/physics/types.ts +50 -0
  51. package/src/physics/world.ts +152 -0
  52. package/src/shaders/materials/hair.ts +2 -2
  53. package/dist/ammo-loader.d.ts +0 -3
  54. package/dist/ammo-loader.d.ts.map +0 -1
  55. package/dist/ammo-loader.js +0 -26
  56. package/dist/physics.d.ts +0 -86
  57. package/dist/physics.d.ts.map +0 -1
  58. package/dist/physics.js +0 -527
  59. package/dist/shaders/body.d.ts +0 -2
  60. package/dist/shaders/body.d.ts.map +0 -1
  61. package/dist/shaders/body.js +0 -199
  62. package/dist/shaders/classify.d.ts +0 -4
  63. package/dist/shaders/classify.d.ts.map +0 -1
  64. package/dist/shaders/classify.js +0 -12
  65. package/dist/shaders/cloth_rough.d.ts +0 -2
  66. package/dist/shaders/cloth_rough.d.ts.map +0 -1
  67. package/dist/shaders/cloth_rough.js +0 -178
  68. package/dist/shaders/cloth_smooth.d.ts +0 -2
  69. package/dist/shaders/cloth_smooth.d.ts.map +0 -1
  70. package/dist/shaders/cloth_smooth.js +0 -174
  71. package/dist/shaders/default.d.ts +0 -2
  72. package/dist/shaders/default.d.ts.map +0 -1
  73. package/dist/shaders/default.js +0 -171
  74. package/dist/shaders/eye.d.ts +0 -2
  75. package/dist/shaders/eye.d.ts.map +0 -1
  76. package/dist/shaders/eye.js +0 -146
  77. package/dist/shaders/face.d.ts +0 -2
  78. package/dist/shaders/face.d.ts.map +0 -1
  79. package/dist/shaders/face.js +0 -199
  80. package/dist/shaders/hair.d.ts +0 -2
  81. package/dist/shaders/hair.d.ts.map +0 -1
  82. package/dist/shaders/hair.js +0 -176
  83. package/dist/shaders/metal.d.ts +0 -2
  84. package/dist/shaders/metal.d.ts.map +0 -1
  85. package/dist/shaders/metal.js +0 -174
  86. package/dist/shaders/nodes.d.ts +0 -2
  87. package/dist/shaders/nodes.d.ts.map +0 -1
  88. package/dist/shaders/nodes.js +0 -456
  89. package/dist/shaders/stockings.d.ts +0 -2
  90. package/dist/shaders/stockings.d.ts.map +0 -1
  91. package/dist/shaders/stockings.js +0 -244
  92. package/src/ammo-loader.ts +0 -31
  93. package/src/physics.ts +0 -706
@@ -0,0 +1,50 @@
1
+ import { Vec3, Mat4 } from "../math"
2
+
3
+ export enum RigidbodyShape {
4
+ Sphere = 0,
5
+ Box = 1,
6
+ Capsule = 2,
7
+ }
8
+
9
+ export enum RigidbodyType {
10
+ Static = 0,
11
+ Dynamic = 1,
12
+ Kinematic = 2,
13
+ }
14
+
15
+ export interface Rigidbody {
16
+ name: string
17
+ englishName: string
18
+ boneIndex: number
19
+ group: number
20
+ collisionMask: number
21
+ shape: RigidbodyShape
22
+ size: Vec3
23
+ shapePosition: Vec3 // Bind pose world space position from PMX
24
+ shapeRotation: Vec3 // Bind pose world space rotation (Euler angles) from PMX
25
+ mass: number
26
+ linearDamping: number
27
+ angularDamping: number
28
+ restitution: number
29
+ friction: number
30
+ type: RigidbodyType
31
+ bodyOffsetMatrixInverse: Mat4 // Inverse of body offset matrix, used to sync rigidbody to bone
32
+ bodyOffsetMatrix?: Mat4 // Cached non-inverse for performance (computed once during initialization)
33
+ }
34
+
35
+ export interface Joint {
36
+ name: string
37
+ englishName: string
38
+ type: number
39
+ rigidbodyIndexA: number
40
+ rigidbodyIndexB: number
41
+ position: Vec3
42
+ rotation: Vec3 // Euler angles in radians
43
+ positionMin: Vec3
44
+ positionMax: Vec3
45
+ rotationMin: Vec3 // Euler angles in radians
46
+ rotationMax: Vec3 // Euler angles in radians
47
+ springPosition: Vec3
48
+ springRotation: Vec3 // Spring stiffness values
49
+ }
50
+
@@ -0,0 +1,152 @@
1
+ import { Vec3 } from "../math"
2
+ import type { RigidBodyStore } from "./body"
3
+ import { RigidbodyType } from "./types"
4
+ import type { SixDofSpringConstraint } from "./constraint"
5
+ import { solveConstraints } from "./solver"
6
+ import { findContacts, type ContactPool } from "./contact"
7
+
8
+ // World step: predict velocities → collide → solve → position correction →
9
+ // integrate. Static and kinematic bodies are skipped during predict and
10
+ // integrate; the parent class syncs them from bones around the step. The
11
+ // solver pass runs on all bodies — kinematic ones have invMass = 0 and
12
+ // act as anchors.
13
+ export class World {
14
+ readonly gravity: Vec3
15
+ solverIterations = 10
16
+
17
+ constructor(gravity: Vec3) {
18
+ this.gravity = new Vec3(gravity.x, gravity.y, gravity.z)
19
+ }
20
+
21
+ setGravity(g: Vec3): void {
22
+ this.gravity.x = g.x
23
+ this.gravity.y = g.y
24
+ this.gravity.z = g.z
25
+ }
26
+
27
+ step(store: RigidBodyStore, constraints: SixDofSpringConstraint[], contacts: ContactPool, dt: number): void {
28
+ if (dt <= 0) return
29
+
30
+ const N = store.count
31
+ const types = store.type
32
+ const lv = store.linearVelocities
33
+ const av = store.angularVelocities
34
+ const pos = store.positions
35
+ const ori = store.orientations
36
+ const ldamp = store.linearDamping
37
+ const adamp = store.angularDamping
38
+ const invMass = store.invMass
39
+
40
+ const gx = this.gravity.x
41
+ const gy = this.gravity.y
42
+ const gz = this.gravity.z
43
+
44
+ // 1. Predict — gravity + damping. The pow form (vs the linear
45
+ // 1−damping·dt approximation) stays stable at high PMX damping
46
+ // values like 0.99.
47
+ for (let i = 0; i < N; i++) {
48
+ if (types[i] !== RigidbodyType.Dynamic || invMass[i] <= 0) continue
49
+ const i3 = i * 3
50
+ lv[i3 + 0] += gx * dt
51
+ lv[i3 + 1] += gy * dt
52
+ lv[i3 + 2] += gz * dt
53
+ const ld = Math.pow(Math.max(0, 1 - ldamp[i]), dt)
54
+ const ad = Math.pow(Math.max(0, 1 - adamp[i]), dt)
55
+ lv[i3 + 0] *= ld; lv[i3 + 1] *= ld; lv[i3 + 2] *= ld
56
+ av[i3 + 0] *= ad; av[i3 + 1] *= ad; av[i3 + 2] *= ad
57
+ }
58
+
59
+ // 2. Collide.
60
+ contacts.reset()
61
+ findContacts(store, contacts)
62
+
63
+ // 3. Solve joint + contact constraints (velocity-only).
64
+ if (constraints.length > 0 || contacts.count > 0) {
65
+ solveConstraints(store, constraints, contacts, dt, this.solverIterations)
66
+ }
67
+
68
+ // 4. Position correction (split impulse). Direct translation along the
69
+ // contact normal — joint constraints in the same SI loop can't undo
70
+ // it because it doesn't go through the velocity channel. Inverse-mass
71
+ // weighted so a kinematic body stays put and only the dynamic one
72
+ // translates.
73
+ const POS_CORRECTION_FACTOR = 0.4
74
+ const POS_SLOP = 0.005
75
+ for (let ci = 0; ci < contacts.count; ci++) {
76
+ const c = contacts.get(ci)
77
+ if (c.depth <= POS_SLOP) continue
78
+ const imA = invMass[c.bodyA]
79
+ const imB = invMass[c.bodyB]
80
+ const total = imA + imB
81
+ if (total <= 0) continue
82
+ const correction = (c.depth - POS_SLOP) * POS_CORRECTION_FACTOR
83
+ const dx = correction * c.nx
84
+ const dy = correction * c.ny
85
+ const dz = correction * c.nz
86
+ const ai = c.bodyA * 3
87
+ const bi = c.bodyB * 3
88
+ if (imA > 0) {
89
+ const fA = imA / total
90
+ pos[ai + 0] -= dx * fA
91
+ pos[ai + 1] -= dy * fA
92
+ pos[ai + 2] -= dz * fA
93
+ }
94
+ if (imB > 0) {
95
+ const fB = imB / total
96
+ pos[bi + 0] += dx * fB
97
+ pos[bi + 1] += dy * fB
98
+ pos[bi + 2] += dz * fB
99
+ }
100
+ }
101
+
102
+ // 5. Integrate. Cap angular velocity at π/2 per step — a high-impulse
103
+ // contact spike on a low-inertia body would otherwise spin past π
104
+ // in one step and trash the quaternion integration.
105
+ const MAX_ANGVEL_DT = Math.PI * 0.5
106
+ for (let i = 0; i < N; i++) {
107
+ if (types[i] !== RigidbodyType.Dynamic || invMass[i] <= 0) continue
108
+ const i3 = i * 3
109
+ const i4 = i * 4
110
+
111
+ pos[i3 + 0] += lv[i3 + 0] * dt
112
+ pos[i3 + 1] += lv[i3 + 1] * dt
113
+ pos[i3 + 2] += lv[i3 + 2] * dt
114
+
115
+ let wx = av[i3 + 0]
116
+ let wy = av[i3 + 1]
117
+ let wz = av[i3 + 2]
118
+ const wmag = Math.sqrt(wx * wx + wy * wy + wz * wz)
119
+ if (wmag * dt > MAX_ANGVEL_DT) {
120
+ const scale = MAX_ANGVEL_DT / (wmag * dt)
121
+ wx *= scale; wy *= scale; wz *= scale
122
+ av[i3 + 0] = wx; av[i3 + 1] = wy; av[i3 + 2] = wz
123
+ }
124
+ if (wx !== 0 || wy !== 0 || wz !== 0) {
125
+ const qx = ori[i4 + 0]
126
+ const qy = ori[i4 + 1]
127
+ const qz = ori[i4 + 2]
128
+ const qw = ori[i4 + 3]
129
+
130
+ const dx = qw * wx + wy * qz - wz * qy
131
+ const dy = qw * wy + wz * qx - wx * qz
132
+ const dz = qw * wz + wx * qy - wy * qx
133
+ const dw = -(wx * qx + wy * qy + wz * qz)
134
+
135
+ const half = 0.5 * dt
136
+ const nx = qx + dx * half
137
+ const ny = qy + dy * half
138
+ const nz = qz + dz * half
139
+ const nw = qw + dw * half
140
+
141
+ const len2 = nx * nx + ny * ny + nz * nz + nw * nw
142
+ if (len2 > 0) {
143
+ const inv = 1 / Math.sqrt(len2)
144
+ ori[i4 + 0] = nx * inv
145
+ ori[i4 + 1] = ny * inv
146
+ ori[i4 + 2] = nz * inv
147
+ ori[i4 + 3] = nw * inv
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
@@ -11,7 +11,7 @@ ${COMMON_MATERIAL_PRELUDE_WGSL}
11
11
 
12
12
  // Pipeline-override: the engine compiles two variants — the normal opaque hair pipeline
13
13
  // (IS_OVER_EYES=false) and a second pipeline that re-draws hair fragments stencil-matched
14
- // against the eye stamp with 50% alpha so eyes read through the hair silhouette. Resolved
14
+ // against the eye stamp with 25% alpha so eyes read through the hair silhouette. Resolved
15
15
  // at pipeline-compile time; the dead branch is dropped by the shader compiler.
16
16
  override IS_OVER_EYES: bool = false;
17
17
 
@@ -71,7 +71,7 @@ const HAIR_MIX_NPR: f32 = 0.2;
71
71
  let final_color = mix(npr_stack, principled, HAIR_MIX_NPR);
72
72
 
73
73
  var outAlpha = alpha;
74
- if (IS_OVER_EYES) { outAlpha = alpha * 0.5; }
74
+ if (IS_OVER_EYES) { outAlpha = alpha * 0.25; }
75
75
 
76
76
  var out: FSOut;
77
77
  out.color = vec4f(final_color, outAlpha);
@@ -1,3 +0,0 @@
1
- import type { AmmoInstance } from "@fred3d/ammo";
2
- export declare function loadAmmo(): Promise<AmmoInstance>;
3
- //# sourceMappingURL=ammo-loader.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ammo-loader.d.ts","sourceRoot":"","sources":["../src/ammo-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAKhD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,CAyBtD"}
@@ -1,26 +0,0 @@
1
- let ammoInstance = null;
2
- let ammoPromise = null;
3
- export async function loadAmmo() {
4
- // Return cached instance if available
5
- if (ammoInstance) {
6
- return ammoInstance;
7
- }
8
- // Return existing promise if already loading
9
- if (ammoPromise) {
10
- return ammoPromise;
11
- }
12
- // Start loading Ammo
13
- ammoPromise = (async () => {
14
- try {
15
- const { Ammo } = await import("@fred3d/ammo");
16
- ammoInstance = await Ammo();
17
- return ammoInstance;
18
- }
19
- catch (error) {
20
- console.error("[Ammo] Failed to load:", error);
21
- ammoPromise = null; // Reset promise so it can be retried
22
- throw error;
23
- }
24
- })();
25
- return ammoPromise;
26
- }
package/dist/physics.d.ts DELETED
@@ -1,86 +0,0 @@
1
- import { Quat, Vec3, Mat4 } from "./math";
2
- export declare enum RigidbodyShape {
3
- Sphere = 0,
4
- Box = 1,
5
- Capsule = 2
6
- }
7
- export declare enum RigidbodyType {
8
- Static = 0,
9
- Dynamic = 1,
10
- Kinematic = 2
11
- }
12
- export interface Rigidbody {
13
- name: string;
14
- englishName: string;
15
- boneIndex: number;
16
- group: number;
17
- collisionMask: number;
18
- shape: RigidbodyShape;
19
- size: Vec3;
20
- shapePosition: Vec3;
21
- shapeRotation: Vec3;
22
- mass: number;
23
- linearDamping: number;
24
- angularDamping: number;
25
- restitution: number;
26
- friction: number;
27
- type: RigidbodyType;
28
- bodyOffsetMatrixInverse: Mat4;
29
- bodyOffsetMatrix?: Mat4;
30
- }
31
- export interface Joint {
32
- name: string;
33
- englishName: string;
34
- type: number;
35
- rigidbodyIndexA: number;
36
- rigidbodyIndexB: number;
37
- position: Vec3;
38
- rotation: Vec3;
39
- positionMin: Vec3;
40
- positionMax: Vec3;
41
- rotationMin: Vec3;
42
- rotationMax: Vec3;
43
- springPosition: Vec3;
44
- springRotation: Vec3;
45
- }
46
- export interface PhysicsOptions {
47
- constraintSolverKeywords?: string[];
48
- }
49
- export declare class Physics {
50
- private rigidbodies;
51
- private joints;
52
- private gravity;
53
- private constraintSolverPattern;
54
- private ammoInitialized;
55
- private ammoPromise;
56
- private ammo;
57
- private dynamicsWorld;
58
- private ammoRigidbodies;
59
- private ammoConstraints;
60
- private rigidbodiesInitialized;
61
- private jointsCreated;
62
- private firstFrame;
63
- private zeroVector;
64
- constructor(rigidbodies: Rigidbody[], joints?: Joint[], options?: PhysicsOptions);
65
- private initAmmo;
66
- setGravity(gravity: Vec3): void;
67
- getGravity(): Vec3;
68
- getRigidbodies(): Rigidbody[];
69
- getJoints(): Joint[];
70
- getRigidbodyTransforms(): Array<{
71
- position: Vec3;
72
- rotation: Quat;
73
- }>;
74
- private createAmmoWorld;
75
- private createAmmoRigidbodies;
76
- private createAmmoJoints;
77
- private normalizeAngle;
78
- reset(boneWorldMatrices: Mat4[]): void;
79
- step(dt: number, boneWorldMatrices: Mat4[], boneInverseBindMatrices: Float32Array): void;
80
- private computeBodyOffsets;
81
- private positionBodiesFromBones;
82
- private syncFromBones;
83
- private stepAmmoPhysics;
84
- private applyAmmoRigidbodiesToBones;
85
- }
86
- //# sourceMappingURL=physics.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"physics.d.ts","sourceRoot":"","sources":["../src/physics.ts"],"names":[],"mappings":"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"}