Update Three.Js Raycaster After CSS Tranformation

Update Three.js Raycaster After CSS Tranformation

1) Please include the full code of your fiddle. When (not if) your fiddle goes away, so does the context of your question, and this answer.

2) You're attaching the mouse events to the document, not to the part that's moving. Use this instead:

canvas.addEventListener('mousemove', onDocumentMouseMove, false);
canvas.addEventListener('mousemove', onHover, false);

3) clientX/clientY don't behave how you're expecting them to. Use offsetX/offsetY to get the coordinates relative to the canvas (provided you followed step 2). (Don't worry that MDN says it's experimental, it works just fine in browsers that support WebGL.)

mouse.x = (event.offsetX / SCREEN_WIDTH) * 2 - 1;
mouse.y = - (event.offsetY / SCREEN_HEIGHT) * 2 + 1;

Changing Raycaster position dynamically

try to change a code as follows:

function onDocumentMouseDown( event ) {

event.preventDefault();

var x = event.offsetX == undefined ? event.layerX : event.offsetX;
var y = event.offsetY == undefined ? event.layerY : event.offsetY;

var vector = new THREE.Vector3();
vector.set( ( x / renderer.domElement.width ) * 2 - 1, - ( y / renderer.domElement.height ) * 2 + 1, 0.5 );
vector.unproject( camera );

raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() );
...

Three.js cube face rotation vector in relation to camera

Disclaimer: I know nothing about three.js. I've just done a bit of OpenGL.

Your euler angles are coming from a model-view-projected origin (lines 74-80). I can't see the logic behind this.

If your div is on the sphere surface, then it should be oriented by the normal of the sphere at the location of the div. Fortunately, you already have these angles. They are named rotation.

If you replace the euler angles in lines 82-84 with the rotation angles used to position the div, then in my browser the div appears edge on when it is at the edge of the circle, and face on when it is at the centre. It kind of looks like it is moving in a circle, edge on to the screen. Is this the effect you want?

My modification to the linked code:

82 var rotX = (rotation.x * (180/ Math.PI));
83 var rotY = (rotation.y * (180/ Math.PI));
84 var rotZ = 0;

EDIT

Ah, ok. The rotation variable is just that of the camera. It governs the tangent at the equator. You also need to modify the orientation to account for latitude.

Make rotY equal to negative your latitude. Then make sure that this rotation happens before the equatorial rotation. Rotations are not commutative.

In summary, changes from the code at https://jsfiddle.net/ao5wdm04/1/ are as follows:

27 var lat = 45 * Math.PI / 180;
...
82 var rotX = (rotation.x * (180/ Math.PI));
83 var rotY = - 45;
...
88 document.getElementById('face').style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px,0px) rotateY('+rotX+'deg) rotateX('+rotY+'deg)';

I don't know how the latitude should propagate between the init and render functions. As I said, I'm not familiar with the language.

Three.js reverse raycasting

Basing on the link provided by @prisoner849, I've implemented the following solution:

a) on mouseup event I set a new tooltip 3D origin point (only if there was no significant delta in mouse position, to discern between clicking and dragging the camera)

b) every frame, the following function is fired, which converts the 3D coords to 2D and calculates the position of the tooltip:

function setTooltipOrigin( camera, renderer, tooltip, lastClickPoint ) {
var canvas = renderer.domElement,
point = new THREE.Vector3();

point.x = lastClickPoint.x,
point.y = lastClickPoint.y,
point.z = lastClickPoint.z,

point.project( camera );

point.x = Math.round(( 0.5 + point.x / 2 ) * ( canvas.width / window.devicePixelRatio ));
point.y = Math.round(( 0.5 - point.y / 2 ) * ( canvas.height / window.devicePixelRatio ));

point.x -= 14; //small adjustment to the position, so the line points to the click point
point.y -= (tooltip.scrollHeight * 0.7); //same for y

tooltip.style.transform = 'translate(' + point.x + 'px, ' + point.y + 'px)';
}

Three.js - Mouse hover effect doesn't restore previous color

Few problems in your code:

  1. You seem to use INTERSECTED.currentRGB to restore previous color. But you never save the previous color into it (maybe the object.currentHex should have done it?)

  2. THREE.Color.setRGB takes 3 arguments: (r, g, b). You code wouldn't work even if you saved [r,g,b] to currentRGB, which you can't since there is no THREE.Color.getRGB. In this case, it's better if you use Hex. (THREE.Color.getHex and THREE.Color.setHex)

Here is fixed part of the code, lines changed by me are commented

if (intersects.length > 0) {

if (intersects[0].object != INTERSECTED) {

if (INTERSECTED) {
// Use hex rather than RGB (setRGB uses 3 arguments, hex one)
INTERSECTED.face.color.setHex(INTERSECTED.currentHex);
}

INTERSECTED = intersects[0];
// Save actual color so we can restore it later
INTERSECTED.currentHex = INTERSECTED.face.color.getHex();
INTERSECTED.face.color.setHex(0x777777);
INTERSECTED.object.geometry.colorsNeedUpdate = true;

}

} else {

if (INTERSECTED) {
// Use hex rather than RGB (setRGB uses 3 arguments, hex one)
INTERSECTED.face.color.setHex( INTERSECTED.currentHex );
}

INTERSECTED = null;
}

You can see it working here: https://jsfiddle.net/ord2rjw5/3/



Related Topics



Leave a reply



Submit