// Create a set of bodies that are to be removed.
Set<RigidBody> bodiesToBeRemoved = new HashSet<RigidBody>();
// For every physics ball ...
for (RigidBody body : balls) {
// Retrieve the ball's position from the JBullet body object.
Vector3f position = body.getMotionState().getWorldTransform(new Transform()).origin;
// If the ball is non-controllable and it is outside the world borders, add it to the set of bodies
// that are to be removed.
if (!body.equals(controlBall) && (position.x < -50 || position.x > 50 || position.z < -50 || position.z > 50)) {
bodiesToBeRemoved.add(body);
}
}
// For every physics ball that is to be removed ...
for (RigidBody body : bodiesToBeRemoved) {
// Remove it from the JBullet world.
dynamicsWorld.removeRigidBody(body);
// Remove it from the list of balls.
balls.remove(body);
}
// If the attraction between the green ball and the camera is enabled ...
if (applyForce) {
// Retrieve the controllable ball's location.
Transform controlBallTransform = new Transform();
controlBall.getMotionState().getWorldTransform(controlBallTransform);
Vector3f controlBallLocation = controlBallTransform.origin;
Vector3f cameraPosition = new Vector3f(camera.x(), camera.y(), camera.z());
// Calculate the force that is applied to the controllable ball as following:
// force = cameraPosition - controlBallLocation
Vector3f force = new Vector3f();
force.sub(cameraPosition, controlBallLocation);
// Wake the controllable ball if it is sleeping.
controlBall.activate(true);
// Apply the force to the controllable ball.
controlBall.applyCentralForce(force);
}
// If a new shape should be created ...
if (createNewShape) {
// Create the collision shape (sphere with radius of 3 metres).
CollisionShape shape = new SphereShape(3);
// Create the motion state (x and z are the same as the camera's).
DefaultMotionState motionState = new DefaultMotionState(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(camera.x(), 35, camera.z()), 1.0f)));
// Calculate the inertia (resistance to movement) using the ball's mass of 1 kilogram.
Vector3f inertia = new Vector3f(0, 0, 0);
shape.calculateLocalInertia(1.0f, inertia);
RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(1, motionState, shape, inertia);
constructionInfo.restitution = 0.75f;
RigidBody rigidBody = new RigidBody(constructionInfo);
balls.add(rigidBody);
dynamicsWorld.addRigidBody(rigidBody);
createNewShape = false;
}
// If the controllable ball's position and orientation should be reset ...
if (resetControlBall) {
// Set the position of the ball to (0, 50, 0).
controlBall.setCenterOfMassTransform(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, 50, 0), 1.0f)));
// Reset the angular velocity (spinning movement) of the ball.
controlBall.setAngularVelocity(new Vector3f(0, 0, 0));
// Reset the linear velocity (x,y,z movement) of the ball.
controlBall.setLinearVelocity(new Vector3f(0, 0, 0));
resetControlBall = false;
}
}