chandlerprall / Physijs

Physics plugin for Three.js
MIT License
2.75k stars 455 forks source link

How do 'applyCentralImpulse' and 'applyImpulse' work? #119

Open juanpscotto opened 10 years ago

juanpscotto commented 10 years ago

Hi, I want to launch a box with a certain angle and velocity, How do 'applyCentralImpulse' and 'applyImpulse' work?, What are the differences between them?. Thanks

chandlerprall commented 10 years ago

applyCentralImpulse is probably what you're looking for. It applies the impulse directly to the box's center of gravity, turning 100% of the impulse into linear velocity. applyImpulse allows you to specify a point in space where the impulse is applied, such as an edge or corner, which will convert the impulse into both linear and angular velocity (so it will move through space and also rotate).

juanpscotto commented 10 years ago

Thanks. I tried to apply it to a box , but the box doesn't move. I saw the jenga example also: Here is my code Mesh.applyCentralImpulse( Vector3 ); instead I pass directly the linearVelocity to the object and that works: Mesh.setLinearVelocity( Vector3 );

chandlerprall commented 10 years ago

If you post your code with applyCentralImpulse I can look into the problem you're having with it. If you're happy using setLinearVeloity feel free to close this issue :)

juanpscotto commented 10 years ago

Ok, I'm happy with the linearVelocity :). But I have another question. How Can I draw the trajectory of a projectile?? Like this example: http://www.physgl.org/index.php/welcome click the projectile motion example and then RUN. How Can I achieve this result?

chandlerprall commented 10 years ago

I would get the object's position every X frames and draw the marker at that location.

juanpscotto commented 10 years ago

I tried this code in the render function, but it only returns the position before the launching, when I launch the projectil the positions don't update any more.

objMesh.geometry.computeBoundingBox();

var boundingBox = objMesh.geometry.boundingBox;

var position = new THREE.Vector3(); position.subVectors( boundingBox.max, boundingBox.min ); position.multiplyScalar( 0.5 ); position.add( boundingBox.min );

position.applyMatrix4( objMesh.matrixWorld );

console.log(position.x + ',' + position.y + ',' + position.z);

brokedRobot commented 10 years ago

You don't need to recompute the bounding box every frame. Can you explain what you are doing with the bounding box min? I don't understand. Seems like you could just use console.log(mesh.position.x + howevermuchoffset, mesh.position.y + offset, mesh.position.z); ...? Are you saying the mesh.position variable doesn't change when the actual mesh's location changes?

Drawing a streak doesn't have much to do with the physics, you can use the scene-graph's positions to create a streak behind any moving object by drawing a particle or extruding a line shape (see http://threejs.org/examples/#webgl_geometry_extrude_shapes ) every frame based on the mesh's current position. Then you connect all those points to form a curve (a series of short lines). All the physics really need to worry about is updating the mesh's position in the scene graph.

ghost commented 8 years ago

If you needed a simple (linear) trajectory, you could do this:

var _ray = new THREE.Ray();

// Draw a ray starting from the mesh to about as as far as the velocity goes
function predictTrajectory(mesh){
  var det = [];
  var vel = mesh.getLinearVelocity();

  det[0] = mesh.position.clone();
  _ray.set(det[0], vel.clone().normalize());
  det[1] = _ray.at(vel.length());

  // Array contains starting point and ending point of line (use it to render trajectory)
  return det;
}

In here, the velocity is used to predict the next position of the specified mesh based on its current position and linear velocity. It uses those informations to draw a line going from the center of the mesh all the way to its next possible position (with only linear velocity counted).

patrickrb commented 8 years ago

I'm having some trouble wrapping my head around applyImpulse and applyForce as well. I'm getting the following error when I try to applyCentralImpulse to my physijs object:

TypeError: _objects[details.id].applyCentralImpulse is not a function

Adding object to scene:

loader.load('assets/models/dice.json',function ( obj ) {
    sixSidedDie = obj.children[0];

    box = new Physijs.BoxMesh(
        new THREE.CubeGeometry( 0.22, 0.22, 0.22 ),
        new THREE.MeshBasicMaterial({ color: 0x888888 })
    );

    box.add(sixSidedDie);
    scene.add( box );
});

Trying to apply impulse:

function rollDie(){
    var force = new THREE.Vector3(0, 100, 0);
    box.applyCentralImpulse(force);

}