Sunday, July 8, 2012

Arbitrary Rotation in Gladius

‹prev | My Chain | next›

I am having some difficulty panning my Gladius-based spaceship. I actually have it working for the initial view above the Solar System:


The problem is that the panning controls operate around the x- and y-axis as seen from this orientation. If I fly down to the Sun, panning up-and down still works. I can pan up to look at the Earth and Mars as they revolve about the Sun. The problem arises when I pan right or left:


The problem here is that I continue to rotate around the y-axis:

        if (controller.states["PanLeft"])
          rotation = [0, -space.clock.delta * 0.0005, 0];
After rotating my spaceship up to look at the Earth and Mars, the left-right panning should be rotating around the z-axis, not the y-axis. I could solve this particular use case by simply switching the hard-coded axis of rotation:
        if (controller.states["PanLeft"])
          rotation = [0, -space.clock.delta * 0.0005, 0];
I tried unsuccessfully last night get this to work by resetting the spaceships frame of reference. Had that worked, then I could have always rotated about the z-axis.

Tonight, I try something a little more complex. Specifically, I get started trasnlating the Python script from Paul Bourke to JavaScript. I end up with:
    function rotate3d(p1, p2, p0, theta) {
      var p = math.vector3.subtract(p1, p0)
        , q = new math.Vector3()
        , N = math.vector3.subtract(p2, p1)
        , Nm = Math.sqrt(N[0]*N[0] + N[1]*N[1] + N[2]*N[2]);

      // rotation axis unit vector
      var n = new math.Vector3(N[0]/Nm, N[1]/Nm, N[2]/Nm);

      // Matrix common factors
      var c = Math.cos(theta)
        , t = (1 - Math.cos(theta))
        , s = Math.sin(theta)
        , X = n[0]
        , Y = n[1]
        , Z = n[2];

      // Matrix 'M'
      var d11 = t*X*X + c
        , d12 = t*X*Y - s*Z
        , d13 = t*X*Z + s*Y
        , d21 = t*X*Y + s*Z
        , d22 = t*Y*Y + c
        , d23 = t*Y*Z - s*X
        , d31 = t*X*Z - s*Y
        , d32 = t*Y*Z + s*X
        , d33 = t*Z*Z + c;

      //            |p.x|
      // Matrix 'M'*|p.y|
      //            |p.z|
      q[0] = d11*p[0] + d12*p[1] + d13*p[2];
      q[1] = d21*p[0] + d22*p[1] + d23*p[2];
      q[2] = d31*p[0] + d32*p[1] + d33*p[2];

      return q;
    }
And it seems to be correct. Tomorrow, I will try to put it to use.


Day #441

No comments:

Post a Comment