I haven't had any experience with physi.js; I usually use cannon.js for physics. However, I do have some knowledge about physics. I can explain how it's done, although I don't have an example ready at the moment. To begin, you need to cast a ray from the camera to the dice to determine if the object is clicked on. Then, you apply a force to the location where the object is clicked. I hope this information is helpful.
EDIT/Follow up:
Upon reviewing physi.js, I noticed that it bears a resemblance to cannon.js. There are various facets to your query, but I'll strive to provide a comprehensive explanation.
The initial step involves setting the gravity. In the examples, this is achieved as follows:
var scene = new Physijs.Scene({ fixedTimeStep: 1 / 120 });
scene.setGravity(new THREE.Vector3( 0, -30, 0 ));
Next, you need to define the plane on which the dice rests as a rigid body, as well as the dice itself.
var dice = new Physijs.BoxMesh(
new THREE.CubeGeometry(5, 5, 5), //the collision geometry
new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture('images/dicetexture.jpg' )});, // material of the dice
5, // mass, use 0 for the plane to indicate it doesn't move
{ restitution: .2, friction: .8 } //contact material
);
Lastly, you must apply a force. Although I couldn't locate an example immediately, a quick perusal of the source code revealed:
// Physijs.Mesh.applyForce
Physijs.Mesh.prototype.applyForce = function ( force, offset ) {
if ( this.world ) {
this.world.execute( 'applyForce', { id: this._physijs.id, force_x: force.x, force_y : force.y, force_z : force.z, x: offset.x, y: offset.y, z: offset.z } );
}
};
Both force
and offset
should be vectors, with force
denoting the direction and magnitude, and offset
indicating the origin point.
I intend to conduct further experimentation with physi.js as it appears to have resolved certain issues I've been contemplating. If the problem persists, I'll provide an example.
Regarding allowing it to rotate a specific number of times at a predetermined height, that may necessitate extensive tinkering with the values...
EDIT 2:
In the fiddle you shared, the issue you described pertained to an undefined variable, effect
.
if (intersects.length > 0) {
intersects[ 0 ].applyImpulse(effect, offset);
}
Modify this to:
if (intersects.length > 0) {
var effect = new THREE.Vector3( 0, 100, 0 );
var offset = new THREE.Vector3( 0, 0, 0 );
intersects[ 0 ].object.applyImpulse(effect, offset);
}
While the values are indeed defined, they are defined within a different function.
function apply_force(){
var effect = new THREE.Vector3( 0, 100, 0 );
var offset = new THREE.Vector3( 0, 0, 0 );
object.applyImpulse( effect, offset );
}
Since this function is no longer utilized, you may consider removing it.
CLICK TIMER:
if(canClick == true){
//process click
canClick = false;
setTimeout(function(){canClick = true}, 5000)//5 seconds before the user can click again.
}