Skip to content

Commit 0dc863f

Browse files
committed
feat(rapier): allow data to be a function
1 parent 4bdd280 commit 0dc863f

File tree

6 files changed

+40
-66
lines changed

6 files changed

+40
-66
lines changed

apps/examples/src/app/rapier/cluster/cluster.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
inject,
88
viewChild,
99
} from '@angular/core';
10-
import { injectBeforeRender, NgtArgs } from 'angular-three';
10+
import { checkUpdate, injectBeforeRender, NgtArgs } from 'angular-three';
1111
import { NgtrInstancedRigidBodies, NgtrPhysics } from 'angular-three-rapier';
1212
import { Color, InstancedMesh, Vector3 } from 'three';
1313

@@ -32,12 +32,10 @@ const BALLS = 1000;
3232
})
3333
export default class ClusterExample {
3434
protected readonly BALLS = BALLS;
35-
protected bodies = Array.from({ length: BALLS }, (_, index) => {
36-
return {
37-
key: index,
38-
position: [Math.floor(index / 30), (index % 30) * 0.5, 0] as [number, number, number],
39-
};
40-
});
35+
protected bodies = Array.from({ length: BALLS }, (_, index) => ({
36+
key: index,
37+
position: [Math.floor(index / 30), (index % 30) * 0.5, 0] as [number, number, number],
38+
}));
4139

4240
private rigidBodiesRef = viewChild.required(NgtrInstancedRigidBodies);
4341
private instancedMeshRef = viewChild<ElementRef<InstancedMesh>>('instancedMesh');
@@ -68,7 +66,7 @@ export default class ClusterExample {
6866
for (let i = 0; i < BALLS; i++) {
6967
instancedMesh.setColorAt(i, new Color(Math.random() * 0xffffff));
7068
}
71-
if (instancedMesh.instanceColor) instancedMesh.instanceColor.needsUpdate = true;
69+
checkUpdate(instancedMesh.instanceColor);
7270
});
7371
}
7472
}

apps/examples/src/app/rapier/instanced-mesh/instanced-mesh.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
signal,
88
viewChild,
99
} from '@angular/core';
10-
import { injectStore, NgtArgs, NgtThreeEvent } from 'angular-three';
10+
import { checkUpdate, injectStore, NgtArgs, NgtThreeEvent } from 'angular-three';
1111
import { NgtrInstancedRigidBodies, NgtrInstancedRigidBodyOptions } from 'angular-three-rapier';
1212
import { Color, InstancedMesh } from 'three';
1313
import { injectSuzanne } from '../suzanne';
@@ -29,7 +29,7 @@ const MAX_COUNT = 2000;
2929
#instancedMesh
3030
castShadow
3131
[count]="bodies().length"
32-
(click)="onClick(instancedRigidBodies, $any($event))"
32+
(click)="onClick(instancedRigidBodies, $event)"
3333
>
3434
<ngt-mesh-physical-material />
3535
</ngt-instanced-mesh>
@@ -60,9 +60,7 @@ export default class InstancedMeshExample {
6060
for (let i = 0; i < MAX_COUNT; i++) {
6161
instancedMesh.setColorAt(i, new Color(Math.random() * 0xffffff));
6262
}
63-
if (instancedMesh.instanceColor) {
64-
instancedMesh.instanceColor.needsUpdate = true;
65-
}
63+
checkUpdate(instancedMesh.instanceColor);
6664
});
6765

6866
effect((onCleanup) => {

apps/examples/src/app/rapier/rope-joint/rope-joint.ts

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,4 @@
1-
import {
2-
afterNextRender,
3-
ChangeDetectionStrategy,
4-
Component,
5-
computed,
6-
CUSTOM_ELEMENTS_SCHEMA,
7-
inject,
8-
Injector,
9-
input,
10-
viewChild,
11-
} from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, computed, CUSTOM_ELEMENTS_SCHEMA, input, viewChild } from '@angular/core';
122
import { NgtArgs, NgtVector3 } from 'angular-three';
133
import { injectRopeJoint, NgtrBallCollider, NgtrRigidBody } from 'angular-three-rapier';
144

@@ -96,16 +86,11 @@ export class RopeJoint {
9686
private ballBody = viewChild.required('ball', { read: NgtrRigidBody });
9787

9888
constructor() {
99-
const injector = inject(Injector);
89+
const anchorBody = computed(() => this.anchorBody().rigidBody());
90+
const ballBody = computed(() => this.ballBody().rigidBody());
10091

101-
afterNextRender(() => {
102-
const anchorBody = computed(() => this.anchorBody().rigidBody());
103-
const ballBody = computed(() => this.ballBody().rigidBody());
104-
105-
injectRopeJoint(anchorBody, ballBody, {
106-
injector,
107-
data: { body1Anchor: [0, 0, 0], body2Anchor: [0, 0, 0], length: this.length() },
108-
});
92+
injectRopeJoint(anchorBody, ballBody, {
93+
data: () => ({ body1Anchor: [0, 0, 0], body2Anchor: [0, 0, 0], length: this.length() }),
10994
});
11095
}
11196
}

apps/examples/src/app/rapier/spring/spring.ts

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,4 @@
1-
import {
2-
afterNextRender,
3-
ChangeDetectionStrategy,
4-
Component,
5-
computed,
6-
CUSTOM_ELEMENTS_SCHEMA,
7-
inject,
8-
Injector,
9-
input,
10-
viewChild,
11-
} from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, computed, CUSTOM_ELEMENTS_SCHEMA, input, viewChild } from '@angular/core';
122
import { NgtArgs, NgtVector3, vector3 } from 'angular-three';
133
import { injectSpringJoint, NgtrBallCollider, NgtrRigidBody } from 'angular-three-rapier';
144
import { ColorRepresentation } from 'three';
@@ -64,27 +54,22 @@ export class BallSpring {
6454
private stiffness = 1.0e3;
6555

6656
constructor() {
67-
const injector = inject(Injector);
57+
const floorBody = computed(() => this.floorRigidBody().rigidBody());
58+
const ballBody = computed(() => this.ballBody().rigidBody());
6859

69-
afterNextRender(() => {
70-
const floorBody = computed(() => this.floorRigidBody().rigidBody());
71-
const ballBody = computed(() => this.ballBody().rigidBody());
60+
const criticalDamping = computed(() => 2 * Math.sqrt(this.stiffness * this.mass()));
61+
const dampingRatio = computed(() => this.jointNum() / (this.total() / 2));
62+
const damping = computed(() => dampingRatio() * criticalDamping());
63+
const positionVector = vector3(this.position);
7264

73-
const criticalDamping = computed(() => 2 * Math.sqrt(this.stiffness * this.mass()));
74-
const dampingRatio = computed(() => this.jointNum() / (this.total() / 2));
75-
const damping = computed(() => dampingRatio() * criticalDamping());
76-
const positionVector = vector3(this.position);
77-
78-
injectSpringJoint(ballBody, floorBody, {
79-
injector,
80-
data: {
81-
body1Anchor: [0, 0, 0],
82-
body2Anchor: [positionVector().x, positionVector().y - 3, positionVector().z],
83-
restLength: 0,
84-
stiffness: this.stiffness,
85-
damping: damping(),
86-
},
87-
});
65+
injectSpringJoint(ballBody, floorBody, {
66+
data: () => ({
67+
body1Anchor: [0, 0, 0],
68+
body2Anchor: [positionVector().x, positionVector().y - 3, positionVector().z],
69+
restLength: 0,
70+
stiffness: this.stiffness,
71+
damping: damping(),
72+
}),
8873
});
8974
}
9075
}

apps/examples/src/app/rapier/suzanne.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ type SuzanneGLTF = GLTF & {
66
nodes: { Suzanne: Mesh };
77
};
88

9+
injectGLTF.preload(() => './suzanne.glb');
10+
911
export function injectSuzanne() {
1012
return injectGLTF<SuzanneGLTF>(() => './suzanne.glb');
1113
}

libs/rapier/src/lib/joints.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { computed, effect, ElementRef, inject, Injector } from '@angular/core';
1+
import { computed, effect, ElementRef, inject, Injector, untracked } from '@angular/core';
22
import {
33
FixedImpulseJoint,
44
ImpulseJoint,
@@ -69,15 +69,21 @@ function createJoint<TJointParams, TJoinType extends ImpulseJoint>(
6969
return function _injectJoint(
7070
bodyA: ElementRef<RigidBody> | RigidBody | (() => ElementRef<RigidBody> | RigidBody | undefined | null),
7171
bodyB: ElementRef<RigidBody> | RigidBody | (() => ElementRef<RigidBody> | RigidBody | undefined | null),
72-
{ injector, data }: { injector?: Injector; data: TJointParams },
72+
{ injector, data }: { injector?: Injector; data: TJointParams | (() => TJointParams) },
7373
) {
7474
return assertInjector(_injectJoint, injector, () => {
7575
const physics = inject(NgtrPhysics);
7676

77+
let dataFn = data as () => TJointParams;
78+
79+
if (typeof data !== 'function') {
80+
dataFn = () => data;
81+
}
82+
7783
const jointData = computed(() => {
7884
const rapier = physics.rapier();
7985
if (!rapier) return null;
80-
return jointDataFn(rapier, data);
86+
return jointDataFn(rapier, untracked(dataFn));
8187
});
8288

8389
return injectImpulseJoint<TJoinType>(bodyA, bodyB, { injector, data: jointData });

0 commit comments

Comments
 (0)