I'm trying to draw the trajectory of a projectile motion with threejs. Which is the best way to do that? Here is an example of it: http://www.physgl.org/index.php/welcome/logout Try the projectile motion demo and click run.
I thought of drawing a second mesh that follows the previous movement by obtaining the position of the mesh as it's moving, but that did not work. This is what I tried (this code) to get the position of the object moving:
box.geometry.computeBoundingBox();
var boundingBox = box.geometry.boundingBox;
var position = new THREE.Vector3();
position.subVectors( boundingBox.max, boundingBox.min );
position.multiplyScalar( 0.5 );
position.add( boundingBox.min );
position.applyMatrix4( box.matrixWorld );
console.log(position.x + ',' + position.y + ',' + position.z);
Please Help. Thanks.
There are a few ways to go about tracking a trajectory. Here, I will show you some alternatives to your desired behavior, in addition to its solution.
In your Physijs application, you should have a scene.simulate
call and an event listener when the update has finished, so that you can loop through physics separately from the rendering process. It shouldn't be too hard to add a little extra code to place a marker of some sort every step into your scene, which preferably doesn't contain too many extra vertices (i.e. not too complex):
var markSize = 2; // Tweak this to set marker size
var markGeom = new THREE.BoxGeometry(markSize, markSize, markSize, 1, 1, 1);
var markMat = new THREE.MeshBasicMaterial({color: "blue"});
scene.addEventListener("update", function(){
// Generate a box where projectile was last moved
var marker = new THREE.Mesh(markGeom.clone(), markMat);
marker.position.copy(projectile.position);
// Display position!
scene.add(marker);
// Keep simulation going
scene.simulate(undefined, 2);
});
In this code, projectile
is the variable referencing your projectile Physijs mesh. Note that you shouldn't format this for your rendering loop, as you might be using requestAnimationFrame
, which stops calling your rendering loop when the window (or tab) goes out of focus. It won't be pleasant when some client does that and gets a messed up trajectory. Plus, this tied directly into your Physijs stepping, which makes it extremely precise.
This is probably what you wanted in the first place. It creates an arrow which will show the direction and speed of the projectile:
// Constructor: direction, origin, length, color in hexadecimal
var arrowMark = new THREE.ArrowHelper(
new THREE.Vector3(0, 1, 0), projectile.position, 0, 0x884400);
function drawDir(){
var pvel = projectile.getLinearVelocity();
// Update arrow
arrowMark.position.set(projectile.position);
arrowMark.setDirection(pvel.normalize());
arrowMark.setLength(pvel.length());
}
Yeah, that was kind of easy. Once again, projectile
is referencing your projectile Physijs mesh. Just call drawDir
every render call and you're good to go!
The THREE.ArrowHelper
documentation: ArrowHelper