Webgl three.js Dependency of several objects - javascript

I have a problem with the dependency of objects. I want to make one object dependent on two other objects. If I change the position of one parent object (for example the y-Position), the dependent object (the child object) should rotate und should also move.
Here is a link where I realized it on a picture. On the left side is the initial state, on the right side the changed condition. The Cylinder should be dependent on the two boxes. That means that the cylinder is the child object and the boxes should be both parent objects of this child object.
I tried it with using parent and child properties, but I could not make the child object dependent on two parent objects.
Can someone help me?
This is my current code, but the lookAt Function does not work correctly.
//cube 1
var cube=new THREE.BoxGeometry(4,4,4);
var material=new THREE.MeshBasicMaterial ({ color: 0xffffff });
mesh1=new THREE.Mesh(cube,material);
mesh1.position.set(-2,2,0);
scene.add(mesh1);
//cube 2
var cube2=new THREE.BoxGeometry(2,2,2);
var material=new THREE.MeshBasicMaterial ({ color:0x000000 });
mesh2=new THREE.Mesh(cube2,material);
mesh2.position.x=6;
mesh2.position.y=2;
//mesh2.position.y=-2;
scene.add(mesh2);
//cylinder
var cylinder=new THREE.CylinderGeometry(1,1,6,30);
var material=new THREE.MeshBasicMaterial({ color:0xff3399 });
mesh3=new THREE.Mesh(cylinder,material);
mesh1.add(mesh3);
mesh3.lookAt(mesh2.position);

You need to two levels of hierarchy, eg:
cube1.add(cylinder)
cylinder.add(cube2)

Yeah, 2pha is right actually. I think what he actually needs is something like this (note you'll need to scale the cylinder or move the squares unless they are exactly cylinder height apart):
cylinder.position.x=cube1.position.x
cylinder.position.y=cube1.position.y
cylinder.position.z=cube1.position.z
cylinder.lookAt(cube2.position)

You may be able to do what you're after with the lookAt function on the Object3D class.
eg.
Add your cylinder as a child of cube1 so moving cube1 will also move the cylinder.
cube1.add(cylinder)
then when cube1 (or / and cube2) is moved call the lookAt function on cylinder to look at the cube2's position.
cylinder.lookAt(cube2.position)

Related

Three.js: how to force update matrix after cloning? (to use with CSG ThreeBSP)

I'm trying to clone and then scale a mesh, but scaling does not seem to be working immediately on the cloned object, for programming purposes using CSG ThreeBSP. I think I should call a function after the scaling to force the matrix or other internal variables to recalculate immediately and not to wait for the full update loop on render side.
My code looks something like this:
var someMesh2 = someMesh1.clone();
someMesh2.scale.set(2,2,2);
someProgrammingOperation(someMesh2);
//It turns out that internally, someMesh2 still has the same properties (matrix?) as someMesh1 :(
What am I missing? Suggestions are also welcomed :)
object.matrix is updated for you by the renderer whenever you call renderer.render().
If you need to update the object matrix manually, call
object.updateMatrix();
and it will update the matrix from the current values of object.position, object.quaternion, and object.scale.
(Note that object.rotation and object.quaternion remain synchronized. When you update one, the other updates automatically.)
three.js r.84
In the end, my problem was that the CSG ThreeBSP object needed to work based on the Geometry of the object, not in the Mesh itself. I applied the scaling on the Geometry and it worked as expected.
There is a caveat though, that one should be careful as with the meshes and geometries instances, therefore is needed to do some cloning in order to keep the original objects as they were, as in the following example:
var clonedMesh = original.mesh.clone()
var clonedGeometry = clonedMesh.geometry.clone()
clonedMesh.geometry = clonedGeometry
clonedMesh.geometry.scale(2,2,2)
var someBsp = new ThreeBSP( clonedMesh )
var newMesh = someBspBsp.toMesh()
someScene.add newMesh

three.js "exploding" an object in predefined pieces

This is a sort of a follow up question of my last problem. I want to explode (technical drawing style) an imported .obj geometry which contains n .obj parts.
For example a table as object, each part is one .obj, four legs and a table top.
5 files. loading them is no problem. Now each objects position is 0,0,0 that means I need to get the world position of them, which I did with this function:
function absPos( myMesh ) {
myMesh.geometry.computeBoundingBox();
var boundingBox = myMesh.geometry.boundingBox;
var position = new THREE.Vector3();
position.subVectors( boundingBox.max, boundingBox.min );
position.multiplyScalar( 0.5 );
position.add( boundingBox.min );
position.applyMatrix4( myMesh.matrixWorld );
var abspos = {x:position.x,y:position.y,z:position.z};
return abspos;
}
now I did assume that setting the object´s position to their world positions would just happen to move them to another world position but keep their relation but that is not the case. So I cannot just use the objects world position and use it to translate the objects until I mess with the world position?
As the objects position is 0,0,0 they don´t have a relation to each other and I cannot just multiply the values to "explode" the geometry.
Is there any chance to achieve this without messing with the world positions?

Three.js - How do I use the BoxHelper on an Object3D with children?

I'd like to use the THREE.BoxHelper to create a bounding box for an Object3D that has children. The motivation is so that I can render a wireframe bounding box for the object, without diagonals on the box's faces. Looking at the source code for BoxHelper, it looks like it doesn't take the object's children into account, which is a problem for my app, since every object has children.
Is there a way to get the BoxHelper to include the object's children? Alternatively, is there a good way to use the BoundingBoxHelper (which does include children), and render it without diagonals?
If you want create a THREE.BoxHelper for an object that has children, you can use this pattern:
// box helper
boxHelper = new THREE.BoxHelper( parent );
boxHelper.material.color.set( 0xffffff );
scene.add( boxHelper );
In your render loop, you may have to do this:
boxHelper.update();
three.js r.85

Making a rotation around a point

I'm using THREE API in order to realize some animations in my app. Now i have a real problem : i'd like making spherical rotation around a specific point. The "rotate" method included in mesh objects allow me to make them, but the center of the rotation is (by default i guess) the center of the mesh.
Then, i only rotate my objects around themself...
I have already found some examples, but they don't solve my problem. I tried to create objects 3D parents like groups, and tried to make the rotation around this groups after having translated them, but this still does not work...
Can you please give me a hand about that ?
I'm so sorry, i found my problem... Making a jsfiddle made me realize i forgot to instanciate my parent as " a new Object 3D() ", that was why i didn't see any objects in my scene when i used animation on my parent... i give you a short part of my code anyway dedicated to interested people finding any help :
// mesh
mesh = new THREE.Mesh( geometry, material );
parent = new THREE.Object3D();
parent.add(mesh);
// if i want my rotation point situated at (300;0;0)
parent.position.set(300,0,0);
mesh.position.set(-300, 0, 0);
scene.add(parent);
http://jsfiddle.net/KqTg8/6/
Thank you

Three.JS, changing the world position of a child 3D object

So basically I have a child object3D of a group Object3D, while the child object's [x,y,z] coordinates are shown relative to the object space of the parent object, I want to change the location of the child object within the 3D space. So first I get the child object's position relative to the world space.
var wrld_pos = childobject.matrixWorld.multiplyVector3(new THREE.Vector3);
This returns a three element vector of the child's position within the world space. Now I wish to set the position my self. So I create a three element vector.
var new_pos = THREE.Vector3();
new_pos.x = 1;
new_pos.y = 2;
new_pos.z = 3;
childobject.matrixWorld.setPosition(new_pos);
Provided the function definition for setPosition, it essentially it sets the last three elements of the object's world matrix to the values of the vector passed as an argument, thus changing the location of the object in world space. And to make sure that the matrix updates after these changes, I call the following functions.
childobject.matrixWorldNeedsUpdate = true;
childobject.updateMatrixWorld();
Now upon inspecting the new world matrix of the object I noticed that the setPosition function did nothing, nothing at all.
Why? If real code examples are needed, I will provide them. But the above should represent the application domain and syntax I used very accurately.
EDIT: Answer updated.
You want to change the world position of a child object.
Assuming the scene has no transform applied, one way to do what you want is to use the following pattern:
scene.attach( child ); // detach from parent and add to scene
child.position.set( x, y, z );
parent.attach( child ); // reattach to original parent
The Object3D.attach( child ) method adds the child object, while maintaining the child's world transform.
three.js r.132
This answer might help with the case. Remove child from parent, change normal position, then attach again.
If use attach for setting position in animation loop for moving objects you can get objects shaking.
For me best solution is:
let newPosition = new THREE.Vector3(1,2,3);
let parentPosition = new THREE.Vector3();
childobject.parent.getWorldPosition(parentPosition);
childobject.position.set(
newPosition.x-parentPosition.x,
newPosition.y-parentPosition.y,
newPosition.z-parentPosition.z
);
If you need position and rotation attach is the only way.

Categories