Raycasting against box geometry within it (three.js) - three.js

I'm trying to detect at which wall of the box geometry is the user looking at. Imagine that user is in a room and I want to detect which wall is the camera currently looking at. I'm raycasting from camera like this:
var lookAtVector = new THREE.Vector3(0,0, -1);
lookAtVector.applyQuaternion(camera.quaternion);
raycaster.setFromCamera(lookAtVector, camera);
var intersection = raycaster.intersectObject(box);
console.log(intersection);
So this raycasting works fine outside the "room" but how to get it working inside the room?

One thing to remember is that the camera is always pointing in the negative z direction. When rotating and moving the camera, you are actualy rotating and moving the whole scene. Therefore I think there are two problems with you code.
I think you have to initialize your raycaster like this:
var raycaster = new THREE.Raycaster(camera.position, lookAtVector);
Where lookAtVector is just var lookAtVector = new THREE.Vector3(0,0, -1);, unmodified. This will send a ray from you camera's position in the direction it is facing.
Then I think that maybe you are not rendering you box backside. When constructing your box material, pass along side: THREE.BackSide (or THREE.DoubleSide) as a parameter
EDIT
I was wrong about the lookAtVector. The ray is probably cast before the camera has modified the scene. Therefore you are absolutely right when applying the cameras quaternion on lookAtVector

To raycast inside the box geometry you need to first make the inside of the box visible:
box.material.side = THREE.DoubleSide;
Or
box.material.side = THREE.BackSide;

Related

ThreeJS - stop slerp camera rotation from drifting around

I'm currently working on a scene, with an object at the centre (0,0,0) and 6 other object orbiting it. I have a camera set up behind and slightly above an outer object, looking back to centre (camera.lookAt(0,0,0) etc).
I want to click an object and just for the camera to arc towards and face the clicked object. I'm using Quaternion.slerp to achieve this, and it sort of works, yet while the camera's moving, it sort of drifts about lazily then slowly focuses just off centre of the object.
So if I click an object to the left of the camera's FOV, it sort of drifts right a little before swinging left, and vice versa.
I found some help regarding movement with slerp, I was hoping to simply adapt it:
How to animate the camera in three.js to look at an object?
Setup
this._endQ = new Quaternion();
this._iniQ = new Quaternion().copy(this._camera.quaternion);
this._curQ = new Quaternion();
this._vec3 = new Vector3();
const euler = new Euler(this._cameraLookAtDestination.x, this._cameraLookAtDestination.y, this._cameraLookAtDestination.z);
this._endQ.setFromEuler(euler);
In renderloop
Quaternion.slerp(this._iniQ, this._endQ, this._curQ, pointInTime);
this._vec3.x = this._cameraLookAtDestination.x;
this._vec3.y = this._cameraLookAtDestination.y;
this._vec3.z = this._cameraLookAtDestination.z;
this._vec3.applyQuaternion(this._curQ);
this._camera.lookAt(this._vec3);
Is this normal slerp behaviour, or is there something I'm missing?
EDIT:
I also noticed that each time I click an object to look at, the camera seems to reset its orientation, then rotates

Three.js / BufferGeometry how to use mesh & line material

I'm using BufferGeometry to draw triangles.
I can use a mesh geometry, specifiyng 3 index-attribute for every triangle. I'm using a basic material without wireframe. I suposse I'll can use raycast.
Also I have seen the linesegments approach for wireframe. Interesting.
Ok, my problem... I'd like to see my triangles as a wireframe and also I need raycast. So .... the solution is to create my own shader, isn't it ?
Thanks
you dont have to create a custom shader you can have a mesh with wireframe material, and the ray should still "hit" the object
var mesh = new THREE.Mesh(geometry,new THREE.MeshBasicMaterial({wireframe : true}));
if it for some reason does not hit or you want to LineSegments object you can keep track of all transformations that affected the object, and apply them onto a mesh you wont add to scene
var segmentObject = new THREE.LineSegments(geometry,lineMaterial);
scene.add(segmentObject);
var meshNotInScene = new THREE.Mesh(geometry,dummyMaterial);
and you will use the mesh object to determine if raycast hit the object
this way you can have a different hitbox for an object for example if you have a flying donut by pairing it with a circle mesh you can select it even if you click in its hole etc...
keep in mind that materials have sides and if you dont care about which side is which set "side" to THREE.DoubleSide

Sphere object does not rotate

I have a THREE.JS scene where there's a plane geometry in the middle of the scene. The plane geometry has a camera added to it. I also am using this example http://mrdoob.github.io/three.js/examples/webgl_materials_lightmap.html to add a lightmap and am adding it to my plane geometry.
Psuedocode:
planeGeometry.add(camera);
planeGeometry.add(sphereGeometryLightMap);
The problem is that when I try to rotate the sphere geometry on any axis, nothing happens. I tried using .rotation and setting the matrix4. Why is it that I can't rotate this sphere object when added to another object? How can I work around this?
You don't need to add the camera to the planeGeometry.
Also I assume that sphereGeometryLightMap is of type THREE.Mesh in which case you need to add it to the scene. Not to the planeGeometry.
If you want the sphereGeometry relative to the planeGeometry you can do:
var object = new THREE.Object3D();
object.add (planeGeometry);
object.add (sphereGeometry);
Before you add the geometries to the object you position them relative as you want.
Then, instead of modifying the planeGeometry, you modify the object.

Rotating Object Around an Axis

I have a geometry object, and I'm trying to add a Torus mesh that goes around that geometry. What I'm trying to do is have the original geometry, and then when the geometry is clicked, it adds a Torus shape on the line around the location that was clicked. However, I'm having trouble getting it to rotate correctly.
I get the torus to show up at the correct place, but I can't orient it around the line. I'm using a raycaster to get the point clicked, so I have the face and the faceindex of the point clicked. On every implementation I try using rotation (using setEulerFromRotationMatrix), it simply moves the location of the torus mesh, not actually rotate it to allow the line to go through the torus.
This seems like it would be trivial, but it's giving me a lot of trouble. What am I doing wrong? Two methods I tried, both unsucessful and exhibiting the behavior above:
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis(geometry.faces[fIndex].centroid.normalize(), Math.PI/2);
torusLoop.matrix.multiply(rotationMatrix);
torusLoop.rotation.setEulerFromRotationMatrix(torusLoop.matrix);
//attempt two, similar results to above attempt
tangent = geometry.tangents[segments/radiusSegments].normalize();
axis.crossVectors( up, tangent ).normalize();
var radians = Math.acos( up.dot( tangent ) );
matrix.makeRotationAxis( axis, radians );
torusLoop.rotation.setEulerFromRotationMatrix( matrix );
I need the torus knot to follow the curve of the spline, but it will only stay flat, and rotations simply cause it to move around, not change angles.
Never mind, I figured it out. For those wondering, I translated before rotating, which caused my figure to be rotating around a different axis. My solution was to rotate first, and then translate, and then after creating the mesh, moving that to the position I needed it to be.

intersection of a cube's front face with a raycaster is not working

In order to know the current front face of a rotating cube I created a raycaster telling me which part of the cube intersects with it. So far I do not get any intersections although I think I did everything correct.
How can this be solved?
Thanks
You need to have your raycaster's ray point toward the object.
//var projector = new THREE.Projector();
var vector = cube.position.clone(); // new THREE.Vector3(100, 100, 0.5);
//projector.unprojectVector(vector, camera);
fiddle: http://jsfiddle.net/an86j/19/
Note: This question is not likely to be of use to anyone else but you, and that is not the purpose of this site. Try to ask questions that will be beneficial to others. See the faq.

Resources