
package org.waltermilner;

import javax.media.opengl.GL;

/**
 *
 * @author Walter Milner
 */
public class Stick {
    /** spatial coords of the center */
    private double x,y,z;
    /** orientation is parameterised as
     * a vector called forward - which way we are pointing, and
     * up - which way is 'up' from the object point of view
     */
    WMVector forward;
    WMVector up;

    private final WMVector zaxis=new WMVector(0,0,1);
    private final WMVector yaxis = new WMVector(0,1,0);
    /** angle is the angle needed to rotate through to make it point the correct way */
    private double angle;
    /** angle2 is the angle to roll to get this correct */
    private double angle2;
    /** turnAxis is the vector to rotate around by 'angle' to point correct way */
    private WMVector turnAxis;
    private double rollAngle=0.0;
    
    private float speed;
    
    public Stick()
    {
        x=y=z=0;
        forward=new WMVector(0,0,1);
        up=new WMVector(0,1,0);
        speed=1e-3f;
        reCalc();
    }
    public void move()
    {
        //x+=speed*axis.getX();
        //y+=speed*axis.getY();
        //z+=speed*axis.getZ();
    }
    
    public void pitchUp()
    {
       // Add to the forward vector a small amount of the up vector
       WMVector sideways = forward.cross(up);
       WMVector newForward = forward.add(up.times(0.01));
       forward=newForward.normalise();
       // adjust up so is still perpendicular to forward
       up= sideways.cross(forward);
       up = up.normalise();
       reCalc(); // adjust orientation parameters
    }
    
    public void pitchDown()
    {  // see pitch up
       WMVector sideways = forward.cross(up);
       WMVector newForward = forward.add(up.times(-0.01));
       forward=newForward.normalise();
       up= sideways.cross(forward);
       up = up.normalise();
       reCalc();
    }
    
    public void roll()
    {
        // rotate the up vector around the forward axis
        rollAngle+=0.01;
        up=up.rotate(0.01, forward);
        reCalc();        
    }
    public void unRoll()
    {   // see roll()
        rollAngle-=0.01;
        up=up.rotate(-0.01, forward);
        reCalc();
        
    }
    
    /** calculations need for altered orientation */
    private void reCalc()
    {
        // how much to rotate to point in correct direction
        angle = forward.angleWith(zaxis);
        // axis to turn on
        turnAxis = zaxis.cross(forward);
        if (!turnAxis.isZero()) // unless forward on z axis
       {
        turnAxis=turnAxis.normalise();
        // where would this rotation have tranformed the up?
        WMVector newUp = yaxis.rotate(angle, turnAxis);
        // what is the angle between that and the actual up?
        angle2 = newUp.angleWith(up);
        if (rollAngle<=0) angle2=-angle2;
        // this is the correct angle to roll

       }
        else angle2=rollAngle;
    }
    public void draw(GL gl)
    {        
        gl.glRotated(angle*180/Math.PI, turnAxis.getX(), turnAxis.getY(), turnAxis.getZ());
        gl.glRotated(angle2*180/Math.PI, 0,0,1);
        fixedDraw(gl);        
    }
    public void fixedDraw(GL gl)
    {
        
        
        gl.glLineWidth(2.0f);
        gl.glBegin(GL.GL_LINES);
        gl.glColor3d(1,0,0); // wings red to green
        gl.glVertex3d(-1.0,0.0,0.0); //along x axis
        gl.glColor3d(0,1,0); 
        gl.glVertex3d(1.0,0.0,0.0);
        gl.glColor3d(1,1,1); // body white to blue
        gl.glVertex3d(0.0,0.0,0);
        gl.glColor3d(0,0,1); 
        gl.glVertex3d(0.0,0.0,4.0);
        gl.glColor3d(1,1,0);
        gl.glVertex3d(0.0,0.0,0);
        gl.glVertex3d(0,1,0);
        
        
        
        
        gl.glEnd();      
    }
}
 /* This bit for Euler angle version
        // see http://en.wikipedia.org/wiki/Euler_angles      
        gl.glRotated(alpha, 0, 0, 1);
        // make the line of nodes vector
        double x=1, y=0, z=0;
        // rotate by alpha about z axis
        double c=Math.cos(alpha);
        double s = Math.sin(alpha);
        double xdash = x*c-y*s;
        y=x*s+y*c;
        WMVector nodes = new WMVector(xdash, y, z);        
        gl.glRotated(beta, xdash, y, z);
        // work out Z vector
        double Zx, Zy, Zz;
        Zz=Math.sin(beta);
        Zx=s;
        Zy=c;
        gl.glRotated(gamma, Zx, Zy, Zz); */
