• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.tests.g3d;
18 
19 import com.badlogic.gdx.Gdx;
20 import com.badlogic.gdx.Input.Keys;
21 import com.badlogic.gdx.graphics.Color;
22 import com.badlogic.gdx.graphics.GL20;
23 import com.badlogic.gdx.graphics.g3d.Material;
24 import com.badlogic.gdx.graphics.g3d.Model;
25 import com.badlogic.gdx.graphics.g3d.ModelBatch;
26 import com.badlogic.gdx.graphics.g3d.ModelInstance;
27 import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute;
28 import com.badlogic.gdx.graphics.g3d.model.Animation;
29 import com.badlogic.gdx.graphics.g3d.model.Node;
30 import com.badlogic.gdx.graphics.g3d.utils.AnimationController;
31 import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
32 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
33 import com.badlogic.gdx.math.Quaternion;
34 import com.badlogic.gdx.math.Vector3;
35 import com.badlogic.gdx.utils.Array;
36 import com.badlogic.gdx.utils.ObjectMap;
37 import com.badlogic.gdx.utils.Pool;
38 import com.badlogic.gdx.utils.StringBuilder;
39 
40 public class SkeletonTest extends BaseG3dHudTest {
41 	ShapeRenderer shapeRenderer;
42 	ObjectMap<ModelInstance, AnimationController> animationControllers = new ObjectMap<ModelInstance, AnimationController>();
43 
44 	@Override
create()45 	public void create () {
46 		super.create();
47 		showAxes = false;
48 		shapeRenderer = new ShapeRenderer();
49 		shapeRenderer.setColor(Color.WHITE);
50 		onModelClicked("g3d/knight.g3db");
51 	}
52 
53 	private final static Vector3 tmpV = new Vector3();
54 	private final static Pool<Vector3> vectorPool = new Pool<Vector3>() {
55 		@Override
56 		protected Vector3 newObject () {
57 			return new Vector3();
58 		}
59 	};
60 	private final static Quaternion tmpQ = new Quaternion();
61 
62 	@Override
render(ModelBatch batch, Array<ModelInstance> instances)63 	protected void render (ModelBatch batch, Array<ModelInstance> instances) {
64 		for (ObjectMap.Entry<ModelInstance, AnimationController> e : animationControllers.entries())
65 			e.value.update(Gdx.graphics.getDeltaTime());
66 		for (final ModelInstance instance : instances)
67 			renderSkeleton(instance);
68 		batch.render(instances);
69 	}
70 
renderSkeleton(final ModelInstance instance)71 	public void renderSkeleton (final ModelInstance instance) {
72 		shapeRenderer.setProjectionMatrix(cam.combined);
73 		shapeRenderer.begin(ShapeType.Line);
74 		for (Node node : instance.nodes) {
75 			shapeRenderer.setColor(node.isAnimated ? Color.RED : Color.YELLOW);
76 			node.globalTransform.getTranslation(tmpV);
77 			shapeRenderer.box(tmpV.x, tmpV.y, tmpV.z, 0.5f, 0.5f, 0.5f);
78 			for (Node child : node.getChildren())
79 				renderSkeleton(tmpV, child);
80 		}
81 		shapeRenderer.end();
82 	}
83 
renderSkeleton(final Vector3 from, final Node node)84 	public void renderSkeleton (final Vector3 from, final Node node) {
85 		final Vector3 pos = vectorPool.obtain();
86 		node.globalTransform.getTranslation(pos);
87 		shapeRenderer.setColor(node.isAnimated ? Color.RED : Color.YELLOW);
88 		shapeRenderer.box(pos.x, pos.y, pos.z, 0.5f, 0.5f, 0.5f);
89 		shapeRenderer.setColor(Color.WHITE);
90 		shapeRenderer.line(from.x, from.y, from.z, pos.x, pos.y, pos.z);
91 		for (Node child : node.getChildren())
92 			renderSkeleton(pos, child);
93 		vectorPool.free(pos);
94 	}
95 
96 	@Override
getStatus(StringBuilder stringBuilder)97 	protected void getStatus (StringBuilder stringBuilder) {
98 		super.getStatus(stringBuilder);
99 
100 		for (final ModelInstance instance : instances) {
101 			if (instance.animations.size > 0) {
102 				stringBuilder.append(" press space or menu to switch animation");
103 				break;
104 			}
105 		}
106 	}
107 
108 	protected String currentlyLoading;
109 
110 	@Override
onModelClicked(final String name)111 	protected void onModelClicked (final String name) {
112 		if (name == null) return;
113 
114 		currentlyLoading = "data/" + name;
115 		assets.load(currentlyLoading, Model.class);
116 		loading = true;
117 	}
118 
119 	@Override
onLoaded()120 	protected void onLoaded () {
121 		if (currentlyLoading == null || currentlyLoading.isEmpty()) return;
122 
123 		instances.clear();
124 		animationControllers.clear();
125 		final ModelInstance instance = new ModelInstance(assets.get(currentlyLoading, Model.class));
126 		for (Material m : instance.materials)
127 			m.set(new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, 0.8f));
128 		instances.add(instance);
129 		if (instance.animations.size > 0) animationControllers.put(instance, new AnimationController(instance));
130 		currentlyLoading = null;
131 	}
132 
switchAnimation()133 	protected void switchAnimation () {
134 		for (ObjectMap.Entry<ModelInstance, AnimationController> e : animationControllers.entries()) {
135 			int animIndex = 0;
136 			if (e.value.current != null) {
137 				for (int i = 0; i < e.key.animations.size; i++) {
138 					final Animation animation = e.key.animations.get(i);
139 					if (e.value.current.animation == animation) {
140 						animIndex = i;
141 						break;
142 					}
143 				}
144 			}
145 			animIndex = (animIndex + 1) % e.key.animations.size;
146 			e.value.animate(e.key.animations.get(animIndex).id, -1, 1f, null, 0.2f);
147 		}
148 	}
149 
150 	@Override
keyUp(int keycode)151 	public boolean keyUp (int keycode) {
152 		if (keycode == Keys.SPACE || keycode == Keys.MENU) switchAnimation();
153 		return super.keyUp(keycode);
154 	}
155 }
156