0
votes

JS Fiddle: http://jsfiddle.net/Nfw9M/1/

Please bear with me on this question as I'm learning the intricacies of matrix operations and have not progressed very far into the result I'm looking for.

What I have is a THREE.Object3D with 3 cube meshes inside. The Object group can be rotated arbitrarily in any direction, but I need to find the normalized vector direction of the mouse movement as one clicks and drags across the object.

To illustrate, I've created some images. In this image, the object is rotated 90 degrees on the X axis. A user would drag from left to right across the face of the black cube.

enter image description here

What I need to do with this, is figure out what that movement would be if the object was not rotated at all. In this case the user would be dragging left to right across the topmost face of the group.

enter image description here

From my research, I think what I need to do is:

  • Get the inverse matrix of the group
  • Find the difference of the vectors between two mouse movements.
  • Multiply those vectors against the original inverse
  • Normalize?

Unfortunately, I am stuck. I have the following intersection code:

function intersect(e) {
    _vector.set((e.pageX / window.innerWidth) * 2 - 1, -(e.pageY / window.innerHeight) * 2 + 1, 0.5);
    _ray.set(_camera.position, _vector.sub(_camera.position).normalize());
    return _ray.intersectObjects(_cube.children);
}

This works properly, but I don't understand what the returning object.point's values are related to.

My code on mouse movement is:

function mouseMove(e) {
    var hit = intersect(e);
    console.log(hit);
    if (!hit[0]) return false;
    var point = hit[0].point;

    if (_last) {
        var p = new THREE.Vector3();
        p.add(point);
        p.sub(_last);

        //this is where I am stuck
    }

    _last = point;
}

Can I even multiply a Vector3 and a Matrix4?

I think what I'm trying to do is fairly complex, and I have some gaps in my knowledge preventing me from completing the task. I'd really appreciate any guidance.

Thanks!

1

1 Answers

2
votes

I think I've solved it!

JS Fiddle: http://jsfiddle.net/Nfw9M/2/

I was missing unprojectVector in the intersect code.

function intersect(e) {
    _vector.set((e.pageX / window.innerWidth) * 2 - 1, -(e.pageY / window.innerHeight) * 2 + 1, 0.5);
    _projector.unprojectVector(_vector, _camera);
    _ray.set(_camera.position, _vector.sub(_camera.position).normalize());
    return _ray.intersectObjects(_cube.children);
}

And the steps were:

  • Get the inverse of the object matrix
  • Convert the Vector3 intersect to Vector4
  • Multiply the Vector4 intersect values by the inverse of the object matrix
  • On mousemove, subtract the Vector4 from the one set at mousedown.

    _inverse.getInverse(_cube.matrix);
    _v4.set(point.x, point.y, point.z, 1);
    _v4.applyMatrix4(_inverse);
    
    var v4 = new THREE.Vector4(_last.x, _last.y, _last.z, 1); //could avoid new here
    v4.sub(_v4);
    

Looking at the changes at v4 over time would give you the direction in x, y, or z space that the mouse was moving across the object as if it were not rotated at all.