Skip to content

Commit 2969e12

Browse files
authored
Merge pull request #152 from dli7319/ballpit
Ballpit: Create and destroy rigidbodies as needed.
2 parents 8402a0b + 899e557 commit 2969e12

File tree

1 file changed

+43
-32
lines changed

1 file changed

+43
-32
lines changed

demos/ballpit/BallShooter.js

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@ export class BallShooter extends xb.Script {
2626
this.spheres.push(sphere);
2727
}
2828

29-
const matrix = new THREE.Matrix4();
3029
for (let i = 0; i < this.spheres.length; i++) {
3130
const x = Math.random() * 2 - 2;
3231
const y = Math.random() * 2;
3332
const z = Math.random() * 2 - 2;
3433

35-
matrix.setPosition(x, y, z);
3634
this.spheres[i].position.set(x, y, z);
3735
if (palette != null) {
3836
this.spheres[i].material.color.copy(palette.getRandomLiteGColor());
@@ -69,20 +67,10 @@ export class BallShooter extends xb.Script {
6967
colliderActiveEvents = 0,
7068
continuousCollisionDetection = false,
7169
}) {
72-
for (let i = 0; i < this.spheres.length; ++i) {
73-
const position = this.spheres[i].position;
74-
const desc = RAPIER.RigidBodyDesc.dynamic()
75-
.setTranslation(...position)
76-
.setCcdEnabled(continuousCollisionDetection);
77-
const body = blendedWorld.createRigidBody(desc);
78-
const shape = RAPIER.ColliderDesc.ball(
79-
this.spheres[i].geometry.parameters.radius
80-
).setActiveEvents(colliderActiveEvents);
81-
const collider = blendedWorld.createCollider(shape, body);
82-
this.colliderHandleToIndex.set(collider.handle, i);
83-
this.rigidBodies.push(body);
84-
this.colliders.push(collider);
85-
}
70+
this.RAPIER = RAPIER;
71+
this.blendedWorld = blendedWorld;
72+
this.colliderActiveEvents = colliderActiveEvents;
73+
this.continuousCollisionDetection = continuousCollisionDetection;
8674
}
8775

8876
/**
@@ -100,23 +88,46 @@ export class BallShooter extends xb.Script {
10088
ball.position.copy(position);
10189
ball.scale.setScalar(1.0);
10290
ball.opacity = 1.0;
103-
if (this.rigidBodies.length > 0) {
104-
const body = this.rigidBodies[this.nextBall];
105-
body.setTranslation(position);
106-
body.setLinvel(velocity);
107-
}
91+
this._createRigidBody(
92+
this.nextBall,
93+
position,
94+
velocity,
95+
ball.geometry.parameters.radius
96+
);
10897
this.spawnTimes[this.nextBall] = now;
10998
this.nextBall = (this.nextBall + 1) % this.spheres.length;
11099
this.add(ball);
111100
}
112101

102+
_createRigidBody(index, position, velocity, radius) {
103+
// Delete existing body if one already exists for this index
104+
if (this.rigidBodies[index] != null) {
105+
const existingBody = this.rigidBodies[index];
106+
this.blendedWorld.removeRigidBody(existingBody);
107+
}
108+
109+
// Create new body
110+
const desc = this.RAPIER.RigidBodyDesc.dynamic()
111+
.setTranslation(position.x, position.y, position.z)
112+
.setLinvel(velocity.x, velocity.y, velocity.z)
113+
.setCcdEnabled(this.continuousCollisionDetection);
114+
const body = this.blendedWorld.createRigidBody(desc);
115+
const shape = this.RAPIER.ColliderDesc.ball(radius).setActiveEvents(
116+
this.colliderActiveEvents
117+
);
118+
const collider = this.blendedWorld.createCollider(shape, body);
119+
this.colliderHandleToIndex.set(collider.handle, index);
120+
this.rigidBodies[index] = body;
121+
this.colliders[index] = collider;
122+
}
123+
113124
physicsStep(now = performance.now()) {
114125
for (let i = 0; i < this.spheres.length; i++) {
115126
const sphere = this.spheres[i];
116127
const body = this.rigidBodies[i];
117128
let spawnTime = this.spawnTimes[i];
118129

119-
if (this.isBallActive(i)) {
130+
if (this.isBallActive(i) && body != null) {
120131
let ballVisibility = 1.0;
121132
const position = sphere.position.copy(body.translation());
122133
// If the ball falls behind the depth then adjust the spawnTime to begin
@@ -165,20 +176,15 @@ export class BallShooter extends xb.Script {
165176
ballVisibility = 1.0 - deflateAmount;
166177
}
167178

168-
body.setTranslation(position);
169179
sphere.material.opacity = ballVisibility;
170180

171181
if (ballVisibility < 0.001) {
172-
sphere.material.opacity = 0.0;
173-
sphere.scale.setScalar(0);
174-
position.set(0.0, -1000.0, 0.0);
175-
body.setTranslation(position);
176182
this.removeBall(i);
183+
} else {
184+
sphere.position.copy(body.translation());
185+
sphere.quaternion.copy(body.rotation());
177186
}
178187
}
179-
180-
sphere.position.copy(body.translation());
181-
sphere.quaternion.copy(body.rotation());
182188
}
183189
}
184190

@@ -188,9 +194,14 @@ export class BallShooter extends xb.Script {
188194

189195
removeBall(index) {
190196
const ball = this.spheres[index];
197+
ball.material.opacity = 0.0;
198+
ball.scale.setScalar(0);
191199
const body = this.rigidBodies[index];
192-
ball.position.set(0.0, -1000.0, 0.0);
193-
body.setTranslation(ball.position);
200+
if (body != null) {
201+
this.blendedWorld.removeRigidBody(body);
202+
this.rigidBodies[index] = null;
203+
this.colliders[index] = null;
204+
}
194205
this.remove(ball);
195206
}
196207

0 commit comments

Comments
 (0)