I have an issue regarding the Raycaster model. I understand the idea and the fact that it intersects meshes, which I can transform, but for example, if I create JS objects that have an inner THREE.Object3D that groups meshes (for their UI), how can I know when the corresponding instance of an object is clicked?
Imagine a button. This button has several characteristics and an inner _model that holds it's THREE.js graphical form (let's say a boxGeometry and a textGeometry that build this button). When the button is added to the scene it adds its buttonInstance.getModel() to the scene, and adds itself to a repository of objects to keep a reference to it.
If I wanted to click this button, I create a raycaster and get the intersecting objects from an array of "buttons" (Objects 3D or Meshes that represent this object).
But how do I fire an event or interact with the button instance itself? I have the mesh but can't get the idea on how to link it with the instance itself.
Any clues? I've searched a lot about raycasting in THREE, but all the examples relate to changing colors or positions of meshes.
_raycaster.setFromCamera(new THREE.Vector2(0,0), _camera);
_activeBtns = _raycaster.intersectObjects(_buttons, true);
_activeBtns[0].object.parent.position.set(curPos.x, curPos.y, curPos.z-.2); // alter position of the Object3D that holds textMesh and BoxMesh
But how do I even know which button is this one that has been 'clicked' if all buttons have two meshes and I dont see a way of idetifying them once they are in the scene?
Thanks
d
#uhara, #WestLangley. In the end I opted to 'bind' them by the uuid that the mesh has in the scene, since the abstract object has access to the mesh also.
Related
I have an object created from importing an .obj
I want to clone this object and give it it's own coordinates.
To be more precise, I have a wall, for which I attach another object (a window) as a child. It all works fine when dragging the window along the wall. Now, when I want to clone the wall and rotate it 180 degrees, dragging the child along it's parent goes exactly the opposite way from the mouse movement.
I would like to reuse the same obj wall for all sides of my building.
You are describing two problems.
One is how to clone an object and give it a different position:
var wallCopy = wall.clone();
scene.add(wallCopy);
wallCopy.position.set( 10,20,30 );
The other question is moving an object in Object space instead of World space.
I.e. if you change the position.x of an object (the window) that is a child of a rotated object, the object will move relative to its rotated parent.
If you are building some sort of editor, you can use SceneUtils to make this easier...
https://threejs.org/docs/#examples/utils/SceneUtils
At the start of your edit, you would detach the window and attach it to the scene, using SceneUtils.detach... then apply your edit movement, and when the movement is done, attach it back to the wall using SceneUtils.attach.
SceneUtils takes care of keeping the visual transform consistent between the detach and attach operations between different places on the scene hierarchy.
edit: So a way to handle the case you describe in comments, without doing anything fiddly, is to just use more intermediate nodes. You can always set up your scaling and stuff on the child nodes, (You can always update thier matrices and then set their matrixAutoUpdate = false; if you're paranoid about the performance impact.}
Here's what I mean:
{"root", scale:1, children:[anchor1, anchor2]}
{"anchor1" scale:1, children:[wall]} {"anchor2" scale:1, children:[wall2]}
Then you can just manipulate the anchors or root to move things around, and the scaling of "wall" will be isolated to its own little sub tree.
I have two scenes, scene1 and scene2. For dragging I have tried with three js draggable but it did not allow me to drag objects outside of scene1. I need to drag objects from scene1 and drop it to scene2.I have attached an image of it. Thanks in Advance.
[The image with two scenes]
"Draggable" in three.js simple means you can transform an object within the space where it exists. To move it between scenes, you would need to view it more as a transaction.
Mousedown on the item you want to drag
Save a reference to the object (var tempobj = selectedObj;)
Start dragging
Detect when your cursor exits the first viewport
Remove the object from scene 1 (scene1.remove(tempobj);)
Detect when your cursor enters the second viewport
Add the object to scene 2 (scene2.add(tempobj);)
Continue dragging the object until you mouse-up
How can I add a point (when I say point I mean a sphere to show that this is where you clicked) to an obj file in three.js onClick? I want it to add to the obj file such that it rotates with it and I would also like to be able to read/save the data of where this point was placed. Is this possible in three.js, and if so how?
Just to be clear - you want to add this to the scene or to an OBJ file that is produced by Three.js?
To add a point to the scene you will need to have a 'work plane' where you are intending the point (as the center of the sphere) to be placed. You would capture the relevant coordinates based on user mouse position within the scene and assign these values the appropriate X, Y or Z value, creating a vector and adding the Sphere to the scene.
To add this to an OBJ file would require that you are writing the file out... or procedurally creating an OBJ in memory, and then writing this out which would be more tedious.
To export an OBJ of your scene, you could try Exporting Threejs Scene to Obj Format
Hii you have to follow below steps to do what you want :-
when mouse click on the object :- add a child mesh in object .
when mouse click else on screen ,remove that mesh object
when mouse interact with now mesh (mouse down event ) ,rotate the object or else you want
Hope it helps you.
I have a web page that is based on the following ThreeJS sample:
http://threejs.org/examples/#css3d_molecules
I create new nodes (atoms) dynamically by attaching them to existing nodes (atoms). After creating it and adding it to the scene, I want to bring the new atom/child element to the forefront using the minimum number of rotate, pan, & zoom operations needed to do so. However, although I know how to do each of those operations, I don't know how to calculate the optimal sequence based on the current position/quaternion of the node (atom) where I created it in the scene, and its new position which will be (0, 0, ). I will be animating the change from the old place in the scene to the new so I don't want to just change the new element's position/quaternion to the new value via an assignment. I want animate the change over time, performing a slice of each operation (pan/zoom/rotate) each animation frame.
Are there any ThreeJS methods to help me do this?
See how to: get the global/world position of a child object to get world position of any mesh in your hierarchy. Then have your camera.lookAt() to that location.
I want to have a reflecting cube surface in a WebGL page with Three.js. It should resemble a mobile phone display, which reflects some light, but it still has to be black.
I have created an example of a reflecting cube (and also a reflective sphere) with detailed comments. The live version is at
http://stemkoski.github.com/Three.js/Reflection.html
with nicely formatted code at
https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Reflection.html
(This is part of a collection of tutorial examples at http://stemkoski.github.com/Three.js/)
The main points are:
add to your scene a second camera (a CubeCamera) positioned at the object whose surface should be reflective
create a material and set the environment map as the results of rendering from this second camera, e.g.
for example:
var mirrorCubeMaterial = new THREE.MeshBasicMaterial(
{ envMap: mirrorCubeCamera.renderTarget } );
in your render function, you have to render from all your cameras. Temporarily hide the object that is reflecting (so that it doesn't get in the way of the camera you are going to use), render from that camera, then unhide the reflective object.
for example:
mirrorCube.visible = false;
mirrorCubeCamera.updateCubeMap( renderer, scene );
mirrorCube.visible = true;
These code snippets are from the links I posted above; check them out!