OSDN Git Service

Merge pull request #430 from dylanetaft/master
[mikumikustudio/libgdx-mikumikustudio.git] / tests / gdx-tests / src / com / badlogic / gdx / tests / g3d / SkeletonTest.java
1 package com.badlogic.gdx.tests.g3d;
2
3 import com.badlogic.gdx.Gdx;
4 import com.badlogic.gdx.Input.Keys;
5 import com.badlogic.gdx.graphics.Color;
6 import com.badlogic.gdx.graphics.GL10;
7 import com.badlogic.gdx.graphics.g3d.Model;
8 import com.badlogic.gdx.graphics.g3d.ModelBatch;
9 import com.badlogic.gdx.graphics.g3d.ModelInstance;
10 import com.badlogic.gdx.graphics.g3d.materials.BlendingAttribute;
11 import com.badlogic.gdx.graphics.g3d.model.Animation;
12 import com.badlogic.gdx.graphics.g3d.model.Node;
13 import com.badlogic.gdx.graphics.g3d.model.NodeAnimation;
14 import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
15 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
16 import com.badlogic.gdx.math.Quaternion;
17 import com.badlogic.gdx.math.Vector3;
18 import com.badlogic.gdx.utils.Array;
19 import com.badlogic.gdx.utils.Pool;
20 import com.badlogic.gdx.utils.StringBuilder;
21
22 public class SkeletonTest extends BaseG3dHudTest {
23         ShapeRenderer shapeRenderer;
24         
25         @Override
26         public void create () {
27                 super.create();
28                 showAxes = false;
29                 shapeRenderer = new ShapeRenderer();
30                 shapeRenderer.setColor(Color.WHITE);
31                 onModelClicked("g3d/knight.g3db");
32         }
33         
34         private final static Vector3 tmpV = new Vector3();
35         private final static Pool<Vector3> vectorPool = new Pool<Vector3>() {
36                 @Override
37                 protected Vector3 newObject () {
38                         return new Vector3();
39                 }
40         };
41         private final static Quaternion tmpQ = new Quaternion();
42         @Override
43         protected void render (ModelBatch batch, Array<ModelInstance> instances) {
44                 for (final ModelInstance instance : instances) {
45                         updateAnimation(instance);
46                         renderSkeleton(instance);
47                 }
48                 batch.render(instances);
49         }
50         
51         public void renderSkeleton(final ModelInstance instance) {
52                 shapeRenderer.setProjectionMatrix(cam.combined);
53                 shapeRenderer.begin(ShapeType.Line);
54                 for (Node node : instance.nodes) {
55                         shapeRenderer.setColor(node.isAnimated ? Color.RED : Color.YELLOW);
56                         node.globalTransform.getTranslation(tmpV);
57                         shapeRenderer.box(tmpV.x, tmpV.y, tmpV.z, 0.5f, 0.5f, 0.5f);
58                         for (Node child : node.children)
59                                 renderSkeleton(tmpV, child);
60                 }
61                 shapeRenderer.end();
62         }
63         
64         public void renderSkeleton(final Vector3 from, final Node node) {
65                 final Vector3 pos = vectorPool.obtain();
66                 node.globalTransform.getTranslation(pos);
67                 shapeRenderer.setColor(node.isAnimated ? Color.RED : Color.YELLOW);
68                 shapeRenderer.box(pos.x, pos.y, pos.z, 0.5f, 0.5f, 0.5f);
69                 shapeRenderer.setColor(Color.WHITE);
70                 shapeRenderer.line(from.x, from.y, from.z, pos.x, pos.y, pos.z);
71                 for (Node child : node.children)
72                         renderSkeleton(pos, child);
73                 vectorPool.free(pos);
74         }
75         
76         @Override
77         protected void getStatus (StringBuilder stringBuilder) {
78                 super.getStatus(stringBuilder);
79
80                 for (final ModelInstance instance : instances) {
81                         if (instance.animations.size > 0) {
82                                 stringBuilder.append(" press space or menu to switch animation");
83                                 break;
84                         }
85                 }
86         }
87
88         protected String currentlyLoading;
89         @Override
90         protected void onModelClicked(final String name) {
91                 if (name == null)
92                         return;
93                 
94                 currentlyLoading = "data/"+name; 
95                 assets.load(currentlyLoading, Model.class);
96                 loading = true;
97         }
98         
99         @Override
100         protected void onLoaded() {
101                 if (currentlyLoading == null || currentlyLoading.isEmpty())
102                         return;
103                 
104                 instances.clear();
105                 final ModelInstance instance = new ModelInstance(assets.get(currentlyLoading, Model.class));
106                 instance.materials.get(0).set(new BlendingAttribute(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA, 0.5f));
107                 instances.add(instance);
108                 currentlyLoading = null;
109         }
110         
111         protected void switchAnimation() {
112                 for (final ModelInstance instance : instances) {
113                         if (instance.animations.size > 0) {
114                                 if (instance.currentAnimation != null) {
115                                         for (final NodeAnimation nodeAnim : instance.currentAnimation.nodeAnimations)
116                                                 nodeAnim.node.isAnimated = false;
117                                         instance.calculateTransforms();
118                                 }
119                                 int animIndex = -1;
120                                 for (int i = 0; i < instance.animations.size; i++) {
121                                         final Animation animation = instance.animations.get(i);
122                                         if (instance.currentAnimation == animation) {
123                                                 animIndex = i;
124                                                 break;
125                                         }
126                                 }
127                                 animIndex = (animIndex + 1) % (instance.animations.size + 1);
128                                 instance.currentAnimation = animIndex == instance.animations.size ? null : instance.animations.get(animIndex);
129                                 instance.currentAnimTime = 0f;
130                         }
131                 }
132         }
133         
134         @Override
135         public boolean needsGL20 () {
136                 return true;
137         }
138         
139         @Override
140         public boolean keyUp (int keycode) {
141                 if (keycode == Keys.SPACE || keycode == Keys.MENU)
142                         switchAnimation();
143                 return super.keyUp(keycode);
144         }
145         
146         public void updateAnimation(final ModelInstance instance) {
147                 if (instance.currentAnimation != null) {
148                         instance.currentAnimTime = (instance.currentAnimTime + Gdx.graphics.getDeltaTime()) % instance.currentAnimation.duration;
149                         for (final NodeAnimation nodeAnim : instance.currentAnimation.nodeAnimations) {
150                                 nodeAnim.node.isAnimated = true;
151                                 final int n = nodeAnim.keyframes.size - 1;
152                                 if (n == 0) {
153                                         nodeAnim.node.localTransform.idt().
154                                                 translate(nodeAnim.keyframes.get(0).translation).
155                                                 rotate(nodeAnim.keyframes.get(0).rotation).
156                                                 scl(nodeAnim.keyframes.get(0).scale);                                   
157                                 }
158                                 for (int i = 0; i < n; i++) {
159                                         if (instance.currentAnimTime >= nodeAnim.keyframes.get(i).keytime && instance.currentAnimTime <= nodeAnim.keyframes.get(i+1).keytime) {
160                                                 final float t = (instance.currentAnimTime - nodeAnim.keyframes.get(i).keytime) / (nodeAnim.keyframes.get(i+1).keytime - nodeAnim.keyframes.get(i).keytime);
161                                                 nodeAnim.node.localTransform.idt().
162                                                         translate(tmpV.set(nodeAnim.keyframes.get(i).translation).lerp(nodeAnim.keyframes.get(i+1).translation, t)).
163                                                         rotate(tmpQ.set(nodeAnim.keyframes.get(i).rotation).slerp(nodeAnim.keyframes.get(i+1).rotation, t)).
164                                                         scl(tmpV.set(nodeAnim.keyframes.get(i).scale).lerp(nodeAnim.keyframes.get(i+1).scale, t));
165                                                 break;
166                                         }
167                                 }
168                         }
169                         instance.calculateTransforms();
170                 }
171         }
172 }