in the XBox - class those three methods are important:
First, call this method. it takes 4 parameters:
current mouse coords x & y,
previous mouse coords x & y.
2D mouse coordinates are mapped to rotation in 3D.
method: freeRotation()
Code:
PVector v1 = new PVector();
PVector v2 = new PVector();
public void freeRotate(int mouseX, int mouseY,
int pMouseX, int pMouseY) {
long err;
err = vectorize(pMouseX, pMouseY, (int)this.x(), (int)this.y(), 800, v1);
err += vectorize(mouseX, mouseY, (int)this.x(), (int)this.y(), 800, v2);
if (err == 0) {
Rot rotation = zeroHysteresisRotation(v1, v2);
Rot prev_rotation = new Rot(RotOrder.XYZ, this.getRotArray()[0], this.getRotArray()[1], this.getRotArray()[2]);
rotation = rotation.applyTo(prev_rotation);
this.rotateTo(rotation.getAngles(RotOrder.XYZ));
}
}
method: zeroHysteresisRotation()
computes the rotation axis and angle. returns a shapes3d Rot object.
Code:private Rot zeroHysteresisRotation(PVector v1, PVector v2 ) {
PVector cross;
float dot, angle;
dot = v1.dot(v2);
if (dot == 1.0)
return null; // nothing to do
cross = v1.cross(v2); // axis of rotation
cross.normalize();
// angle of rotation
angle = (float) (2.*Math.acos(dot));
Rot rotationMatrix = new Rot(cross, angle);
return rotationMatrix;
}
method: vectorize()
compared to this
code, we don't need to invert the y-axis.
Code:private long vectorize(int mouseX, int mouseY, int originSpX,
int originSpY, int radius, PVector vec) {
float x,y,z, modulus;
x = (float)(mouseX - originSpX)/radius;
y = (float)(mouseY - originSpY)/radius;
modulus = x*x + y*y;
if (modulus > 1.) {
return 1L; // error
}
// compute fictitious 'z' value
z = (float) Math.sqrt(1. - (x*x + y*y));
vec.set(x,y,z);
return 0L;
}