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