Skip to content

Commit 6ff21e0

Browse files
RapierPhysics: Add heightfield support. (#30906)
* Add rapier terrain physics example * Add screenshot (same as ammo version) and entry to files.json for physics_rapier_terrain * fix linting error by removing unused variable declaration * Responding to PR feedback Use RapierPhysics instead of direct Rapier in example. Update RapierPhysics with addHeightfield. * Fix CodeQL notice - remove unused function * Update physics_rapier_terrain.html Clean up code style. * Update RapierPhysics.js * Update RapierPhysics.js --------- Co-authored-by: Michael Herzog <[email protected]>
1 parent 92bd89f commit 6ff21e0

File tree

4 files changed

+401
-4
lines changed

4 files changed

+401
-4
lines changed

examples/files.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,9 @@
509509
"physics_rapier_instancing",
510510
"physics_rapier_joints",
511511
"physics_rapier_character_controller",
512-
"physics_rapier_vehicle_controller"
512+
"physics_rapier_vehicle_controller",
513+
"physics_rapier_terrain"
514+
513515
],
514516
"misc": [
515517
"misc_animation_groups",

examples/jsm/physics/RapierPhysics.js

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ function getShape( geometry ) {
3131
} else if ( geometry.type === 'CylinderGeometry' ) {
3232

3333
const radius = parameters.radiusBottom !== undefined ? parameters.radiusBottom : 0.5;
34-
const length = parameters.length !== undefined ? parameters.length : 0.5;
34+
const length = parameters.height !== undefined ? parameters.height : 0.5;
3535

3636
return RAPIER.ColliderDesc.cylinder( length / 2, radius );
3737

3838
} else if ( geometry.type === 'CapsuleGeometry' ) {
3939

4040
const radius = parameters.radius !== undefined ? parameters.radius : 0.5;
41-
const length = parameters.length !== undefined ? parameters.length : 0.5;
41+
const length = parameters.height !== undefined ? parameters.height : 0.5;
4242

4343
return RAPIER.ColliderDesc.capsule( length / 2, radius );
4444

@@ -209,6 +209,24 @@ async function RapierPhysics() {
209209

210210
}
211211

212+
function addHeightfield( mesh, width, depth, heights, scale ) {
213+
214+
const shape = RAPIER.ColliderDesc.heightfield( width, depth, heights, scale );
215+
216+
const bodyDesc = RAPIER.RigidBodyDesc.fixed();
217+
bodyDesc.setTranslation( mesh.position.x, mesh.position.y, mesh.position.z );
218+
bodyDesc.setRotation( mesh.quaternion );
219+
220+
const body = world.createRigidBody( bodyDesc );
221+
world.createCollider( shape, body );
222+
223+
if ( ! mesh.userData.physics ) mesh.userData.physics = {};
224+
mesh.userData.physics.body = body;
225+
226+
return body;
227+
228+
}
229+
212230
//
213231

214232
const clock = new Clock();
@@ -309,7 +327,25 @@ async function RapierPhysics() {
309327
* @param {Vector3} velocity - The new velocity.
310328
* @param {number} [index=0] - If the mesh is instanced, the index represents the instanced ID.
311329
*/
312-
setMeshVelocity: setMeshVelocity
330+
setMeshVelocity: setMeshVelocity,
331+
332+
/**
333+
* Adds a heightfield terrain to the physics simulation.
334+
*
335+
* @method
336+
* @name RapierPhysics#addHeightfield
337+
* @param {Mesh} mesh - The Three.js mesh representing the terrain.
338+
* @param {number} width - The number of vertices along the width (x-axis) of the heightfield.
339+
* @param {number} depth - The number of vertices along the depth (z-axis) of the heightfield.
340+
* @param {Float32Array} heights - Array of height values for each vertex in the heightfield.
341+
* @param {Object} scale - Scale factors for the heightfield dimensions.
342+
* @param {number} scale.x - Scale factor for width.
343+
* @param {number} scale.y - Scale factor for height.
344+
* @param {number} scale.z - Scale factor for depth.
345+
* @returns {RigidBody} The created Rapier rigid body for the heightfield.
346+
*/
347+
addHeightfield: addHeightfield
348+
313349
};
314350

315351
}

0 commit comments

Comments
 (0)