Up today, would like to get the river in my Three.js / Physijs rafting simulation to push the raft. Last night, I tried to accomplish this with Physijs events, but was thwarted in my efforts. Having considered it some, I believe that an events-based approach would not be an appropriate solution, even had I been successful.
So tonight, I give another approach a shot: Three.js rays. The idea here is that on every
animation()
step, I ask if a ray from the raft pointing straight down impacts a river segment. It should always do so (because the river banks should bound the raft) and I should then be able to query the segment for its rotation so that I can apply a force in the appropriate direction.I collect the active river segments in a
river_segments
array. Then, in the animate()
function, I call to a function that will use those segments to see where the raft is:function animate() { requestAnimationFrame(animate); applyRiverCurrent(); scene.simulate(); // run physics render(); }In
applyRiverCurrent()
, I create a ray from the raft down. Then I check to see which active river segment that ray passes through:function applyRiverCurrent() { var ray = new THREE.Ray( raft.position, new THREE.Vector3(0, -1, 0) ); var intersects = ray.intersectObjects(river_segments); console.log(intersects); // raft.applyCentralForce(new THREE.Vector3(1e8 * c, 0, 1e8 * s)); }Once I verify that I am, in fact, seeing the correct river segments in the
console.log()
output, I apply a force in the appropriate direction:function applyRiverCurrent() { var ray = new THREE.Ray( raft.position, new THREE.Vector3(0, -1, 0) ); var intersects = ray.intersectObjects(river_segments); if (!intersects[0]) return; var current_segment = intersects[0].object; if (!current_segment) return; var angle = -current_segment.rotation.y , cos = Math.cos(angle) , sine = Math.sin(angle); raft.applyCentralForce( new THREE.Vector3(1e6 * cos, 0, 1e6 * sine) ); }And oooh! I think that does the trick. When I first start off on my journey, the river current pushes me straight down the river, even though the first segment is rotated:
Momentum carries me into the bank of the second river segment, but it is a Physijs bank, so I bounce off. At this point, the downward current also kicks in, carrying me further downstream.
There is still room for clean-up here. Applying current seems a bit CPU intensive, so I might modulo the application of the river current to some number of clock cycles. Still, it works and it feels like a pretty decent approach, which makes this a good stopping point for today.
Day #489
No comments:
Post a Comment