three js same position (reference) for 2 Object3D() - javascript

I am trying to add 2 (or more) Meshes to the same scene, but i want all the Object3D to share the same position (but with a different rotation for each object).
I know the ".copy()" method, but in my case, there are so many objects and using a loop to change the position of all the objects (60 times per seconds) is resulting a poor performance.
So, I tried to use the same position reference for the objects:
var o=new THREE.Object3D(); // the first object
var p=new THREE.Object3D(); // the second object
o.position=p.position; // the position of the first object becomes the reference to the position of the second object
o.position==p.position; // false, but why?
But it isn't working and I don't get why!
My question is:
Is it possible to change the position reference of a THREE.Object3D()?
And if it isn't, how can I improve the performance of my scene?
Thanks in advance!
Edit: seems to works for someone (this answer is exactly what i can't do): How to set the Object3D position and rotation same as the added mesh ? [three.js]

Related

THREE.JS Multiple groups containing the same objects

I'm currently learning THREE.js and trying to make a playable rubik's cube.
I want to be able to rotate a face as a whole instead of moving every single cube one at a time, and I can do so by creating a THREE.Group and adding the cubes in it. The problem is that a single cube is contained in multiple faces, and I can't find a solution. If I create an object, add it to a first group, then add it to a second group, it is removed from the first group.
I'm pretty sure there is a workaround but can't find it as I'm really new to THREE.js and 3D programming (I only followed a basic course https://www.udemy.com/3d-programming-with-javascript-and-the-threejs-3d-library/).
There is my code but I don't think it will be very usefull anyway.
https://pastebin.com/Hq66UvBU
Thanks
Welcome to Stack Overflow. Please remember to edit your question to include your code, because when the pastebin link dies, your question loses important context.
The correct way to add an object to a THREE.Group is through the add function, like you do. But an object added to multiple groups will only ever be a child of the last group to which it was added. This is because add looks to see if the object already has a defined parent, and removes the object from that parent before setting the new parent (r97 code).
Example:
let obj = new THREE.Object3D()
let p1 = new THREE.Group()
let p2 = new THREE.Group()
p1.add(obj) // obj.parent == p1
p2.add(obj) // 1. three.js calls p1.remove(obj) 2. obj.parent == p2
Beyond this reason, and as #Mugen87 mentioned, your cubes need to not only be able to have multiple memberships, but also to be able to enter and leave face groups as their positions change. To me this says you will almost need to transform the cubes individually. You could use a THREE.Group to make it easier to conceptualize, but there would be extra overhead to actually implement it that way.
Maybe a late answer but try to work in another way and group the cubes that need to turn the moment the turn function is activated and then turn the group around, then empty the group.

How do I move an individual vertex in AFrame?

In Three.js I could use:
myObject.geometry.vertices[i].y += 12;
but in A-Frame nothing is even visible in console.log.
I had seen where between 0.2.0 and 0.3.0 everything
defaults to to buffer geometry and vertices were hidden.
Overriding this was possible, but now in 0.5.0 not even
the geometry array is listed in console.log.
console.log(myObject.geoetry); //now returns 'undefined'.
console.log(myObject); //returns the markup only, no array!?
Is there currently a way to address individual vertices to change their positions?
Set geometry="buffer: false".
https://aframe.io/docs/0.5.0/components/geometry.html#base_properties_buffer
Then get the geometry:
el.getObject3D('mesh').geometry

ThreeJS - adding objects in different order affects alpha / display

My program creates dynamic number of point cloud objects with custom attributes that includes the alpha value of each particle. This works fine, however, when the objects are nested within each other (say spheres) the smaller (inner) ones are getting obscured by the bigger ones, even though their particles' alpha is set properly. When I reverse the order of adding the point-cloud objects to the scene, starting with the bigger ones, going down to the smaller ones, I can see the smaller ones thru the bigger ones.
My question is whether there is a way to tell the renderer to update or recalculate the alpha values or re-render the smaller inner objects so that they show up?
I ran into the same problem as you do. I fixed it to calculate and set the renderdepth for each mesh. For this you need the camera position and the center of your mesh.
You probably already created meshes for each object. If you save all these meshes into an array, it's easier to calculate and set the renderdepth on these objects.
Here's an example how I did it.
updateRenderDepthOnRooms(cameraPosition: THREE.Vector3): void {
var rooms: Room[] = this.getAllRooms();
rooms.forEach((room) => {
var roomCenter = getCenter(room.mesh.geometry);
var renderDepth = 0 - roomCenter.distanceToSquared(cameraPosition);
room.mesh.renderDepth = renderDepth;
});
}
function getCenter(geometry: THREE.Geometry): THREE.Vector3 {
geometry.computeBoundingBox();
var bb = geometry.boundingBox;
var offset = new THREE.Vector3();
offset.addVectors(bb.min, bb.max);
offset.multiplyScalar(0.5);
return offset;
}
So, to get the center of your object, you can ask the geometry from your mesh and use the getCenter(..) function from my example. Then you calculate the renderdepth with the ThreeJs function distanceToSquared(..) and then set this renderdepth to your mesh.
That's it. Hope this will help you.

three js getting coordinates of mesh.lookAt(object);

I have scene,meshes and target object.
When i set up
mesh.lookAt(object)
mesh correctly facing of object.
How can i repeat this rotation of mesh on another mesh, to force another mesh facing the same direction (not the same object, but the same orientation as a first mesh have)?
How can i get rotation coordinates of first mesh?
How can i get this coordinates without need of creating mesh and order mesh.lookAt(object). That mean only to calculate this coordinates without need to use it on some object?
UPDATE:
Only possible solution is to create new THREE.Object3D() and use object.lookAt(target). Then repeat rotation for all later loaded object like: new_object.rotation.set(object.rotation.x,object.rotation.y,object.rotation.z)
You will create only one Object, not a lot of unuseful Vector3-s.
Do not use new_object.rotation = object.rotation it is functional solution, but a variables stay connected. Change of object rotation, will update new_object.rotation too (renderer is updating all values each frame).
You can set the local rotation of the other meshes to the local rotation of the mech facing in the correct direction.
anyOtherMesh.rotation = mesh.rotation;
what about a
lookAt( new THREE.Vector3( target.position.x, target.position.y, target.position.z )
?

three.js Object3D local location, versus global location

So originally I wanted my little 'ship' to have turrets that track a target. This is the jfiddle for it. http://jsfiddle.net/czGZF/2/ When they track, they act odd. I noticed that it thinks that the turret is slighly next to it (at the origin), by this peice of code.
turret_a.position.y = .25;
turret_a.position.z = 2;
However, I had done that so it could be a relative position for when i called (below) to add it to the 'base ship'
ship = new THREE.Object3D();
ship.add( ship_base );
ship.add( turret_a ) ;
When i changed the position of turret_a after it had been added to the ship, and after the ship was added to the scene, the turret tracked mostly how i wanted it to look.
I guess my question is, Why is the lookAt() function using its old location of that, and not the location of where it currently is on its parent object to determine the rotation angles that it needs to be at?
If you look at the code for Object3D.lookA(), you will see
// This routine does not support objects with rotated and/or translated parent(s)
Your code works if the parent ship is located at the origin and is not rotated.
Updated fiddle: http://jsfiddle.net/czGZF/4/
three.js r.59
From the API, the lookAt() method for Camera objects is defined to use world position, as you've discovered. This seems to be relatively common way to handle things.
I'm not that familiar with the three.js API in particular, but it appears that if you want to get the global position of ball, you can use the following:
var targetPos = ball.position.clone();
ball.localToWorld(targetPos);
Hopefully that gets you closer to your goal. Unfortunately, the fiddle you have seems to be (very) non-deterministic, so I can't quickly get a 100% solution for you.

Categories

Resources