Package com.ardor3d.example.pipeline

Source Code of com.ardor3d.example.pipeline.PrimitiveSkeletonExample

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.example.pipeline;

import java.io.IOException;

import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.animation.skeletal.Joint;
import com.ardor3d.extension.animation.skeletal.Skeleton;
import com.ardor3d.extension.animation.skeletal.SkeletonPose;
import com.ardor3d.extension.animation.skeletal.SkinnedMesh;
import com.ardor3d.extension.animation.skeletal.util.SkeletalDebugger;
import com.ardor3d.framework.Canvas;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Transform;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.GLSLShaderObjectsState;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Cylinder;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.geom.BufferUtils;
import com.ardor3d.util.resource.ResourceLocatorTool;

/**
* A demonstration of combining the skeletal animation classes with OpenGL Shading Language.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.pipeline.PrimitiveSkeletonExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/pipeline_PrimitiveSkeletonExample.jpg", //
maxHeapMemory = 64)
public class PrimitiveSkeletonExample extends ExampleBase {

    private boolean runAnimation = true;
    private boolean showSkeleton = false;
    private boolean useGPU = false;

    private SkeletonPose pose1, pose2;
    private SkinnedMesh arm, arm1, arm2;
    private BasicText t1, t2, t3;

    public static void main(final String[] args) {
        ExampleBase.start(PrimitiveSkeletonExample.class);
    }

    @Override
    protected void initExample() {
        final Transform j1Transform = new Transform();
        j1Transform.setTranslation(0, 0, -5);
        j1Transform.invert(j1Transform);
        final Joint j1 = new Joint("j1");
        j1.setInverseBindPose(j1Transform);
        j1.setParentIndex(Joint.NO_PARENT);

        final Transform j2Transform = new Transform();
        j2Transform.setTranslation(0, 0, 5);
        j2Transform.invert(j2Transform);
        final Joint j2 = new Joint("j2");
        j2.setInverseBindPose(j2Transform);
        j2.setParentIndex((short) 0);

        final Skeleton sk = new Skeleton("arm sk", new Joint[] { j1, j2 });

        pose1 = new SkeletonPose(sk);
        pose1.updateTransforms();
        pose2 = new SkeletonPose(sk);
        pose2.updateTransforms();

        arm = new SkinnedMesh("arm");
        final Cylinder cy = new Cylinder("cylinder", 3, 8, 1, 10);
        arm.setBindPoseData(cy.getMeshData());
        arm.getMeshData().setVertexBuffer(BufferUtils.createFloatBuffer(cy.getMeshData().getVertexBuffer().capacity()));
        arm.getMeshData().setNormalBuffer(BufferUtils.createFloatBuffer(cy.getMeshData().getNormalBuffer().capacity()));
        arm.getMeshData().setIndices(BufferUtils.clone(cy.getMeshData().getIndices()));
        arm.getMeshData().setTextureBuffer(BufferUtils.clone(cy.getMeshData().getTextureBuffer(0)), 0);
        arm.setTranslation(0, 0, -10);
        arm.getSceneHints().setCullHint(CullHint.Dynamic);

        arm.setWeightsPerVert(4);

        final float[] weights = { //
        1, 0, 0, 0, //
                1, 0, 0, 0, //
                1, 0, 0, 0, //
                1, 0, 0, 0, //
                1, 0, 0, 0, //
                1, 0, 0, 0, //
                1, 0, 0, 0, //
                1, 0, 0, 0, //
                1, 0, 0, 0, //

                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //
                0.5f, 0.5f, 0, 0, //

                0, 1, 0, 0, //
                0, 1, 0, 0, //
                0, 1, 0, 0, //
                0, 1, 0, 0, //
                0, 1, 0, 0, //
                0, 1, 0, 0, //
                0, 1, 0, 0, //
                0, 1, 0, 0, //
                0, 1, 0, 0 //
        };
        arm.setWeights(weights);

        final short[] indices = new short[4 * 27];
        for (int i = 0; i < 27; i++) {
            indices[i * 4 + 0] = 0;
            indices[i * 4 + 1] = 1;
            indices[i * 4 + 2] = 0;
            indices[i * 4 + 3] = 0;
        }
        arm.setJointIndices(indices);

        final GLSLShaderObjectsState gpuShader = new GLSLShaderObjectsState();
        gpuShader.setEnabled(useGPU);
        try {
            gpuShader.setVertexShader(ResourceLocatorTool.getClassPathResourceAsStream(PrimitiveSkeletonExample.class,
                    "com/ardor3d/extension/animation/skeletal/skinning_gpu.vert"));
            gpuShader.setFragmentShader(ResourceLocatorTool.getClassPathResourceAsStream(PrimitiveSkeletonExample.class,
                    "com/ardor3d/extension/animation/skeletal/skinning_gpu.frag"));
        } catch (final IOException ioe) {
            ioe.printStackTrace();
        }
        arm.setGPUShader(gpuShader);
        arm.setUseGPU(useGPU);

        arm1 = arm.makeCopy(true);
        arm2 = arm.makeCopy(true);

        arm1.setCurrentPose(pose1);
        arm2.setCurrentPose(pose2);

        arm1.addTranslation(1, 0, 0);
        arm2.addTranslation(-1, 0, 0);

        _root.attachChild(arm1);
        _root.attachChild(arm2);

        t1 = BasicText.createDefaultTextLabel("Text1", "[SPACE] Pause joint animation.");
        t1.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
        t1.getSceneHints().setLightCombineMode(LightCombineMode.Off);
        t1.setTranslation(new Vector3(5, 2 * (t1.getHeight() + 5) + 10, 0));
        _root.attachChild(t1);

        t2 = BasicText.createDefaultTextLabel("Text2", "[G] GPU Skinning is " + (useGPU ? "ON." : "OFF."));
        t2.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
        t2.getSceneHints().setLightCombineMode(LightCombineMode.Off);
        t2.setTranslation(new Vector3(5, 1 * (t1.getHeight() + 5) + 10, 0));
        _root.attachChild(t2);

        t3 = BasicText.createDefaultTextLabel("Text3", "[K] Show Skeleton.");
        t3.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
        t3.getSceneHints().setLightCombineMode(LightCombineMode.Off);
        t3.setTranslation(new Vector3(5, 0 * (t1.getHeight() + 5) + 10, 0));
        _root.attachChild(t3);
        _root.getSceneHints().setCullHint(CullHint.Never);

        _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.K), new TriggerAction() {
            public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
                showSkeleton = !showSkeleton;
                if (showSkeleton) {
                    t3.setText("[K] Hide Skeleton.");
                } else {
                    t3.setText("[K] Show Skeleon.");
                }
            }
        }));

        _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
            public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
                useGPU = !useGPU;
                arm1.getGPUShader().setEnabled(useGPU);
                arm1.setUseGPU(useGPU);
                arm2.getGPUShader().setEnabled(useGPU);
                arm2.setUseGPU(useGPU);
                if (useGPU) {
                    t2.setText("[G] GPU Skinning is ON.");
                } else {
                    t2.setText("[G] GPU Skinning is OFF.");
                }
            }
        }));

        _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
            public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
                runAnimation = !runAnimation;
                if (runAnimation) {
                    t1.setText("[SPACE] Pause joint animation.");
                } else {
                    t1.setText("[SPACE] Start joint animation.");
                }
            }
        }));
    }

    @Override
    protected void renderDebug(final Renderer renderer) {
        super.renderDebug(renderer);

        if (showSkeleton) {
            SkeletalDebugger.drawSkeletons(_root, renderer, true, false);
        }
    }

    double angle = 0;

    private double counter = 0;
    private int frames = 0;

    @Override
    protected void updateExample(final ReadOnlyTimer timer) {
        counter += timer.getTimePerFrame();
        frames++;
        if (counter > 1) {
            final double fps = frames / counter;
            counter = 0;
            frames = 0;
            System.out.printf("%7.1f FPS\n", fps);
        }

        if (runAnimation) {
            angle += timer.getTimePerFrame() * 50;
            angle %= 360;

            // move the end of the arm up and down.
            final Transform t1 = pose1.getLocalJointTransforms()[1];
            t1.setTranslation(t1.getTranslation().getX(), Math.sin(angle * MathUtils.DEG_TO_RAD) * 2, t1
                    .getTranslation().getZ());

            final Transform t2 = pose2.getLocalJointTransforms()[1];
            t2.setTranslation(t2.getTranslation().getX(), Math.cos(angle * MathUtils.DEG_TO_RAD) * 2, t2
                    .getTranslation().getZ());

            pose1.updateTransforms();
            pose2.updateTransforms();

            if (!useGPU) {
                // no point to updating the model bound in gpu mode
                arm1.updateModelBound();
                arm2.updateModelBound();
            }
        }
    }
}
TOP

Related Classes of com.ardor3d.example.pipeline.PrimitiveSkeletonExample

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.