PageRenderTime 58ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/model-loaders/model-loaders/src/com/badlogic/gdx/graphics/g3d/loaders/ogre/OgreXmlLoader.java

https://github.com/Tapay/libgdx
Java | 534 lines | 455 code | 63 blank | 16 comment | 93 complexity | 01e90f8d4d782eaa74191fc6b75febd9 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, CC-BY-SA-3.0, Apache-2.0, GPL-2.0
  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. package com.badlogic.gdx.graphics.g3d.loaders.ogre;
  17. import java.io.InputStream;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import javax.xml.bind.JAXBContext;
  23. import javax.xml.bind.JAXBException;
  24. import javax.xml.bind.Unmarshaller;
  25. import com.badlogic.gdx.files.FileHandle;
  26. import com.badlogic.gdx.graphics.Color;
  27. import com.badlogic.gdx.graphics.GL10;
  28. import com.badlogic.gdx.graphics.VertexAttribute;
  29. import com.badlogic.gdx.graphics.VertexAttributes;
  30. import com.badlogic.gdx.graphics.VertexAttributes.Usage;
  31. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.BaseGeometry;
  32. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Boneassignments;
  33. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.ColourDiffuse;
  34. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Face;
  35. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Geometry;
  36. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Mesh;
  37. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Submesh;
  38. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Submeshname;
  39. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Texcoord;
  40. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Vertex;
  41. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Vertexboneassignment;
  42. import com.badlogic.gdx.graphics.g3d.loaders.ogre.mesh.Vertexbuffer;
  43. import com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Animation;
  44. import com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Bone;
  45. import com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Boneparent;
  46. import com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Keyframe;
  47. import com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Track;
  48. import com.badlogic.gdx.graphics.g3d.model.SubMesh;
  49. import com.badlogic.gdx.graphics.g3d.model.skeleton.Skeleton;
  50. import com.badlogic.gdx.graphics.g3d.model.skeleton.SkeletonAnimation;
  51. import com.badlogic.gdx.graphics.g3d.model.skeleton.SkeletonJoint;
  52. import com.badlogic.gdx.graphics.g3d.model.skeleton.SkeletonKeyframe;
  53. import com.badlogic.gdx.graphics.g3d.model.skeleton.SkeletonModel;
  54. import com.badlogic.gdx.graphics.g3d.model.skeleton.SkeletonSubMesh;
  55. import com.badlogic.gdx.graphics.g3d.model.still.StillModel;
  56. import com.badlogic.gdx.graphics.g3d.model.still.StillSubMesh;
  57. import com.badlogic.gdx.graphics.glutils.ShaderProgram;
  58. import com.badlogic.gdx.math.MathUtils;
  59. import com.badlogic.gdx.math.Matrix4;
  60. import com.badlogic.gdx.utils.Array;
  61. import com.badlogic.gdx.utils.FloatArray;
  62. import com.badlogic.gdx.utils.GdxRuntimeException;
  63. import com.badlogic.gdx.utils.IntArray;
  64. public class OgreXmlLoader {
  65. public SubMesh[] loadMeshes (FileHandle file) {
  66. InputStream in = null;
  67. try {
  68. in = file.read();
  69. return loadMesh(in);
  70. } catch (Throwable t) {
  71. throw new GdxRuntimeException("Couldn't load file '" + file.name() + "'", t);
  72. } finally {
  73. if (in != null) try {
  74. in.close();
  75. } catch (Exception e) {
  76. }
  77. }
  78. }
  79. public SubMesh[] loadMesh (InputStream in) {
  80. try {
  81. Mesh ogreMesh = loadOgreMesh(in);
  82. SubMesh[] meshes = generateSubMeshes(ogreMesh);
  83. return meshes;
  84. } catch (Throwable t) {
  85. throw new GdxRuntimeException("Couldn't load meshes", t);
  86. }
  87. }
  88. public SkeletonModel load (FileHandle mesh, FileHandle skeleton) {
  89. SubMesh[] meshes = loadMeshes(mesh);
  90. return new SkeletonModel(loadSkeleton(skeleton), meshes);
  91. }
  92. public StillModel load (FileHandle mesh) {
  93. SubMesh[] meshes = loadMeshes(mesh);
  94. return new StillModel(meshes);
  95. }
  96. private SubMesh[] generateSubMeshes (Mesh ogreMesh) {
  97. List<Submesh> ogreSubmeshes = ogreMesh.getSubmeshes().getSubmesh();
  98. SubMesh[] submeshes = new SubMesh[ogreSubmeshes.size()];
  99. for (int i = 0; i < ogreSubmeshes.size(); i++) {
  100. Submesh ogreSubmesh = ogreSubmeshes.get(i);
  101. boolean usesTriangleList = false;
  102. if (ogreSubmesh.use32Bitindexes) throw new GdxRuntimeException("submesh '" + i + "' uses 32-bit indices");
  103. if (ogreSubmesh.getOperationtype().equals("triangle_list")) {
  104. usesTriangleList = true;
  105. }
  106. short[] indices = new short[ogreSubmesh.getFaces().count * (usesTriangleList ? 3 : 1)];
  107. for (int j = 0, idx = 0; j < ogreSubmesh.getFaces().count; j++) {
  108. Face face = ogreSubmesh.getFaces().getFace().get(j);
  109. indices[idx++] = face.v1;
  110. if (usesTriangleList || j == 0) {
  111. indices[idx++] = face.v2;
  112. indices[idx++] = face.v3;
  113. }
  114. }
  115. List<VertexAttribute> attributes = new ArrayList<VertexAttribute>();
  116. IntArray offsets = new IntArray();
  117. int offset = 0;
  118. BaseGeometry geom;
  119. if (ogreSubmesh.useSharedVertices) {
  120. geom = ogreMesh.getSharedgeometry();
  121. } else {
  122. geom = ogreSubmesh.getGeometry();
  123. }
  124. for (int j = 0; j < geom.getVertexbuffer().size(); j++) {
  125. Vertexbuffer buffer = geom.getVertexbuffer().get(j);
  126. offsets.add(offset);
  127. if (buffer.positions) {
  128. attributes.add(new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE));
  129. offset += 3;
  130. }
  131. if (buffer.normals) {
  132. attributes.add(new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
  133. offset += 3;
  134. }
  135. if (buffer.tangents) {
  136. attributes.add(new VertexAttribute(Usage.Generic, buffer.tangentDimensions, ShaderProgram.TANGENT_ATTRIBUTE));
  137. offset += buffer.tangentDimensions;
  138. }
  139. if (buffer.binormals) {
  140. attributes.add(new VertexAttribute(Usage.Generic, 3, ShaderProgram.BINORMAL_ATTRIBUTE));
  141. offset += 3;
  142. }
  143. if (buffer.coloursDiffuse) {
  144. attributes.add(new VertexAttribute(Usage.ColorPacked, 4, ShaderProgram.COLOR_ATTRIBUTE));
  145. offset += 4;
  146. }
  147. for (int k = 0; k < buffer.textureCoords; k++) {
  148. try {
  149. int numTexCoords = 0;
  150. switch (k) {
  151. case 0:
  152. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions0());
  153. break;
  154. case 1:
  155. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions1());
  156. break;
  157. case 2:
  158. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions2());
  159. break;
  160. case 3:
  161. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions3());
  162. break;
  163. case 4:
  164. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions4());
  165. break;
  166. case 5:
  167. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions5());
  168. break;
  169. case 6:
  170. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions6());
  171. break;
  172. case 7:
  173. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions7());
  174. break;
  175. }
  176. attributes
  177. .add(new VertexAttribute(Usage.TextureCoordinates, numTexCoords, ShaderProgram.TEXCOORD_ATTRIBUTE + k));
  178. offset += numTexCoords;
  179. } catch (NumberFormatException e) {
  180. throw new GdxRuntimeException("Can't process texture coords with dimensions != 1, 2, 3, 4 (e.g. float1)");
  181. }
  182. }
  183. }
  184. VertexAttributes attribs = new VertexAttributes(attributes.toArray(new VertexAttribute[0]));
  185. int vertexSize = offset;
  186. float[] vertices = new float[geom.getVertexCount() * offset];
  187. for (int j = 0; j < geom.getVertexbuffer().size(); j++) {
  188. Vertexbuffer buffer = geom.getVertexbuffer().get(j);
  189. offset = offsets.get(j);
  190. int idx = offset;
  191. for (int k = 0; k < buffer.getVertex().size(); k++) {
  192. Vertex v = buffer.getVertex().get(k);
  193. if (v.getPosition() != null) {
  194. vertices[idx++] = v.getPosition().x;
  195. vertices[idx++] = v.getPosition().y;
  196. vertices[idx++] = v.getPosition().z;
  197. }
  198. if (v.getNormal() != null) {
  199. vertices[idx++] = v.getNormal().x;
  200. vertices[idx++] = v.getNormal().y;
  201. vertices[idx++] = v.getNormal().z;
  202. }
  203. if (v.getTangent() != null) {
  204. vertices[idx++] = v.getTangent().x;
  205. vertices[idx++] = v.getTangent().y;
  206. vertices[idx++] = v.getTangent().z;
  207. if (buffer.tangentDimensions == 4) vertices[idx++] = v.getTangent().w;
  208. }
  209. if (v.getBinormal() != null) {
  210. vertices[idx++] = v.getBinormal().x;
  211. vertices[idx++] = v.getBinormal().y;
  212. vertices[idx++] = v.getBinormal().z;
  213. }
  214. if (v.getColourDiffuse() != null) {
  215. float color = getColor(v.getColourDiffuse());
  216. vertices[idx++] = color;
  217. }
  218. if (v.getTexcoord() != null) {
  219. for (int l = 0; l < v.getTexcoord().size(); l++) {
  220. Texcoord texCoord = v.getTexcoord().get(l);
  221. int numTexCoords = 0;
  222. switch (l) {
  223. case 0:
  224. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions0());
  225. break;
  226. case 1:
  227. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions1());
  228. break;
  229. case 2:
  230. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions2());
  231. break;
  232. case 3:
  233. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions3());
  234. break;
  235. case 4:
  236. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions4());
  237. break;
  238. case 5:
  239. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions5());
  240. break;
  241. case 6:
  242. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions6());
  243. break;
  244. case 7:
  245. numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions7());
  246. break;
  247. }
  248. if (numTexCoords == 1) {
  249. vertices[idx++] = texCoord.u;
  250. }
  251. if (numTexCoords == 2) {
  252. vertices[idx++] = texCoord.u;
  253. vertices[idx++] = texCoord.v;
  254. }
  255. if (numTexCoords == 3) {
  256. vertices[idx++] = texCoord.u;
  257. vertices[idx++] = texCoord.v;
  258. vertices[idx++] = texCoord.w;
  259. }
  260. if (numTexCoords == 4) {
  261. vertices[idx++] = texCoord.u;
  262. vertices[idx++] = texCoord.v;
  263. vertices[idx++] = texCoord.w;
  264. vertices[idx++] = texCoord.x;
  265. }
  266. }
  267. }
  268. offset += vertexSize;
  269. idx = offset;
  270. }
  271. }
  272. com.badlogic.gdx.graphics.Mesh mesh = new com.badlogic.gdx.graphics.Mesh(false, vertices.length / vertexSize,
  273. indices.length, attribs);
  274. mesh.setIndices(indices);
  275. mesh.setVertices(vertices);
  276. String meshName = "";
  277. if(ogreMesh.getSubmeshnames() != null) {
  278. List<Submeshname> names = ogreMesh.getSubmeshnames().getSubmeshname();
  279. for(int n = 0; n < names.size(); ++n) {
  280. if(Integer.parseInt(names.get(n).getIndex()) == i)
  281. meshName = names.get(n).getName();
  282. }
  283. }
  284. SubMesh subMesh;
  285. Boneassignments boneAssigments = (ogreSubmesh.getBoneassignments() != null)? ogreSubmesh.getBoneassignments() : ogreMesh.getBoneassignments();
  286. if (boneAssigments != null) {
  287. subMesh = new SkeletonSubMesh(meshName, mesh, GL10.GL_TRIANGLES);
  288. } else {
  289. subMesh = new StillSubMesh(meshName, mesh, GL10.GL_TRIANGLES);
  290. }
  291. // FIXME ? subMesh.materialName = ogreSubmesh.material;
  292. if (boneAssigments != null) {
  293. SkeletonSubMesh subSkelMesh = (SkeletonSubMesh) subMesh;
  294. subSkelMesh.setVertices(vertices);
  295. subSkelMesh.setIndices(indices);
  296. subSkelMesh.skinnedVertices = new float[vertices.length];
  297. System.arraycopy(subSkelMesh.vertices, 0, subSkelMesh.skinnedVertices, 0, subSkelMesh.vertices.length);
  298. loadBones(boneAssigments, subSkelMesh);
  299. }
  300. if (ogreSubmesh.getOperationtype().equals("triangle_list")) subMesh.primitiveType = GL10.GL_TRIANGLES;
  301. if (ogreSubmesh.getOperationtype().equals("triangle_fan")) subMesh.primitiveType = GL10.GL_TRIANGLE_FAN;
  302. if (ogreSubmesh.getOperationtype().equals("triangle_strip")) subMesh.primitiveType = GL10.GL_TRIANGLE_STRIP;
  303. submeshes[i] = subMesh;
  304. }
  305. return submeshes;
  306. }
  307. private void loadBones (Boneassignments boneAssigments, SkeletonSubMesh subMesh) {
  308. Array<IntArray> boneAssignments = new Array<IntArray>();
  309. Array<FloatArray> boneWeights = new Array<FloatArray>();
  310. for (int j = 0; j < subMesh.getMesh().getNumVertices(); j++) {
  311. boneAssignments.add(new IntArray(4));
  312. boneWeights.add(new FloatArray(4));
  313. }
  314. List<Vertexboneassignment> vertexboneassignment = boneAssigments.getVertexboneassignment();
  315. for (int j = 0; j < vertexboneassignment.size(); j++) {
  316. Vertexboneassignment assignment = vertexboneassignment.get(j);
  317. int boneIndex = assignment.boneindex;
  318. int vertexIndex = assignment.vertexindex;
  319. float weight = assignment.weight;
  320. boneAssignments.get(vertexIndex).add(boneIndex);
  321. boneWeights.get(vertexIndex).add(weight);
  322. }
  323. subMesh.boneAssignments = new int[boneAssignments.size][];
  324. subMesh.boneWeights = new float[boneWeights.size][];
  325. for (int j = 0; j < boneAssignments.size; j++) {
  326. subMesh.boneAssignments[j] = new int[boneAssignments.get(j).size];
  327. subMesh.boneWeights[j] = new float[boneWeights.get(j).size];
  328. for (int k = 0; k < boneAssignments.get(j).size; k++) {
  329. subMesh.boneAssignments[j][k] = boneAssignments.get(j).get(k);
  330. }
  331. for (int k = 0; k < boneWeights.get(j).size; k++) {
  332. subMesh.boneWeights[j][k] = boneWeights.get(j).get(k);
  333. }
  334. }
  335. }
  336. Color color = new Color();
  337. private float getColor (ColourDiffuse colourDiffuse) {
  338. String[] tokens = colourDiffuse.getValue().split(" ");
  339. if (tokens.length == 3)
  340. color.set(Float.valueOf(tokens[0]), Float.valueOf(tokens[1]), Float.valueOf(tokens[2]), 1);
  341. else
  342. color.set(Float.valueOf(tokens[0]), Float.valueOf(tokens[1]), Float.valueOf(tokens[2]), Float.valueOf(tokens[3]));
  343. return color.toFloatBits();
  344. }
  345. private Mesh loadOgreMesh (InputStream in) throws JAXBException {
  346. JAXBContext context = JAXBContext.newInstance(Mesh.class);
  347. Unmarshaller unmarshaller = context.createUnmarshaller();
  348. long start = System.nanoTime();
  349. Mesh mesh = (Mesh)unmarshaller.unmarshal(in);
  350. System.out.println("took: " + (System.nanoTime() - start) / 1000000000.0f);
  351. return mesh;
  352. }
  353. public Skeleton loadSkeleton (FileHandle file) {
  354. InputStream in = null;
  355. try {
  356. in = file.read();
  357. return loadSkeleton(in);
  358. } catch (Throwable t) {
  359. throw new GdxRuntimeException("Couldn't load file '" + file.name() + "'", t);
  360. } finally {
  361. if (in != null) try {
  362. in.close();
  363. } catch (Exception e) {
  364. }
  365. }
  366. }
  367. public Skeleton loadSkeleton (InputStream in) {
  368. try {
  369. com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Skeleton ogreSkel = loadOgreSkeleton(in);
  370. return generateSkeleton(ogreSkel);
  371. } catch (Throwable t) {
  372. throw new GdxRuntimeException("Couldn't load model", t);
  373. }
  374. }
  375. private Skeleton generateSkeleton (com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Skeleton ogreSkel) {
  376. List<Bone> bones = ogreSkel.getBones().getBone();
  377. List<SkeletonJoint> joints = new ArrayList<SkeletonJoint>();
  378. Map<String, SkeletonJoint> nameToJoint = new HashMap<String, SkeletonJoint>();
  379. for (int i = 0; i < bones.size(); i++) {
  380. Bone bone = bones.get(i);
  381. SkeletonJoint joint = new SkeletonJoint();
  382. joint.name = bone.name;
  383. joint.position.set(bone.position.x, bone.position.y, bone.position.z);
  384. joint.rotation.setFromAxis(bone.rotation.axis.x, bone.rotation.axis.y, bone.rotation.axis.z, MathUtils.radiansToDegrees
  385. * bone.rotation.angle);
  386. if (bone.scale != null) {
  387. if (bone.scale.factor == 0)
  388. joint.scale.set(bone.scale.x, bone.scale.y, bone.scale.z);
  389. else
  390. joint.scale.set(bone.scale.factor, bone.scale.factor, bone.scale.factor);
  391. }
  392. joints.add(joint);
  393. nameToJoint.put(joint.name, joint);
  394. }
  395. List<Boneparent> hierarchy = ogreSkel.getBonehierarchy().getBoneparent();
  396. for (int i = 0; i < hierarchy.size(); i++) {
  397. Boneparent link = hierarchy.get(i);
  398. SkeletonJoint joint = nameToJoint.get(link.getBone());
  399. SkeletonJoint parent = nameToJoint.get(link.getParent());
  400. parent.children.add(joint);
  401. joint.parent = parent;
  402. }
  403. Skeleton skel = new Skeleton();
  404. for (int i = 0; i < joints.size(); i++) {
  405. SkeletonJoint joint = joints.get(i);
  406. if (joint.parent == null) skel.hierarchy.add(joint);
  407. }
  408. skel.buildFromHierarchy();
  409. List<Animation> animations = ogreSkel.getAnimations().getAnimation();
  410. for (int i = 0; i < animations.size(); i++) {
  411. Animation animation = animations.get(i);
  412. SkeletonKeyframe[][] perJointkeyFrames = new SkeletonKeyframe[skel.bindPoseJoints.size][];
  413. List<Track> tracks = animation.getTracks().getTrack();
  414. if (tracks.size() != perJointkeyFrames.length)
  415. throw new IllegalArgumentException("Number of tracks does not equal number of joints");
  416. Matrix4 rotation = new Matrix4();
  417. Matrix4 transform = new Matrix4();
  418. for (int j = 0; j < tracks.size(); j++) {
  419. Track track = tracks.get(j);
  420. String jointName = track.getBone();
  421. int jointIndex = skel.namesToIndices.get(jointName);
  422. if (perJointkeyFrames[jointIndex] != null)
  423. throw new IllegalArgumentException("Track for bone " + jointName + " in animation " + animation.name
  424. + " already defined!");
  425. SkeletonKeyframe[] jointKeyFrames = new SkeletonKeyframe[track.getKeyframes().getKeyframe().size()];
  426. perJointkeyFrames[jointIndex] = jointKeyFrames;
  427. for (int k = 0; k < track.getKeyframes().getKeyframe().size(); k++) {
  428. Keyframe keyFrame = track.getKeyframes().getKeyframe().get(k);
  429. SkeletonKeyframe jointKeyframe = new SkeletonKeyframe();
  430. jointKeyframe.timeStamp = keyFrame.time;
  431. jointKeyframe.position.set(keyFrame.translate.x, keyFrame.translate.y, keyFrame.translate.z);
  432. if (keyFrame.scale != null) {
  433. if (keyFrame.scale.factor == 0)
  434. jointKeyframe.scale.set(keyFrame.scale.x, keyFrame.scale.y, keyFrame.scale.z);
  435. else
  436. jointKeyframe.scale.set(keyFrame.scale.factor, keyFrame.scale.factor, keyFrame.scale.factor);
  437. }
  438. jointKeyframe.rotation
  439. .setFromAxis(keyFrame.rotate.axis.x, keyFrame.rotate.axis.y, keyFrame.rotate.axis.z,
  440. MathUtils.radiansToDegrees * keyFrame.rotate.angle).nor();
  441. jointKeyframe.parentIndex = skel.bindPoseJoints.get(jointIndex).parentIndex;
  442. jointKeyFrames[k] = jointKeyframe;
  443. rotation.set(jointKeyframe.rotation);
  444. rotation.trn(jointKeyframe.position);
  445. transform.set(skel.sceneMatrices.get(jointIndex));
  446. transform.mul(rotation);
  447. if (jointKeyframe.parentIndex != -1) {
  448. rotation.set(skel.offsetMatrices.get(jointKeyframe.parentIndex)).mul(transform);
  449. transform.set(rotation);
  450. }
  451. transform.getTranslation(jointKeyframe.position);
  452. transform.getRotation(jointKeyframe.rotation);
  453. }
  454. }
  455. for (int j = 0; j < perJointkeyFrames.length; j++) {
  456. if (perJointkeyFrames[j] == null) throw new IllegalArgumentException("No track for bone " + skel.jointNames.get(j));
  457. }
  458. skel.animations.put(animation.name, new SkeletonAnimation(animation.name, animation.length, perJointkeyFrames));
  459. }
  460. return skel;
  461. }
  462. private com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Skeleton loadOgreSkeleton (InputStream in) throws JAXBException {
  463. JAXBContext context = JAXBContext.newInstance(com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Skeleton.class);
  464. Unmarshaller unmarshaller = context.createUnmarshaller();
  465. long start = System.nanoTime();
  466. com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Skeleton skel = (com.badlogic.gdx.graphics.g3d.loaders.ogre.skeleton.Skeleton)unmarshaller
  467. .unmarshal(in);
  468. System.out.println("took: " + (System.nanoTime() - start) / 1000000000.0f);
  469. return skel;
  470. }
  471. }