aboutsummaryrefslogtreecommitdiffstats
path: root/ardor3d-extras/src
diff options
context:
space:
mode:
authorJulien Gouesse <[email protected]>2014-02-07 22:58:27 +0100
committerJulien Gouesse <[email protected]>2014-02-07 22:58:27 +0100
commit03b39214b9740f3847d11dac76787dd1ae2f5d29 (patch)
tree49b1dd2238c18c4179c64a91f40b13310c619832 /ardor3d-extras/src
parentf7b44e9467c48fc623c0d451c3456263b8a04ffc (diff)
Implements most of the MD3 parsing
Diffstat (limited to 'ardor3d-extras/src')
-rw-r--r--ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3DataStore.java53
-rw-r--r--ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Header.java6
-rw-r--r--ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Importer.java154
-rw-r--r--ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Surface.java59
4 files changed, 249 insertions, 23 deletions
diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3DataStore.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3DataStore.java
new file mode 100644
index 0000000..2300a5b
--- /dev/null
+++ b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3DataStore.java
@@ -0,0 +1,53 @@
+/**
+ * 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.extension.model.md3;
+
+import java.util.List;
+
+import com.ardor3d.extension.model.util.KeyframeController;
+import com.ardor3d.scenegraph.Mesh;
+import com.google.common.collect.Lists;
+
+public class Md3DataStore {
+
+ private final Mesh _mainMesh;
+ private final KeyframeController<Mesh> _controller;
+
+ private final List<String> _frameNames = Lists.newArrayList();
+
+ private final List<String> _skinNames = Lists.newArrayList();
+
+ public Md3DataStore(final Mesh mainMesh, final KeyframeController<Mesh> controller) {
+ super();
+ _mainMesh = mainMesh;
+ _controller = controller;
+ }
+
+ public Mesh getScene() {
+ return _mainMesh;
+ }
+
+ public KeyframeController<Mesh> getController() {
+ return _controller;
+ }
+
+ public List<String> getFrameNames() {
+ return _frameNames;
+ }
+
+ public int getFrameIndex(final String frameName) {
+ return _frameNames.indexOf(frameName);
+ }
+
+ public List<String> getSkinNames() {
+ return _skinNames;
+ }
+}
diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Header.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Header.java
index ddc96ab..ac1ee27 100644
--- a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Header.java
+++ b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Header.java
@@ -30,7 +30,7 @@ final class Md3Header {
*/
final int _numTags;
/** Number of Surface objects, with a maximum of MD3_MAX_SURFACES. Current value of MD3_MAX_SURFACES is 32. */
- final int _numSurface;
+ final int _numSurfaces;
/** Number of Skin objects, unused */
final int _numSkins;
/**
@@ -46,7 +46,7 @@ final class Md3Header {
final int _offsetEnd;
Md3Header(final int magic, final int version, final String name, final int flags, final int numFrames,
- final int numTags, final int numSurface, final int numSkins, final int offsetFrame, final int offsetTag,
+ final int numTags, final int numSurfaces, final int numSkins, final int offsetFrame, final int offsetTag,
final int offsetSurface, final int offsetEnd) {
super();
_magic = magic;
@@ -55,7 +55,7 @@ final class Md3Header {
_flags = flags;
_numFrames = numFrames;
_numTags = numTags;
- _numSurface = numSurface;
+ _numSurfaces = numSurfaces;
_numSkins = numSkins;
_offsetFrame = offsetFrame;
_offsetTag = offsetTag;
diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Importer.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Importer.java
new file mode 100644
index 0000000..34f6601
--- /dev/null
+++ b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Importer.java
@@ -0,0 +1,154 @@
+/**
+ * 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.extension.model.md3;
+
+import java.io.InputStream;
+
+import com.ardor3d.math.Matrix3;
+import com.ardor3d.math.Vector2;
+import com.ardor3d.math.Vector3;
+import com.ardor3d.util.Ardor3dException;
+import com.ardor3d.util.LittleEndianRandomAccessDataInput;
+import com.ardor3d.util.resource.ResourceSource;
+
+public class Md3Importer {
+
+ private static final float XYZ_SCALE = 1.0f / 64;
+
+ /**
+ * Reads an MD3 file from the given resource
+ *
+ * @param resource
+ * a resource pointing to the model we wish to load.
+ * @return an Md3DataStore data object containing the scene and other useful elements.
+ */
+ public Md3DataStore load(final ResourceSource resource) {
+ if (resource == null) {
+ throw new NullPointerException("Unable to load null resource");
+ }
+
+ try {
+ final InputStream md3Stream = resource.openStream();
+ if (md3Stream == null) {
+ throw new NullPointerException("Unable to load null streams");
+ }
+ final LittleEndianRandomAccessDataInput bis = new LittleEndianRandomAccessDataInput(md3Stream);
+
+ // parse the header
+ final Md3Header header = new Md3Header(bis.readInt(), bis.readInt(), bis.readString(64), bis.readInt(),
+ bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(),
+ bis.readInt(), bis.readInt());
+
+ // Check magic word and version
+ if (header._magic != ('3' << 24) + ('P' << 16) + ('D' << 8) + 'I') {
+ throw new Ardor3dException("Not an MD3 file.");
+ }
+ if (header._version != 15) {
+ throw new Ardor3dException("Invalid file version (Version not 15)!");
+ }
+
+ // Parse out frames
+ final Md3Frame[] frames = new Md3Frame[header._numFrames];
+ bis.seek(header._offsetFrame);
+ final Vector3 minBounds = new Vector3();
+ final Vector3 maxBounds = new Vector3();
+ final Vector3 localOrigin = new Vector3();
+ for (int i = 0; i < header._numFrames; i++) {
+ minBounds.set(bis.readFloat(), bis.readFloat(), bis.readFloat());
+ maxBounds.set(bis.readFloat(), bis.readFloat(), bis.readFloat());
+ localOrigin.set(bis.readFloat(), bis.readFloat(), bis.readFloat());
+ frames[i] = new Md3Frame(minBounds, maxBounds, localOrigin, bis.readFloat(), bis.readString(16));
+ }
+
+ // Parse out tags
+ final Md3Tag[] tags = new Md3Tag[header._numTags];
+ bis.seek(header._offsetTag);
+ final Vector3 origin = new Vector3();
+ final Matrix3 axis = new Matrix3();
+ for (int i = 0; i < header._numTags; i++) {
+ final String name = bis.readString(64);
+ origin.set(bis.readFloat(), bis.readFloat(), bis.readFloat());
+ axis.set(bis.readFloat(), bis.readFloat(), bis.readFloat(), bis.readFloat(), bis.readFloat(),
+ bis.readFloat(), bis.readFloat(), bis.readFloat(), bis.readFloat());
+ tags[i] = new Md3Tag(name, origin, axis);
+ }
+
+ // Parse out surfaces
+ final Md3Surface[] surfaces = new Md3Surface[header._numSurfaces];
+ bis.seek(header._offsetSurface);
+ for (int i = 0; i < header._numSurfaces; i++) {
+ final int surfaceStart = bis.position();
+ final int magic = bis.readInt();
+ if (magic != ('3' << 24) + ('P' << 16) + ('D' << 8) + 'I') {
+ throw new Ardor3dException("Not an MD3 surface.");
+ }
+ surfaces[i] = new Md3Surface(magic, bis.readString(64), bis.readInt(), bis.readInt(), bis.readInt(),
+ bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(), bis.readInt(),
+ bis.readInt());
+ // Parse out shaders
+ bis.seek(surfaceStart + surfaces[i]._offsetShaders);
+ for (int j = 0; j < surfaces[i]._numShaders; j++) {
+ // final String name = bis.readString(64);
+ // final int index = bis.readInt();
+ // unused yet
+ }
+ // Parse out triangles
+ bis.seek(surfaceStart + surfaces[i]._offsetTriangles);
+ for (int j = 0; j < surfaces[i]._triIndexes.length; j++) {
+ surfaces[i]._triIndexes[j] = bis.readInt();
+ }
+ // Parse out texture coordinates
+ bis.seek(surfaceStart + surfaces[i]._offsetTexCoords);
+ for (final int j = 0; j < surfaces[i]._texCoords.length; i++) {
+ surfaces[i]._texCoords[j] = new Vector2(bis.readFloat(), bis.readFloat());
+ }
+ // Parse out vertices
+ bis.seek(surfaceStart + surfaces[i]._offsetXyzNormals);
+ for (int j = 0; j < surfaces[i]._numFrames; j++) {
+ for (int k = 0; k < surfaces[i]._numVerts; k++) {
+ surfaces[i]._verts[j][k] = new Vector3(bis.readShort(), bis.readShort(), bis.readShort())
+ .multiplyLocal(Md3Importer.XYZ_SCALE);
+ final int zenith = bis.readByte();
+ final int azimuth = bis.readByte();
+ final float lat = (float) (zenith * 2 * Math.PI / 255);
+ final float lng = (float) (azimuth * 2 * Math.PI / 255);
+ surfaces[i]._norms[j][k] = new Vector3(Math.cos(lat) * Math.sin(lng), Math.sin(lat)
+ * Math.sin(lng), Math.cos(lng));
+ }
+ }
+ }
+
+ for (int i = 0; i < header._numSurfaces; i++) {
+ final Md3Surface surface = surfaces[i];
+
+ for (int j = 0; j < surface._numFrames; j++) {
+ final Md3Frame frame = frames[j];
+
+ }
+ // TODO
+ }
+
+ // Make a store object to return
+ final Md3DataStore store = new Md3DataStore(/* mesh, controller */null, null);
+
+ // store names
+ for (final Md3Frame frame : frames) {
+ store.getFrameNames().add(frame._name);
+ }
+
+ // TODO look for the textures filenames in the .skin files
+
+ return store;
+ } catch (final Exception e) {
+ throw new Error("Unable to load md3 resource from URL: " + resource, e);
+ }
+ }
+}
diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Surface.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Surface.java
index 03905c0..ba28df2 100644
--- a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Surface.java
+++ b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/md3/Md3Surface.java
@@ -18,44 +18,63 @@ import com.ardor3d.math.Vector3;
*/
final class Md3Surface {
+ final int _magic;
/** name */
- String name;
+ final String _name;
/** flags */
- int flags;
+ final int _flags;
/** Number of animation frames. This should match NUM_FRAMES in the MD3 header. */
- int numFrames;
+ final int _numFrames;
/**
* Number of Shader objects defined in this Surface, with a limit of MD3_MAX_SHADERS. Current value of
* MD3_MAX_SHADERS is 256.
*/
- int numShaders;
+ final int _numShaders;
/** Number of Vertex objects defined in this Surface, up to MD3_MAX_VERTS. Current value of MD3_MAX_VERTS is 4096. */
- int numVerts;
+ final int _numVerts;
/**
* Number of Triangle objects defined in this Surface, maximum of MD3_MAX_TRIANGLES. Current value of
* MD3_MAX_TRIANGLES is 8192.
*/
- int numTriangles;
+ final int _numTriangles;
/** Relative offset from SURFACE_START where the list of Triangle objects starts. */
- int offsetTriangles;
+ final int _offsetTriangles;
/** Relative offset from SURFACE_START where the list of Shader objects starts. */
- int offsetShaders;
+ final int _offsetShaders;
/** Relative offset from SURFACE_START where the list of ST objects (s-t texture coordinates) starts. */
- int offsetTexCoord;
+ final int _offsetTexCoords;
/** Relative offset from SURFACE_START where the list of Vertex objects (X-Y-Z-N vertices) starts. */
- int offsetXyzNormal;
+ final int _offsetXyzNormals;
/** Relative offset from SURFACE_START to where the Surface object ends. */
- int offsetEnd;
- /** */
- int[] triIndexes;
- /** */
- Vector2[] texCoords;
- /** */
- Vector3[][] verts;
- /** */
- Vector3[][] norms;
+ final int _offsetEnd;
+ /** Indices of triangles' vertices */
+ final int[] _triIndexes;
+ /** Texture coordinates of triangles' vertices */
+ final Vector2[] _texCoords;
+ /** Triangles' vertices */
+ final Vector3[][] _verts;
+ /** Triangles' normals */
+ final Vector3[][] _norms;
- Md3Surface() {
+ Md3Surface(final int magic, final String name, final int flags, final int numFrames, final int numShaders,
+ final int numVerts, final int numTriangles, final int offsetTriangles, final int offsetShaders,
+ final int offsetTexCoords, final int offsetXyzNormals, final int offsetEnd) {
super();
+ _magic = magic;
+ _name = name;
+ _flags = flags;
+ _numFrames = numFrames;
+ _numShaders = numShaders;
+ _numVerts = numVerts;
+ _numTriangles = numTriangles;
+ _offsetTriangles = offsetTriangles;
+ _offsetShaders = offsetShaders;
+ _offsetTexCoords = offsetTexCoords;
+ _offsetXyzNormals = offsetXyzNormals;
+ _offsetEnd = offsetEnd;
+ _triIndexes = new int[_numTriangles * 3];
+ _texCoords = new Vector2[_numVerts];
+ _verts = new Vector3[_numFrames][_numVerts];
+ _norms = new Vector3[_numFrames][_numVerts];
}
}