Package fcagnin.jgltut.tut06

Source Code of fcagnin.jgltut.tut06.Hierarchy$Armature

package fcagnin.jgltut.tut06;

import fcagnin.jglsdk.glm.Mat3;
import fcagnin.jglsdk.glm.Mat4;
import fcagnin.jglsdk.glm.Vec3;
import fcagnin.jglsdk.glm.Vec4;
import fcagnin.jgltut.LWJGLWindow;
import fcagnin.jgltut.framework.Framework;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Keyboard;

import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Stack;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30.glGenVertexArrays;


/**
* Visit https://github.com/integeruser/jgltut for info, updates and license terms.
* <p/>
* Part II. Positioning
* Chapter 6. Objects in Motion
* http://www.arcsynthesis.org/gltut/Positioning/Tutorial%2006.html
* <p/>
* Node Angle      Increase/Left   Decrease/Right
* Base Spin              D               A
* Arm Raise              S               W
* Elbow Raise            F               R
* Wrist Raise            G               T
* Wrist Spin             C               Z
* Finger                 Q               E
* <p/>
* SPACE   - print current armature position.
*
* @author integeruser
*/
public class Hierarchy extends LWJGLWindow {
    public static void main(String[] args) {
        Framework.CURRENT_TUTORIAL_DATAPATH = "/fcagnin/jgltut/tut06/data/";

        new Hierarchy().start( 700, 700 );
    }


    @Override
    protected void init() {
        initializeProgram();
        initializeVAO();

        glEnable( GL_CULL_FACE );
        glCullFace( GL_BACK );
        glFrontFace( GL_CW );

        glEnable( GL_DEPTH_TEST );
        glDepthMask( true );
        glDepthFunc( GL_LEQUAL );
        glDepthRange( 0.0f, 1.0f );
    }

    @Override
    protected void display() {
        glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
        glClearDepth( 1.0f );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

        armature.draw();
    }

    @Override
    protected void reshape(int w, int h) {
        cameraToClipMatrix.set( 0, 0, frustumScale / (w / (float) h) );
        cameraToClipMatrix.set( 1, 1, frustumScale );

        glUseProgram( theProgram );
        glUniformMatrix4( cameraToClipMatrixUnif, false, cameraToClipMatrix.fillAndFlipBuffer( mat4Buffer ) );
        glUseProgram( 0 );

        glViewport( 0, 0, w, h );
    }

    @Override
    protected void update() {
        if ( Keyboard.isKeyDown( Keyboard.KEY_A ) ) {
            armature.adjBase( false );
        } else if ( Keyboard.isKeyDown( Keyboard.KEY_D ) ) {
            armature.adjBase( true );
        }

        if ( Keyboard.isKeyDown( Keyboard.KEY_W ) ) {
            armature.adjUpperArm( false );
        } else if ( Keyboard.isKeyDown( Keyboard.KEY_S ) ) {
            armature.adjUpperArm( true );
        }

        if ( Keyboard.isKeyDown( Keyboard.KEY_R ) ) {
            armature.adjLowerArm( false );
        } else if ( Keyboard.isKeyDown( Keyboard.KEY_F ) ) {
            armature.adjLowerArm( true );
        }

        if ( Keyboard.isKeyDown( Keyboard.KEY_T ) ) {
            armature.adjWristPitch( false );
        } else if ( Keyboard.isKeyDown( Keyboard.KEY_G ) ) {
            armature.adjWristPitch( true );
        }

        if ( Keyboard.isKeyDown( Keyboard.KEY_Z ) ) {
            armature.adjWristRoll( false );
        } else if ( Keyboard.isKeyDown( Keyboard.KEY_C ) ) {
            armature.adjWristRoll( true );
        }

        if ( Keyboard.isKeyDown( Keyboard.KEY_Q ) ) {
            armature.adjFingerOpen( true );
        } else if ( Keyboard.isKeyDown( Keyboard.KEY_E ) ) {
            armature.adjFingerOpen( false );
        }


        while ( Keyboard.next() ) {
            if ( Keyboard.getEventKeyState() ) {
                switch ( Keyboard.getEventKey() ) {
                    case Keyboard.KEY_SPACE:
                        armature.writePose();
                        break;

                    case Keyboard.KEY_ESCAPE:
                        leaveMainLoop();
                        break;
                }
            }
        }
    }


    ////////////////////////////////
    private int theProgram;
    private int positionAttrib;
    private int colorAttrib;

    private int modelToCameraMatrixUnif;
    private int cameraToClipMatrixUnif;

    private Mat4 cameraToClipMatrix = new Mat4( 0.0f );
    private FloatBuffer mat4Buffer = BufferUtils.createFloatBuffer( Mat4.SIZE );

    private final float frustumScale = calcFrustumScale( 45.0f );


    private void initializeProgram() {
        ArrayList<Integer> shaderList = new ArrayList<>();
        shaderList.add( Framework.loadShader( GL_VERTEX_SHADER, "PosColorLocalTransform.vert" ) );
        shaderList.add( Framework.loadShader( GL_FRAGMENT_SHADER, "ColorPassthrough.frag" ) );

        theProgram = Framework.createProgram( shaderList );

        positionAttrib = glGetAttribLocation( theProgram, "position" );
        colorAttrib = glGetAttribLocation( theProgram, "color" );

        modelToCameraMatrixUnif = glGetUniformLocation( theProgram, "modelToCameraMatrix" );
        cameraToClipMatrixUnif = glGetUniformLocation( theProgram, "cameraToClipMatrix" );

        float zNear = 1.0f;
        float zFar = 100.0f;

        cameraToClipMatrix.set( 0, 0, frustumScale );
        cameraToClipMatrix.set( 1, 1, frustumScale );
        cameraToClipMatrix.set( 2, 2, (zFar + zNear) / (zNear - zFar) );
        cameraToClipMatrix.set( 2, 3, -1.0f );
        cameraToClipMatrix.set( 3, 2, (2 * zFar * zNear) / (zNear - zFar) );

        glUseProgram( theProgram );
        glUniformMatrix4( cameraToClipMatrixUnif, false, cameraToClipMatrix.fillAndFlipBuffer( mat4Buffer ) );
        glUseProgram( 0 );
    }


    private float calcFrustumScale(float fovDeg) {
        final float degToRad = 3.14159f * 2.0f / 360.0f;
        float fovRad = fovDeg * degToRad;
        return 1.0f / (float) (Math.tan( fovRad / 2.0f ));
    }


    ////////////////////////////////
    private final int numberOfVertices = 24;

    private final float vertexData[] = {
            // Front
            +1.0f, +1.0f, +1.0f,
            +1.0f, -1.0f, +1.0f,
            -1.0f, -1.0f, +1.0f,
            -1.0f, +1.0f, +1.0f,

            // Top
            +1.0f, +1.0f, +1.0f,
            -1.0f, +1.0f, +1.0f,
            -1.0f, +1.0f, -1.0f,
            +1.0f, +1.0f, -1.0f,

            // Left
            +1.0f, +1.0f, +1.0f,
            +1.0f, +1.0f, -1.0f,
            +1.0f, -1.0f, -1.0f,
            +1.0f, -1.0f, +1.0f,

            // Back
            +1.0f, +1.0f, -1.0f,
            -1.0f, +1.0f, -1.0f,
            -1.0f, -1.0f, -1.0f,
            +1.0f, -1.0f, -1.0f,

            // Bottom
            +1.0f, -1.0f, +1.0f,
            +1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f, +1.0f,

            // Right
            -1.0f, +1.0f, +1.0f,
            -1.0f, -1.0f, +1.0f,
            -1.0f, -1.0f, -1.0f,
            -1.0f, +1.0f, -1.0f,


            0.0f, 1.0f, 0.0f, 1.0f,     // GREEN_COLOR
            0.0f, 1.0f, 0.0f, 1.0f,     // GREEN_COLOR
            0.0f, 1.0f, 0.0f, 1.0f,     // GREEN_COLOR
            0.0f, 1.0f, 0.0f, 1.0f,     // GREEN_COLOR

            0.0f, 0.0f, 1.0f, 1.0f,     // BLUE_COLOR
            0.0f, 0.0f, 1.0f, 1.0f,     // BLUE_COLOR
            0.0f, 0.0f, 1.0f, 1.0f,     // BLUE_COLOR
            0.0f, 0.0f, 1.0f, 1.0f,     // BLUE_COLOR

            1.0f, 0.0f, 0.0f, 1.0f,     // RED_COLOR
            1.0f, 0.0f, 0.0f, 1.0f,     // RED_COLOR
            1.0f, 0.0f, 0.0f, 1.0f,     // RED_COLOR
            1.0f, 0.0f, 0.0f, 1.0f,     // RED_COLOR

            1.0f, 1.0f, 0.0f, 1.0f,     // YELLOW_COLOR
            1.0f, 1.0f, 0.0f, 1.0f,     // YELLOW_COLOR
            1.0f, 1.0f, 0.0f, 1.0f,     // YELLOW_COLOR
            1.0f, 1.0f, 0.0f, 1.0f,     // YELLOW_COLOR

            0.0f, 1.0f, 1.0f, 1.0f,     // CYAN_COLOR
            0.0f, 1.0f, 1.0f, 1.0f,     // CYAN_COLOR
            0.0f, 1.0f, 1.0f, 1.0f,     // CYAN_COLOR
            0.0f, 1.0f, 1.0f, 1.0f,     // CYAN_COLOR

            1.0f, 0.0f, 1.0f, 1.0f,     // MAGENTA_COLOR
            1.0f, 0.0f, 1.0f, 1.0f,     // MAGENTA_COLOR
            1.0f, 0.0f, 1.0f, 1.0f,     // MAGENTA_COLOR
            1.0f, 0.0f, 1.0f, 1.0f      // MAGENTA_COLOR
    };

    private final short indexData[] = {
            0, 1, 2,
            2, 3, 0,

            4, 5, 6,
            6, 7, 4,

            8, 9, 10,
            10, 11, 8,

            12, 13, 14,
            14, 15, 12,

            16, 17, 18,
            18, 19, 16,

            20, 21, 22,
            22, 23, 20
    };

    private int vertexBufferObject;
    private int indexBufferObject;

    private int vao;


    private void initializeVAO() {
        FloatBuffer vertexDataBuffer = BufferUtils.createFloatBuffer( vertexData.length );
        vertexDataBuffer.put( vertexData );
        vertexDataBuffer.flip();

        vertexBufferObject = glGenBuffers();
        glBindBuffer( GL_ARRAY_BUFFER, vertexBufferObject );
        glBufferData( GL_ARRAY_BUFFER, vertexDataBuffer, GL_STATIC_DRAW );
        glBindBuffer( GL_ARRAY_BUFFER, 0 );

        ShortBuffer indexDataBuffer = BufferUtils.createShortBuffer( indexData.length );
        indexDataBuffer.put( indexData );
        indexDataBuffer.flip();

        indexBufferObject = glGenBuffers();
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBufferObject );
        glBufferData( GL_ELEMENT_ARRAY_BUFFER, indexDataBuffer, GL_STATIC_DRAW );
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );

        vao = glGenVertexArrays();
        glBindVertexArray( vao );

        int colorDataOffset = FLOAT_SIZE * 3 * numberOfVertices;
        glBindBuffer( GL_ARRAY_BUFFER, vertexBufferObject );
        glEnableVertexAttribArray( positionAttrib );
        glEnableVertexAttribArray( colorAttrib );
        glVertexAttribPointer( positionAttrib, 3, GL_FLOAT, false, 0, 0 );
        glVertexAttribPointer( colorAttrib, 4, GL_FLOAT, false, 0, colorDataOffset );
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBufferObject );

        glBindVertexArray( 0 );
    }


    ////////////////////////////////
    private class MatrixStack {
        Stack<Mat4> matrices;
        Mat4 currMat;


        MatrixStack() {
            matrices = new Stack<>();
            currMat = new Mat4( 1.0f );
        }


        Mat4 top() {
            return currMat;
        }

        void push() {
            matrices.push( new Mat4( currMat ) );
        }

        void pop() {
            currMat = matrices.pop();
        }


        void rotateX(float angDeg) {
            currMat.mul( new Mat4( Hierarchy.this.rotateX( angDeg ) ) );
        }

        void rotateY(float angDeg) {
            currMat.mul( new Mat4( Hierarchy.this.rotateY( angDeg ) ) );
        }

        void rotateZ(float angDeg) {
            currMat.mul( new Mat4( Hierarchy.this.rotateZ( angDeg ) ) );
        }

        void scale(Vec3 scaleVec) {
            Mat4 scaleMat = new Mat4( 1.0f );
            scaleMat.set( 0, 0, scaleVec.x );
            scaleMat.set( 1, 1, scaleVec.y );
            scaleMat.set( 2, 2, scaleVec.z );

            currMat.mul( scaleMat );
        }

        void translate(Vec3 offsetVec) {
            Mat4 translateMat = new Mat4( 1.0f );
            translateMat.setColumn( 3, new Vec4( offsetVec, 1.0f ) );

            currMat.mul( translateMat );
        }
    }


    ////////////////////////////////
    private final float STANDARD_ANGLE_INCREMENT = 11.25f;
    private final float SMALL_ANGLE_INCREMENT = 9.0f;

    private Armature armature = new Armature();

    private class Armature {
        Vec3 posBase;
        float angBase;

        Vec3 posBaseLeft, posBaseRight;
        float scaleBaseZ;

        float angUpperArm;
        float sizeUpperArm;

        Vec3 posLowerArm;
        float angLowerArm;
        float lenLowerArm;
        float widthLowerArm;

        Vec3 posWrist;
        float angWristRoll;
        float angWristPitch;
        float lenWrist;
        float widthWrist;

        Vec3 posLeftFinger, posRightFinger;
        float angFingerOpen;
        float lenFinger;
        float widthFinger;
        float angLowerFinger;


        Armature() {
            posBase = new Vec3( 3.0f, -5.0f, -40.0f );
            angBase = -45.0f;

            posBaseLeft = new Vec3( 2.0f, 0.0f, 0.0f );
            posBaseRight = new Vec3( -2.0f, 0.0f, 0.0f );
            scaleBaseZ = 3.0f;

            angUpperArm = -70.75f;
            sizeUpperArm = 9.0f;

            posLowerArm = new Vec3( 0.0f, 0.0f, 8.0f );
            angLowerArm = 60.25f;
            lenLowerArm = 5.0f;
            widthLowerArm = 1.5f;

            posWrist = new Vec3( 0.0f, 0.0f, 5.0f );
            angWristRoll = 0.0f;
            angWristPitch = 67.5f;
            lenWrist = 2.0f;
            widthWrist = 2.0f;

            posLeftFinger = new Vec3( 1.0f, 0.0f, 1.0f );
            posRightFinger = new Vec3( -1.0f, 0.0f, 1.0f );
            angFingerOpen = 45.0f;
            lenFinger = 2.0f;
            widthFinger = 0.5f;
            angLowerFinger = 45.0f;
        }


        void draw() {
            MatrixStack modelToCameraStack = new MatrixStack();

            glUseProgram( theProgram );
            glBindVertexArray( vao );

            modelToCameraStack.translate( posBase );
            modelToCameraStack.rotateY( angBase );

            // Draw left base.
            {
                modelToCameraStack.push();
                modelToCameraStack.translate( posBaseLeft );
                modelToCameraStack.scale( new Vec3( 1.0f, 1.0f, scaleBaseZ ) );
                glUniformMatrix4( modelToCameraMatrixUnif, false,
                        modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
                glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
                modelToCameraStack.pop();
            }

            // Draw right base.
            {
                modelToCameraStack.push();
                modelToCameraStack.translate( posBaseRight );
                modelToCameraStack.scale( new Vec3( 1.0f, 1.0f, scaleBaseZ ) );
                glUniformMatrix4( modelToCameraMatrixUnif, false,
                        modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
                glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
                modelToCameraStack.pop();
            }

            // Draw main arm.
            drawUpperArm( modelToCameraStack );

            glBindVertexArray( 0 );
            glUseProgram( 0 );
        }

        void drawUpperArm(MatrixStack modelToCameraStack) {
            modelToCameraStack.push();
            modelToCameraStack.rotateX( angUpperArm );

            {
                modelToCameraStack.push();
                modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, (sizeUpperArm / 2.0f) - 1.0f ) );
                modelToCameraStack.scale( new Vec3( 1.0f, 1.0f, sizeUpperArm / 2.0f ) );
                glUniformMatrix4( modelToCameraMatrixUnif, false,
                        modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
                glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
                modelToCameraStack.pop();
            }

            drawLowerArm( modelToCameraStack );

            modelToCameraStack.pop();
        }

        void drawLowerArm(MatrixStack modelToCameraStack) {
            modelToCameraStack.push();
            modelToCameraStack.translate( posLowerArm );
            modelToCameraStack.rotateX( angLowerArm );

            modelToCameraStack.push();
            modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, lenLowerArm / 2.0f ) );
            modelToCameraStack.scale( new Vec3( widthLowerArm / 2.0f, widthLowerArm / 2.0f, lenLowerArm / 2.0f ) );
            glUniformMatrix4( modelToCameraMatrixUnif, false,
                    modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
            glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
            modelToCameraStack.pop();

            drawWrist( modelToCameraStack );

            modelToCameraStack.pop();
        }

        void drawWrist(MatrixStack modelToCameraStack) {
            modelToCameraStack.push();
            modelToCameraStack.translate( posWrist );
            modelToCameraStack.rotateZ( angWristRoll );
            modelToCameraStack.rotateX( angWristPitch );

            modelToCameraStack.push();
            modelToCameraStack.scale( new Vec3( widthWrist / 2.0f, widthWrist / 2.0f, lenWrist / 2.0f ) );
            glUniformMatrix4( modelToCameraMatrixUnif, false,
                    modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
            glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
            modelToCameraStack.pop();

            drawFingers( modelToCameraStack );

            modelToCameraStack.pop();
        }

        void drawFingers(MatrixStack modelToCameraStack) {
            // Draw left finger
            modelToCameraStack.push();
            modelToCameraStack.translate( posLeftFinger );
            modelToCameraStack.rotateY( angFingerOpen );

            modelToCameraStack.push();
            modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, lenFinger / 2.0f ) );
            modelToCameraStack.scale( new Vec3( widthFinger / 2.0f, widthFinger / 2.0f, lenFinger / 2.0f ) );
            glUniformMatrix4( modelToCameraMatrixUnif, false,
                    modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
            glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
            modelToCameraStack.pop();

            {
                // Draw left lower finger
                modelToCameraStack.push();
                modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, lenFinger ) );
                modelToCameraStack.rotateY( -angLowerFinger );

                modelToCameraStack.push();
                modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, lenFinger / 2.0f ) );
                modelToCameraStack.scale( new Vec3( widthFinger / 2.0f, widthFinger / 2.0f, lenFinger / 2.0f ) );
                glUniformMatrix4( modelToCameraMatrixUnif, false,
                        modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
                glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
                modelToCameraStack.pop();

                modelToCameraStack.pop();
            }

            modelToCameraStack.pop();

            // Draw right finger
            modelToCameraStack.push();
            modelToCameraStack.translate( posRightFinger );
            modelToCameraStack.rotateY( -angFingerOpen );

            modelToCameraStack.push();
            modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, lenFinger / 2.0f ) );
            modelToCameraStack.scale( new Vec3( widthFinger / 2.0f, widthFinger / 2.0f, lenFinger / 2.0f ) );
            glUniformMatrix4( modelToCameraMatrixUnif, false,
                    modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
            glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
            modelToCameraStack.pop();

            {
                // Draw right lower finger
                modelToCameraStack.push();
                modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, lenFinger ) );
                modelToCameraStack.rotateY( angLowerFinger );

                modelToCameraStack.push();
                modelToCameraStack.translate( new Vec3( 0.0f, 0.0f, lenFinger / 2.0f ) );
                modelToCameraStack.scale( new Vec3( widthFinger / 2.0f, widthFinger / 2.0f, lenFinger / 2.0f ) );
                glUniformMatrix4( modelToCameraMatrixUnif, false,
                        modelToCameraStack.top().fillAndFlipBuffer( mat4Buffer ) );
                glDrawElements( GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0 );
                modelToCameraStack.pop();

                modelToCameraStack.pop();
            }

            modelToCameraStack.pop();
        }


        void adjBase(boolean increment) {
            float lastFrameDuration = getLastFrameDuration() * 5 / 1000.0f;
            angBase += increment ?
                    STANDARD_ANGLE_INCREMENT * lastFrameDuration :
                    -STANDARD_ANGLE_INCREMENT * lastFrameDuration;
            angBase = angBase % 360.0f;
        }

        void adjUpperArm(boolean increment) {
            float lastFrameDuration = getLastFrameDuration() * 5 / 1000.0f;
            angUpperArm += increment ?
                    STANDARD_ANGLE_INCREMENT * lastFrameDuration :
                    -STANDARD_ANGLE_INCREMENT * lastFrameDuration;
            angUpperArm = clamp( angUpperArm, -90.0f, 0.0f );
        }

        void adjLowerArm(boolean increment) {
            float lastFrameDuration = getLastFrameDuration() * 5 / 1000.0f;
            angLowerArm += increment ?
                    STANDARD_ANGLE_INCREMENT * lastFrameDuration :
                    -STANDARD_ANGLE_INCREMENT * lastFrameDuration;
            angLowerArm = clamp( angLowerArm, 0.0f, 146.25f );
        }

        void adjWristPitch(boolean increment) {
            float lastFrameDuration = getLastFrameDuration() * 5 / 1000.0f;
            angWristPitch += increment ?
                    STANDARD_ANGLE_INCREMENT * lastFrameDuration :
                    -STANDARD_ANGLE_INCREMENT * lastFrameDuration;
            angWristPitch = clamp( angWristPitch, 0.0f, 90.0f );
        }

        void adjWristRoll(boolean increment) {
            float lastFrameDuration = getLastFrameDuration() * 5 / 1000.0f;
            angWristRoll += increment ?
                    STANDARD_ANGLE_INCREMENT * lastFrameDuration :
                    -STANDARD_ANGLE_INCREMENT * lastFrameDuration;
            angWristRoll = angWristRoll % 360.0f;
        }

        void adjFingerOpen(boolean increment) {
            float lastFrameDuration = getLastFrameDuration() * 5 / 1000.0f;
            angFingerOpen += increment ?
                    SMALL_ANGLE_INCREMENT * lastFrameDuration :
                    -SMALL_ANGLE_INCREMENT * lastFrameDuration;
            angFingerOpen = clamp( angFingerOpen, 9.0f, 90.0f );
        }


        void writePose() {
            System.out.printf( "angBase:\t%f\n", angBase );
            System.out.printf( "angUpperArm:\t%f\n", angUpperArm );
            System.out.printf( "angLowerArm:\t%f\n", angLowerArm );
            System.out.printf( "angWristPitch:\t%f\n", angWristPitch );
            System.out.printf( "angWristRoll:\t%f\n", angWristRoll );
            System.out.printf( "angFingerOpen:\t%f\n", angFingerOpen );
            System.out.printf( "\n" );
        }
    }


    private Mat3 rotateX(float angDeg) {
        float angRad = degToRad( angDeg );
        float cos = (float) Math.cos( angRad );
        float sin = (float) Math.sin( angRad );

        Mat3 theMat = new Mat3( 1.0f );
        theMat.set( 1, 1, cos );
        theMat.set( 2, 1, -sin );
        theMat.set( 1, 2, sin );
        theMat.set( 2, 2, cos );
        return theMat;
    }

    private Mat3 rotateY(float angDeg) {
        float angRad = degToRad( angDeg );
        float cos = (float) Math.cos( angRad );
        float sin = (float) Math.sin( angRad );

        Mat3 theMat = new Mat3( 1.0f );
        theMat.set( 0, 0, cos );
        theMat.set( 2, 0, sin );
        theMat.set( 0, 2, -sin );
        theMat.set( 2, 2, cos );
        return theMat;
    }

    private Mat3 rotateZ(float angDeg) {
        float angRad = degToRad( angDeg );
        float cos = (float) Math.cos( angRad );
        float sin = (float) Math.sin( angRad );

        Mat3 theMat = new Mat3( 1.0f );
        theMat.set( 0, 0, cos );
        theMat.set( 1, 0, -sin );
        theMat.set( 0, 1, sin );
        theMat.set( 1, 1, cos );
        return theMat;
    }

    private float degToRad(float angDeg) {
        final float degToRad = 3.14159f * 2.0f / 360.0f;
        return angDeg * degToRad;
    }


    private float clamp(float value, float minValue, float maxValue) {
        if ( value < minValue ) { return minValue; }
        if ( value > maxValue ) { return maxValue; }
        return value;
    }
}
TOP

Related Classes of fcagnin.jgltut.tut06.Hierarchy$Armature

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.