diff --git a/port/jAssimp/src/assimp/Animation.java b/port/jAssimp/src/assimp/Animation.java new file mode 100644 index 000000000..7858ff1a6 --- /dev/null +++ b/port/jAssimp/src/assimp/Animation.java @@ -0,0 +1,11 @@ +package assimp; + +/** + * Created by IntelliJ IDEA. + * User: Alex + * Date: 22.05.2008 + * Time: 13:05:35 + * To change this template use File | Settings | File Templates. + */ +public class Animation { +} diff --git a/port/jAssimp/src/assimp/Importer.java b/port/jAssimp/src/assimp/Importer.java index f232d470c..da5ff8b41 100644 --- a/port/jAssimp/src/assimp/Importer.java +++ b/port/jAssimp/src/assimp/Importer.java @@ -1,6 +1,6 @@ /* --------------------------------------------------------------------------- -Free Asset Import Library (ASSIMP) +Open Asset Import Library (ASSIMP) --------------------------------------------------------------------------- Copyright (c) 2006-2008, ASSIMP Development Team @@ -42,31 +42,244 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package assimp; +import java.util.Vector; + /** + * Main class of jAssimp. The class is a simple wrapper for the native + * Assimp::Importer and aiScene classes. + * If multiple threads are used to load assets, each thread should manage its + * own instance of this class to avoid threading issues. The class requires + * the native jAssimp library to work. It must be named "jassimpNN.EXT", where + * NN is the platform's default int size, e.g. 32 for the x86 architecture. + * EXT is the default extension for program libraries on the system, .DLL for + * Windows, .SO for Linux derivates. * + * @author Aramis (Alexander Gessler) + * @version 1.0 */ public class Importer { - public Importer() { + /** + * List of all postprocess steps to apply to the model + * Empty by default. + */ + private Vector m_vPPSteps = new Vector(); + + /** + * Unique number representing the address of the internal + * Assimp::Importer object. + */ + private int m_iNativeHandle = 0xffffffff; + + /** + * Loaded scene. It can't be used after the Importer class instance + * has been finalized! + */ + private Scene scene = null; + + /** + * Path to the scene loaded + */ + private String path = null; + + /** + * Public constructor. Initialises the JNI bridge to the native + * ASSIMP library. A native Assimp::Importer object is constructed and + * initialized. The flag list is set to zero, a default I/O handler + * is constructed. + * @throws NativeError Thrown if the jassimp library could not be loaded + * or if the entry point to the module wasn't found. if this exception + * is not thrown, you can assume that jAssimp is fully available. + */ + public Importer() throws NativeError { /** try to load the jassimp library. First try to load the * x64 version, in case of failure the x86 version */ try { - System.loadLibrary("jassimp_x64"); + System.loadLibrary("jassimp64"); } catch (UnsatisfiedLinkError exc) { try { - System.loadLibrary("jassimp_x86"); + System.loadLibrary("jassimp32"); } catch (UnsatisfiedLinkError exc2) { - - /** Seems we're definitely unable to load the assimp library - * This doesn't make life easier btw ... - */ - + throw new NativeError("Unable to load the jassimp library"); } } + // now create the native Importer class and setup our internal + // data structures outside the VM. + try { + if (0xffffffff == (this.m_iNativeHandle = _NativeInitContext())) { + throw new NativeError( + "Unable to initialize the native library context." + + "The initialization routine has failed"); + } + } + catch (UnsatisfiedLinkError exc) { + throw new NativeError( + "Unable to initialize the native library context." + + "The initialization routine has not been found"); + } + return; } + /** + * Add a postprocess step to the list of steps to be executed on + * the model. Postprocess steps are applied to the model after it + * has been loaded. They are implemented in C/C++, this is only a wrapper. + * + * @param p_Step Postprocess step to be added + * @return true if the step has been added successfully + * @see PostProcessStep + */ + public boolean addPostProcessStep(PostProcessStep p_Step) { + + if (isPostProcessStepActive(p_Step)) return false; + this.m_vPPSteps.add(p_Step); + return true; + } + + + /** + * Check whether a given postprocess step is existing in the list + * of all steps to be executed on the model. Postprocess steps are + * applied to the model after it has been loaded. They are implemented + * in C/C++, this is only a wrapper. + * + * @param p_Step Postprocess step to be queried + * @return true if the step is active + * @see PostProcessStep + */ + public boolean isPostProcessStepActive(PostProcessStep p_Step) { + + for (PostProcessStep step : m_vPPSteps) { + if (step.equals(p_Step)) return true; + } + return false; + } + + + /** + * Remove a postprocess step from the list of steps to be executed + * on the model. Postprocess steps are applied to the model after it + * has been loaded. They are implemented in C/C++, this is only a wrapper. + * + * @param p_Step Postprocess step to be removed + * @return true if the step has been removed successfully, false if + * it was not existing + * @see PostProcessStep + */ + public boolean removePostProcessStep(PostProcessStep p_Step) { + + return this.m_vPPSteps.remove(p_Step); + } + + + /** + * Load a model from a file using the current list of postprocess steps + * and the current I/O handler. If no custom I/O handler was provided, + * a default implementation is used. This implementation uses fopen()/ + * fread()/fwrite()/fclose()/ftell()/fseek() and provides no support + * for archives like ZIP or PAK. + * @param path Path to the file to be read + * @return null if the import failed, otherwise a valid Scene instance + */ + public Scene readFile(String path) { + this.scene = new Scene(this); + this.path = path; + + // we need to build a path that is valid for the current OS + char sep = System.getProperty("file.separator").charAt(0); + if(sep != '\\') this.path.replace('\\',sep); + if(sep != '/') this.path.replace('/',sep); + + // now load the mesh + if(0xffffffff == this._NativeLoad(this.path,this.m_vPPSteps) || ! this.scene.construct()) { + this.scene = null; + this.path = null; + return null; + } + return this.scene; + } + + + /** + * Implementation of java.lang.Object.equals() + * + * @param o Object to be compred with *this* + * @return true if *this* is equal to o + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Importer importer = (Importer) o; + + if (m_iNativeHandle != importer.m_iNativeHandle) return false; + + return true; + } + + /** + * Implementation of java.lang.Object.finalize() + * We override this to make sure that all native resources are + * deleted properly. This will free the native Assimp::Importer object + * and its associated aiScene instance. A NativeError is thrown + * if the destruction failed. This means that not all resources have + * been deallocated and memory leaks are remaining. + */ + @Override + protected void finalize() throws Throwable { + super.finalize(); + + // be sure that native resources are deallocated properly + if (0xffffffff == _NativeFreeContext()) { + throw new NativeError("Unable to destroy the native library context"); + } + return; + } + + /** + * Implementation of java.lang.Object.hashCode() + * + * The native handle obtained from the JNI bridge is used as hash code. + * It is assumed to be unique, in fact it is normall the address of + * the native Assimp::Importer object. + * @return An unique value representing the object + */ + @Override + public int hashCode() { + return m_iNativeHandle; + } + + /** + * JNI bridge call. For internal use only + * The method initializes the ASSIMP-JNI bridge for use. No native + * function call to assimp will be successful unless this function has + * been called. If the function is found by the Java VM (and no + * UnsatisfiedLinkError is thrown), jAssimp assumes that all other + * library functions are available, too. If they are not, an + * UnsatisfiedLinkError will be thrown during model loading. + * + * @return Unique handle for the class or 0xffffffff if an error occured + */ + private native int _NativeInitContext(); + + /** + * JNI bridge call. For internal use only + * The method destroys the ASSIMP-JNI bridge. No native function call + * to assimp will be successful after this method has been called. + * @return 0xffffffff if an error occured + */ + private native int _NativeFreeContext(); + + /** + * JNI bridge call. For internal use only + * The method loads the model into memory, but does not map it into the VM + * @param path Path (valid separators for the OS) to the model to be loaded + * @param steps List of postprocess steps to be executed + * @return 0xffffffff if an error occured + */ + private native int _NativeLoad(String path,Vector< PostProcessStep > steps); } diff --git a/port/jAssimp/src/assimp/Material.java b/port/jAssimp/src/assimp/Material.java new file mode 100644 index 000000000..c87aadea5 --- /dev/null +++ b/port/jAssimp/src/assimp/Material.java @@ -0,0 +1,11 @@ +package assimp; + +/** + * Created by IntelliJ IDEA. + * User: Alex + * Date: 22.05.2008 + * Time: 13:05:05 + * To change this template use File | Settings | File Templates. + */ +public class Material { +} diff --git a/port/jAssimp/src/assimp/Mesh.java b/port/jAssimp/src/assimp/Mesh.java new file mode 100644 index 000000000..354b6d36b --- /dev/null +++ b/port/jAssimp/src/assimp/Mesh.java @@ -0,0 +1,11 @@ +package assimp; + +/** + * Created by IntelliJ IDEA. + * User: Alex + * Date: 22.05.2008 + * Time: 13:04:42 + * To change this template use File | Settings | File Templates. + */ +public class Mesh { +} diff --git a/port/jAssimp/src/assimp/NativeError.java b/port/jAssimp/src/assimp/NativeError.java new file mode 100644 index 000000000..49688dcae --- /dev/null +++ b/port/jAssimp/src/assimp/NativeError.java @@ -0,0 +1,57 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (ASSIMP) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2008, ASSIMP Development Team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the ASSIMP team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the ASSIMP Development Team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +package assimp; + +/** + * Exception class used by jAssimp. It is thrown whenever an unknown error + * occurs in the JNI bridge between the native Assimp library and the Java VM. + */ +public class NativeError extends Exception { + + public NativeError() { + super("Unknown error"); + } + + public NativeError(String sz) { + super(sz); + } +} diff --git a/port/jAssimp/src/assimp/Node.java b/port/jAssimp/src/assimp/Node.java new file mode 100644 index 000000000..cdd79b8f8 --- /dev/null +++ b/port/jAssimp/src/assimp/Node.java @@ -0,0 +1,11 @@ +package assimp; + +/** + * Created by IntelliJ IDEA. + * User: Alex + * Date: 22.05.2008 + * Time: 13:05:12 + * To change this template use File | Settings | File Templates. + */ +public class Node { +} diff --git a/port/jAssimp/src/assimp/PostProcessStep.java b/port/jAssimp/src/assimp/PostProcessStep.java new file mode 100644 index 000000000..635a18738 --- /dev/null +++ b/port/jAssimp/src/assimp/PostProcessStep.java @@ -0,0 +1,210 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (ASSIMP) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2008, ASSIMP Development Team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the ASSIMP team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the ASSIMP Development Team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + + +package assimp; + +/** + * Enumeration class that defines postprocess steps that can be executed on a model + * after it has been loaded. All PPSteps are implemented in C++, so their performance + * is awesome. Most steps are O(n * log(n)). + * + * @author Aramis (Alexander Gessler) + * @version 1.0 + */ +public class PostProcessStep { + + /** Default vertex split limit for the SplitLargeMeshes process + */ + public static final int DEFAULT_VERTEX_SPLIT_LIMIT = 1000000; + + /** Default triangle split limit for the SplitLargeMeshes process + */ + public static final int DEFAULT_TRIANGLE_SPLIT_LIMIT = 1000000; + + private static int s_iVertexSplitLimit = DEFAULT_VERTEX_SPLIT_LIMIT; + private static int s_iTriangleSplitLimit = DEFAULT_TRIANGLE_SPLIT_LIMIT; + + + /** + * Triangulates all faces of all meshes. By default the imported + * mesh data might contain faces with more than 3 indices. For + * rendering a mesh you usually need all faces to be triangles. This + * post processing step splits up all higher faces to triangles. + */ + public static final PostProcessStep Triangulate = + new PostProcessStep("Triangulate"); + + + /** + * Identifies and joins identical vertex data sets within all imported + * meshes. After this step is run each mesh does contain only unique + * vertices anymore, so a vertex is possibly used by multiple faces. + * You propably always want to use this post processing step. + */ + public static final PostProcessStep JoinIdenticalVertices = + new PostProcessStep("JoinIdenticalVertices"); + + + /** + * Splits large meshes into submeshes + * This is quite useful for realtime rendering where the number of + * vertices is usually limited by the video driver. + *

+ * The split limits can be set through SetVertexSplitLimit() and + * SetTriangleSplitLimit(). The default values are + * DEFAULT_VERTEX_SPLIT_LIMIT and + * DEFAULT_TRIANGLE_SPLIT_LIMIT + */ + public static final PostProcessStep SplitLargeMeshes = + new PostProcessStep("SplitLargeMeshes"); + + + /** + * Omits all normals found in the file. This can be used together + * with either the GenSmoothNormals or the + * GenFaceNormal step to force the recomputation of the + * normals. If none of the two flags is specified, the output mesh + * won't have normals + */ + public static final PostProcessStep KillNormals = + new PostProcessStep("KillNormals"); + + + /** + * Generates smooth normals for all vertices in the mesh. This is + * ignored if normals are already existing. This step may not be used + * together with GenFaceNormals + */ + public static final PostProcessStep GenSmoothNormals = + new PostProcessStep("GenSmoothNormals"); + + + /** + * Generates normals for all faces of all meshes. The normals are + * shared between the three vertices of a face. This is ignored + * if normals are already existing. This step may not be used together + * with GenSmoothNormals + */ + public static final PostProcessStep GenFaceNormals = + new PostProcessStep("GenFaceNormals"); + + + /** + * Calculates the tangents and bitangents for the imported meshes. Does + * nothing if a mesh does not have normals. You might want this post + * processing step to be executed if you plan to use tangent space + * calculations such as normal mapping applied to the meshes. + */ + public static final PostProcessStep CalcTangentSpace = + new PostProcessStep("CalcTangentSpace"); + + + /** + * Converts all the imported data to a left-handed coordinate space + * such as the DirectX coordinate system. By default the data is + * returned in a right-handed coordinate space which for example + * OpenGL prefers. In this space, +X points to the right, +Y points towards + * the viewer and and +Z points upwards. In the DirectX coordinate space + * +X points to the right, +Y points upwards and +Z points away from + * the viewer. + */ + public static final PostProcessStep ConvertToLeftHanded = + new PostProcessStep("ConvertToLeftHanded "); + + + /** + * Set the vertex split limit for the "SplitLargeMeshes" process + * If a mesh exceeds this limit it will be splitted + * + * @param limit New vertex split limit + * @return Old vertex split limit + */ + public static synchronized int setVertexSplitLimit(int limit) { + if (s_iVertexSplitLimit != limit) { + // send to the JNI bridge ... + s_iVertexSplitLimit = limit; + _NativeSetVertexSplitLimit(limit); + } + return limit; + } + + /** + * Set the triangle split limit for the "SplitLargeMeshes" process + * If a mesh exceeds this limit it will be splitted + * + * @param limit new triangle split limit + * @return Old triangle split limit + */ + public static synchronized int setTriangleSplitLimit(int limit) { + if (s_iTriangleSplitLimit != limit) { + // send to the JNI bridge ... + s_iTriangleSplitLimit = limit; + _NativeSetTriangleSplitLimit(limit); + } + return limit; + } + + /** + * JNI bridge call. For internal use only + * + * @param limit New vertex split limit + */ + private native static void _NativeSetVertexSplitLimit(int limit); + + /** + * JNI bridge call. For internal use only + * + * @param limit New triangle split limit + */ + private native static void _NativeSetTriangleSplitLimit(int limit); + + + private final String myName; // for debug only + + private PostProcessStep(String name) { + myName = name; + } + + public String toString() { + return myName; + } +} diff --git a/port/jAssimp/src/assimp/Scene.java b/port/jAssimp/src/assimp/Scene.java new file mode 100644 index 000000000..ffa5d58d0 --- /dev/null +++ b/port/jAssimp/src/assimp/Scene.java @@ -0,0 +1,108 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (ASSIMP) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2008, ASSIMP Development Team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the ASSIMP team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the ASSIMP Development Team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + + +package assimp; + +import java.util.Vector; + +/** + * Represents the asset data that has been loaded. A scene consists of + * multiple meshes, animations, materials and embedded textures. + * And it defines the scenegraph of the asset (the hierarchy of all + * meshes, ...). + * + * An instance of this class is returned by Importer.readFile(). + * + * @author Aramis (Alexander Gessler) + * @version 1.0 + */ +public class Scene { + + private Vector m_vMeshes; + private Vector m_vTextures; + private Vector m_vMaterials; + private Vector m_vAnimations; + private Node m_rootNode; + + /** Get the mesh list + * + * @return mesh list + */ + public Vector getMeshes() { + return m_vMeshes; + } + + /** Get the texture list + * + * @return Texture list + */ + public Vector getTextures() { + return m_vTextures; + } + + /** Get the material list + * + * @return Material list + */ + public Vector getMaterials() { + return m_vMaterials; + } + + /** Get the animation list + * + * @return Animation list + */ + public Vector getAnimations() { + return m_vAnimations; + } + + /** Get the root node of the scenegraph + * + * @return Root node + */ + public Node getRootNode() { + return m_rootNode; + } + + protected boolean construct() { + } +} diff --git a/port/jAssimp/src/assimp/Texture.java b/port/jAssimp/src/assimp/Texture.java new file mode 100644 index 000000000..248b7341c --- /dev/null +++ b/port/jAssimp/src/assimp/Texture.java @@ -0,0 +1,142 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (ASSIMP) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2008, ASSIMP Development Team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the ASSIMP team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the ASSIMP Development Team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + + +package assimp; + +import java.util.Vector; +import java.awt.*; + +/** + * Represents an embedded texture. Sometimes textures are not referenced + * with a path, instead they are directly embedded into the model file. + * Example file formats doing this include MDL3, MDL5 and MDL7 (3D GameStudio). + * Embedded textures are converted to an array of color values (RGBA). + *

+ * Embedded textures in compressed file formats, such as JPEG or DDS + * are NOT supported by jAssimp. + * + * @author Aramis (Alexander Gessler) + * @version 1.0 + */ +public class Texture { + + private int width = 0; + private int height = 0; + + private Color[] data = null; + + /** + * Retrieve the height of the texture image + * + * @return Height, in pixels + */ + public int getHeight() { + return height; + } + + /** + * Retrieve the width of the texture image + * + * @return Width, in pixels + */ + public int getWidth() { + return width; + } + + /** + * Get the color at a given position of the texture + * + * @param x X coordinate, zero based + * @param y Y coordinate, zero based + * @return Color at this position + */ + public Color getPixel(int x, int y) { + + assert(x < width && y < height); + + // map the color data in memory if required ... + if (null == data) { + try { + this.MapColorData(); + } catch (NativeError nativeError) { + return Color.black; + } + } + return data[y * width + x]; + } + + /** + * Internal helper function to map the native texture data into + * a java.awt.Color array + */ + private void MapColorData() throws NativeError { + final int iNumPixels = width * height; + + // first allocate the output array + data = new Color[iNumPixels]; + + // now allocate a temporary output array + byte[] temp = new byte[(iNumPixels) << 2]; + + // and copy the native color data to it + if (0xffffffff == this._NativeMapColorData(temp)) { + throw new NativeError("Unable to map aiTexture into Java-VM"); + } + + // now convert the temporary representation to a Color array + // (data is given in BGRA order, we need RGBA) + for (int i = 0, iBase = 0; i < iNumPixels; ++i, iBase += 4) { + data[i] = new Color(temp[iBase + 2], temp[iBase + 1], temp[iBase], temp[iBase + 3]); + } + return; + } + + /** + * JNI bridge call. For internal use only + * The method maps the contents of the native aiTexture object into memory + * the native memory area will be deleted afterwards. + * + * @param temp Output array. Assumed to be width * height * 4 in size + * @return 0xffffffff if an error occured + */ + private native int _NativeMapColorData(byte[] temp); +}