I've been struggling to figure out how to lock two sibling meshes in a scene, so that when I rotate them their relationship to each other remains fixed.
I know this can be done using a dummy Object3D or by adding one object to the other, but I need to use Physijs, and want both meshes to respond to collisions and other physics in the scene.
This is a simplified example, but I would love to know how to get the upper sphere/cylinder pair to behave exactly like the lower pair in the following code (the lower pair have a parent/child relationship, while the upper meshes are both added directly to the scene):
$(document).ready
(
function()
{
var renderer,scene,camera,globe,globe2,disc,disc2,params;
params = { rotation: {x:0,y:0,z:0}};
var init = function()
{
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 100;
scene.add(camera);
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// create a mesh with models geometry and material
globe = new THREE.Mesh(new THREE.SphereGeometry(5, 32, 32), new THREE.MeshNormalMaterial({color: 0xff3300,transparent:false, opacity: 1}));
THREE.GeometryUtils.center( globe.geometry );
scene.add(globe);
disc = new THREE.Mesh(new THREE.CylinderGeometry( 5, 5, 1, 32), new THREE.MeshNormalMaterial());
disc.position.y = 5;
scene.add(disc);
globe2 = new THREE.Mesh(new THREE.SphereGeometry(5, 32, 32), new THREE.MeshNormalMaterial({color: 0xff3300,transparent:false, opacity: 1}));
THREE.GeometryUtils.center( globe2.geometry );
globe2.position.y = -20;
scene.add(globe2);
disc2 = new THREE.Mesh(new THREE.CylinderGeometry( 5, 5, 1, 32), new THREE.MeshNormalMaterial());
disc2.position.y = 5;
globe2.add(disc2);
controls = new dat.GUI();
controls.add( params.rotation, 'x', -180, 180 );
controls.add( params.rotation, 'y', -180, 180 );
controls.add( params.rotation, 'z', -180, 180 );
//controls.close();
}
var rotateAroundWorldAxis = function( object, axis, radians )
{
rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
rotWorldMatrix.multiplySelf(object.matrix);
object.matrix = rotWorldMatrix;
object.rotation.setEulerFromRotationMatrix(object.matrix, object.order);
}
var animate = function()
{
requestAnimationFrame(render);
render();
}
var render = function()
{
requestAnimationFrame(render);
globe.rotation.set( params.rotation.x*Math.PI/180,params.rotation.y*Math.PI/180,params.rotation.z*Math.PI/180)
disc.rotation.copy(globe.rotation);
globe2.rotation.set( params.rotation.x*Math.PI/180,params.rotation.y*Math.PI/180,params.rotation.z*Math.PI/180)
renderer.render(scene,camera);
}
init();
animate();
}
);
Fiddle here: http://jsfiddle.net/lostnation/9pd0kpwo/30/
Unfortunatly, when adding compound meshes (parent/child relationship meshes) to a scene, their children are finalized and can't be changed after (Physijs). This surely must be the same thing in THREE.
Do you know about Physijs
__dirtyRotation
? You have to set this flag totrue
before you can change any actual Physijs mesh rotation. Using the same algorithm, you can do the same thing as if you were only using THREE. Just make sure the shapes are not added to each other.