diff --git a/port/jassimp/README b/port/jassimp/README new file mode 100644 index 000000000..be78db404 --- /dev/null +++ b/port/jassimp/README @@ -0,0 +1,52 @@ +jassimp +------- + +Java binding for assimp. + +The class model used by jassimp is not a one-to-one mapping of assimps class/ +structure model (due to performance considerations). Please read the javadoc +descriptions of AiMesh and AiWrapperProvider. + +The jassimp.lwjgl package contains a LWJGL specific wrapper provider and some +application examples using this wrapper + + + +How To Build +------------ + + I) native library + +II) Java binding + The java library is built using ant. Executing "ant" in the port/jassimp + directory should be sufficient to build the library including docs. You + still need to build the native library separately, see above + + The java build is configured to create java 1.6 classes + + + +Limitations +----------- + +Not all data imports have been tested yet, especially the countless texture +parameters. If you find bugs please report them. + +jassimp supports most of assimps features. Current limitations are +* only importing scenes is supported. There are some methods that allow a + modification of the returned objects, but these should be considered as + work in progress. Full blown export support is planned for a future release +* no support for mesh animations +* no support for embedded textures +* no support for importer configurations +* no support for the custom I/O API of assimp +* some texture related material properties are not exposed via the API but only + accessible by traversing the list of properties. However this limitation is + also present in the c-API ... + + +License +------- + +The license for jassimp is the same as the main Assimp license. + diff --git a/port/jassimp/build.xml b/port/jassimp/build.xml new file mode 100644 index 000000000..d81d1958a --- /dev/null +++ b/port/jassimp/build.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/port/jassimp/jassimp-native/src/jassimp.cpp b/port/jassimp/jassimp-native/src/jassimp.cpp new file mode 100644 index 000000000..ae64ad191 --- /dev/null +++ b/port/jassimp/jassimp-native/src/jassimp.cpp @@ -0,0 +1,1408 @@ +#include "jassimp.h" + +#include +#include + + +#ifdef JNI_LOG +#define lprintf(...) printf (__VA_ARGS__) +#else +#define lprintf +#endif + + +static bool createInstance(JNIEnv *env, const char* className, jobject& newInstance) +{ + jclass clazz = env->FindClass(className); + + if (NULL == clazz) + { + lprintf("could not find class %s\n", className); + return false; + } + + jmethodID ctr_id = env->GetMethodID(clazz, "", "()V"); + + if (NULL == ctr_id) + { + lprintf("could not find no-arg constructor for class %s\n", className); + return false; + } + + newInstance = env->NewObject(clazz, ctr_id); + + if (NULL == newInstance) + { + lprintf("error calling no-arg constructor for class %s\n", className); + return false; + } + + return true; +} + + +static bool createInstance(JNIEnv *env, const char* className, const char* signature, const jvalue* params, jobject& newInstance) +{ + jclass clazz = env->FindClass(className); + + if (NULL == clazz) + { + lprintf("could not find class %s\n", className); + return false; + } + + jmethodID ctr_id = env->GetMethodID(clazz, "", signature); + + if (NULL == ctr_id) + { + lprintf("could not find no-arg constructor for class %s\n", className); + return false; + } + + newInstance = env->NewObjectA(clazz, ctr_id, params); + + if (NULL == newInstance) + { + lprintf("error calling constructor for class %s, signature %s\n", className, signature); + return false; + } + + return true; +} + + +static bool getField(JNIEnv *env, jobject object, const char* fieldName, const char* signature, jobject& field) +{ + jclass clazz = env->GetObjectClass(object); + + if (NULL == clazz) + { + lprintf("could not get class for object\n"); + return false; + } + + jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature); + + if (NULL == fieldId) + { + lprintf("could not get field %s with signature %s\n", fieldName, signature); + return false; + } + + field = env->GetObjectField(object, fieldId); + + return true; +} + + +static bool setIntField(JNIEnv *env, jobject object, const char* fieldName, jint value) +{ + jclass clazz = env->GetObjectClass(object); + + if (NULL == clazz) + { + lprintf("could not get class for object\n"); + return false; + } + + jfieldID fieldId = env->GetFieldID(clazz, fieldName, "I"); + + if (NULL == fieldId) + { + lprintf("could not get field %s with signature I\n", fieldName); + return false; + } + + env->SetIntField(object, fieldId, value); + + return true; +} + + +static bool setFloatField(JNIEnv *env, jobject object, const char* fieldName, jfloat value) +{ + jclass clazz = env->GetObjectClass(object); + + if (NULL == clazz) + { + lprintf("could not get class for object\n"); + return false; + } + + jfieldID fieldId = env->GetFieldID(clazz, fieldName, "F"); + + if (NULL == fieldId) + { + lprintf("could not get field %s with signature F\n", fieldName); + return false; + } + + env->SetFloatField(object, fieldId, value); + + return true; +} + + +static bool setObjectField(JNIEnv *env, jobject object, const char* fieldName, const char* signature, jobject value) +{ + jclass clazz = env->GetObjectClass(object); + + if (NULL == clazz) + { + lprintf("could not get class for object\n"); + return false; + } + + jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature); + + if (NULL == fieldId) + { + lprintf("could not get field %s with signature %s\n", fieldName, signature); + return false; + } + + env->SetObjectField(object, fieldId, value); + + return true; +} + + +static bool getStaticField(JNIEnv *env, const char* className, const char* fieldName, const char* signature, jobject& field) +{ + jclass clazz = env->FindClass(className); + + if (NULL == clazz) + { + lprintf("could not find class %s\n", className); + return false; + } + + jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature); + + if (NULL == fieldId) + { + lprintf("could not get field %s with signature %s\n", fieldName, signature); + return false; + } + + field = env->GetStaticObjectField(clazz, fieldId); + + return true; +} + + +static bool call(JNIEnv *env, jobject object, const char* typeName, const char* methodName, + const char* signature, const jvalue* params) +{ + jclass clazz = env->FindClass(typeName); + + if (NULL == clazz) + { + lprintf("could not find class %s\n", typeName); + return false; + } + + jmethodID mid = env->GetMethodID(clazz, methodName, signature); + + if (NULL == mid) + { + lprintf("could not find method %s with signature %s in type %s\n", methodName, signature, typeName); + return false; + } + + env->CallVoidMethodA(object, mid, params); + + return true; +} + + +static bool callStaticObject(JNIEnv *env, const char* typeName, const char* methodName, + const char* signature, const jvalue* params, jobject& returnValue) +{ + jclass clazz = env->FindClass(typeName); + + if (NULL == clazz) + { + lprintf("could not find class %s\n", typeName); + return false; + } + + jmethodID mid = env->GetStaticMethodID(clazz, methodName, signature); + + if (NULL == mid) + { + lprintf("could not find method %s with signature %s in type %s\n", methodName, signature, typeName); + return false; + } + + returnValue = env->CallStaticObjectMethodA(clazz, mid, params); + + return true; +} + + +static bool copyBuffer(JNIEnv *env, jobject jMesh, const char* jBufferName, void* cData, size_t size) +{ + jobject jBuffer = NULL; + + if (!getField(env, jMesh, jBufferName, "Ljava/nio/ByteBuffer;", jBuffer)) + { + return false; + } + + if (env->GetDirectBufferCapacity(jBuffer) != size) + { + lprintf("invalid direct buffer, expected %u, got %u\n", size, env->GetDirectBufferCapacity(jBuffer)); + return false; + } + + void* jBufferPtr = env->GetDirectBufferAddress(jBuffer); + + if (NULL == jBufferPtr) + { + lprintf("could not access direct buffer\n"); + return false; + } + + memcpy(jBufferPtr, cData, size); + + return true; +} + + +static bool copyBufferArray(JNIEnv *env, jobject jMesh, const char* jBufferName, int index, void* cData, size_t size) +{ + jobject jBufferArray = NULL; + + if (!getField(env, jMesh, jBufferName, "[Ljava/nio/ByteBuffer;", jBufferArray)) + { + return false; + } + + jobject jBuffer = env->GetObjectArrayElement((jobjectArray) jBufferArray, index); + + if (env->GetDirectBufferCapacity(jBuffer) != size) + { + lprintf("invalid direct buffer, expected %u, got %u\n", size, env->GetDirectBufferCapacity(jBuffer)); + return false; + } + + void* jBufferPtr = env->GetDirectBufferAddress(jBuffer); + + if (NULL == jBufferPtr) + { + lprintf("could not access direct buffer\n"); + return false; + } + + memcpy(jBufferPtr, cData, size); + + return true; +} + + + +static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene) +{ + for (unsigned int meshNr = 0; meshNr < cScene->mNumMeshes; meshNr++) + { + const aiMesh *cMesh = cScene->mMeshes[meshNr]; + + lprintf("converting mesh %s ...\n", cMesh->mName.C_Str()); + + /* create mesh */ + jobject jMesh = NULL; + + if (!createInstance(env, "jassimp/AiMesh", jMesh)) + { + return false; + } + + + /* add mesh to m_meshes java.util.List */ + jobject jMeshes = NULL; + + if (!getField(env, jScene, "m_meshes", "Ljava/util/List;", jMeshes)) + { + return false; + } + + jvalue addParams[1]; + addParams[0].l = jMesh; + if (!call(env, jMeshes, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addParams)) + { + return false; + } + + + /* set general mesh data in java */ + jvalue setTypesParams[1]; + setTypesParams[0].i = cMesh->mPrimitiveTypes; + if (!call(env, jMesh, "jassimp/AiMesh", "setPrimitiveTypes", "(I)V", setTypesParams)) + { + return false; + } + + + if (!setIntField(env, jMesh, "m_materialIndex", cMesh->mMaterialIndex)) + { + return false; + } + + if (!setObjectField(env, jMesh, "m_name", "Ljava/lang/String;", env->NewStringUTF(cMesh->mName.C_Str()))) + { + return false; + } + + + /* determine face buffer size */ + bool isPureTriangle = cMesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE; + size_t faceBufferSize; + if (isPureTriangle) + { + faceBufferSize = cMesh->mNumFaces * 3 * sizeof(unsigned int); + } + else + { + int numVertexReferences = 0; + for (unsigned int face = 0; face < cMesh->mNumFaces; face++) + { + numVertexReferences += cMesh->mFaces[face].mNumIndices; + } + + faceBufferSize = numVertexReferences * sizeof(unsigned int); + } + + + /* allocate buffers - we do this from java so they can be garbage collected */ + jvalue allocateBuffersParams[4]; + allocateBuffersParams[0].i = cMesh->mNumVertices; + allocateBuffersParams[1].i = cMesh->mNumFaces; + allocateBuffersParams[2].z = isPureTriangle; + allocateBuffersParams[3].i = (jint) faceBufferSize; + if (!call(env, jMesh, "jassimp/AiMesh", "allocateBuffers", "(IIZI)V", allocateBuffersParams)) + { + return false; + } + + + if (cMesh->mNumVertices > 0) + { + /* push vertex data to java */ + if (!copyBuffer(env, jMesh, "m_vertices", cMesh->mVertices, cMesh->mNumVertices * sizeof(aiVector3D))) + { + lprintf("could not copy vertex data\n"); + return false; + } + + lprintf(" with %u vertices\n", cMesh->mNumVertices); + } + + + /* push face data to java */ + if (cMesh->mNumFaces > 0) + { + if (isPureTriangle) + { + char* faceBuffer = (char*) malloc(faceBufferSize); + + size_t faceDataSize = 3 * sizeof(unsigned int); + for (unsigned int face = 0; face < cMesh->mNumFaces; face++) + { + memcpy(faceBuffer + face * faceDataSize, cMesh->mFaces[face].mIndices, faceDataSize); + } + + bool res = copyBuffer(env, jMesh, "m_faces", faceBuffer, faceBufferSize); + + free(faceBuffer); + + if (!res) + { + lprintf("could not copy face data\n"); + return false; + } + } + else + { + char* faceBuffer = (char*) malloc(faceBufferSize); + char* offsetBuffer = (char*) malloc(cMesh->mNumFaces * sizeof(unsigned int)); + + size_t faceBufferPos = 0; + for (unsigned int face = 0; face < cMesh->mNumFaces; face++) + { + size_t faceBufferOffset = faceBufferPos / sizeof(unsigned int); + memcpy(offsetBuffer + face * sizeof(unsigned int), &faceBufferOffset, sizeof(unsigned int)); + + size_t faceDataSize = cMesh->mFaces[face].mNumIndices * sizeof(unsigned int); + memcpy(faceBuffer + faceBufferPos, cMesh->mFaces[face].mIndices, faceDataSize); + faceBufferPos += faceDataSize; + } + + if (faceBufferPos != faceBufferSize) + { + /* this should really not happen */ + lprintf("faceBufferPos %u, faceBufferSize %u\n", faceBufferPos, faceBufferSize); + env->FatalError("error copying face data"); + exit(-1); + } + + + bool res = copyBuffer(env, jMesh, "m_faces", faceBuffer, faceBufferSize); + res &= copyBuffer(env, jMesh, "m_faceOffsets", offsetBuffer, cMesh->mNumFaces * sizeof(unsigned int)); + + free(faceBuffer); + free(offsetBuffer); + + if (!res) + { + lprintf("could not copy face data\n"); + return false; + } + } + + lprintf(" with %u faces\n", cMesh->mNumFaces); + } + + + /* push normals to java */ + if (cMesh->HasNormals()) + { + jvalue allocateDataChannelParams[2]; + allocateDataChannelParams[0].i = 0; + allocateDataChannelParams[1].i = 0; + if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams)) + { + lprintf("could not allocate normal data channel\n"); + return false; + } + if (!copyBuffer(env, jMesh, "m_normals", cMesh->mNormals, cMesh->mNumVertices * 3 * sizeof(float))) + { + lprintf("could not copy normal data\n"); + return false; + } + + lprintf(" with normals\n"); + } + + + /* push tangents to java */ + if (cMesh->mTangents != NULL) + { + jvalue allocateDataChannelParams[2]; + allocateDataChannelParams[0].i = 1; + allocateDataChannelParams[1].i = 0; + if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams)) + { + lprintf("could not allocate tangents data channel\n"); + return false; + } + if (!copyBuffer(env, jMesh, "m_tangents", cMesh->mTangents, cMesh->mNumVertices * 3 * sizeof(float))) + { + lprintf("could not copy tangents data\n"); + return false; + } + + lprintf(" with tangents\n"); + } + + + /* push bitangents to java */ + if (cMesh->mBitangents != NULL) + { + jvalue allocateDataChannelParams[2]; + allocateDataChannelParams[0].i = 2; + allocateDataChannelParams[1].i = 0; + if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams)) + { + lprintf("could not allocate bitangents data channel\n"); + return false; + } + if (!copyBuffer(env, jMesh, "m_bitangents", cMesh->mBitangents, cMesh->mNumVertices * 3 * sizeof(float))) + { + lprintf("could not copy bitangents data\n"); + return false; + } + + lprintf(" with bitangents\n"); + } + + + /* push color sets to java */ + for (int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; c++) + { + if (cMesh->mColors[c] != NULL) + { + jvalue allocateDataChannelParams[2]; + allocateDataChannelParams[0].i = 3; + allocateDataChannelParams[1].i = c; + if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams)) + { + lprintf("could not allocate colorset data channel\n"); + return false; + } + if (!copyBufferArray(env, jMesh, "m_colorsets", c, cMesh->mColors[c], cMesh->mNumVertices * 4 * sizeof(float))) + { + lprintf("could not copy colorset data\n"); + return false; + } + + lprintf(" with colorset[%d]\n", c); + } + } + + + /* push tex coords to java */ + for (int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; c++) + { + if (cMesh->mTextureCoords[c] != NULL) + { + jvalue allocateDataChannelParams[2]; + + switch (cMesh->mNumUVComponents[c]) + { + case 1: + allocateDataChannelParams[0].i = 4; + break; + case 2: + allocateDataChannelParams[0].i = 5; + break; + case 3: + allocateDataChannelParams[0].i = 6; + break; + default: + return false; + } + + allocateDataChannelParams[1].i = c; + if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams)) + { + lprintf("could not allocate texture coordinates data channel\n"); + return false; + } + + /* gather data */ + size_t coordBufferSize = cMesh->mNumVertices * cMesh->mNumUVComponents[c] * sizeof(float); + char* coordBuffer = (char*) malloc(coordBufferSize); + size_t coordBufferOffset = 0; + + for (unsigned int v = 0; v < cMesh->mNumVertices; v++) + { + memcpy(coordBuffer + coordBufferOffset, &cMesh->mTextureCoords[c][v], cMesh->mNumUVComponents[c] * sizeof(float)); + coordBufferOffset += cMesh->mNumUVComponents[c] * sizeof(float); + } + + if (coordBufferOffset != coordBufferSize) + { + /* this should really not happen */ + lprintf("coordBufferPos %u, coordBufferSize %u\n", coordBufferOffset, coordBufferSize); + env->FatalError("error copying coord data"); + exit(-1); + } + + bool res = copyBufferArray(env, jMesh, "m_texcoords", c, coordBuffer, coordBufferSize); + + free(coordBuffer); + + if (!res) + { + lprintf("could not copy texture coordinates data\n"); + return false; + } + + lprintf(" with %uD texcoord[%d]\n", cMesh->mNumUVComponents[c], c); + } + } + + + for (unsigned int b = 0; b < cMesh->mNumBones; b++) + { + aiBone *cBone = cMesh->mBones[b]; + + jobject jBone; + if (!createInstance(env, "jassimp/AiBone", jBone)) + { + return false; + } + + /* add bone to bone list */ + jobject jBones = NULL; + + if (!getField(env, jMesh, "m_bones", "Ljava/util/List;", jBones)) + { + return false; + } + + jvalue addParams[1]; + addParams[0].l = jBone; + if (!call(env, jBones, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addParams)) + { + return false; + } + + /* set bone data */ + if (!setObjectField(env, jBone, "m_name", "Ljava/lang/String;", env->NewStringUTF(cBone->mName.C_Str()))) + { + return false; + } + + /* add bone weights */ + for (unsigned int w = 0; w < cBone->mNumWeights; w++) + { + jobject jBoneWeight; + if (!createInstance(env, "jassimp/AiBoneWeight", jBoneWeight)) + { + return false; + } + + /* add boneweight to bone list */ + jobject jBoneWeights = NULL; + + if (!getField(env, jBone, "m_boneWeights", "Ljava/util/List;", jBoneWeights)) + { + return false; + } + + + /* copy offset matrix */ + jfloatArray jMatrixArr = env->NewFloatArray(16); + env->SetFloatArrayRegion(jMatrixArr, 0, 16, (jfloat*) &cBone->mOffsetMatrix); + + jvalue wrapParams[1]; + wrapParams[0].l = jMatrixArr; + jobject jMatrix; + + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapMatrix", "([F)Ljava/lang/Object;", wrapParams, jMatrix)) + { + return false; + } + + if (!setObjectField(env, jBone, "m_offsetMatrix", "Ljava/lang/Object;", jMatrix)) + { + return false; + } + + + jvalue addBwParams[1]; + addBwParams[0].l = jBoneWeight; + if (!call(env, jBoneWeights, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addBwParams)) + { + return false; + } + + + if (!setIntField(env, jBoneWeight, "m_vertexId", cBone->mWeights[w].mVertexId)) + { + return false; + } + + if (!setFloatField(env, jBoneWeight, "m_weight", cBone->mWeights[w].mWeight)) + { + return false; + } + } + } + } + + return true; +} + + +static bool loadSceneNode(JNIEnv *env, const aiNode *cNode, jobject parent, jobject* loadedNode = NULL) +{ + lprintf(" converting node %s ...\n", cNode->mName.C_Str()); + + /* wrap matrix */ + jfloatArray jMatrixArr = env->NewFloatArray(16); + env->SetFloatArrayRegion(jMatrixArr, 0, 16, (jfloat*) &cNode->mTransformation); + + jvalue wrapMatParams[1]; + wrapMatParams[0].l = jMatrixArr; + jobject jMatrix; + + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapMatrix", "([F)Ljava/lang/Object;", wrapMatParams, jMatrix)) + { + return false; + } + + + /* create mesh references array */ + jintArray jMeshrefArr = env->NewIntArray(cNode->mNumMeshes); + jint *temp = (jint*) malloc(sizeof(jint) * cNode->mNumMeshes); + + for (unsigned int i = 0; i < cNode->mNumMeshes; i++) + { + temp[i] = cNode->mMeshes[i]; + } + env->SetIntArrayRegion(jMeshrefArr, 0, cNode->mNumMeshes, (jint*) temp); + + free(temp); + + + /* convert name */ + jstring jNodeName = env->NewStringUTF(cNode->mName.C_Str()); + + + /* wrap scene node */ + jvalue wrapNodeParams[4]; + wrapNodeParams[0].l = parent; + wrapNodeParams[1].l = jMatrix; + wrapNodeParams[2].l = jMeshrefArr; + wrapNodeParams[3].l = jNodeName; + jobject jNode; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapSceneNode", + "(Ljava/lang/Object;Ljava/lang/Object;[ILjava/lang/String;)Ljava/lang/Object;", wrapNodeParams, jNode)) + { + return false; + } + + + /* and recurse */ + for (unsigned int c = 0; c < cNode->mNumChildren; c++) + { + if (!loadSceneNode(env, cNode->mChildren[c], jNode)) + { + return false; + } + } + + if (NULL != loadedNode) + { + *loadedNode = jNode; + } + + return true; +} + + +static bool loadSceneGraph(JNIEnv *env, const aiScene* cScene, jobject& jScene) +{ + lprintf("converting scene graph ...\n"); + + if (NULL != cScene->mRootNode) + { + jobject jRoot; + + if (!loadSceneNode(env, cScene->mRootNode, NULL, &jRoot)) + { + return false; + } + + if (!setObjectField(env, jScene, "m_sceneRoot", "Ljava/lang/Object;", jRoot)) + { + return false; + } + } + + lprintf("converting scene graph finished\n"); + + return true; +} + + +static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene) +{ + for (unsigned int m = 0; m < cScene->mNumMaterials; m++) + { + const aiMaterial* cMaterial = cScene->mMaterials[m]; + + lprintf("converting material ...\n", m); + + jobject jMaterial = NULL; + + if (!createInstance(env, "jassimp/AiMaterial", jMaterial)) + { + return false; + } + + /* add material to m_materials java.util.List */ + jobject jMaterials = NULL; + + if (!getField(env, jScene, "m_materials", "Ljava/util/List;", jMaterials)) + { + return false; + } + + jvalue addMatParams[1]; + addMatParams[0].l = jMaterial; + if (!call(env, jMaterials, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addMatParams)) + { + return false; + } + + /* set texture numbers */ + for (int ttInd = aiTextureType_DIFFUSE; ttInd < aiTextureType_UNKNOWN; ttInd++) + { + aiTextureType tt = static_cast(ttInd); + + unsigned int num = cMaterial->GetTextureCount(tt); + + lprintf(" found %d textures of type %d ...\n", num, ttInd); + + jvalue setNumberParams[2]; + setNumberParams[0].i = ttInd; + setNumberParams[1].i = num; + + if (!call(env, jMaterial, "jassimp/AiMaterial", "setTextureNumber", "(II)V", setNumberParams)) + { + return false; + } + } + + + for (unsigned int p = 0; p < cMaterial->mNumProperties; p++) + { + //printf("%s - %u - %u\n", cScene->mMaterials[m]->mProperties[p]->mKey.C_Str(), + // cScene->mMaterials[m]->mProperties[p]->mSemantic, + // cScene->mMaterials[m]->mProperties[p]->mDataLength); + + const aiMaterialProperty* cProperty = cMaterial->mProperties[p]; + + lprintf(" converting property %s ...\n", cProperty->mKey.C_Str()); + + jobject jProperty = NULL; + + jvalue constructorParams[5]; + constructorParams[0].l = env->NewStringUTF(cProperty->mKey.C_Str()); + constructorParams[1].i = cProperty->mSemantic; + constructorParams[2].i = cProperty->mIndex; + constructorParams[3].i = cProperty->mType; + + + /* special case conversion for color3 */ + if (NULL != strstr(cProperty->mKey.C_Str(), "clr") && + cProperty->mType == aiPTI_Float && + cProperty->mDataLength == 3 * sizeof(float)) + { + jobject jData = NULL; + + /* wrap color */ + jvalue wrapColorParams[3]; + wrapColorParams[0].f = ((float*) cProperty->mData)[0]; + wrapColorParams[1].f = ((float*) cProperty->mData)[1]; + wrapColorParams[2].f = ((float*) cProperty->mData)[2]; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jData)) + { + return false; + } + + constructorParams[4].l = jData; + if (!createInstance(env, "jassimp/AiMaterial$Property", "(Ljava/lang/String;IIILjava/lang/Object;)V", + constructorParams, jProperty)) + { + return false; + } + } + /* special case conversion for color4 */ + else if (NULL != strstr(cProperty->mKey.C_Str(), "clr") && + cProperty->mType == aiPTI_Float && + cProperty->mDataLength == 4 * sizeof(float)) + { + jobject jData = NULL; + + /* wrap color */ + jvalue wrapColorParams[4]; + wrapColorParams[0].f = ((float*) cProperty->mData)[0]; + wrapColorParams[1].f = ((float*) cProperty->mData)[1]; + wrapColorParams[2].f = ((float*) cProperty->mData)[2]; + wrapColorParams[3].f = ((float*) cProperty->mData)[3]; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor4", "(FFFF)Ljava/lang/Object;", wrapColorParams, jData)) + { + return false; + } + + constructorParams[4].l = jData; + if (!createInstance(env, "jassimp/AiMaterial$Property", "(Ljava/lang/String;IIILjava/lang/Object;)V", + constructorParams, jProperty)) + { + return false; + } + } + else if (cProperty->mType == aiPTI_Float && cProperty->mDataLength == sizeof(float)) + { + jobject jData = NULL; + + jvalue newFloatParams[1]; + newFloatParams[0].f = ((float*) cProperty->mData)[0]; + if (!createInstance(env, "java/lang/Float", "(F)V", newFloatParams, jData)) + { + return false; + } + + constructorParams[4].l = jData; + if (!createInstance(env, "jassimp/AiMaterial$Property", "(Ljava/lang/String;IIILjava/lang/Object;)V", + constructorParams, jProperty)) + { + return false; + } + } + else if (cProperty->mType == aiPTI_Integer && cProperty->mDataLength == sizeof(int)) + { + jobject jData = NULL; + + jvalue newIntParams[1]; + newIntParams[0].i = ((int*) cProperty->mData)[0]; + if (!createInstance(env, "java/lang/Integer", "(I)V", newIntParams, jData)) + { + return false; + } + + constructorParams[4].l = jData; + if (!createInstance(env, "jassimp/AiMaterial$Property", "(Ljava/lang/String;IIILjava/lang/Object;)V", + constructorParams, jProperty)) + { + return false; + } + } + else if (cProperty->mType == aiPTI_String) + { + /* skip length prefix */ + jobject jData = env->NewStringUTF(cProperty->mData + 4); + + constructorParams[4].l = jData; + if (!createInstance(env, "jassimp/AiMaterial$Property", "(Ljava/lang/String;IIILjava/lang/Object;)V", + constructorParams, jProperty)) + { + return false; + } + } + else + { + constructorParams[4].i = cProperty->mDataLength; + + /* generic copy code, uses dump ByteBuffer on java side */ + if (!createInstance(env, "jassimp/AiMaterial$Property", "(Ljava/lang/String;IIII)V", constructorParams, jProperty)) + { + return false; + } + + jobject jBuffer = NULL; + + if (!getField(env, jProperty, "m_data", "Ljava/lang/Object;", jBuffer)) + { + return false; + } + + if (env->GetDirectBufferCapacity(jBuffer) != cProperty->mDataLength) + { + lprintf("invalid direct buffer\n"); + return false; + } + + void* jBufferPtr = env->GetDirectBufferAddress(jBuffer); + + if (NULL == jBufferPtr) + { + lprintf("could not access direct buffer\n"); + return false; + } + + memcpy(jBufferPtr, cProperty->mData, cProperty->mDataLength); + } + + + /* add property */ + jobject jProperties = NULL; + + if (!getField(env, jMaterial, "m_properties", "Ljava/util/List;", jProperties)) + { + return false; + } + + jvalue addPropParams[1]; + addPropParams[0].l = jProperty; + if (!call(env, jProperties, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addPropParams)) + { + return false; + } + } + } + + lprintf("materials finished\n"); + + return true; +} + + +static bool loadAnimations(JNIEnv *env, const aiScene* cScene, jobject& jScene) +{ + lprintf("converting %d animations ...\n", cScene->mNumAnimations); + + for (unsigned int a = 0; a < cScene->mNumAnimations; a++) + { + const aiAnimation *cAnimation = cScene->mAnimations[a]; + + lprintf(" converting animation %s ...\n", cAnimation->mName.C_Str()); + + jobject jAnimation; + jvalue newAnimParams[3]; + newAnimParams[0].l = env->NewStringUTF(cAnimation->mName.C_Str()); + newAnimParams[1].d = cAnimation->mDuration; + newAnimParams[2].d = cAnimation->mTicksPerSecond; + + if (!createInstance(env, "jassimp/AiAnimation", "(Ljava/lang/String;DD)V", newAnimParams, jAnimation)) + { + return false; + } + + /* add animation to m_animations java.util.List */ + jobject jAnimations = NULL; + + if (!getField(env, jScene, "m_animations", "Ljava/util/List;", jAnimations)) + { + return false; + } + + jvalue addParams[1]; + addParams[0].l = jAnimation; + if (!call(env, jAnimations, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addParams)) + { + return false; + } + + + for (unsigned int c = 0; c < cAnimation->mNumChannels; c++) + { + const aiNodeAnim *cNodeAnim = cAnimation->mChannels[c]; + + jobject jNodeAnim; + jvalue newNodeAnimParams[6]; + newNodeAnimParams[0].l = env->NewStringUTF(cNodeAnim->mNodeName.C_Str()); + newNodeAnimParams[1].i = cNodeAnim->mNumPositionKeys; + newNodeAnimParams[2].i = cNodeAnim->mNumRotationKeys; + newNodeAnimParams[3].i = cNodeAnim->mNumScalingKeys; + newNodeAnimParams[4].i = cNodeAnim->mPreState; + newNodeAnimParams[5].i = cNodeAnim->mPostState; + + if (!createInstance(env, "jassimp/AiNodeAnim", "(Ljava/lang/String;IIIII)V", newNodeAnimParams, jNodeAnim)) + { + return false; + } + + + /* add nodeanim to m_animations java.util.List */ + jobject jNodeAnims = NULL; + + if (!getField(env, jAnimation, "m_nodeAnims", "Ljava/util/List;", jNodeAnims)) + { + return false; + } + + jvalue addParams[1]; + addParams[0].l = jNodeAnim; + if (!call(env, jNodeAnims, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addParams)) + { + return false; + } + + /* copy keys */ + if (!copyBuffer(env, jNodeAnim, "m_posKeys", cNodeAnim->mPositionKeys, + cNodeAnim->mNumPositionKeys * sizeof(aiVectorKey))) + { + return false; + } + + if (!copyBuffer(env, jNodeAnim, "m_rotKeys", cNodeAnim->mRotationKeys, + cNodeAnim->mNumRotationKeys * sizeof(aiQuatKey))) + { + return false; + } + + if (!copyBuffer(env, jNodeAnim, "m_scaleKeys", cNodeAnim->mScalingKeys, + cNodeAnim->mNumScalingKeys * sizeof(aiVectorKey))) + { + return false; + } + } + } + + lprintf("converting animations finished\n"); + + return true; +} + + +static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene) +{ + lprintf("converting %d lights ...\n", cScene->mNumLights); + + for (unsigned int l = 0; l < cScene->mNumLights; l++) + { + const aiLight *cLight = cScene->mLights[l]; + + lprintf("converting light %s ...\n", cLight->mName.C_Str()); + + /* wrap color nodes */ + jvalue wrapColorParams[3]; + wrapColorParams[0].f = cLight->mColorDiffuse.r; + wrapColorParams[1].f = cLight->mColorDiffuse.g; + wrapColorParams[2].f = cLight->mColorDiffuse.b; + jobject jDiffuse; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jDiffuse)) + { + return false; + } + + wrapColorParams[0].f = cLight->mColorSpecular.r; + wrapColorParams[1].f = cLight->mColorSpecular.g; + wrapColorParams[2].f = cLight->mColorSpecular.b; + jobject jSpecular; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jSpecular)) + { + return false; + } + + wrapColorParams[0].f = cLight->mColorAmbient.r; + wrapColorParams[1].f = cLight->mColorAmbient.g; + wrapColorParams[2].f = cLight->mColorAmbient.b; + jobject jAmbient; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jAmbient)) + { + return false; + } + + + /* wrap vec3 nodes */ + jvalue wrapVec3Params[3]; + wrapVec3Params[0].f = cLight->mPosition.x; + wrapVec3Params[1].f = cLight->mPosition.y; + wrapVec3Params[2].f = cLight->mPosition.z; + jobject jPosition; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jPosition)) + { + return false; + } + + wrapVec3Params[0].f = cLight->mPosition.x; + wrapVec3Params[1].f = cLight->mPosition.y; + wrapVec3Params[2].f = cLight->mPosition.z; + jobject jDirection; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jDirection)) + { + return false; + } + + + jobject jLight; + + jvalue params[12]; + params[0].l = env->NewStringUTF(cLight->mName.C_Str());; + params[1].i = cLight->mType; + params[2].l = jPosition; + params[3].l = jDirection; + params[4].f = cLight->mAttenuationConstant; + params[5].f = cLight->mAttenuationLinear; + params[6].f = cLight->mAttenuationQuadratic; + params[7].l = jDiffuse; + params[8].l = jSpecular; + params[9].l = jAmbient; + params[10].f = cLight->mAngleInnerCone; + params[11].f = cLight->mAngleOuterCone; + + if (!createInstance(env, "jassimp/AiLight", "(Ljava/lang/String;ILjava/lang/Object;Ljava/lang/Object;FFFLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;FF)V", + params, jLight)) + { + return false; + } + + /* add light to m_lights java.util.List */ + jobject jLights = NULL; + + if (!getField(env, jScene, "m_lights", "Ljava/util/List;", jLights)) + { + return false; + } + + jvalue addParams[1]; + addParams[0].l = jLight; + if (!call(env, jLights, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addParams)) + { + return false; + } + } + + lprintf("converting lights finished ...\n"); + + return true; +} + + +static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene) +{ + lprintf("converting %d cameras ...\n", cScene->mNumCameras); + + for (unsigned int c = 0; c < cScene->mNumCameras; c++) + { + const aiCamera *cCamera = cScene->mCameras[c]; + + lprintf("converting camera %s ...\n", cCamera->mName.C_Str()); + + /* wrap color nodes */ + jvalue wrapPositionParams[3]; + wrapPositionParams[0].f = cCamera->mPosition.x; + wrapPositionParams[1].f = cCamera->mPosition.y; + wrapPositionParams[2].f = cCamera->mPosition.z; + jobject jPosition; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jPosition)) + { + return false; + } + + wrapPositionParams[0].f = cCamera->mUp.x; + wrapPositionParams[1].f = cCamera->mUp.y; + wrapPositionParams[2].f = cCamera->mUp.z; + jobject jUp; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jUp)) + { + return false; + } + + wrapPositionParams[0].f = cCamera->mLookAt.x; + wrapPositionParams[1].f = cCamera->mLookAt.y; + wrapPositionParams[2].f = cCamera->mLookAt.z; + jobject jLookAt; + if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jLookAt)) + { + return false; + } + + + jobject jCamera; + + jvalue params[8]; + params[0].l = env->NewStringUTF(cCamera->mName.C_Str()); + params[1].l = jPosition; + params[2].l = jUp; + params[3].l = jLookAt; + params[4].f = cCamera->mHorizontalFOV; + params[5].f = cCamera->mClipPlaneNear; + params[6].f = cCamera->mClipPlaneFar; + params[7].f = cCamera->mAspect; + + if (!createInstance(env, "jassimp/AiCamera", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;FFFF)V", + params, jCamera)) + { + return false; + } + + /* add camera to m_cameras java.util.List */ + jobject jCameras = NULL; + + if (!getField(env, jScene, "m_cameras", "Ljava/util/List;", jCameras)) + { + return false; + } + + jvalue addParams[1]; + addParams[0].l = jCamera; + if (!call(env, jCameras, "java/util/Collection", "add", "(Ljava/lang/Object;)Z", addParams)) + { + return false; + } + } + + lprintf("converting cameras finished\n"); + + return true; +} + + +JNIEXPORT jstring JNICALL Java_jassimp_Jassimp_getErrorString + (JNIEnv *env, jclass jClazz) +{ + const char *err = aiGetErrorString(); + + if (NULL == err) + { + return env->NewStringUTF(""); + } + + return env->NewStringUTF(err); +} + + +JNIEXPORT jobject JNICALL Java_jassimp_Jassimp_aiImportFile + (JNIEnv *env, jclass jClazz, jstring jFilename, jlong postProcess) +{ + jobject jScene = NULL; + + /* convert params */ + const char* cFilename = env->GetStringUTFChars(jFilename, NULL); + + + lprintf("opening file: %s\n", cFilename); + + /* do import */ + const aiScene *cScene = aiImportFile(cFilename, (unsigned int) postProcess); + + if (!cScene) + { + lprintf("import file returned null\n"); + goto error; + } + + if (!createInstance(env, "jassimp/AiScene", jScene)) + { + goto error; + } + + if (!loadMeshes(env, cScene, jScene)) + { + goto error; + } + + if (!loadMaterials(env, cScene, jScene)) + { + goto error; + } + + if (!loadAnimations(env, cScene, jScene)) + { + goto error; + } + + if (!loadLights(env, cScene, jScene)) + { + goto error; + } + + if (!loadCameras(env, cScene, jScene)) + { + goto error; + } + + if (!loadSceneGraph(env, cScene, jScene)) + { + goto error; + } + + /* jump over error handling section */ + goto end; + +error: + jclass exception = env->FindClass("java/io/IOException"); + + if (NULL == exception) + { + /* thats really a problem because we cannot throw in this case */ + env->FatalError("could not throw java.io.IOException"); + } + + env->ThrowNew(exception, aiGetErrorString()); + + lprintf("problem detected\n"); + +end: + /* + * NOTE: this releases all memory used in the native domain. + * Ensure all data has been passed to java before! + */ + aiReleaseImport(cScene); + + + /* free params */ + env->ReleaseStringUTFChars(jFilename, cFilename); + + lprintf("return from native\n"); + + return jScene; +} \ No newline at end of file diff --git a/port/jassimp/jassimp-native/src/jassimp.h b/port/jassimp/jassimp-native/src/jassimp.h new file mode 100644 index 000000000..4eaec5541 --- /dev/null +++ b/port/jassimp/jassimp-native/src/jassimp.h @@ -0,0 +1,31 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class jassimp_Jassimp */ + +#ifndef _Included_jassimp_Jassimp +#define _Included_jassimp_Jassimp +#ifdef __cplusplus +extern "C" { +#endif +/* Inaccessible static: BUILTIN */ +/* Inaccessible static: s_wrapperProvider */ +/* + * Class: jassimp_Jassimp + * Method: getErrorString + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_jassimp_Jassimp_getErrorString + (JNIEnv *, jclass); + +/* + * Class: jassimp_Jassimp + * Method: aiImportFile + * Signature: (Ljava/lang/String;J)Ljassimp/AiScene; + */ +JNIEXPORT jobject JNICALL Java_jassimp_Jassimp_aiImportFile + (JNIEnv *, jclass, jstring, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/port/jassimp/jassimp/src/jassimp/AiAnimBehavior.java b/port/jassimp/jassimp/src/jassimp/AiAnimBehavior.java new file mode 100644 index 000000000..7dd3fb560 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiAnimBehavior.java @@ -0,0 +1,112 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Defines how an animation channel behaves outside the defined time range. + */ +public enum AiAnimBehavior { + /** + * The value from the default node transformation is taken. + */ + DEFAULT(0x0), + + + /** + * The nearest key value is used without interpolation. + */ + CONSTANT(0x1), + + + /** + * The value of the nearest two keys is linearly extrapolated for the + * current time value. + */ + LINEAR(0x2), + + + /** + * The animation is repeated.

+ * + * If the animation key go from n to m and the current time is t, use the + * value at (t-n) % (|m-n|). + */ + REPEAT(0x3); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static AiAnimBehavior fromRawValue(int rawValue) { + for (AiAnimBehavior type : AiAnimBehavior.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiAnimBehavior(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiAnimation.java b/port/jassimp/jassimp/src/jassimp/AiAnimation.java new file mode 100644 index 000000000..fca3bc53d --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiAnimation.java @@ -0,0 +1,179 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.util.ArrayList; +import java.util.List; + +/** + * An animation.

+ * + * An animation consists of keyframe data for a number of nodes. For + * each node affected by the animation a separate series of data is given.

+ * + * Like {@link AiMesh}, the animation related classes offer a Buffer API, a + * Direct API and a wrapped API. Please consult the documentation of + * {@link AiMesh} for a description and comparison of these APIs. + */ +public final class AiAnimation { + /** + * Constructor. + * + * @param name name + * @param duration duration + * @param ticksPerSecond ticks per second + */ + AiAnimation(String name, double duration, double ticksPerSecond) { + m_name = name; + m_duration = duration; + m_ticksPerSecond = ticksPerSecond; + } + + + /** + * Returns the name of the animation.

+ * + * If the modeling package this data was exported from does support only + * a single animation channel, this name is usually empty (length is zero). + * + * @return the name + */ + public String getName() { + return m_name; + } + + + /** + * Returns the duration of the animation in ticks. + * + * @return the duration + */ + public double getDuration() { + return m_duration; + } + + + /** + * Returns the ticks per second.

+ * + * 0 if not specified in the imported file + * + * @return the number of ticks per second + */ + public double getTicksPerSecond() { + return m_ticksPerSecond; + } + + + /** + * Returns the number of bone animation channels.

+ * + * Each channel affects a single node. This method will return the same + * value as getChannels().size() + * + * @return the number of bone animation channels + */ + public int getNumChannels() { + return m_nodeAnims.size(); + } + + + /** + * Returns the list of bone animation channels.

+ * + * Each channel affects a single node. The array is mNumChannels in size. + * + * @return the list of bone animation channels + */ + public List getChannels() { + return m_nodeAnims; + } + + + /** + * Returns the number of mesh animation channels.

+ * + * Each channel affects a single mesh and defines vertex-based animation. + * This method will return the same value as + * getMeshChannels().size() + * + * @return the number of mesh animation channels + */ + public int getNumMeshChannels() { + throw new UnsupportedOperationException("not implemented yet"); + } + + + /** + * Returns the list of mesh animation channels.

+ * + * Each channel affects a single mesh. + * + * @return the list of mesh animation channels + */ + public List getMeshChannels() { + throw new UnsupportedOperationException("not implemented yet"); + } + + + /** + * Name. + */ + private final String m_name; + + + /** + * Duration. + */ + private final double m_duration; + + + /** + * Ticks per second. + */ + private final double m_ticksPerSecond; + + + /** + * Bone animation channels. + */ + private final List m_nodeAnims = new ArrayList(); +} \ No newline at end of file diff --git a/port/jassimp/jassimp/src/jassimp/AiBlendMode.java b/port/jassimp/jassimp/src/jassimp/AiBlendMode.java new file mode 100644 index 000000000..941ace11e --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiBlendMode.java @@ -0,0 +1,117 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Defines alpha-blend flags.

+ * + * If you're familiar with OpenGL or D3D, these flags aren't new to you. + * They define *how* the final color value of a pixel is computed, basing + * on the previous color at that pixel and the new color value from the + * material. The blend formula is: + *
+ * SourceColor * SourceBlend + DestColor * DestBlend + *
+ * where DestColor is the previous color in the framebuffer at + * this position and SourceColor is the material color before the + * transparency calculation. + */ +public enum AiBlendMode { + /** + * Default blending.

+ * + * Formula: + * + * SourceColor*SourceAlpha + DestColor*(1-SourceAlpha) + * + */ + DEFAULT(0x0), + + + /** + * Additive blending.

+ * + * Formula: + * + * SourceColor*1 + DestColor*1 + * + */ + ADDITIVE(0x1); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static AiBlendMode fromRawValue(int rawValue) { + for (AiBlendMode type : AiBlendMode.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiBlendMode(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} \ No newline at end of file diff --git a/port/jassimp/jassimp/src/jassimp/AiBone.java b/port/jassimp/jassimp/src/jassimp/AiBone.java new file mode 100644 index 000000000..87c4b8199 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiBone.java @@ -0,0 +1,137 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.util.ArrayList; +import java.util.List; + + +/** + * A single bone of a mesh.

+ * + * A bone has a name by which it can be found in the frame hierarchy and by + * which it can be addressed by animations. In addition it has a number of + * influences on vertices.

+ * + * This class is designed to be mutable, i.e., the returned collections are + * writable and may be modified. + */ +public final class AiBone { + /** + * Constructor. + */ + AiBone() { + /* nothing to do */ + } + + + /** + * Returns the name of the bone. + * + * @return the name + */ + public String getName() { + return m_name; + } + + + /** + * Returns the number of bone weights.

+ * + * This method exists for compatibility with the native assimp API. + * The returned value is identical to getBoneWeights().size() + * + * @return the number of weights + */ + public int getNumWeights() { + return m_boneWeights.size(); + } + + + /** + * Returns a list of bone weights. + * + * @return the bone weights + */ + public List getBoneWeights() { + return m_boneWeights; + } + + + /** + * Returns the offset matrix.

+ * + * The offset matrix is a 4x4 matrix that transforms from mesh space to + * bone space in bind pose.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers). + * + * @param wrapperProvider the wrapper provider (used for type inference) + * + * @return the offset matrix + */ + @SuppressWarnings("unchecked") + public M4 getOffsetMatrix( + AiWrapperProvider wrapperProvider) { + + return (M4) m_offsetMatrix; + } + + + /** + * Name of the bone. + */ + private String m_name; + + + /** + * Bone weights. + */ + private final List m_boneWeights = + new ArrayList(); + + + /** + * Offset matrix. + */ + private Object m_offsetMatrix; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiBoneWeight.java b/port/jassimp/jassimp/src/jassimp/AiBoneWeight.java new file mode 100644 index 000000000..7d1d74bcc --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiBoneWeight.java @@ -0,0 +1,88 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * A single influence of a bone on a vertex. + */ +public final class AiBoneWeight { + /** + * Constructor. + */ + AiBoneWeight() { + /* nothing to do */ + } + + + /** + * Index of the vertex which is influenced by the bone. + * + * @return the vertex index + */ + public int getVertexId() { + return m_vertexId; + } + + + /** + * The strength of the influence in the range (0...1).

+ * + * The influence from all bones at one vertex amounts to 1 + * + * @return the influence + */ + public float getWeight() { + return m_weight; + } + + + /** + * Vertex index. + */ + private int m_vertexId; + + + /** + * Influence of bone on vertex. + */ + private float m_weight; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiBuiltInWrapperProvider.java b/port/jassimp/jassimp/src/jassimp/AiBuiltInWrapperProvider.java new file mode 100644 index 000000000..64fad515a --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiBuiltInWrapperProvider.java @@ -0,0 +1,84 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; + + +/** + * Wrapper provider using jassimp built in types. + */ +public final class AiBuiltInWrapperProvider implements AiWrapperProvider< + AiVector, AiMatrix4f, AiColor, AiNode, AiQuaternion> { + + @Override + public AiVector wrapVector3f(ByteBuffer buffer, int offset, + int numComponents) { + + return new AiVector(buffer, offset, numComponents); + } + + + @Override + public AiMatrix4f wrapMatrix4f(float[] data) { + return new AiMatrix4f(data); + } + + + @Override + public AiColor wrapColor(ByteBuffer buffer, int offset) { + return new AiColor(buffer, offset); + } + + + @Override + public AiNode wrapSceneNode(Object parent, Object matrix, + int[] meshReferences, String name) { + + return new AiNode((AiNode) parent, matrix, meshReferences, name); + } + + + @Override + public AiQuaternion wrapQuaternion(ByteBuffer buffer, int offset) { + return new AiQuaternion(buffer, offset); + } +} diff --git a/port/jassimp/jassimp/src/jassimp/AiCamera.java b/port/jassimp/jassimp/src/jassimp/AiCamera.java new file mode 100644 index 000000000..6378210f7 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiCamera.java @@ -0,0 +1,303 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Helper structure to describe a virtual camera.

+ * + * Cameras have a representation in the node graph and can be animated. + * An important aspect is that the camera itself is also part of the + * scenegraph. This means, any values such as the look-at vector are not + * *absolute*, they're relative to the coordinate system defined + * by the node which corresponds to the camera. This allows for camera + * animations. For static cameras parameters like the 'look-at' or 'up' vectors + * are usually specified directly in aiCamera, but beware, they could also + * be encoded in the node transformation. The following (pseudo)code sample + * shows how to do it:

+ *

+ * // Get the camera matrix for a camera at a specific time
+ * // if the node hierarchy for the camera does not contain
+ * // at least one animated node this is a static computation
+ * get-camera-matrix (node sceneRoot, camera cam) : matrix
+ * {
+ *    node   cnd = find-node-for-camera(cam)
+ *    matrix cmt = identity()
+ *
+ *    // as usual - get the absolute camera transformation for this frame
+ *    for each node nd in hierarchy from sceneRoot to cnd
+ *      matrix cur
+ *      if (is-animated(nd))
+ *         cur = eval-animation(nd)
+ *      else cur = nd->mTransformation;
+ *      cmt = mult-matrices( cmt, cur )
+ *    end for
+ *
+ *    // now multiply with the camera's own local transform
+ *    cam = mult-matrices (cam, get-camera-matrix(cmt) )
+ * }
+ * 
+ * + * Note: some file formats (such as 3DS, ASE) export a "target point" - + * the point the camera is looking at (it can even be animated). Assimp + * writes the target point as a subnode of the camera's main node, + * called ".Target". However this is just additional information + * then the transformation tracks of the camera main node make the + * camera already look in the right direction. + */ +public final class AiCamera { + /** + * Constructor. + * + * @param name name + * @param position position + * @param up up vector + * @param lookAt look-at vector + * @param horizontalFOV field of view + * @param clipNear near clip plane + * @param clipFar far clip plane + * @param aspect aspect ratio + */ + AiCamera(String name, Object position, Object up, Object lookAt, + float horizontalFOV, float clipNear, float clipFar, float aspect) { + + m_name = name; + m_position = position; + m_up = up; + m_lookAt = lookAt; + m_horizontalFOV = horizontalFOV; + m_clipNear = clipNear; + m_clipFar = clipFar; + m_aspect = aspect; + } + + + /** + * Returns the name of the camera.

+ * + * There must be a node in the scenegraph with the same name. + * This node specifies the position of the camera in the scene + * hierarchy and can be animated. + */ + public String getName() { + return m_name; + } + + + /** + * Returns the position of the camera.

+ * + * The returned position is relative to the coordinate space defined by the + * corresponding node.

+ * + * The default value is 0|0|0.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the position vector + */ + @SuppressWarnings("unchecked") + public V3 getPosition(AiWrapperProvider + wrapperProvider) { + + return (V3) m_position; + } + + + /** + * Returns the 'Up' - vector of the camera coordinate system. + * + * The returned vector is relative to the coordinate space defined by the + * corresponding node.

+ * + * The 'right' vector of the camera coordinate system is the cross product + * of the up and lookAt vectors. The default value is 0|1|0. The vector + * may be normalized, but it needn't.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the 'Up' vector + */ + @SuppressWarnings("unchecked") + public V3 getUp(AiWrapperProvider + wrapperProvider) { + + return (V3) m_up; + } + + + /** + * Returns the 'LookAt' - vector of the camera coordinate system.

+ * + * The returned vector is relative to the coordinate space defined by the + * corresponding node.

+ * + * This is the viewing direction of the user. The default value is 0|0|1. + * The vector may be normalized, but it needn't.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the 'LookAt' vector + */ + @SuppressWarnings("unchecked") + public V3 getLookAt(AiWrapperProvider + wrapperProvider) { + + return (V3) m_lookAt; + } + + + /** + * Returns the half horizontal field of view angle, in radians.

+ * + * The field of view angle is the angle between the center line of the + * screen and the left or right border. The default value is 1/4PI. + * + * @return the half horizontal field of view angle + */ + public float getHorizontalFOV() { + return m_horizontalFOV; + } + + + /** + * Returns the distance of the near clipping plane from the camera.

+ * + * The value may not be 0.f (for arithmetic reasons to prevent a division + * through zero). The default value is 0.1f. + * + * @return the distance of the near clipping plane + */ + public float getClipPlaneNear() { + return m_clipNear; + } + + + /** + * Returns the distance of the far clipping plane from the camera.

+ * + * The far clipping plane must, of course, be further away than the + * near clipping plane. The default value is 1000.0f. The ratio + * between the near and the far plane should not be too + * large (between 1000-10000 should be ok) to avoid floating-point + * inaccuracies which could lead to z-fighting. + * + * @return the distance of the far clipping plane + */ + public float getClipPlaneFar() { + return m_clipFar; + } + + + /** + * Returns the screen aspect ratio.

+ * + * This is the ration between the width and the height of the + * screen. Typical values are 4/3, 1/2 or 1/1. This value is + * 0 if the aspect ratio is not defined in the source file. + * 0 is also the default value. + * + * @return the screen aspect ratio + */ + public float getAspect() { + return m_aspect; + } + + + /** + * Name. + */ + private final String m_name; + + + /** + * Position. + */ + private final Object m_position; + + + /** + * Up vector. + */ + private final Object m_up; + + + /** + * Look-At vector. + */ + private final Object m_lookAt; + + + /** + * FOV. + */ + private final float m_horizontalFOV; + + + /** + * Near clipping plane. + */ + private final float m_clipNear; + + + /** + * Far clipping plane. + */ + private final float m_clipFar; + + + /** + * Aspect ratio. + */ + private final float m_aspect; +} \ No newline at end of file diff --git a/port/jassimp/jassimp/src/jassimp/AiColor.java b/port/jassimp/jassimp/src/jassimp/AiColor.java new file mode 100644 index 000000000..25eb251d6 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiColor.java @@ -0,0 +1,162 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; + + +/** + * Wrapper for colors.

+ * + * The wrapper is writable, i.e., changes performed via the set-methods will + * modify the underlying mesh. + */ +public final class AiColor { + /** + * Constructor. + * + * @param buffer the buffer to wrap + * @param offset offset into buffer + */ + public AiColor(ByteBuffer buffer, int offset) { + m_buffer = buffer; + m_offset = offset; + } + + + /** + * Returns the red color component. + * + * @return the red component + */ + public float getRed() { + return m_buffer.getFloat(m_offset); + } + + + /** + * Returns the green color component. + * + * @return the green component + */ + public float getGreen() { + return m_buffer.getFloat(m_offset + 4); + } + + + /** + * Returns the blue color component. + * + * @return the blue component + */ + public float getBlue() { + return m_buffer.getFloat(m_offset + 8); + } + + + /** + * Returns the alpha color component. + * + * @return the alpha component + */ + public float getAlpha() { + return m_buffer.getFloat(m_offset + 12); + } + + + /** + * Sets the red color component. + * + * @param red the new value + */ + public void setRed(float red) { + m_buffer.putFloat(m_offset, red); + } + + + /** + * Sets the green color component. + * + * @param green the new value + */ + public void setGreen(float green) { + m_buffer.putFloat(m_offset + 4, green); + } + + + /** + * Sets the blue color component. + * + * @param blue the new value + */ + public void setBlue(float blue) { + m_buffer.putFloat(m_offset + 8, blue); + } + + + /** + * Sets the alpha color component. + * + * @param alpha the new value + */ + public void setAlpha(float alpha) { + m_buffer.putFloat(m_offset + 12, alpha); + } + + + @Override + public String toString() { + return "[" + getRed() + ", " + getGreen() + ", " + getBlue() + ", " + + getAlpha() + "]"; + } + + + /** + * Wrapped buffer. + */ + private final ByteBuffer m_buffer; + + + /** + * Offset into m_buffer. + */ + private final int m_offset; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiConfig.java b/port/jassimp/jassimp/src/jassimp/AiConfig.java new file mode 100644 index 000000000..f49ce8625 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiConfig.java @@ -0,0 +1,15 @@ +/* + * $Revision$ + * $Date$ + */ +package jassimp; + + +/** + * Configuration interface for assimp importer.

+ * + * This class is work-in-progress + */ +public class AiConfig { + +} diff --git a/port/jassimp/jassimp/src/jassimp/AiConfigOptions.java b/port/jassimp/jassimp/src/jassimp/AiConfigOptions.java new file mode 100644 index 000000000..6196598cd --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiConfigOptions.java @@ -0,0 +1,663 @@ +/* + * $Revision$ + * $Date$ + */ +package jassimp; + + +/** + * Lists all possible configuration options.

+ * + * This class is work-in-progress + */ +public enum AiConfigOptions { + /** + * Maximum bone count per mesh for the SplitbyBoneCount step.

+ * + * Meshes are split until the maximum number of bones is reached. The + * default value is AI_SBBC_DEFAULT_MAX_BONES, which may be altered at + * compile-time. This limit is imposed by the native jassimp library + * and typically is 60.

+ * + * Property data type: integer. + */ + PP_SBBC_MAX_BONES("PP_SBBC_MAX_BONES"), + + + /** + * Specifies the maximum angle that may be between two vertex tangents + * that their tangents and bi-tangents are smoothed.

+ * + * This applies to the CalcTangentSpace-Step. The angle is specified + * in degrees. The maximum value is 175.

+ * + * Property type: float. Default value: 45 degrees + */ + PP_CT_MAX_SMOOTHING_ANGLE("PP_CT_MAX_SMOOTHING_ANGLE"), + + + /** + * Source UV channel for tangent space computation.

+ * + * The specified channel must exist or an error will be raised.

+ * + * Property type: integer. Default value: 0 + */ + PP_CT_TEXTURE_CHANNEL_INDEX("PP_CT_TEXTURE_CHANNEL_INDEX"), + + + /** + * Specifies the maximum angle that may be between two face normals + * at the same vertex position that their are smoothed together.

+ * + * Sometimes referred to as 'crease angle'. This applies to the + * GenSmoothNormals-Step. The angle is specified in degrees, so 180 is PI. + * The default value is 175 degrees (all vertex normals are smoothed). The + * maximum value is 175, too.

+ * + * Property type: float.

+ * + * Warning: setting this option may cause a severe loss of performance. The + * performance is unaffected if the {@link #CONFIG_FAVOUR_SPEED} flag is + * set but the output quality may be reduced. + */ + PP_GSN_MAX_SMOOTHING_ANGLE("PP_GSN_MAX_SMOOTHING_ANGLE"), + + + /** + * Sets the colormap (= palette) to be used to decode embedded textures in + * MDL (Quake or 3DGS) files.

+ * + * This must be a valid path to a file. The file is 768 (256*3) bytes + * large and contains RGB triplets for each of the 256 palette entries. + * The default value is colormap.lmp. If the file is not found, + * a default palette (from Quake 1) is used.

+ * + * Property type: string. + */ + IMPORT_MDL_COLORMAP("IMPORT_MDL_COLORMAP"), + + + /** + * Configures the #aiProcess_RemoveRedundantMaterials step to keep + * materials matching a name in a given list.

+ * + * This is a list of 1 to n strings, ' ' serves as delimiter character. + * Identifiers containing whitespaces must be enclosed in *single* + * quotation marks. For example: + * "keep-me and_me_to anotherMaterialToBeKept \'name with whitespace\'". + * If a material matches on of these names, it will not be modified or + * removed by the postprocessing step nor will other materials be replaced + * by a reference to it.

+ * + * This option might be useful if you are using some magic material names + * to pass additional semantics through the content pipeline. This ensures + * they won't be optimized away, but a general optimization is still + * performed for materials not contained in the list.

+ * + * Property type: String. Default value: n/a

+ * + * Note:Linefeeds, tabs or carriage returns are treated as + * whitespace. Material names are case sensitive. + */ + PP_RRM_EXCLUDE_LIST("PP_RRM_EXCLUDE_LIST"), + + + /** + * Configures the {@link AiPostProcessSteps#PRE_TRANSFORM_VERTICES} step + * to keep the scene hierarchy. Meshes are moved to worldspace, but no + * optimization is performed (read: meshes with equal materials are not + * joined. The total number of meshes won't change).

+ * + * This option could be of use for you if the scene hierarchy contains + * important additional information which you intend to parse. + * For rendering, you can still render all meshes in the scene without + * any transformations.

+ * + * Property type: bool. Default value: false. + */ + PP_PTV_KEEP_HIERARCHY("PP_PTV_KEEP_HIERARCHY"), + + + /** + * Configures the {@link AiPostProcessSteps#PRE_TRANSFORM_VERTICES} step + * to normalize all vertex components into the [-1,1] range.

+ * + * That is, a bounding box for the whole scene is computed, the maximum + * component is taken and all meshes are scaled appropriately (uniformly + * of course!). This might be useful if you don't know the spatial + * dimension of the input data.

+ * + * Property type: bool. Default value: false. + */ + PP_PTV_NORMALIZE("PP_PTV_NORMALIZE"), + + + /** + * Configures the {@link AiPostProcessSteps#FIND_DEGENERATES} step to + * remove degenerated primitives from the import - immediately.

+ * + * The default behaviour converts degenerated triangles to lines and + * degenerated lines to points. See the documentation to the + * {@link AiPostProcessSteps#FIND_DEGENERATES} step for a detailed example + * of the various ways to get rid of these lines and points if you don't + * want them.

+ * + * Property type: bool. Default value: false. + */ + PP_FD_REMOVE("PP_FD_REMOVE") + + +// // --------------------------------------------------------------------------- +// /** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes +// * matching a name in a given list. +// * +// * This is a list of 1 to n strings, ' ' serves as delimiter character. +// * Identifiers containing whitespaces must be enclosed in *single* +// * quotation marks. For example: +// * "keep-me and_me_to anotherNodeToBeKept \'name with whitespace\'". +// * If a node matches on of these names, it will not be modified or +// * removed by the postprocessing step.
+// * This option might be useful if you are using some magic node names +// * to pass additional semantics through the content pipeline. This ensures +// * they won't be optimized away, but a general optimization is still +// * performed for nodes not contained in the list. +// * Property type: String. Default value: n/a +// * @note Linefeeds, tabs or carriage returns are treated as whitespace. +// * Node names are case sensitive. +// */ +// #define AI_CONFIG_PP_OG_EXCLUDE_LIST \ +// "PP_OG_EXCLUDE_LIST" +// +// // --------------------------------------------------------------------------- +// /** @brief Set the maximum number of triangles in a mesh. +// * +// * This is used by the "SplitLargeMeshes" PostProcess-Step to determine +// * whether a mesh must be split or not. +// * @note The default value is AI_SLM_DEFAULT_MAX_TRIANGLES +// * Property type: integer. +// */ +// #define AI_CONFIG_PP_SLM_TRIANGLE_LIMIT \ +// "PP_SLM_TRIANGLE_LIMIT" +// +// // default value for AI_CONFIG_PP_SLM_TRIANGLE_LIMIT +// #if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES) +// # define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000 +// #endif +// +// // --------------------------------------------------------------------------- +// /** @brief Set the maximum number of vertices in a mesh. +// * +// * This is used by the "SplitLargeMeshes" PostProcess-Step to determine +// * whether a mesh must be split or not. +// * @note The default value is AI_SLM_DEFAULT_MAX_VERTICES +// * Property type: integer. +// */ +// #define AI_CONFIG_PP_SLM_VERTEX_LIMIT \ +// "PP_SLM_VERTEX_LIMIT" +// +// // default value for AI_CONFIG_PP_SLM_VERTEX_LIMIT +// #if (!defined AI_SLM_DEFAULT_MAX_VERTICES) +// # define AI_SLM_DEFAULT_MAX_VERTICES 1000000 +// #endif +// +// // --------------------------------------------------------------------------- +// /** @brief Set the maximum number of bones affecting a single vertex +// * +// * This is used by the #aiProcess_LimitBoneWeights PostProcess-Step. +// * @note The default value is AI_LBW_MAX_WEIGHTS +// * Property type: integer.*/ +// #define AI_CONFIG_PP_LBW_MAX_WEIGHTS \ +// "PP_LBW_MAX_WEIGHTS" +// +// // default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS +// #if (!defined AI_LMW_MAX_WEIGHTS) +// # define AI_LMW_MAX_WEIGHTS 0x4 +// #endif // !! AI_LMW_MAX_WEIGHTS +// +// // --------------------------------------------------------------------------- +// /** @brief Lower the deboning threshold in order to remove more bones. +// * +// * This is used by the #aiProcess_Debone PostProcess-Step. +// * @note The default value is AI_DEBONE_THRESHOLD +// * Property type: float.*/ +// #define AI_CONFIG_PP_DB_THRESHOLD \ +// "PP_DB_THRESHOLD" +// +// // default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS +// #if (!defined AI_DEBONE_THRESHOLD) +// # define AI_DEBONE_THRESHOLD 1.0f +// #endif // !! AI_DEBONE_THRESHOLD +// +// // --------------------------------------------------------------------------- +// /** @brief Require all bones qualify for deboning before removing any +// * +// * This is used by the #aiProcess_Debone PostProcess-Step. +// * @note The default value is 0 +// * Property type: bool.*/ +// #define AI_CONFIG_PP_DB_ALL_OR_NONE \ +// "PP_DB_ALL_OR_NONE" +// +// /** @brief Default value for the #AI_CONFIG_PP_ICL_PTCACHE_SIZE property +// */ +// #ifndef PP_ICL_PTCACHE_SIZE +// # define PP_ICL_PTCACHE_SIZE 12 +// #endif +// +// // --------------------------------------------------------------------------- +// /** @brief Set the size of the post-transform vertex cache to optimize the +// * vertices for. This configures the #aiProcess_ImproveCacheLocality step. +// * +// * The size is given in vertices. Of course you can't know how the vertex +// * format will exactly look like after the import returns, but you can still +// * guess what your meshes will probably have. +// * @note The default value is #PP_ICL_PTCACHE_SIZE. That results in slight +// * performance improvements for most nVidia/AMD cards since 2002. +// * Property type: integer. +// */ +// #define AI_CONFIG_PP_ICL_PTCACHE_SIZE "PP_ICL_PTCACHE_SIZE" +// +// // --------------------------------------------------------------------------- +// /** @brief Enumerates components of the aiScene and aiMesh data structures +// * that can be excluded from the import using the #aiPrpcess_RemoveComponent step. +// * +// * See the documentation to #aiProcess_RemoveComponent for more details. +// */ +// enum aiComponent +// { +// /** Normal vectors */ +// #ifdef SWIG +// aiComponent_NORMALS = 0x2, +// #else +// aiComponent_NORMALS = 0x2u, +// #endif +// +// /** Tangents and bitangents go always together ... */ +// #ifdef SWIG +// aiComponent_TANGENTS_AND_BITANGENTS = 0x4, +// #else +// aiComponent_TANGENTS_AND_BITANGENTS = 0x4u, +// #endif +// +// /** ALL color sets +// * Use aiComponent_COLORn(N) to specify the N'th set */ +// aiComponent_COLORS = 0x8, +// +// /** ALL texture UV sets +// * aiComponent_TEXCOORDn(N) to specify the N'th set */ +// aiComponent_TEXCOORDS = 0x10, +// +// /** Removes all bone weights from all meshes. +// * The scenegraph nodes corresponding to the bones are NOT removed. +// * use the #aiProcess_OptimizeGraph step to do this */ +// aiComponent_BONEWEIGHTS = 0x20, +// +// /** Removes all node animations (aiScene::mAnimations). +// * The corresponding scenegraph nodes are NOT removed. +// * use the #aiProcess_OptimizeGraph step to do this */ +// aiComponent_ANIMATIONS = 0x40, +// +// /** Removes all embedded textures (aiScene::mTextures) */ +// aiComponent_TEXTURES = 0x80, +// +// /** Removes all light sources (aiScene::mLights). +// * The corresponding scenegraph nodes are NOT removed. +// * use the #aiProcess_OptimizeGraph step to do this */ +// aiComponent_LIGHTS = 0x100, +// +// /** Removes all light sources (aiScene::mCameras). +// * The corresponding scenegraph nodes are NOT removed. +// * use the #aiProcess_OptimizeGraph step to do this */ +// aiComponent_CAMERAS = 0x200, +// +// /** Removes all meshes (aiScene::mMeshes). */ +// aiComponent_MESHES = 0x400, +// +// /** Removes all materials. One default material will +// * be generated, so aiScene::mNumMaterials will be 1. */ +// aiComponent_MATERIALS = 0x800, +// +// +// /** This value is not used. It is just there to force the +// * compiler to map this enum to a 32 Bit integer. */ +// #ifndef SWIG +// _aiComponent_Force32Bit = 0x9fffffff +// #endif +// }; +// +// // Remove a specific color channel 'n' +// #define aiComponent_COLORSn(n) (1u << (n+20u)) +// +// // Remove a specific UV channel 'n' +// #define aiComponent_TEXCOORDSn(n) (1u << (n+25u)) +// +// // --------------------------------------------------------------------------- +// /** @brief Input parameter to the #aiProcess_RemoveComponent step: +// * Specifies the parts of the data structure to be removed. +// * +// * See the documentation to this step for further details. The property +// * is expected to be an integer, a bitwise combination of the +// * #aiComponent flags defined above in this header. The default +// * value is 0. Important: if no valid mesh is remaining after the +// * step has been executed (e.g you thought it was funny to specify ALL +// * of the flags defined above) the import FAILS. Mainly because there is +// * no data to work on anymore ... +// */ +// #define AI_CONFIG_PP_RVC_FLAGS \ +// "PP_RVC_FLAGS" +// +// // --------------------------------------------------------------------------- +// /** @brief Input parameter to the #aiProcess_SortByPType step: +// * Specifies which primitive types are removed by the step. +// * +// * This is a bitwise combination of the aiPrimitiveType flags. +// * Specifying all of them is illegal, of course. A typical use would +// * be to exclude all line and point meshes from the import. This +// * is an integer property, its default value is 0. +// */ +// #define AI_CONFIG_PP_SBP_REMOVE \ +// "PP_SBP_REMOVE" +// +// // --------------------------------------------------------------------------- +// /** @brief Input parameter to the #aiProcess_FindInvalidData step: +// * Specifies the floating-point accuracy for animation values. The step +// * checks for animation tracks where all frame values are absolutely equal +// * and removes them. This tweakable controls the epsilon for floating-point +// * comparisons - two keys are considered equal if the invariant +// * abs(n0-n1)>epsilon holds true for all vector respectively quaternion +// * components. The default value is 0.f - comparisons are exact then. +// */ +// #define AI_CONFIG_PP_FID_ANIM_ACCURACY \ +// "PP_FID_ANIM_ACCURACY" +// +// +// // TransformUVCoords evaluates UV scalings +// #define AI_UVTRAFO_SCALING 0x1 +// +// // TransformUVCoords evaluates UV rotations +// #define AI_UVTRAFO_ROTATION 0x2 +// +// // TransformUVCoords evaluates UV translation +// #define AI_UVTRAFO_TRANSLATION 0x4 +// +// // Everything baked together -> default value +// #define AI_UVTRAFO_ALL (AI_UVTRAFO_SCALING | AI_UVTRAFO_ROTATION | AI_UVTRAFO_TRANSLATION) +// +// // --------------------------------------------------------------------------- +// /** @brief Input parameter to the #aiProcess_TransformUVCoords step: +// * Specifies which UV transformations are evaluated. +// * +// * This is a bitwise combination of the AI_UVTRAFO_XXX flags (integer +// * property, of course). By default all transformations are enabled +// * (AI_UVTRAFO_ALL). +// */ +// #define AI_CONFIG_PP_TUV_EVALUATE \ +// "PP_TUV_EVALUATE" +// +// // --------------------------------------------------------------------------- +// /** @brief A hint to assimp to favour speed against import quality. +// * +// * Enabling this option may result in faster loading, but it needn't. +// * It represents just a hint to loaders and post-processing steps to use +// * faster code paths, if possible. +// * This property is expected to be an integer, != 0 stands for true. +// * The default value is 0. +// */ +// #define AI_CONFIG_FAVOUR_SPEED \ +// "FAVOUR_SPEED" +// +// +// // ########################################################################### +// // IMPORTER SETTINGS +// // Various stuff to fine-tune the behaviour of specific importer plugins. +// // ########################################################################### +// +// +// // --------------------------------------------------------------------------- +// /** @brief Set the vertex animation keyframe to be imported +// * +// * ASSIMP does not support vertex keyframes (only bone animation is supported). +// * The library reads only one frame of models with vertex animations. +// * By default this is the first frame. +// * \note The default value is 0. This option applies to all importers. +// * However, it is also possible to override the global setting +// * for a specific loader. You can use the AI_CONFIG_IMPORT_XXX_KEYFRAME +// * options (where XXX is a placeholder for the file format for which you +// * want to override the global setting). +// * Property type: integer. +// */ +// #define AI_CONFIG_IMPORT_GLOBAL_KEYFRAME "IMPORT_GLOBAL_KEYFRAME" +// +// #define AI_CONFIG_IMPORT_MD3_KEYFRAME "IMPORT_MD3_KEYFRAME" +// #define AI_CONFIG_IMPORT_MD2_KEYFRAME "IMPORT_MD2_KEYFRAME" +// #define AI_CONFIG_IMPORT_MDL_KEYFRAME "IMPORT_MDL_KEYFRAME" +// #define AI_CONFIG_IMPORT_MDC_KEYFRAME "IMPORT_MDC_KEYFRAME" +// #define AI_CONFIG_IMPORT_SMD_KEYFRAME "IMPORT_SMD_KEYFRAME" +// #define AI_CONFIG_IMPORT_UNREAL_KEYFRAME "IMPORT_UNREAL_KEYFRAME" +// +// +// // --------------------------------------------------------------------------- +// /** @brief Configures the AC loader to collect all surfaces which have the +// * "Backface cull" flag set in separate meshes. +// * +// * Property type: bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL \ +// "IMPORT_AC_SEPARATE_BFCULL" +// +// // --------------------------------------------------------------------------- +// /** @brief Configures whether the AC loader evaluates subdivision surfaces ( +// * indicated by the presence of the 'subdiv' attribute in the file). By +// * default, Assimp performs the subdivision using the standard +// * Catmull-Clark algorithm +// * +// * * Property type: bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION \ +// "IMPORT_AC_EVAL_SUBDIVISION" +// +// // --------------------------------------------------------------------------- +// /** @brief Configures the UNREAL 3D loader to separate faces with different +// * surface flags (e.g. two-sided vs. single-sided). +// * +// * * Property type: bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS \ +// "UNREAL_HANDLE_FLAGS" +// +// // --------------------------------------------------------------------------- +// /** @brief Configures the terragen import plugin to compute uv's for +// * terrains, if not given. Furthermore a default texture is assigned. +// * +// * UV coordinates for terrains are so simple to compute that you'll usually +// * want to compute them on your own, if you need them. This option is intended +// * for model viewers which want to offer an easy way to apply textures to +// * terrains. +// * * Property type: bool. Default value: false. +// */ +// #define AI_CONFIG_IMPORT_TER_MAKE_UVS \ +// "IMPORT_TER_MAKE_UVS" +// +// // --------------------------------------------------------------------------- +// /** @brief Configures the ASE loader to always reconstruct normal vectors +// * basing on the smoothing groups loaded from the file. +// * +// * Some ASE files have carry invalid normals, other don't. +// * * Property type: bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS \ +// "IMPORT_ASE_RECONSTRUCT_NORMALS" +// +// // --------------------------------------------------------------------------- +// /** @brief Configures the M3D loader to detect and process multi-part +// * Quake player models. +// * +// * These models usually consist of 3 files, lower.md3, upper.md3 and +// * head.md3. If this property is set to true, Assimp will try to load and +// * combine all three files if one of them is loaded. +// * Property type: bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART \ +// "IMPORT_MD3_HANDLE_MULTIPART" +// +// // --------------------------------------------------------------------------- +// /** @brief Tells the MD3 loader which skin files to load. +// * +// * When loading MD3 files, Assimp checks whether a file +// * _.skin is existing. These files are used by +// * Quake III to be able to assign different skins (e.g. red and blue team) +// * to models. 'default', 'red', 'blue' are typical skin names. +// * Property type: String. Default value: "default". +// */ +// #define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ +// "IMPORT_MD3_SKIN_NAME" +// +// // --------------------------------------------------------------------------- +// /** @brief Specify the Quake 3 shader file to be used for a particular +// * MD3 file. This can also be a search path. +// * +// * By default Assimp's behaviour is as follows: If a MD3 file +// * /models///.md3 is +// * loaded, the library tries to locate the corresponding shader file in +// * /scripts/.shader. This property overrides this +// * behaviour. It can either specify a full path to the shader to be loaded +// * or alternatively the path (relative or absolute) to the directory where +// * the shaders for all MD3s to be loaded reside. Assimp attempts to open +// *

/.shader first, /.shader +// * is the fallback file. Note that should have a terminal (back)slash. +// * Property type: String. Default value: n/a. +// */ +// #define AI_CONFIG_IMPORT_MD3_SHADER_SRC \ +// "IMPORT_MD3_SHADER_SRC" +// +// // --------------------------------------------------------------------------- +// /** @brief Configures the LWO loader to load just one layer from the model. +// * +// * LWO files consist of layers and in some cases it could be useful to load +// * only one of them. This property can be either a string - which specifies +// * the name of the layer - or an integer - the index of the layer. If the +// * property is not set the whole LWO model is loaded. Loading fails if the +// * requested layer is not available. The layer index is zero-based and the +// * layer name may not be empty.
+// * Property type: Integer. Default value: all layers are loaded. +// */ +// #define AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY \ +// "IMPORT_LWO_ONE_LAYER_ONLY" +// +// // --------------------------------------------------------------------------- +// /** @brief Configures the MD5 loader to not load the MD5ANIM file for +// * a MD5MESH file automatically. +// * +// * The default strategy is to look for a file with the same name but the +// * MD5ANIM extension in the same directory. If it is found, it is loaded +// * and combined with the MD5MESH file. This configuration option can be +// * used to disable this behaviour. +// * +// * * Property type: bool. Default value: false. +// */ +// #define AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD \ +// "IMPORT_MD5_NO_ANIM_AUTOLOAD" +// +// // --------------------------------------------------------------------------- +// /** @brief Defines the begin of the time range for which the LWS loader +// * evaluates animations and computes aiNodeAnim's. +// * +// * Assimp provides full conversion of LightWave's envelope system, including +// * pre and post conditions. The loader computes linearly subsampled animation +// * chanels with the frame rate given in the LWS file. This property defines +// * the start time. Note: animation channels are only generated if a node +// * has at least one envelope with more tan one key assigned. This property. +// * is given in frames, '0' is the first frame. By default, if this property +// * is not set, the importer takes the animation start from the input LWS +// * file ('FirstFrame' line)
+// * Property type: Integer. Default value: taken from file. +// * +// * @see AI_CONFIG_IMPORT_LWS_ANIM_END - end of the imported time range +// */ +// #define AI_CONFIG_IMPORT_LWS_ANIM_START \ +// "IMPORT_LWS_ANIM_START" +// #define AI_CONFIG_IMPORT_LWS_ANIM_END \ +// "IMPORT_LWS_ANIM_END" +// +// // --------------------------------------------------------------------------- +// /** @brief Defines the output frame rate of the IRR loader. +// * +// * IRR animations are difficult to convert for Assimp and there will +// * always be a loss of quality. This setting defines how many keys per second +// * are returned by the converter.
+// * Property type: integer. Default value: 100 +// */ +// #define AI_CONFIG_IMPORT_IRR_ANIM_FPS \ +// "IMPORT_IRR_ANIM_FPS" +// +// +// // --------------------------------------------------------------------------- +// /** @brief Ogre Importer will try to load this Materialfile. +// * +// * Ogre Meshes contain only the MaterialName, not the MaterialFile. If there +// * is no material file with the same name as the material, Ogre Importer will +// * try to load this file and search the material in it. +// *
+// * Property type: String. Default value: guessed. +// */ +// #define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE "IMPORT_OGRE_MATERIAL_FILE" +// +// +// // --------------------------------------------------------------------------- +// /** @brief Ogre Importer detect the texture usage from its filename +// * +// * Normally, a texture is loaded as a colormap, if no target is specified in the +// * materialfile. Is this switch is enabled, texture names ending with _n, _l, _s +// * are used as normalmaps, lightmaps or specularmaps. +// *
+// * Property type: Bool. Default value: false. +// */ +// #define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME" +// +// +// +// // --------------------------------------------------------------------------- +// /** @brief Specifies whether the IFC loader skips over IfcSpace elements. +// * +// * IfcSpace elements (and their geometric representations) are used to +// * represent, well, free space in a building storey.
+// * Property type: Bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS" +// +// +// // --------------------------------------------------------------------------- +// /** @brief Specifies whether the IFC loader skips over +// * shape representations of type 'Curve2D'. +// * +// * A lot of files contain both a faceted mesh representation and a outline +// * with a presentation type of 'Curve2D'. Currently Assimp doesn't convert those, +// * so turning this option off just clutters the log with errors.
+// * Property type: Bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS "IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS" +// +// // --------------------------------------------------------------------------- +// /** @brief Specifies whether the IFC loader will use its own, custom triangulation +// * algorithm to triangulate wall and floor meshes. +// * +// * If this property is set to false, walls will be either triangulated by +// * #aiProcess_Triangulate or will be passed through as huge polygons with +// * faked holes (i.e. holes that are connected with the outer boundary using +// * a dummy edge). It is highly recommended to set this property to true +// * if you want triangulated data because #aiProcess_Triangulate is known to +// * have problems with the kind of polygons that the IFC loader spits out for +// * complicated meshes. +// * Property type: Bool. Default value: true. +// */ +// #define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION" +// + ; + + private AiConfigOptions(String name) { + m_name = name; + } + + + private final String m_name; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiLight.java b/port/jassimp/jassimp/src/jassimp/AiLight.java new file mode 100644 index 000000000..0b1dd2f67 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiLight.java @@ -0,0 +1,387 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Describes a light source.

+ * + * Assimp supports multiple sorts of light sources, including + * directional, point and spot lights. All of them are defined with just + * a single structure and distinguished by their parameters. + * Note - some file formats (such as 3DS, ASE) export a "target point" - + * the point a spot light is looking at (it can even be animated). Assimp + * writes the target point as a subnode of a spotlights's main node, + * called "<spotName>.Target". However, this is just additional + * information then, the transformation tracks of the main node make the + * spot light already point in the right direction. + */ +public final class AiLight { + /** + * Constructor. + * + * @param name + * @param type + * @param position + * @param direction + * @param attenuationConstant + * @param attenuationLinear + * @param attenuationQuadratic + * @param diffuse + * @param specular + * @param ambient + * @param innerCone + * @param outerCone + */ + AiLight(String name, int type, Object position, Object direction, + float attenuationConstant, float attenuationLinear, + float attenuationQuadratic, Object diffuse, Object specular, + Object ambient, float innerCone, float outerCone) { + + m_name = name; + m_type = AiLightType.fromRawValue(type); + m_position = position; + m_direction = direction; + m_attenuationConstant = attenuationConstant; + m_attenuationLinear = attenuationLinear; + m_attenuationQuadratic = attenuationQuadratic; + m_diffuse = diffuse; + m_specular = specular; + m_ambient = ambient; + m_innerCone = innerCone; + m_outerCone = outerCone; + } + + + /** + * Returns the name of the light source.

+ * + * There must be a node in the scenegraph with the same name. + * This node specifies the position of the light in the scene + * hierarchy and can be animated. + * + * @return the name + */ + public String getName() { + return m_name; + } + + + /** + * Returns The type of the light source. + * + * @return the type + */ + public AiLightType getType() { + return m_type; + } + + + /** + * Returns the position of the light.

+ * + * The position is relative to the transformation of the scene graph node + * corresponding to the light. The position is undefined for directional + * lights.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiVector}. + * + * + * @param wrapperProvider the wrapper provider (used for type inference) + * + * @return the position + */ + @SuppressWarnings("unchecked") + public V3 getPosition(AiWrapperProvider + wrapperProvider) { + + return (V3) m_position; + } + + + /** + * Returns the direction of the light.

+ * + * The direction is relative to the transformation of the scene graph node + * corresponding to the light. The direction is undefined for point lights. + * The vector may be normalized, but it needn't..

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the position + */ + @SuppressWarnings("unchecked") + public V3 getDirection(AiWrapperProvider + wrapperProvider) { + + return (V3) m_direction; + } + + + /** + * Constant light attenuation factor.

+ * + * The intensity of the light source at a given distance 'd' from + * the light's position is + * Atten = 1/( att0 + att1 * d + att2 * d*d) + * This member corresponds to the att0 variable in the equation. + * Naturally undefined for directional lights. + * + * @return the constant light attenuation factor + */ + public float getAttenuationConstant() { + return m_attenuationConstant; + } + + + /** + * Linear light attenuation factor.

+ * + * The intensity of the light source at a given distance 'd' from + * the light's position is + * Atten = 1/( att0 + att1 * d + att2 * d*d) + * This member corresponds to the att1 variable in the equation. + * Naturally undefined for directional lights. + * + * @return the linear light attenuation factor + */ + public float getAttenuationLinear() { + return m_attenuationLinear; + } + + + /** + * Quadratic light attenuation factor.

+ * + * The intensity of the light source at a given distance 'd' from + * the light's position is + * Atten = 1/( att0 + att1 * d + att2 * d*d) + * This member corresponds to the att2 variable in the equation. + * Naturally undefined for directional lights. + * + * @return the quadratic light attenuation factor + */ + public float getAttenuationQuadratic() { + return m_attenuationQuadratic; + } + + + /** + * Diffuse color of the light source.

+ * + * The diffuse light color is multiplied with the diffuse + * material color to obtain the final color that contributes + * to the diffuse shading term.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiColor}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the diffuse color (alpha will be 1) + */ + @SuppressWarnings("unchecked") + public C getColorDiffuse( + AiWrapperProvider wrapperProvider) { + + return (C) m_diffuse; + } + + + /** + * Specular color of the light source.

+ * + * The specular light color is multiplied with the specular + * material color to obtain the final color that contributes + * to the specular shading term.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiColor}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the specular color (alpha will be 1) + */ + @SuppressWarnings("unchecked") + public C getColorSpecular( + AiWrapperProvider wrapperProvider) { + + return (C) m_specular; + } + + + /** + * Ambient color of the light source.

+ * + * The ambient light color is multiplied with the ambient + * material color to obtain the final color that contributes + * to the ambient shading term. Most renderers will ignore + * this value it, is just a remaining of the fixed-function pipeline + * that is still supported by quite many file formats.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiColor}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the ambient color (alpha will be 1) + */ + @SuppressWarnings("unchecked") + public C getColorAmbient( + AiWrapperProvider wrapperProvider) { + + return (C) m_ambient; + } + + + /** + * Inner angle of a spot light's light cone.

+ * + * The spot light has maximum influence on objects inside this + * angle. The angle is given in radians. It is 2PI for point + * lights and undefined for directional lights. + * + * @return the inner angle + */ + public float getAngleInnerCone() { + return m_innerCone; + } + + + /** + * Outer angle of a spot light's light cone.

+ * + * The spot light does not affect objects outside this angle. + * The angle is given in radians. It is 2PI for point lights and + * undefined for directional lights. The outer angle must be + * greater than or equal to the inner angle. + * It is assumed that the application uses a smooth + * interpolation between the inner and the outer cone of the + * spot light. + * + * @return the outer angle + */ + public float getAngleOuterCone() { + return m_outerCone; + } + + + /** + * Name. + */ + private final String m_name; + + + /** + * Type. + */ + private final AiLightType m_type; + + + /** + * Position. + */ + private final Object m_position; + + + /** + * Direction. + */ + private final Object m_direction; + + + /** + * Constant attenuation. + */ + private final float m_attenuationConstant; + + + /** + * Linear attenuation. + */ + private final float m_attenuationLinear; + + + /** + * Quadratic attenuation. + */ + private final float m_attenuationQuadratic; + + + /** + * Diffuse color. + */ + private final Object m_diffuse; + + + /** + * Specular color. + */ + private final Object m_specular; + + + /** + * Ambient color. + */ + private final Object m_ambient; + + + /** + * Inner cone of spotlight. + */ + private final float m_innerCone; + + + /** + * Outer cone of spotlight. + */ + private final float m_outerCone; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiLightType.java b/port/jassimp/jassimp/src/jassimp/AiLightType.java new file mode 100644 index 000000000..5df38763c --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiLightType.java @@ -0,0 +1,112 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * List of light types supported by {@link AiLight}. + */ +public enum AiLightType { + /** + * A directional light source.

+ * + * A directional light has a well-defined direction but is infinitely far + * away. That's quite a good approximation for sun light. + */ + DIRECTIONAL(0x1), + + + /** + * A point light source.

+ * + * A point light has a well-defined position in space but no direction - + * it emits light in all directions. A normal bulb is a point light. + */ + POINT(0x2), + + + /** + * A spot light source.

+ * + * A spot light emits light in a specific angle. It has a position and a + * direction it is pointing to. A good example for a spot light is a light + * spot in sport arenas. + */ + SPOT(0x3); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static AiLightType fromRawValue(int rawValue) { + for (AiLightType type : AiLightType.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiLightType(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiMaterial.java b/port/jassimp/jassimp/src/jassimp/AiMaterial.java new file mode 100644 index 000000000..7a9abc0d3 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiMaterial.java @@ -0,0 +1,1202 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * Data structure for a material.

+ * + * Depending on the imported scene and scene format, individual properties + * might be present or not. A list of all imported properties can be retrieved + * via {@link #getProperties()}.

+ * + * This class offers getXXX() for all supported properties. These + * methods are fail-save, i.e., will return a default value when the + * corresponding property is not set. To change the built in default values, + * use the setDefaultXXX() methods.

+ * + * If your application expects a certain set of properties to be available, + * the {@link #hasProperties(Set)} method can be used to check whether all + * these properties are actually set. If this check fails, you can still + * use this material via the getXXX() methods without special + * error handling code as the implementation guarantees to return default + * values for missing properties. This check will not work on texture related + * properties (i.e., properties starting with TEX_). + */ +public final class AiMaterial { + /** + * Enumerates all supported material properties. + */ + public static enum PropertyKey { + /** + * Name. + */ + NAME("?mat.name", String.class), + + /** + * Two-sided flag. + */ + TWO_SIDED("$mat.twosided", Integer.class), + + /** + * Shading mode. + */ + SHADING_MODE("$mat.shadingm", AiShadingMode.class), + + /** + * Wireframe flag. + */ + WIREFRAME("$mat.wireframe", Integer.class), + + /** + * Blend mode. + */ + BLEND_MODE("$mat.blend", AiBlendMode.class), + + /** + * Opacity. + */ + OPACITY("$mat.opacity", Float.class), + + /** + * Bump scaling. + */ + BUMP_SCALING("$mat.bumpscaling", Float.class), + + + /** + * Shininess. + */ + SHININESS("$mat.shininess", Float.class), + + + /** + * Reflectivity. + */ + REFLECTIVITY("$mat.reflectivity", Float.class), + + + /** + * Shininess strength. + */ + SHININESS_STRENGTH("$mat.shinpercent", Float.class), + + + /** + * Refract index. + */ + REFRACTI("$mat.refracti", Float.class), + + + /** + * Diffuse color. + */ + COLOR_DIFFUSE("$clr.diffuse", Object.class), + + + /** + * Ambient color. + */ + COLOR_AMBIENT("$clr.ambient", Object.class), + + + /** + * Ambient color. + */ + COLOR_SPECULAR("$clr.specular", Object.class), + + + /** + * Emissive color. + */ + COLOR_EMISSIVE("$clr.emissive", Object.class), + + + /** + * Transparent color. + */ + COLOR_TRANSPARENT("$clr.transparent", Object.class), + + + /** + * Reflective color. + */ + COLOR_REFLECTIVE("$clr.reflective", Object.class), + + + /** + * Global background image. + */ + GLOBAL_BACKGROUND_IMAGE("?bg.global", String.class), + + + /** + * Texture file path. + */ + TEX_FILE("$tex.file", String.class), + + + /** + * Texture uv index. + */ + TEX_UV_INDEX("$tex.uvwsrc", Integer.class), + + + /** + * Texture blend factor. + */ + TEX_BLEND("$tex.blend", Float.class), + + + /** + * Texture operation. + */ + TEX_OP("$tex.op", AiTextureOp.class), + + + /** + * Texture map mode for u axis. + */ + TEX_MAP_MODE_U("$tex.mapmodeu", AiTextureMapMode.class), + + + /** + * Texture map mode for v axis. + */ + TEX_MAP_MODE_V("$tex.mapmodev", AiTextureMapMode.class), + + + /** + * Texture map mode for w axis. + */ + TEX_MAP_MODE_W("$tex.mapmodew", AiTextureMapMode.class); + + /** + * Constructor. + * + * @param key key name as used by assimp + * @param type key type, used for casts and checks + */ + private PropertyKey(String key, Class type) { + m_key = key; + m_type = type; + } + + + /** + * Key. + */ + private final String m_key; + + + /** + * Type. + */ + private final Class m_type; + } + + + /** + * A very primitive RTTI system for the contents of material properties. + */ + public static enum PropertyType { + /** + * Array of single-precision (32 Bit) floats. + */ + FLOAT(0x1), + + + /** + * The material property is a string. + */ + STRING(0x3), + + + /** + * Array of (32 Bit) integers. + */ + INTEGER(0x4), + + + /** + * Simple binary buffer, content undefined. Not convertible to anything. + */ + BUFFER(0x5); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static PropertyType fromRawValue(int rawValue) { + for (PropertyType type : PropertyType.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private PropertyType(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; + } + + + /** + * Data structure for a single material property.

+ * + * As an user, you'll probably never need to deal with this data structure. + * Just use the provided get() family of functions to query material + * properties easily. + */ + public static final class Property { + /** + * Constructor. + * + * @param key + * @param semantic + * @param index + * @param type + * @param data + */ + Property(String key, int semantic, int index, int type, + Object data) { + + m_key = key; + m_semantic = semantic; + m_index = index; + m_type = PropertyType.fromRawValue(type); + m_data = data; + } + + + /** + * Constructor. + * + * @param key + * @param semantic + * @param index + * @param type + * @param dataLen + */ + Property(String key, int semantic, int index, int type, + int dataLen) { + + m_key = key; + m_semantic = semantic; + m_index = index; + m_type = PropertyType.fromRawValue(type); + + ByteBuffer b = ByteBuffer.allocateDirect(dataLen); + b.order(ByteOrder.nativeOrder()); + + m_data = b; + } + + + /** + * Returns the key of the property.

+ * + * Keys are generally case insensitive. + * + * @return the key + */ + public String getKey() { + return m_key; + } + + + /** + * Textures: Specifies their exact usage semantic. + * For non-texture properties, this member is always 0 + * (or, better-said, #aiTextureType_NONE). + * + * @return the semantic + */ + public int getSemantic() { + return m_semantic; + } + + + /** + * Textures: Specifies the index of the texture. + * For non-texture properties, this member is always 0. + * + * @return the index + */ + public int getIndex() { + return m_index; + } + + + /** + * Type information for the property.

+ * + * Defines the data layout inside the data buffer. This is used + * by the library internally to perform debug checks and to + * utilize proper type conversions. + * (It's probably a hacky solution, but it works.) + * + * @return the type + */ + public PropertyType getType() { + return m_type; + } + + + /** + * Binary buffer to hold the property's value. + * The size of the buffer is always mDataLength. + * + * @return the data + */ + Object getData() { + return m_data; + } + + + /** + * Key. + */ + private final String m_key; + + + /** + * Semantic. + */ + private final int m_semantic; + + + /** + * Index. + */ + private final int m_index; + + + /** + * Type. + */ + private final PropertyType m_type; + + + /** + * Data. + */ + private final Object m_data; + } + + + /** + * Constructor. + */ + AiMaterial() { + /* nothing to do */ + } + + + /** + * Checks whether the given set of properties is available. + * + * @param keys the keys to check + * @return true if all properties are available, false otherwise + */ + public boolean hasProperties(Set keys) { + for (PropertyKey key : keys) { + if (null == getProperty(key.m_key)) { + return false; + } + } + + return true; + } + + + /** + * Sets a default value.

+ * + * The passed in Object must match the type of the key as returned by + * the corresponding getXXX() method. + * + * @param key the key + * @param defaultValue the new default, may not be null + * @throws IllegalArgumentException if defaultValue is null or has a wrong + * type + */ + public void setDefault(PropertyKey key, Object defaultValue) { + if (null == defaultValue) { + throw new IllegalArgumentException("defaultValue may not be null"); + } + if (key.m_type != defaultValue.getClass()) { + throw new IllegalArgumentException( + "defaultValue has wrong type, " + + "expected: " + key.m_type + ", found: " + + defaultValue.getClass()); + } + + m_defaults.put(key, defaultValue); + } + + + // {{ Fail-save Getters + /** + * Returns the name of the material.

+ * + * If missing, defaults to empty string + * + * @return the name + */ + public String getName() { + return getTyped(PropertyKey.NAME, String.class); + } + + + /** + * Returns the two-sided flag.

+ * + * If missing, defaults to 0 + * + * @return the two-sided flag + */ + public int getTwoSided() { + return getTyped(PropertyKey.TWO_SIDED, Integer.class); + } + + + /** + * Returns the shading mode.

+ * + * If missing, defaults to {@link AiShadingMode#FLAT} + * + * @return the shading mode + */ + public AiShadingMode getShadingMode() { + Property p = getProperty(PropertyKey.SHADING_MODE.m_key); + + if (null == p || null == p.getData()) { + return (AiShadingMode) m_defaults.get(PropertyKey.SHADING_MODE); + } + + return AiShadingMode.fromRawValue((Integer) p.getData()); + } + + + /** + * Returns the wireframe flag.

+ * + * If missing, defaults to 0 + * + * @return the wireframe flag + */ + public int getWireframe() { + return getTyped(PropertyKey.WIREFRAME, Integer.class); + } + + + /** + * Returns the blend mode.

+ * + * If missing, defaults to {@link AiBlendMode#DEFAULT} + * + * @return the blend mode + */ + public AiBlendMode getBlendMode() { + Property p = getProperty(PropertyKey.BLEND_MODE.m_key); + + if (null == p || null == p.getData()) { + return (AiBlendMode) m_defaults.get(PropertyKey.BLEND_MODE); + } + + return AiBlendMode.fromRawValue((Integer) p.getData()); + } + + + /** + * Returns the opacity.

+ * + * If missing, defaults to 1.0 + * + * @return the opacity + */ + public float getOpacity() { + return getTyped(PropertyKey.OPACITY, Float.class); + } + + + /** + * Returns the bump scaling factor.

+ * + * If missing, defaults to 1.0 + * + * @return the bump scaling factor + */ + public float getBumpScaling() { + return getTyped(PropertyKey.BUMP_SCALING, Float.class); + } + + + /** + * Returns the shininess.

+ * + * If missing, defaults to 1.0 + * + * @return the shininess + */ + public float getShininess() { + return getTyped(PropertyKey.SHININESS, Float.class); + } + + + /** + * Returns the reflectivity.

+ * + * If missing, defaults to 0.0 + * + * @return the reflectivity + */ + public float getReflectivity() { + return getTyped(PropertyKey.REFLECTIVITY, Float.class); + } + + + /** + * Returns the shininess strength.

+ * + * If missing, defaults to 0.0 + * + * @return the shininess strength + */ + public float getShininessStrength() { + return getTyped(PropertyKey.SHININESS_STRENGTH, Float.class); + } + + + /** + * Returns the refract index.

+ * + * If missing, defaults to 0.0 + * + * @return the refract index + */ + public float getRefractIndex() { + return getTyped(PropertyKey.REFRACTI, Float.class); + } + + + /** + * Returns the diffuse color.

+ * + * If missing, defaults to opaque white (1.0, 1.0, 1.0, 1.0)

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the diffuse color + */ + @SuppressWarnings("unchecked") + public C getDiffuseColor( + AiWrapperProvider wrapperProvider) { + + Property p = getProperty(PropertyKey.COLOR_DIFFUSE.m_key); + + if (null == p || null == p.getData()) { + Object def = m_defaults.get(PropertyKey.COLOR_DIFFUSE); + if (def == null) { + return (C) Jassimp.wrapColor4(1.0f, 1.0f, 1.0f, 1.0f); + } + + return (C) def; + } + + return (C) p.getData(); + } + + + /** + * Returns the ambient color.

+ * + * If missing, defaults to opaque white (1.0, 1.0, 1.0, 1.0)

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the ambient color + */ + @SuppressWarnings("unchecked") + public C getAmbientColor( + AiWrapperProvider wrapperProvider) { + + Property p = getProperty(PropertyKey.COLOR_AMBIENT.m_key); + + if (null == p || null == p.getData()) { + Object def = m_defaults.get(PropertyKey.COLOR_AMBIENT); + if (def == null) { + return (C) Jassimp.wrapColor4(1.0f, 1.0f, 1.0f, 1.0f); + } + + return (C) def; + } + + return (C) p.getData(); + } + + + /** + * Returns the specular color.

+ * + * If missing, defaults to opaque white (1.0, 1.0, 1.0, 1.0)

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the specular color + */ + @SuppressWarnings("unchecked") + public C getSpecularColor( + AiWrapperProvider wrapperProvider) { + + Property p = getProperty(PropertyKey.COLOR_SPECULAR.m_key); + + if (null == p || null == p.getData()) { + Object def = m_defaults.get(PropertyKey.COLOR_SPECULAR); + if (def == null) { + return (C) Jassimp.wrapColor4(1.0f, 1.0f, 1.0f, 1.0f); + } + + return (C) def; + } + + return (C) p.getData(); + } + + + /** + * Returns the emissive color.

+ * + * If missing, defaults to opaque white (1.0, 1.0, 1.0, 1.0)

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the emissive color + */ + @SuppressWarnings("unchecked") + public C getEmissiveColor( + AiWrapperProvider wrapperProvider) { + + Property p = getProperty(PropertyKey.COLOR_EMISSIVE.m_key); + + if (null == p || null == p.getData()) { + Object def = m_defaults.get(PropertyKey.COLOR_EMISSIVE); + if (def == null) { + return (C) Jassimp.wrapColor4(1.0f, 1.0f, 1.0f, 1.0f); + } + + return (C) def; + } + + return (C) p.getData(); + } + + + /** + * Returns the transparent color.

+ * + * If missing, defaults to opaque white (1.0, 1.0, 1.0, 1.0)

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the transparent color + */ + @SuppressWarnings("unchecked") + public C getTransparentColor( + AiWrapperProvider wrapperProvider) { + + Property p = getProperty(PropertyKey.COLOR_TRANSPARENT.m_key); + + if (null == p || null == p.getData()) { + Object def = m_defaults.get(PropertyKey.COLOR_TRANSPARENT); + if (def == null) { + return (C) Jassimp.wrapColor4(1.0f, 1.0f, 1.0f, 1.0f); + } + + return (C) def; + } + + return (C) p.getData(); + } + + + /** + * Returns the reflective color.

+ * + * If missing, defaults to opaque white (1.0, 1.0, 1.0, 1.0)

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the reflective color + */ + @SuppressWarnings("unchecked") + public C getReflectiveColor( + AiWrapperProvider wrapperProvider) { + + Property p = getProperty(PropertyKey.COLOR_REFLECTIVE.m_key); + + if (null == p || null == p.getData()) { + Object def = m_defaults.get(PropertyKey.COLOR_REFLECTIVE); + if (def == null) { + return (C) Jassimp.wrapColor4(1.0f, 1.0f, 1.0f, 1.0f); + } + + return (C) def; + } + + return (C) p.getData(); + } + + + /** + * Returns the global background image.

+ * + * If missing, defaults to empty string + * + * @return the global background image + */ + public String getGlobalBackgroundImage() { + return getTyped(PropertyKey.GLOBAL_BACKGROUND_IMAGE, String.class); + } + + + /** + * Returns the number of textures of the given type. + * + * @param type the type + * @return the number of textures + */ + public int getNumTextures(AiTextureType type) { + return m_numTextures.get(type); + } + + + /** + * Returns the texture file.

+ * + * If missing, defaults to empty string + * + * @param type the texture type + * @param index the index in the texture stack + * @return the file + * @throws IndexOutOfBoundsException if index is invalid + */ + public String getTextureFile(AiTextureType type, int index) { + checkTexRange(type, index); + + return getTyped(PropertyKey.TEX_FILE, type, index, String.class); + } + + + /** + * Returns the index of the UV coordinate set used by the texture.

+ * + * If missing, defaults to 0 + * + * @param type the texture type + * @param index the index in the texture stack + * @return the UV index + * @throws IndexOutOfBoundsException if index is invalid + */ + public int getTextureUVIndex(AiTextureType type, int index) { + checkTexRange(type, index); + + return getTyped(PropertyKey.TEX_UV_INDEX, type, index, Integer.class); + } + + + /** + * Returns the blend factor of the texture.

+ * + * If missing, defaults to 1.0 + * + * @param type the texture type + * @param index the index in the texture stack + * @return the blend factor + */ + public float getBlendFactor(AiTextureType type, int index) { + checkTexRange(type, index); + + return getTyped(PropertyKey.TEX_BLEND, type, index, Float.class); + } + + + /** + * Returns the texture operation.

+ * + * If missing, defaults to {@link AiTextureOp#ADD} + * + * @param type the texture type + * @param index the index in the texture stack + * @return the texture operation + */ + public AiTextureOp getTextureOp(AiTextureType type, int index) { + checkTexRange(type, index); + + Property p = getProperty(PropertyKey.TEX_OP.m_key); + + if (null == p || null == p.getData()) { + return (AiTextureOp) m_defaults.get(PropertyKey.TEX_OP); + } + + return AiTextureOp.fromRawValue((Integer) p.getData()); + } + + + /** + * Returns the texture mapping mode for the u axis.

+ * + * If missing, defaults to {@link AiTextureMapMode#CLAMP} + * + * @param type the texture type + * @param index the index in the texture stack + * @return the texture mapping mode + */ + public AiTextureMapMode getTextureMapModeU(AiTextureType type, int index) { + checkTexRange(type, index); + + Property p = getProperty(PropertyKey.TEX_MAP_MODE_U.m_key); + + if (null == p || null == p.getData()) { + return (AiTextureMapMode) m_defaults.get( + PropertyKey.TEX_MAP_MODE_U); + } + + return AiTextureMapMode.fromRawValue((Integer) p.getData()); + } + + + /** + * Returns the texture mapping mode for the v axis.

+ * + * If missing, defaults to {@link AiTextureMapMode#CLAMP} + * + * @param type the texture type + * @param index the index in the texture stack + * @return the texture mapping mode + */ + public AiTextureMapMode getTextureMapModeV(AiTextureType type, int index) { + checkTexRange(type, index); + + Property p = getProperty(PropertyKey.TEX_MAP_MODE_V.m_key); + + if (null == p || null == p.getData()) { + return (AiTextureMapMode) m_defaults.get( + PropertyKey.TEX_MAP_MODE_V); + } + + return AiTextureMapMode.fromRawValue((Integer) p.getData()); + } + + + /** + * Returns the texture mapping mode for the w axis.

+ * + * If missing, defaults to {@link AiTextureMapMode#CLAMP} + * + * @param type the texture type + * @param index the index in the texture stack + * @return the texture mapping mode + */ + public AiTextureMapMode getTextureMapModeW(AiTextureType type, int index) { + checkTexRange(type, index); + + Property p = getProperty(PropertyKey.TEX_MAP_MODE_W.m_key); + + if (null == p || null == p.getData()) { + return (AiTextureMapMode) m_defaults.get( + PropertyKey.TEX_MAP_MODE_W); + } + + return AiTextureMapMode.fromRawValue((Integer) p.getData()); + } + + + /** + * Returns all information related to a single texture. + * + * @param type the texture type + * @param index the index in the texture stack + * @return the texture information + */ + public AiTextureInfo getTextureInfo(AiTextureType type, int index) { + return new AiTextureInfo(type, index, getTextureFile(type, index), + getTextureUVIndex(type, index), getBlendFactor(type, index), + getTextureOp(type, index), getTextureMapModeW(type, index), + getTextureMapModeW(type, index), + getTextureMapModeW(type, index)); + } + // }} + + // {{ Generic Getters + /** + * Returns a single property based on its key. + * + * @param key the key + * @return the property or null if the property is not set + */ + public Property getProperty(String key) { + for (Property property : m_properties) { + if (property.getKey().equals(key)) { + return property; + } + } + + return null; + } + + + /** + * Returns a single property based on its key. + * + * @param key the key + * @param semantic the semantic type (texture type) + * @param index the index + * @return the property or null if the property is not set + */ + public Property getProperty(String key, int semantic, int index) { + for (Property property : m_properties) { + if (property.getKey().equals(key) && + property.m_semantic == semantic && + property.m_index == index) { + + return property; + } + } + + return null; + } + + + /** + * Returns all properties of the material. + * + * @return the list of properties + */ + public List getProperties() { + return m_properties; + } + // }} + + + /** + * Helper method. Returns typed property data. + * + * @param type + * @param key the key + * @param clazz type + * @return the data + */ + private T getTyped(PropertyKey key, Class clazz) { + Property p = getProperty(key.m_key); + + if (null == p || null == p.getData()) { + return clazz.cast(m_defaults.get(key)); + } + + return clazz.cast(p.getData()); + } + + + /** + * Helper method. Returns typed property data. + * + * @param type + * @param key the key + * @param type the texture type + * @param index the texture index + * @param clazz type + * @return the data + */ + private T getTyped(PropertyKey key, AiTextureType type, int index, + Class clazz) { + + Property p = getProperty(key.m_key, AiTextureType.toRawValue(type), + index); + + if (null == p || null == p.getData()) { + return clazz.cast(m_defaults.get(key)); + } + + return clazz.cast(p.getData()); + } + + + /** + * Checks that index is valid an throw an exception if not. + * + * @param type the type + * @param index the index to check + */ + private void checkTexRange(AiTextureType type, int index) { + if (index < 0 || index > m_numTextures.get(type)) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + + m_numTextures.get(type)); + } + } + + + /** + * Defaults for missing properties. + */ + private Map m_defaults = + new EnumMap(PropertyKey.class); + + { + setDefault(PropertyKey.NAME, ""); + setDefault(PropertyKey.TWO_SIDED, 0); + setDefault(PropertyKey.SHADING_MODE, AiShadingMode.FLAT); + setDefault(PropertyKey.WIREFRAME, 0); + setDefault(PropertyKey.BLEND_MODE, AiBlendMode.DEFAULT); + setDefault(PropertyKey.OPACITY, 1.0f); + setDefault(PropertyKey.BUMP_SCALING, 1.0f); + setDefault(PropertyKey.SHININESS, 1.0f); + setDefault(PropertyKey.REFLECTIVITY, 0.0f); + setDefault(PropertyKey.SHININESS_STRENGTH, 0.0f); + setDefault(PropertyKey.REFRACTI, 0.0f); + + /* bypass null checks for colors */ + m_defaults.put(PropertyKey.COLOR_DIFFUSE, null); + m_defaults.put(PropertyKey.COLOR_AMBIENT, null); + m_defaults.put(PropertyKey.COLOR_SPECULAR, null); + m_defaults.put(PropertyKey.COLOR_EMISSIVE, null); + m_defaults.put(PropertyKey.COLOR_TRANSPARENT, null); + m_defaults.put(PropertyKey.COLOR_REFLECTIVE, null); + + setDefault(PropertyKey.GLOBAL_BACKGROUND_IMAGE, ""); + + /* texture related values */ + setDefault(PropertyKey.TEX_FILE, ""); + setDefault(PropertyKey.TEX_UV_INDEX, 0); + setDefault(PropertyKey.TEX_BLEND, 1.0f); + setDefault(PropertyKey.TEX_OP, AiTextureOp.ADD); + setDefault(PropertyKey.TEX_MAP_MODE_U, AiTextureMapMode.CLAMP); + setDefault(PropertyKey.TEX_MAP_MODE_V, AiTextureMapMode.CLAMP); + setDefault(PropertyKey.TEX_MAP_MODE_W, AiTextureMapMode.CLAMP); + + /* ensure we have defaults for everything */ + for (PropertyKey key : PropertyKey.values()) { + if (!m_defaults.containsKey(key)) { + throw new IllegalStateException("missing default for: " + key); + } + } + } + + + /** + * This method is used by JNI, do not call or modify. + * + * @param type the type + * @param number the number + */ + @SuppressWarnings("unused") + private void setTextureNumber(int type, int number) { + m_numTextures.put(AiTextureType.fromRawValue(type), number); + } + + + /** + * List of properties. + */ + private final List m_properties = new ArrayList(); + + + /** + * Number of textures for each type. + */ + private final Map m_numTextures = + new EnumMap(AiTextureType.class); +} diff --git a/port/jassimp/jassimp/src/jassimp/AiMatrix4f.java b/port/jassimp/jassimp/src/jassimp/AiMatrix4f.java new file mode 100644 index 000000000..19640888d --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiMatrix4f.java @@ -0,0 +1,133 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +/** + * Simple 4x4 matrix of floats. + */ +public final class AiMatrix4f { + /** + * Wraps the given array of floats as matrix. + *

+ * + * The array must have exactly 16 entries. The data in the array must be in + * row-major order. + * + * @param data + * the array to wrap, may not be null + */ + public AiMatrix4f(float[] data) { + if (data == null) { + throw new IllegalArgumentException("data may not be null"); + } + if (data.length != 16) { + throw new IllegalArgumentException("array length is not 16"); + } + + m_data = data; + } + + /** + * Gets an element of the matrix. + * + * @param row + * the row + * @param col + * the column + * @return the element at the given position + */ + public float get(int row, int col) { + if (row < 0 || row > 3) { + throw new IndexOutOfBoundsException("Index: " + row + ", Size: 4"); + } + if (col < 0 || col > 3) { + throw new IndexOutOfBoundsException("Index: " + col + ", Size: 4"); + } + + return m_data[row * 4 + col]; + } + + /** + * Stores the matrix in a new direct ByteBuffer with native byte order. + *

+ * + * The returned buffer can be passed to rendering APIs such as LWJGL, e.g., + * as parameter for GL20.glUniformMatrix4(). Be sure to set + * transpose to true in this case, as OpenGL + * expects the matrix in column order. + * + * @return a new native order, direct ByteBuffer + */ + public FloatBuffer toByteBuffer() { + ByteBuffer bbuf = ByteBuffer.allocateDirect(16 * 4); + bbuf.order(ByteOrder.nativeOrder()); + FloatBuffer fbuf = bbuf.asFloatBuffer(); + fbuf.put(m_data); + fbuf.flip(); + + return fbuf; + } + + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + + for (int row = 0; row < 4; row++) { + for (int col = 0; col < 4; col++) { + buf.append(m_data[row * 4 + col]).append(" "); + } + buf.append("\n"); + } + + return buf.toString(); + } + + + /** + * Data buffer. + */ + private final float[] m_data; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiMesh.java b/port/jassimp/jassimp/src/jassimp/AiMesh.java new file mode 100644 index 000000000..81ac0b775 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiMesh.java @@ -0,0 +1,1429 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + + +/** + * A mesh represents a geometry or model with a single material. + *

+ * + *

Data

+ * Meshes usually consist of a number of vertices and a series of faces + * referencing the vertices. In addition there might be a series of bones, each + * of them addressing a number of vertices with a certain weight. Vertex data is + * presented in channels with each channel containing a single per-vertex + * information such as a set of texture coordinates or a normal vector.

+ * + * Faces consist of one or more references to vertices, called vertex indices. + * The {@link #getPrimitiveTypes()} method can be used to check what + * face types are present in the mesh. Note that a single mesh can possess + * faces of different types. The number of indices used by a specific face can + * be retrieved with the {@link #getFaceNumIndices(int)} method. + * + * + *

API for vertex and face data

+ * The jassimp interface for accessing vertex and face data is not a one-to-one + * mapping of the c/c++ interface. The c/c++ interface uses an object-oriented + * approach to represent data, which provides a considerable + * overhead using a naive java based realization (cache locality would be + * unpredictable and most likely bad, bulk data transfer would be impossible). + *

+ * + * The jassimp interface uses flat byte buffers to store vertex and face data. + * This data can be accessed through three APIs: + *

    + *
  • Buffer API: the getXXXBuffer() methods return + * raw data buffers. + *
  • Direct API: the getXXX() methods allow reading + * and writing of individual data values. + *
  • Wrapped API: the getWrappedXXX() methods provide + * an object oriented view on the data. + *
+ * + * The Buffer API is optimized for use in conjunction with rendering APIs + * such as LWJGL. The returned buffers are guaranteed to have native byte order + * and to be direct byte buffers. They can be passed directly to LWJGL + * methods, e.g., to fill VBOs with data. Each invocation of a + * getXXXBuffer() method will return a new view of the internal + * buffer, i.e., if is safe to use the relative byte buffer operations. + * The Buffer API provides the best performance of all three APIs, especially + * if large data volumes have to be processed.

+ * + * The Direct API provides an easy to use interface for reading and writing + * individual data values. Its performance is comparable to the Buffer API's + * performance for these operations. The main difference to the Buffer API is + * the missing support for bulk operations. If you intend to retrieve or modify + * large subsets of the raw data consider using the Buffer API, especially + * if the subsets are contiguous. + *

+ * + * The Wrapped API offers an object oriented interface for accessing + * and modifying mesh data. As the name implies, this interface is realized + * through wrapper objects that provide a view on the raw data. For each + * invocation of a getWrappedXXX() method, a new wrapper object + * is created. Iterating over mesh data via this interface will create many + * short-lived wrapper objects which -depending on usage and virtual machine- + * may cause considerable garbage collection overhead. The Wrapped API provides + * the worst performance of all three APIs, which may nevertheless still be + * good enough to warrant its usage. See {@link AiWrapperProvider} for more + * details on wrappers. + * + * + *

API for bones

+ * As there is no standardized way for doing skinning in different graphics + * engines, bones are not represented as flat buffers but as object structure. + * Users of this library should convert this structure to the format required + * by the specific graphics engine. + * + * + *

Changing Data

+ * This class is designed to be mutable, i.e., the returned objects and buffers + * may be modified. It is not possible to add/remove vertices as this would + * require reallocation of the data buffers. Wrapped objects may or may not + * propagate changes to the underlying data buffers. Consult the documentation + * of your wrapper provider for details. The built in wrappers will propagate + * changes. + *

+ * Modification of face data is theoretically possible by modifying the face + * buffer and the faceOffset buffer however it is strongly disadvised to do so + * because it might break all algorithms that depend on the internal consistency + * of these two data structures. + */ +public final class AiMesh { + /** + * Number of bytes per float value. + */ + private static final int SIZEOF_FLOAT = 4; + + + /** + * Number of bytes per int value. + */ + private static final int SIZEOF_INT = 4; + + + /** + * This class is instantiated via JNI, no accessible constructor. + */ + private AiMesh() { + /* nothing to do */ + } + + + /** + * Returns the primitive types used by this mesh. + * + * @return a set of primitive types used by this mesh + */ + public Set getPrimitiveTypes() { + return m_primitiveTypes; + } + + + /** + * Tells whether the mesh is a pure triangle mesh, i.e., contains only + * triangular faces.

+ * + * To automatically triangulate meshes the + * {@link AiPostProcessSteps#TRIANGULATE} post processing option can be + * used when loading the scene + * + * @return true if the mesh is a pure triangle mesh, false otherwise + */ + public boolean isPureTriangle() { + return m_primitiveTypes.contains(AiPrimitiveType.TRIANGLE) && + m_primitiveTypes.size() == 1; + } + + + /** + * Tells whether the mesh has vertex positions.

+ * + * Meshes almost always contain position data + * + * @return true if positions are available + */ + public boolean hasPositions() { + return m_vertices != null; + } + + + /** + * Tells whether the mesh has faces.

+ * + * Meshes almost always contain faces + * + * @return true if faces are available + */ + public boolean hasFaces() { + return m_faces != null; + } + + + /** + * Tells whether the mesh has normals. + * + * @return true if normals are available + */ + public boolean hasNormals() { + return m_normals != null; + } + + + /** + * Tells whether the mesh has tangents and bitangents.

+ * + * It is not possible that it contains tangents and no bitangents (or the + * other way round). The existence of one of them implies that the second + * is there, too. + * + * @return true if tangents and bitangents are available + */ + public boolean hasTangentsAndBitangents() { + return m_tangents != null && m_tangents != null; + } + + + /** + * Tells whether the mesh has a vertex color set. + * + * @param colorset index of the color set + * @return true if colors are available + */ + public boolean hasColors(int colorset) { + return m_colorsets[colorset] != null; + } + + + /** + * Tells whether the mesh has any vertex colors.

+ * + * Use {@link #hasColors(int)} to check which color sets are + * available. + * + * @return true if any colors are available + */ + public boolean hasVertexColors() { + for (ByteBuffer buf : m_colorsets) { + if (buf != null) { + return true; + } + } + + return false; + } + + + /** + * Tells whether the mesh has a texture coordinate set. + * + * @param coords index of the texture coordinate set + * @return true if texture coordinates are available + */ + public boolean hasTexCoords(int coords) { + return m_texcoords[coords] != null; + } + + + /** + * Tells whether the mesh has any texture coordinate sets.

+ * + * Use {@link #hasTexCoords(int)} to check which texture coordinate + * sets are available + * + * @return true if any texture coordinates are available + */ + public boolean hasTexCoords() { + for (ByteBuffer buf : m_texcoords) { + if (buf != null) { + return true; + } + } + + return false; + } + + + /** + * Tells whether the mesh has bones. + * + * @return true if bones are available + */ + public boolean hasBones() { + return !m_bones.isEmpty(); + } + + + /** + * Returns the bones of this mesh. + * + * @return a list of bones + */ + public List getBones() { + return m_bones; + } + + + /** + * Returns the number of vertices in this mesh. + * + * @return the number of vertices. + */ + public int getNumVertives() { + return m_numVertices; + } + + + /** + * Returns the number of faces in the mesh. + * + * @return the number of faces + */ + public int getNumFaces() { + return m_numFaces; + } + + + /** + * Returns the number of vertex indices for a single face. + * + * @param face the face + * @return the number of indices + */ + public int getFaceNumIndices(int face) { + if (null == m_faceOffsets) { + if (face >= m_numFaces || face < 0) { + throw new IndexOutOfBoundsException("Index: " + face + + ", Size: " + m_numFaces); + } + return 3; + } + else { + /* + * no need to perform bound checks here as the array access will + * throw IndexOutOfBoundsExceptions if the index is invalid + */ + + if (face == m_numFaces - 1) { + return m_faces.capacity() / 4 - m_faceOffsets.getInt(face * 4); + } + + return m_faceOffsets.getInt((face + 1) * 4) - + m_faceOffsets.getInt(face * 4); + } + } + + + /** + * Returns the number of UV components for a texture coordinate set.

+ * + * Possible values range from 1 to 3 (1D to 3D texture coordinates) + * + * @param coords the coordinate set + * @return the number of components + */ + public int getNumUVComponents(int coords) { + return m_numUVComponents[coords]; + } + + + /** + * Returns the material used by this mesh.

+ * + * A mesh does use only a single material. If an imported model uses + * multiple materials, the import splits up the mesh. Use this value + * as index into the scene's material list. + * + * @return the material index + */ + public int getMaterialIndex() { + return m_materialIndex; + } + + + /** + * Returns the name of the mesh.

+ * + * Not all meshes have a name, if no name is set an empty string is + * returned. + * + * @return the name or an empty string if no name is set + */ + public String getName() { + return m_name; + } + + + // CHECKSTYLE:OFF + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("Mesh(").append(m_numVertices).append(" vertices, "). + append(m_numFaces).append(" faces"); + + if (hasNormals()) { + buf.append(", normals"); + } + if (hasTangentsAndBitangents()) { + buf.append(", (bi-)tangents"); + } + if (hasVertexColors()) { + buf.append(", colors"); + } + if (hasTexCoords()) { + buf.append(", texCoords"); + } + + buf.append(")"); + return buf.toString(); + } + // CHECKSTYLE:ON + + + // {{ Buffer API + /** + * Returns a buffer containing vertex positions.

+ * + * A vertex position consists of a triple of floats, the buffer will + * therefore contain 3 * getNumVertives() floats + * + * @return a native-order direct buffer, or null if no data is available + */ + public FloatBuffer getPositionBuffer() { + if (m_vertices == null) { + return null; + } + + return m_vertices.asFloatBuffer(); + } + + + /** + * Returns a buffer containing face data.

+ * + * You should use the {@link #getIndexBuffer()} method if you are + * interested in getting an index buffer used by graphics APIs such as + * LWJGL.

+ * + * The buffer contains all vertex indices from all faces as a flat list. If + * the mesh is a pure triangle mesh, the buffer returned by this method is + * identical to the buffer returned by {@link #getIndexBuffer()}. For other + * meshes, the {@link #getFaceOffsets()} method can be used to retrieve + * an index structure that allows addressing individual faces in the list. + * + * @return a native-order direct buffer, or null if no data is available + */ + public IntBuffer getFaceBuffer() { + if (m_faces == null) { + return null; + } + + return m_faces.asIntBuffer(); + } + + + /** + * Returns an index structure for the buffer returned by + * {@link #getFaceBuffer()}.

+ * + * You should use the {@link #getIndexBuffer()} method if you are + * interested in getting an index buffer used by graphics APIs such as + * LWJGL.

+ * + * The returned buffer contains one integer entry for each face. This entry + * specifies the offset at which the face's data is located inside the + * face buffer. The difference between two subsequent entries can be used + * to determine how many vertices belong to a given face (the last face + * contains all entries between the offset and the end of the face buffer). + * + * @return a native-order direct buffer, or null if no data is available + */ + public IntBuffer getFaceOffsets() { + if (m_faceOffsets == null) { + return null; + } + + return m_faceOffsets.asIntBuffer(); + } + + + + /** + * Returns a buffer containing vertex indices for the mesh's faces.

+ * + * This method may only be called on pure triangle meshes, i.e., meshes + * containing only triangles. The {@link #isPureTriangle()} method can be + * used to check whether this is the case.

+ * + * Indices are stored as integers, the buffer will therefore contain + * 3 * getNumVertives() integers (3 indices per triangle) + * + * @return a native-order direct buffer + * @throws UnsupportedOperationException + * if the mesh is not a pure triangle mesh + */ + public IntBuffer getIndexBuffer() { + if (!isPureTriangle()) { + throw new UnsupportedOperationException( + "mesh is not a pure triangle mesh"); + } + + return getFaceBuffer(); + } + + + /** + * Returns a buffer containing normals.

+ * + * A normal consists of a triple of floats, the buffer will + * therefore contain 3 * getNumVertives() floats + * + * @return a native-order direct buffer + */ + public FloatBuffer getNormalBuffer() { + if (m_normals == null) { + return null; + } + + return m_normals.asFloatBuffer(); + } + + + /** + * Returns a buffer containing tangents.

+ * + * A tangent consists of a triple of floats, the buffer will + * therefore contain 3 * getNumVertives() floats + * + * @return a native-order direct buffer + */ + public FloatBuffer getTangentBuffer() { + if (m_tangents == null) { + return null; + } + + return m_tangents.asFloatBuffer(); + } + + + /** + * Returns a buffer containing bitangents.

+ * + * A bitangent consists of a triple of floats, the buffer will + * therefore contain 3 * getNumVertives() floats + * + * @return a native-order direct buffer + */ + public FloatBuffer getBitangentBuffer() { + if (m_bitangents == null) { + return null; + } + + return m_bitangents.asFloatBuffer(); + } + + + /** + * Returns a buffer containing vertex colors for a color set.

+ * + * A vertex color consists of 4 floats (red, green, blue and alpha), the + * buffer will therefore contain 4 * getNumVertives() floats + * + * @param colorset the color set + * + * @return a native-order direct buffer, or null if no data is available + */ + public FloatBuffer getColorBuffer(int colorset) { + if (m_colorsets[colorset] == null) { + return null; + } + + return m_colorsets[colorset].asFloatBuffer(); + } + + + /** + * Returns a buffer containing coordinates for a texture coordinate set.

+ * + * A texture coordinate consists of up to 3 floats (u, v, w). The actual + * number can be queried via {@link #getNumUVComponents(int)}. The + * buffer will contain + * getNumUVComponents(coords) * getNumVertives() floats + * + * @param coords the texture coordinate set + * + * @return a native-order direct buffer, or null if no data is available + */ + public FloatBuffer getTexCoordBuffer(int coords) { + if (m_texcoords[coords] == null) { + return null; + } + + return m_texcoords[coords].asFloatBuffer(); + } + // }} + + + // {{ Direct API + /** + * Returns the x-coordinate of a vertex position. + * + * @param vertex the vertex index + * @return the x coordinate + */ + public float getPositionX(int vertex) { + if (!hasPositions()) { + throw new IllegalStateException("mesh has no positions"); + } + + checkVertexIndexBounds(vertex); + + return m_vertices.getFloat(vertex * 3 * SIZEOF_FLOAT); + } + + + /** + * Returns the y-coordinate of a vertex position. + * + * @param vertex the vertex index + * @return the y coordinate + */ + public float getPositionY(int vertex) { + if (!hasPositions()) { + throw new IllegalStateException("mesh has no positions"); + } + + checkVertexIndexBounds(vertex); + + return m_vertices.getFloat((vertex * 3 + 1) * SIZEOF_FLOAT); + } + + /** + * Returns the z-coordinate of a vertex position. + * + * @param vertex the vertex index + * @return the z coordinate + */ + public float getPositionZ(int vertex) { + if (!hasPositions()) { + throw new IllegalStateException("mesh has no positions"); + } + + checkVertexIndexBounds(vertex); + + return m_vertices.getFloat((vertex * 3 + 2) * SIZEOF_FLOAT); + } + + + /** + * Returns a vertex reference from a face.

+ * + * A face contains getFaceNumIndices(face) vertex references. + * This method returns the n'th of these. The returned index can be passed + * directly to the vertex oriented methods, such as + * getPosition() etc. + * + * @param face the face + * @param n the reference + * @return a vertex index + */ + public int getFaceVertex(int face, int n) { + if (!hasFaces()) { + throw new IllegalStateException("mesh has no faces"); + } + + if (face >= m_numFaces || face < 0) { + throw new IndexOutOfBoundsException("Index: " + face + ", Size: " + + m_numFaces); + } + if (n >= getFaceNumIndices(face) || n < 0) { + throw new IndexOutOfBoundsException("Index: " + n + ", Size: " + + getFaceNumIndices(face)); + } + + int faceOffset = 0; + if (m_faceOffsets == null) { + faceOffset = 3 * face * SIZEOF_INT; + } + else { + faceOffset = m_faceOffsets.getInt(face * SIZEOF_INT) * SIZEOF_INT; + } + + return m_faces.getInt(faceOffset + n * SIZEOF_INT); + } + + + /** + * Returns the x-coordinate of a vertex normal. + * + * @param vertex the vertex index + * @return the x coordinate + */ + public float getNormalX(int vertex) { + if (!hasNormals()) { + throw new IllegalStateException("mesh has no normals"); + } + + checkVertexIndexBounds(vertex); + + return m_normals.getFloat(vertex * 3 * SIZEOF_FLOAT); + } + + + /** + * Returns the y-coordinate of a vertex normal. + * + * @param vertex the vertex index + * @return the y coordinate + */ + public float getNormalY(int vertex) { + if (!hasNormals()) { + throw new IllegalStateException("mesh has no normals"); + } + + checkVertexIndexBounds(vertex); + + return m_normals.getFloat((vertex * 3 + 1) * SIZEOF_FLOAT); + } + + + /** + * Returns the z-coordinate of a vertex normal. + * + * @param vertex the vertex index + * @return the z coordinate + */ + public float getNormalZ(int vertex) { + if (!hasNormals()) { + throw new IllegalStateException("mesh has no normals"); + } + + checkVertexIndexBounds(vertex); + + return m_normals.getFloat((vertex * 3 + 2) * SIZEOF_FLOAT); + } + + + /** + * Returns the x-coordinate of a vertex tangent. + * + * @param vertex the vertex index + * @return the x coordinate + */ + public float getTangentX(int vertex) { + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no tangents"); + } + + checkVertexIndexBounds(vertex); + + return m_tangents.getFloat(vertex * 3 * SIZEOF_FLOAT); + } + + + /** + * Returns the y-coordinate of a vertex bitangent. + * + * @param vertex the vertex index + * @return the y coordinate + */ + public float getTangentY(int vertex) { + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no bitangents"); + } + + checkVertexIndexBounds(vertex); + + return m_tangents.getFloat((vertex * 3 + 1) * SIZEOF_FLOAT); + } + + + /** + * Returns the z-coordinate of a vertex tangent. + * + * @param vertex the vertex index + * @return the z coordinate + */ + public float getTangentZ(int vertex) { + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no tangents"); + } + + checkVertexIndexBounds(vertex); + + return m_tangents.getFloat((vertex * 3 + 2) * SIZEOF_FLOAT); + } + + + /** + * Returns the x-coordinate of a vertex tangent. + * + * @param vertex the vertex index + * @return the x coordinate + */ + public float getBitangentX(int vertex) { + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no bitangents"); + } + + checkVertexIndexBounds(vertex); + + return m_bitangents.getFloat(vertex * 3 * SIZEOF_FLOAT); + } + + + /** + * Returns the y-coordinate of a vertex tangent. + * + * @param vertex the vertex index + * @return the y coordinate + */ + public float getBitangentY(int vertex) { + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no bitangents"); + } + + checkVertexIndexBounds(vertex); + + return m_bitangents.getFloat((vertex * 3 + 1) * SIZEOF_FLOAT); + } + + + /** + * Returns the z-coordinate of a vertex tangent. + * + * @param vertex the vertex index + * @return the z coordinate + */ + public float getBitangentZ(int vertex) { + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no bitangents"); + } + + checkVertexIndexBounds(vertex); + + return m_bitangents.getFloat((vertex * 3 + 2) * SIZEOF_FLOAT); + } + + + /** + * Returns the red color component of a color from a vertex color set. + * + * @param vertex the vertex index + * @param colorset the color set + * @return the red color component + */ + public float getColorR(int vertex, int colorset) { + if (!hasColors(colorset)) { + throw new IllegalStateException("mesh has no colorset " + colorset); + } + + checkVertexIndexBounds(vertex); + /* bound checks for colorset are done by java for us */ + + return m_colorsets[colorset].getFloat(vertex * 4 * SIZEOF_FLOAT); + } + + + /** + * Returns the green color component of a color from a vertex color set. + * + * @param vertex the vertex index + * @param colorset the color set + * @return the green color component + */ + public float getColorG(int vertex, int colorset) { + if (!hasColors(colorset)) { + throw new IllegalStateException("mesh has no colorset " + colorset); + } + + checkVertexIndexBounds(vertex); + /* bound checks for colorset are done by java for us */ + + return m_colorsets[colorset].getFloat((vertex * 4 + 1) * SIZEOF_FLOAT); + } + + + /** + * Returns the blue color component of a color from a vertex color set. + * + * @param vertex the vertex index + * @param colorset the color set + * @return the blue color component + */ + public float getColorB(int vertex, int colorset) { + if (!hasColors(colorset)) { + throw new IllegalStateException("mesh has no colorset " + colorset); + } + + checkVertexIndexBounds(vertex); + /* bound checks for colorset are done by java for us */ + + return m_colorsets[colorset].getFloat((vertex * 4 + 2) * SIZEOF_FLOAT); + } + + + /** + * Returns the alpha color component of a color from a vertex color set. + * + * @param vertex the vertex index + * @param colorset the color set + * @return the alpha color component + */ + public float getColorA(int vertex, int colorset) { + if (!hasColors(colorset)) { + throw new IllegalStateException("mesh has no colorset " + colorset); + } + + checkVertexIndexBounds(vertex); + /* bound checks for colorset are done by java for us */ + + return m_colorsets[colorset].getFloat((vertex * 4 + 3) * SIZEOF_FLOAT); + } + + + /** + * Returns the u component of a coordinate from a texture coordinate set. + * + * @param vertex the vertex index + * @param coords the texture coordinate set + * @return the u component + */ + public float getTexCoordU(int vertex, int coords) { + if (!hasTexCoords(coords)) { + throw new IllegalStateException( + "mesh has no texture coordinate set " + coords); + } + + checkVertexIndexBounds(vertex); + /* bound checks for coords are done by java for us */ + + return m_texcoords[coords].getFloat( + vertex * m_numUVComponents[coords] * SIZEOF_FLOAT); + } + + + /** + * Returns the v component of a coordinate from a texture coordinate set.

+ * + * This method may only be called on 2- or 3-dimensional coordinate sets. + * Call getNumUVComponents(coords) to determine how may + * coordinate components are available. + * + * @param vertex the vertex index + * @param coords the texture coordinate set + * @return the v component + */ + public float getTexCoordV(int vertex, int coords) { + if (!hasTexCoords(coords)) { + throw new IllegalStateException( + "mesh has no texture coordinate set " + coords); + } + + checkVertexIndexBounds(vertex); + + /* bound checks for coords are done by java for us */ + + if (getNumUVComponents(coords) < 2) { + throw new IllegalArgumentException("coordinate set " + coords + + " does not contain 2D texture coordinates"); + } + + return m_texcoords[coords].getFloat( + (vertex * m_numUVComponents[coords] + 1) * SIZEOF_FLOAT); + } + + + /** + * Returns the w component of a coordinate from a texture coordinate set.

+ * + * This method may only be called on 3-dimensional coordinate sets. + * Call getNumUVComponents(coords) to determine how may + * coordinate components are available. + * + * @param vertex the vertex index + * @param coords the texture coordinate set + * @return the w component + */ + public float getTexCoordW(int vertex, int coords) { + if (!hasTexCoords(coords)) { + throw new IllegalStateException( + "mesh has no texture coordinate set " + coords); + } + + checkVertexIndexBounds(vertex); + + /* bound checks for coords are done by java for us */ + + if (getNumUVComponents(coords) < 3) { + throw new IllegalArgumentException("coordinate set " + coords + + " does not contain 3D texture coordinates"); + } + + return m_texcoords[coords].getFloat( + (vertex * m_numUVComponents[coords] + 1) * SIZEOF_FLOAT); + } + // }} + + + // {{ Wrapped API + /** + * Returns the vertex position as 3-dimensional vector.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param vertex the vertex index + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the position wrapped as object + */ + public V3 getWrappedPosition(int vertex, + AiWrapperProvider wrapperProvider) { + + if (!hasPositions()) { + throw new IllegalStateException("mesh has no positions"); + } + + checkVertexIndexBounds(vertex); + + return wrapperProvider.wrapVector3f(m_vertices, + vertex * 3 * SIZEOF_FLOAT, 3); + } + + + /** + * Returns the vertex normal as 3-dimensional vector.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param vertex the vertex index + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the normal wrapped as object + */ + public V3 getWrappedNormal(int vertex, + AiWrapperProvider wrapperProvider) { + + if (!hasNormals()) { + throw new IllegalStateException("mesh has no positions"); + } + + checkVertexIndexBounds(vertex); + + return wrapperProvider.wrapVector3f(m_normals, + vertex * 3 * SIZEOF_FLOAT, 3); + } + + + /** + * Returns the vertex tangent as 3-dimensional vector.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param vertex the vertex index + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the tangent wrapped as object + */ + public V3 getWrappedTangent(int vertex, + AiWrapperProvider wrapperProvider) { + + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no tangents"); + } + + checkVertexIndexBounds(vertex); + + return wrapperProvider.wrapVector3f(m_tangents, + vertex * 3 * SIZEOF_FLOAT, 3); + } + + + /** + * Returns the vertex bitangent as 3-dimensional vector.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param vertex the vertex index + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the bitangent wrapped as object + */ + public V3 getWrappedBitangent(int vertex, + AiWrapperProvider wrapperProvider) { + + if (!hasTangentsAndBitangents()) { + throw new IllegalStateException("mesh has no bitangents"); + } + + checkVertexIndexBounds(vertex); + + return wrapperProvider.wrapVector3f(m_bitangents, + vertex * 3 * SIZEOF_FLOAT, 3); + } + + + /** + * Returns the vertex color.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiColor}. + * + * @param vertex the vertex index + * @param colorset the color set + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the vertex color wrapped as object + */ + public C getWrappedColor(int vertex, int colorset, + AiWrapperProvider wrapperProvider) { + + if (!hasColors(colorset)) { + throw new IllegalStateException("mesh has no colorset " + colorset); + } + + checkVertexIndexBounds(vertex); + + return wrapperProvider.wrapColor( + m_colorsets[colorset], vertex * 4 * SIZEOF_FLOAT); + } + + + /** + * Returns the texture coordinates as n-dimensional vector.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param vertex the vertex index + * @param coords the texture coordinate set + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the texture coordinates wrapped as object + */ + public V3 getWrappedTexCoords(int vertex, int coords, + AiWrapperProvider wrapperProvider) { + + if (!hasTexCoords(coords)) { + throw new IllegalStateException( + "mesh has no texture coordinate set " + coords); + } + + checkVertexIndexBounds(vertex); + + return wrapperProvider.wrapVector3f(m_texcoords[coords], + vertex * 3 * SIZEOF_FLOAT, getNumUVComponents(coords)); + } + // }} + + + // {{ Helpers + /** + * Throws an exception if the vertex index is not in the allowed range. + * + * @param vertex the index to check + */ + private void checkVertexIndexBounds(int vertex) { + if (vertex >= m_numVertices || vertex < 0) { + throw new IndexOutOfBoundsException("Index: " + vertex + + ", Size: " + m_numVertices); + } + } + // }} + + // {{ JNI interface + /* + * Channel constants used by allocate data channel. Do not modify or use + * as these may change at will + */ + // CHECKSTYLE:OFF + private static final int NORMALS = 0; + private static final int TANGENTS = 1; + private static final int BITANGENTS = 2; + private static final int COLORSET = 3; + private static final int TEXCOORDS_1D = 4; + private static final int TEXCOORDS_2D = 5; + private static final int TEXCOORDS_3D = 6; + // CHECKSTYLE:ON + + + /** + * This method is used by JNI. Do not call or modify.

+ * + * Sets the primitive types enum set + * + * @param types the bitwise or'ed c/c++ aiPrimitiveType enum values + */ + @SuppressWarnings("unused") + private void setPrimitiveTypes(int types) { + AiPrimitiveType.fromRawValue(m_primitiveTypes, types); + } + + + /** + * This method is used by JNI. Do not call or modify.

+ * + * Allocates byte buffers + * + * @param numVertices the number of vertices in the mesh + * @param numFaces the number of faces in the mesh + * @param optimizedFaces set true for optimized face representation + * @param faceBufferSize size of face buffer for non-optimized face + * representation + */ + @SuppressWarnings("unused") + private void allocateBuffers(int numVertices, int numFaces, + boolean optimizedFaces, int faceBufferSize) { + /* + * the allocated buffers are native order direct byte buffers, so they + * can be passed directly to LWJGL or similar graphics APIs + */ + + /* ensure face optimization is possible */ + if (optimizedFaces && !isPureTriangle()) { + throw new IllegalArgumentException("mesh is not purely triangular"); + } + + + m_numVertices = numVertices; + m_numFaces = numFaces; + + + /* allocate for each vertex 3 floats */ + if (m_numVertices > 0) { + m_vertices = ByteBuffer.allocateDirect(numVertices * 3 * + SIZEOF_FLOAT); + m_vertices.order(ByteOrder.nativeOrder()); + } + + + if (m_numFaces > 0) { + /* for optimized faces allocate 3 integers per face */ + if (optimizedFaces) { + m_faces = ByteBuffer.allocateDirect(numFaces * 3 * SIZEOF_INT); + m_faces.order(ByteOrder.nativeOrder()); + } + /* + * for non-optimized faces allocate the passed in buffer size + * and allocate the face index structure + */ + else { + m_faces = ByteBuffer.allocateDirect(faceBufferSize); + m_faces.order(ByteOrder.nativeOrder()); + + m_faceOffsets = ByteBuffer.allocateDirect(numFaces * + SIZEOF_INT); + m_faceOffsets.order(ByteOrder.nativeOrder()); + } + } + } + + + /** + * This method is used by JNI. Do not call or modify.

+ * + * Allocates a byte buffer for a vertex data channel + * + * @param channelType the channel type + * @param channelIndex sub-index, used for types that can have multiple + * channels, such as texture coordinates + */ + @SuppressWarnings("unused") + private void allocateDataChannel(int channelType, int channelIndex) { + switch (channelType) { + case NORMALS: + m_normals = ByteBuffer.allocateDirect( + m_numVertices * 3 * SIZEOF_FLOAT); + m_normals.order(ByteOrder.nativeOrder()); + break; + case TANGENTS: + m_tangents = ByteBuffer.allocateDirect( + m_numVertices * 3 * SIZEOF_FLOAT); + m_tangents.order(ByteOrder.nativeOrder()); + break; + case BITANGENTS: + m_bitangents = ByteBuffer.allocateDirect( + m_numVertices * 3 * SIZEOF_FLOAT); + m_bitangents.order(ByteOrder.nativeOrder()); + break; + case COLORSET: + m_colorsets[channelIndex] = ByteBuffer.allocateDirect( + m_numVertices * 4 * SIZEOF_FLOAT); + m_colorsets[channelIndex].order(ByteOrder.nativeOrder()); + break; + case TEXCOORDS_1D: + m_numUVComponents[channelIndex] = 1; + m_texcoords[channelIndex] = ByteBuffer.allocateDirect( + m_numVertices * 1 * SIZEOF_FLOAT); + m_texcoords[channelIndex].order(ByteOrder.nativeOrder()); + break; + case TEXCOORDS_2D: + m_numUVComponents[channelIndex] = 2; + m_texcoords[channelIndex] = ByteBuffer.allocateDirect( + m_numVertices * 2 * SIZEOF_FLOAT); + m_texcoords[channelIndex].order(ByteOrder.nativeOrder()); + break; + case TEXCOORDS_3D: + m_numUVComponents[channelIndex] = 3; + m_texcoords[channelIndex] = ByteBuffer.allocateDirect( + m_numVertices * 3 * SIZEOF_FLOAT); + m_texcoords[channelIndex].order(ByteOrder.nativeOrder()); + break; + default: + throw new IllegalArgumentException("unsupported channel type"); + } + } + // }} + + + /** + * The primitive types used by this mesh. + */ + private final Set m_primitiveTypes = + EnumSet.noneOf(AiPrimitiveType.class); + + + /** + * Number of vertices in this mesh. + */ + private int m_numVertices = 0; + + + /** + * Number of faces in this mesh. + */ + private int m_numFaces = 0; + + + /** + * Material used by this mesh. + */ + private int m_materialIndex = -1; + + + /** + * The name of the mesh. + */ + private String m_name = ""; + + + /** + * Buffer for vertex position data. + */ + private ByteBuffer m_vertices = null; + + + /** + * Buffer for faces/ indices. + */ + private ByteBuffer m_faces = null; + + + /** + * Index structure for m_faces.

+ * + * Only used by meshes that are not pure triangular + */ + private ByteBuffer m_faceOffsets = null; + + + /** + * Buffer for normals. + */ + private ByteBuffer m_normals = null; + + + /** + * Buffer for tangents. + */ + private ByteBuffer m_tangents = null; + + + /** + * Buffer for bitangents. + */ + private ByteBuffer m_bitangents = null; + + + /** + * Vertex colors. + */ + private ByteBuffer[] m_colorsets = + new ByteBuffer[JassimpConfig.MAX_NUMBER_COLORSETS]; + + + /** + * Number of UV components for each texture coordinate set. + */ + private int[] m_numUVComponents = new int[JassimpConfig.MAX_NUMBER_TEXCOORDS]; + + + /** + * Texture coordinates. + */ + private ByteBuffer[] m_texcoords = + new ByteBuffer[JassimpConfig.MAX_NUMBER_TEXCOORDS]; + + + /** + * Bones. + */ + private final List m_bones = new ArrayList(); +} diff --git a/port/jassimp/jassimp/src/jassimp/AiMeshAnim.java b/port/jassimp/jassimp/src/jassimp/AiMeshAnim.java new file mode 100644 index 000000000..bbccc71ac --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiMeshAnim.java @@ -0,0 +1,49 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * This class is a stub - mesh animations are currently not supported. + */ +public class AiMeshAnim { + +} diff --git a/port/jassimp/jassimp/src/jassimp/AiNode.java b/port/jassimp/jassimp/src/jassimp/AiNode.java new file mode 100644 index 000000000..5cd26b668 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiNode.java @@ -0,0 +1,228 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.util.ArrayList; +import java.util.List; + + +/** + * A node in the imported hierarchy.

+ * + * Each node has name, a parent node (except for the root node), + * a transformation relative to its parent and possibly several child nodes. + * Simple file formats don't support hierarchical structures - for these formats + * the imported scene consists of only a single root node without children. + */ +public final class AiNode { + /** + * Constructor. + * + * @param parent the parent node, may be null + * @param transform the transform matrix + * @param meshReferences array of mesh references + * @param name the name of the node + */ + AiNode(AiNode parent, Object transform, int[] meshReferences, String name) { + m_parent = parent; + m_transformationMatrix = transform; + m_meshReferences = meshReferences; + m_name = name; + + if (null != m_parent) { + m_parent.addChild(this); + } + } + + + /** + * Returns the name of this node. + * + * @return the name + */ + public String getName() { + return m_name; + } + + + /** + * Returns the number of child nodes.

+ * + * This method exists for compatibility reasons with the native assimp API. + * The returned value is identical to getChildren().size() + * + * @return the number of child nodes + */ + public int getNumChildren() { + return getChildren().size(); + } + + + /** + * Returns a 4x4 matrix that specifies the transformation relative to + * the parent node.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiMatrix4f}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * + * @return a matrix + */ + @SuppressWarnings("unchecked") + public M4 getTransform(AiWrapperProvider + wrapperProvider) { + + return (M4) m_transformationMatrix; + } + + + /** + * Returns the children of this node. + * + * @return the children, or an empty list if the node has no children + */ + public List getChildren() { + return m_children; + } + + + /** + * Returns the parent node. + * + * @return the parent, or null of the node has no parent + */ + public AiNode getParent() { + return m_parent; + } + + + /** + * Searches the node hierarchy below (and including) this node for a node + * with the specified name. + * + * @param name the name to look for + * @return the first node with the given name, or null if no such node + * exists + */ + public AiNode findNode(String name) { + /* classic recursive depth first search */ + + if (m_name.equals(name)) { + return this; + } + + for (AiNode child : m_children) { + if (null != child.findNode(name)) { + return child; + } + } + + return null; + } + + + /** + * Returns the number of meshes references by this node.

+ * + * This method exists for compatibility with the native assimp API. + * The returned value is identical to getMeshes().length + * + * @return the number of references + */ + public int getNumMeshes() { + return m_meshReferences.length; + } + + + /** + * Returns the meshes referenced by this node.

+ * + * Each entry is an index into the mesh list stored in {@link AiScene}. + * + * @return an array of indices + */ + public int[] getMeshes() { + return m_meshReferences; + } + + + /** + * Adds a child node. + * + * @param child the child to add + */ + void addChild(AiNode child) { + m_children.add(child); + } + + + /** + * Name. + */ + private final String m_name; + + + /** + * Parent node. + */ + private final AiNode m_parent; + + + /** + * Mesh references. + */ + private final int[] m_meshReferences; + + + /** + * List of children. + */ + private final List m_children = new ArrayList(); + + + /** + * Buffer for transformation matrix. + */ + private final Object m_transformationMatrix; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiNodeAnim.java b/port/jassimp/jassimp/src/jassimp/AiNodeAnim.java new file mode 100644 index 000000000..43b4ce66b --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiNodeAnim.java @@ -0,0 +1,502 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + + +/** + * Describes the animation of a single node.

+ * + * The node name ({@link #getNodeName()} specifies the bone/node which is + * affected by this animation channel. The keyframes are given in three + * separate series of values, one each for position, rotation and scaling. + * The transformation matrix computed from these values replaces the node's + * original transformation matrix at a specific time.

+ * + * This means all keys are absolute and not relative to the bone default pose. + * The order in which the transformations are applied is - as usual - + * scaling, rotation, translation.

+ * + * Note: All keys are returned in their correct, chronological order. + * Duplicate keys don't pass the validation step. Most likely there + * will be no negative time values, but they are not forbidden also (so + * implementations need to cope with them!)

+ * + * Like {@link AiMesh}, the animation related classes offer a Buffer API, a + * Direct API and a wrapped API. Please consult the documentation of + * {@link AiMesh} for a description and comparison of these APIs. + */ +public final class AiNodeAnim { + /** + * Size of one position key entry (includes padding). + */ + private static final int POS_KEY_SIZE = 24; + + /** + * Size of one rotation key entry. + */ + private static final int ROT_KEY_SIZE = 24; + + /** + * Size of one scaling key entry (includes padding). + */ + private static final int SCALE_KEY_SIZE = 24; + + + /** + * Constructor. + * + * @param nodeName name of corresponding scene graph node + * @param numPosKeys number of position keys + * @param numRotKeys number of rotation keys + * @param numScaleKeys number of scaling keys + * @param preBehavior behavior before animation start + * @param postBehavior behavior after animation end + */ + AiNodeAnim(String nodeName, int numPosKeys, int numRotKeys, + int numScaleKeys, int preBehavior, int postBehavior) { + + m_nodeName = nodeName; + m_numPosKeys = numPosKeys; + m_numRotKeys = numRotKeys; + m_numScaleKeys = numScaleKeys; + m_preState = AiAnimBehavior.fromRawValue(preBehavior); + m_postState = AiAnimBehavior.fromRawValue(postBehavior); + + /* c data is padded -> 24 bytes with 20 bytes data */ + m_posKeys = ByteBuffer.allocateDirect(numPosKeys * POS_KEY_SIZE); + m_posKeys.order(ByteOrder.nativeOrder()); + + m_rotKeys = ByteBuffer.allocateDirect(numRotKeys * 24); + m_rotKeys.order(ByteOrder.nativeOrder()); + + m_scaleKeys = ByteBuffer.allocateDirect(numScaleKeys * 24); + m_scaleKeys.order(ByteOrder.nativeOrder()); + } + + + /** + * Returns the name of the scene graph node affected by this animation.

+ * + * The node must exist and it must be unique. + * + * @return the name of the affected node + */ + public String getNodeName() { + return m_nodeName; + } + + + /** + * Returns the number of position keys. + * + * @return the number of position keys + */ + public int getNumPosKeys() { + return m_numPosKeys; + } + + + /** + * Returns the buffer with position keys of this animation channel.

+ * + * Position keys consist of a time value (double) and a position (3D vector + * of floats), resulting in a total of 24 bytes per entry with padding. + * The buffer contains {@link #getNumPosKeys()} of these entries.

+ * + * If there are position keys, there will also be at least one + * scaling and one rotation key.

+ * + * @return a native order, direct ByteBuffer + */ + public ByteBuffer getPosKeyBuffer() { + ByteBuffer buf = m_posKeys.duplicate(); + buf.order(ByteOrder.nativeOrder()); + + return buf; + } + + + /** + * Returns the time component of the specified position key. + * + * @param keyIndex the index of the position key + * @return the time component + */ + public double getPosKeyTime(int keyIndex) { + return m_posKeys.getDouble(POS_KEY_SIZE * keyIndex); + } + + + /** + * Returns the position x component of the specified position key. + * + * @param keyIndex the index of the position key + * @return the x component + */ + public float getPosKeyX(int keyIndex) { + return m_posKeys.getFloat(POS_KEY_SIZE * keyIndex + 8); + } + + + /** + * Returns the position y component of the specified position key. + * + * @param keyIndex the index of the position key + * @return the y component + */ + public float getPosKeyY(int keyIndex) { + return m_posKeys.getFloat(POS_KEY_SIZE * keyIndex + 12); + } + + + /** + * Returns the position z component of the specified position key. + * + * @param keyIndex the index of the position key + * @return the z component + */ + public float getPosKeyZ(int keyIndex) { + return m_posKeys.getFloat(POS_KEY_SIZE * keyIndex + 16); + } + + + /** + * Returns the position as vector.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * + * @return the position as vector + */ + public V3 getPosKeyVector(int keyIndex, + AiWrapperProvider wrapperProvider) { + + return wrapperProvider.wrapVector3f(m_posKeys, + POS_KEY_SIZE * keyIndex + 8, 3); + } + + + /** + * Returns the number of rotation keys. + * + * @return the number of rotation keys + */ + public int getNumRotKeys() { + return m_numRotKeys; + } + + + /** + * Returns the buffer with rotation keys of this animation channel.

+ * + * Rotation keys consist of a time value (double) and a quaternion (4D + * vector of floats), resulting in a total of 24 bytes per entry. The + * buffer contains {@link #getNumRotKeys()} of these entries.

+ * + * If there are rotation keys, there will also be at least one + * scaling and one position key. + * + * @return a native order, direct ByteBuffer + */ + public ByteBuffer getRotKeyBuffer() { + ByteBuffer buf = m_rotKeys.duplicate(); + buf.order(ByteOrder.nativeOrder()); + + return buf; + } + + + /** + * Returns the time component of the specified rotation key. + * + * @param keyIndex the index of the position key + * @return the time component + */ + public double getRotKeyTime(int keyIndex) { + return m_rotKeys.getDouble(ROT_KEY_SIZE * keyIndex); + } + + + /** + * Returns the rotation w component of the specified rotation key. + * + * @param keyIndex the index of the position key + * @return the w component + */ + public float getRotKeyW(int keyIndex) { + return m_rotKeys.getFloat(ROT_KEY_SIZE * keyIndex + 8); + } + + + /** + * Returns the rotation x component of the specified rotation key. + * + * @param keyIndex the index of the position key + * @return the x component + */ + public float getRotKeyX(int keyIndex) { + return m_rotKeys.getFloat(ROT_KEY_SIZE * keyIndex + 12); + } + + + /** + * Returns the rotation y component of the specified rotation key. + * + * @param keyIndex the index of the position key + * @return the y component + */ + public float getRotKeyY(int keyIndex) { + return m_rotKeys.getFloat(ROT_KEY_SIZE * keyIndex + 16); + } + + + /** + * Returns the rotation z component of the specified rotation key. + * + * @param keyIndex the index of the position key + * @return the z component + */ + public float getRotKeyZ(int keyIndex) { + return m_rotKeys.getFloat(ROT_KEY_SIZE * keyIndex + 20); + } + + + /** + * Returns the rotation as quaternion.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiQuaternion}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * + * @return the rotation as quaternion + */ + public Q getRotKeyQuaternion(int keyIndex, + AiWrapperProvider wrapperProvider) { + + return wrapperProvider.wrapQuaternion(m_rotKeys, + ROT_KEY_SIZE * keyIndex + 8); + } + + + /** + * Returns the number of scaling keys. + * + * @return the number of scaling keys + */ + public int getNumScaleKeys() { + return m_numScaleKeys; + } + + + /** + * Returns the buffer with scaling keys of this animation channel.

+ * + * Scaling keys consist of a time value (double) and a 3D vector of floats, + * resulting in a total of 24 bytes per entry with padding. The buffer + * contains {@link #getNumScaleKeys()} of these entries.

+ * + * If there are scaling keys, there will also be at least one + * position and one rotation key. + * + * @return a native order, direct ByteBuffer + */ + public ByteBuffer getScaleKeyBuffer() { + ByteBuffer buf = m_scaleKeys.duplicate(); + buf.order(ByteOrder.nativeOrder()); + + return buf; + } + + + /** + * Returns the time component of the specified scaling key. + * + * @param keyIndex the index of the position key + * @return the time component + */ + public double getScaleKeyTime(int keyIndex) { + return m_scaleKeys.getDouble(SCALE_KEY_SIZE * keyIndex); + } + + + /** + * Returns the scaling x component of the specified scaling key. + * + * @param keyIndex the index of the position key + * @return the x component + */ + public float getScaleKeyX(int keyIndex) { + return m_scaleKeys.getFloat(SCALE_KEY_SIZE * keyIndex + 8); + } + + + /** + * Returns the scaling y component of the specified scaling key. + * + * @param keyIndex the index of the position key + * @return the y component + */ + public float getScaleKeyY(int keyIndex) { + return m_scaleKeys.getFloat(SCALE_KEY_SIZE * keyIndex + 12); + } + + + /** + * Returns the scaling z component of the specified scaling key. + * + * @param keyIndex the index of the position key + * @return the z component + */ + public float getScaleKeyZ(int keyIndex) { + return m_scaleKeys.getFloat(SCALE_KEY_SIZE * keyIndex + 16); + } + + + /** + * Returns the scaling factor as vector.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built in behavior is to return an {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * + * @return the scaling factor as vector + */ + public V3 getScaleKeyVector(int keyIndex, + AiWrapperProvider wrapperProvider) { + + return wrapperProvider.wrapVector3f(m_scaleKeys, + SCALE_KEY_SIZE * keyIndex + 8, 3); + } + + + /** + * Defines how the animation behaves before the first key is encountered. + *

+ * + * The default value is {@link AiAnimBehavior#DEFAULT} (the original + * transformation matrix of the affected node is used). + * + * @return the animation behavior before the first key + */ + public AiAnimBehavior getPreState() { + return m_preState; + } + + + /** + * Defines how the animation behaves after the last key was processed.

+ * + * The default value is {@link AiAnimBehavior#DEFAULT} (the original + * transformation matrix of the affected node is taken). + * + * @return the animation behavior before after the last key + */ + public AiAnimBehavior getPostState() { + return m_postState; + } + + + /** + * Node name. + */ + private final String m_nodeName; + + + /** + * Number of position keys. + */ + private final int m_numPosKeys; + + + /** + * Buffer with position keys. + */ + private ByteBuffer m_posKeys; + + + /** + * Number of rotation keys. + */ + private final int m_numRotKeys; + + + /** + * Buffer for rotation keys. + */ + private ByteBuffer m_rotKeys; + + + /** + * Number of scaling keys. + */ + private final int m_numScaleKeys; + + + /** + * Buffer for scaling keys. + */ + private ByteBuffer m_scaleKeys; + + + /** + * Pre animation behavior. + */ + private final AiAnimBehavior m_preState; + + + /** + * Post animation behavior. + */ + private final AiAnimBehavior m_postState; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiPostProcessSteps.java b/port/jassimp/jassimp/src/jassimp/AiPostProcessSteps.java new file mode 100644 index 000000000..905229190 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiPostProcessSteps.java @@ -0,0 +1,571 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.util.Set; + +/** + * Enumerates the post processing steps supported by assimp. + */ +public enum AiPostProcessSteps { + + /** + * 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. There's a + * config setting, #AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, which + * allows you to specify a maximum smoothing angle for the algorithm. + * However, usually you'll want to leave it at the default value. + */ + CALC_TANGENT_SPACE(0x1), + + + /** + * Identifies and joins identical vertex data sets within all imported + * meshes.

+ * + * After this step is run, each mesh contains unique vertices, so a vertex + * may be used by multiple faces. You usually want to use this post + * processing step. If your application deals with indexed geometry, this + * step is compulsory or you'll just waste rendering time. If this flag + * is not specified, no vertices are referenced by more than one face + * and no index buffer is required for rendering. + */ + JOIN_IDENTICAL_VERTICES(0x2), + + + /** + * Converts all the imported data to a left-handed coordinate space.

+ * + * By default the data is returned in a right-handed coordinate space (which + * OpenGL prefers). In this space, +X points to the right, +Z points towards + * the viewer, and +Y points upwards. In the DirectX coordinate space +X + * points to the right, +Y points upwards, and +Z points away from the + * viewer.

+ * + * You'll probably want to consider this flag if you use Direct3D for + * rendering. The #ConvertToLeftHanded flag supersedes this + * setting and bundles all conversions typically required for D3D-based + * applications. + */ + MAKE_LEFT_HANDED(0x4), + + + /** + * Triangulates all faces of all meshes.

+ * + * By default the imported mesh data might contain faces with more than 3 + * indices. For rendering you'll usually want all faces to be triangles. + * This post processing step splits up faces with more than 3 indices into + * triangles. Line and point primitives are *not* modified! If you want + * 'triangles only' with no other kinds of primitives, try the following + * solution: + *

    + *
  • Specify both #Triangulate and #SortByPType + *
  • Ignore all point and line meshes when you process assimp's output + *
+ */ + TRIANGULATE(0x8), + + + /** + * Removes some parts of the data structure (animations, materials, light + * sources, cameras, textures, vertex components).

+ * + * The components to be removed are specified in a separate configuration + * option, #AI_CONFIG_PP_RVC_FLAGS. This is quite useful if you + * don't need all parts of the output structure. Vertex colors are rarely + * used today for example... Calling this step to remove unneeded data from + * the pipeline as early as possible results in increased performance and a + * more optimized output data structure. This step is also useful if you + * want to force Assimp to recompute normals or tangents. The corresponding + * steps don't recompute them if they're already there (loaded from the + * source asset). By using this step you can make sure they are NOT there. + *

+ * + * This flag is a poor one, mainly because its purpose is usually + * misunderstood. Consider the following case: a 3D model has been exported + * from a CAD app, and it has per-face vertex colors. Vertex positions can't + * be shared, thus the #JoinIdenticalVertices step fails to + * optimize the data because of these nasty little vertex colors. Most apps + * don't even process them, so it's all for nothing. By using this step, + * unneeded components are excluded as early as possible thus opening more + * room for internal optimizations. + */ + REMOVE_COMPONENT(0x10), + + + /** + * Generates normals for all faces of all meshes.

+ * + * This is ignored if normals are already there at the time this flag is + * evaluated. Model importers try to load them from the source file, so + * they're usually already there. Face normals are shared between all points + * of a single face, so a single point can have multiple normals, which + * forces the library to duplicate vertices in some cases. + * #JoinIdenticalVertices is *senseless* then.

+ * + * This flag may not be specified together with {@link #GEN_SMOOTH_NORMALS}. + */ + GEN_NORMALS(0x20), + + + /** + * Generates smooth normals for all vertices in the mesh.

+ * + * This is ignored if normals are already there at the time this flag is + * evaluated. Model importers try to load them from the source file, so + * they're usually already there.

+ * + * This flag may not be specified together with {@link #GEN_NORMALS} + * There's a configuration option, + * #AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE which allows you to + * specify an angle maximum for the normal smoothing algorithm. Normals + * exceeding this limit are not smoothed, resulting in a 'hard' seam between + * two faces. Using a decent angle here (e.g. 80 degrees) results in very + * good visual appearance. + */ + GEN_SMOOTH_NORMALS(0x40), + + + /** + * Splits large meshes into smaller sub-meshes.

+ * + * This is quite useful for real-time rendering, where the number of + * triangles which can be maximally processed in a single draw-call is + * limited by the video driver/hardware. The maximum vertex buffer is + * usually limited too. Both requirements can be met with this step: you may + * specify both a triangle and vertex limit for a single mesh.

+ * + * The split limits can (and should!) be set through the + * #AI_CONFIG_PP_SLM_VERTEX_LIMIT and + * #AI_CONFIG_PP_SLM_TRIANGLE_LIMIT settings. The default values + * are #AI_SLM_DEFAULT_MAX_VERTICES and + * #AI_SLM_DEFAULT_MAX_TRIANGLES.

+ * + * Note that splitting is generally a time-consuming task, but only if + * there's something to split. The use of this step is recommended for most + * users. + */ + SPLIT_LARGE_MESHES(0x80), + + + /** + * Removes the node graph and pre-transforms all vertices with the local + * transformation matrices of their nodes.

+ * + * The output scene still contains nodes, however there is only a root node + * with children, each one referencing only one mesh, and each mesh + * referencing one material. For rendering, you can simply render all meshes + * in order - you don't need to pay attention to local transformations and + * the node hierarchy. Animations are removed during this step. This step is + * intended for applications without a scenegraph. The step CAN cause some + * problems: if e.g. a mesh of the asset contains normals and another, using + * the same material index, does not, they will be brought together, but the + * first meshes's part of the normal list is zeroed. However, these + * artifacts are rare.

+ * + * Note: The #AI_CONFIG_PP_PTV_NORMALIZE configuration + * property can be set to normalize the scene's spatial dimension to the + * -1...1 range. + */ + PRE_TRANSFORM_VERTICES(0x100), + + + /** + * Limits the number of bones simultaneously affecting a single vertex to a + * maximum value.

+ * + * If any vertex is affected by more than the maximum number of bones, the + * least important vertex weights are removed and the remaining vertex + * weights are renormalized so that the weights still sum up to 1. The + * default bone weight limit is 4 (defined as #AI_LMW_MAX_WEIGHTS + * in config.h), but you can use the #AI_CONFIG_PP_LBW_MAX_WEIGHTS + * setting to supply your own limit to the post processing step.

+ * + * If you intend to perform the skinning in hardware, this post processing + * step might be of interest to you. + */ + LIMIT_BONE_WEIGHTS(0x200), + + + /** + * Validates the imported scene data structure. This makes sure that all + * indices are valid, all animations and bones are linked correctly, all + * material references are correct .. etc.

+ * + * It is recommended that you capture Assimp's log output if you use this + * flag, so you can easily find out what's wrong if a file fails the + * validation. The validator is quite strict and will find *all* + * inconsistencies in the data structure... It is recommended that plugin + * developers use it to debug their loaders. There are two types of + * validation failures: + *

    + *
  • Error: There's something wrong with the imported data. Further + * postprocessing is not possible and the data is not usable at all. The + * import fails. #Importer::GetErrorString() or #aiGetErrorString() carry + * the error message around.
  • + *
  • Warning: There are some minor issues (e.g. 1000000 animation + * keyframes with the same time), but further postprocessing and use of the + * data structure is still safe. Warning details are written to the log + * file, #AI_SCENE_FLAGS_VALIDATION_WARNING is set in + * #aiScene::mFlags
  • + *
+ * + * This post-processing step is not time-consuming. Its use is not + * compulsory, but recommended. + */ + VALIDATE_DATA_STRUCTURE(0x400), + + + /** + * Reorders triangles for better vertex cache locality.

+ * + * The step tries to improve the ACMR (average post-transform vertex cache + * miss ratio) for all meshes. The implementation runs in O(n) and is + * roughly based on the 'tipsify' algorithm (see this + * paper).

+ * + * If you intend to render huge models in hardware, this step might be of + * interest to you. The #AI_CONFIG_PP_ICL_PTCACHE_SIZEconfig + * setting can be used to fine-tune the cache optimization. + */ + IMPROVE_CACHE_LOCALITY(0x800), + + + /** + * Searches for redundant/unreferenced materials and removes them.

+ * + * This is especially useful in combination with the + * #PretransformVertices and #OptimizeMeshes flags. Both + * join small meshes with equal characteristics, but they can't do their + * work if two meshes have different materials. Because several material + * settings are lost during Assimp's import filters, (and because many + * exporters don't check for redundant materials), huge models often have + * materials which are are defined several times with exactly the same + * settings.

+ * + * Several material settings not contributing to the final appearance of a + * surface are ignored in all comparisons (e.g. the material name). So, if + * you're passing additional information through the content pipeline + * (probably using *magic* material names), don't specify this flag. + * Alternatively take a look at the #AI_CONFIG_PP_RRM_EXCLUDE_LIST + * setting. + */ + REMOVE_REDUNDANT_MATERIALS(0x1000), + + + /** + * This step tries to determine which meshes have normal vectors that are + * facing inwards and inverts them.

+ * + * The algorithm is simple but effective: the bounding box of all vertices + + * their normals is compared against the volume of the bounding box of all + * vertices without their normals. This works well for most objects, + * problems might occur with planar surfaces. However, the step tries to + * filter such cases. The step inverts all in-facing normals. Generally it + * is recommended to enable this step, although the result is not always + * correct. + */ + FIX_INFACING_NORMALS(0x2000), + + + /** + * This step splits meshes with more than one primitive type in homogeneous + * sub-meshes.

+ * + * The step is executed after the triangulation step. After the step + * returns, just one bit is set in aiMesh::mPrimitiveTypes. This is + * especially useful for real-time rendering where point and line primitives + * are often ignored or rendered separately. You can use the + * #AI_CONFIG_PP_SBP_REMOVE option to specify which primitive types + * you need. This can be used to easily exclude lines and points, which are + * rarely used, from the import. + */ + SORT_BY_PTYPE(0x8000), + + + /** + * This step searches all meshes for degenerate primitives and converts them + * to proper lines or points.

+ * + * A face is 'degenerate' if one or more of its points are identical. To + * have the degenerate stuff not only detected and collapsed but removed, + * try one of the following procedures:
+ * 1. (if you support lines and points for rendering but don't want + * the degenerates)
+ *

    + *
  • Specify the #FindDegenerates flag.
  • + *
  • Set the AI_CONFIG_PP_FD_REMOVE option to 1. This will cause + * the step to remove degenerate triangles from the import as soon as + * they're detected. They won't pass any further pipeline steps.
  • + *
+ *
+ * 2.(if you don't support lines and points at all)
+ *
    + *
  • Specify the #FindDegenerates flag. + *
  • Specify the #SortByPType flag. This moves line and point + * primitives to separate meshes. + *
  • Set the AI_CONFIG_PP_SBP_REMOVE option to + * aiPrimitiveType_POINTS | aiPrimitiveType_LINES + * to cause SortByPType to reject point and line meshes from the + * scene. + *
+ * Note: Degenerated polygons are not necessarily evil and that's + * why they're not removed by default. There are several file formats + * which don't support lines or points, and some exporters bypass the + * format specification and write them as degenerate triangles instead. + */ + FIND_DEGENERATES(0x10000), + + + /** + * This step searches all meshes for invalid data, such as zeroed normal + * vectors or invalid UV coords and removes/fixes them. This is intended to + * get rid of some common exporter errors.

+ * + * This is especially useful for normals. If they are invalid, and the step + * recognizes this, they will be removed and can later be recomputed, i.e. + * by the {@link #GEN_SMOOTH_NORMALS} flag.

+ * + * The step will also remove meshes that are infinitely small and reduce + * animation tracks consisting of hundreds if redundant keys to a single + * key. The AI_CONFIG_PP_FID_ANIM_ACCURACY config property decides + * the accuracy of the check for duplicate animation tracks. + */ + FIND_INVALID_DATA(0x20000), + + + /** + * This step converts non-UV mappings (such as spherical or cylindrical + * mapping) to proper texture coordinate channels.

+ * + * Most applications will support UV mapping only, so you will probably want + * to specify this step in every case. Note that Assimp is not always able + * to match the original mapping implementation of the 3D app which produced + * a model perfectly. It's always better to let the modelling app compute + * the UV channels - 3ds max, Maya, Blender, LightWave, and Modo do this for + * example.

+ * + * Note: If this step is not requested, you'll need to process the + * MATKEY_MAPPING material property in order to display all + * assets properly. + */ + GEN_UV_COORDS(0x40000), + + + /** + * This step applies per-texture UV transformations and bakes them into + * stand-alone vtexture coordinate channels.

+ * + * UV transformations are specified per-texture - see the + * MATKEY_UVTRANSFORM material key for more information. This + * step processes all textures with transformed input UV coordinates and + * generates a new (pre-transformed) UV channel which replaces the old + * channel. Most applications won't support UV transformations, so you will + * probably want to specify this step.

+ * + * Note: UV transformations are usually implemented in real-time + * apps by transforming texture coordinates at vertex shader stage with a + * 3x3 (homogenous) transformation matrix. + */ + TRANSFORM_UV_COORDS(0x80000), + + + /** + * This step searches for duplicate meshes and replaces them with references + * to the first mesh.

+ * + * This step takes a while, so don't use it if speed is a concern. Its main + * purpose is to workaround the fact that many export file formats don't + * support instanced meshes, so exporters need to duplicate meshes. This + * step removes the duplicates again. Please note that Assimp does not + * currently support per-node material assignment to meshes, which means + * that identical meshes with different materials are currently *not* + * joined, although this is planned for future versions. + */ + FIND_INSTANCES(0x100000), + + + /** + * A postprocessing step to reduce the number of meshes.

+ * + * This will, in fact, reduce the number of draw calls.

+ * + * This is a very effective optimization and is recommended to be used + * together with #OptimizeGraph, if possible. The flag is fully + * compatible with both {@link #SPLIT_LARGE_MESHES} and + * {@link #SORT_BY_PTYPE}. + */ + OPTIMIZE_MESHES(0x200000), + + + /** + * A postprocessing step to optimize the scene hierarchy.

+ * + * Nodes without animations, bones, lights or cameras assigned are collapsed + * and joined.

+ * + * Node names can be lost during this step. If you use special 'tag nodes' + * to pass additional information through your content pipeline, use the + * #AI_CONFIG_PP_OG_EXCLUDE_LIST setting to specify a list of node + * names you want to be kept. Nodes matching one of the names in this list + * won't be touched or modified.

+ * + * Use this flag with caution. Most simple files will be collapsed to a + * single node, so complex hierarchies are usually completely lost. This is + * not useful for editor environments, but probably a very effective + * optimization if you just want to get the model data, convert it to your + * own format, and render it as fast as possible.

+ * + * This flag is designed to be used with #OptimizeMeshes for best + * results.

+ * + * Note: 'Crappy' scenes with thousands of extremely small meshes + * packed in deeply nested nodes exist for almost all file formats. + * {@link #OPTIMIZE_MESHES} in combination with {@link #OPTIMIZE_GRAPH} + * usually fixes them all and makes them renderable. + */ + OPTIMIZE_GRAPH(0x400000), + + + /** + * This step flips all UV coordinates along the y-axis and adjusts material + * settings and bitangents accordingly.

+ * + * Output UV coordinate system:
+ *

+     * 0y|0y ---------- 1x|0y 
+     *   |                | 
+     *   |                |
+     *   |                | 
+     * 0x|1y ---------- 1x|1y
+     * 
+ *

+ * + * You'll probably want to consider this flag if you use Direct3D for + * rendering. The {@link #MAKE_LEFT_HANDED} flag supersedes this setting + * and bundles all conversions typically required for D3D-based + * applications. + */ + FLIP_UVS(0x800000), + + + /** + * This step adjusts the output face winding order to be CW.

+ * + * The default face winding order is counter clockwise (CCW). + * + * Output face order: + * + *

+     *        x2
+     * 
+     *                      x0 
+     *  x1
+     * 
+ */ + FLIP_WINDING_ORDER(0x1000000), + + + /** + * This step splits meshes with many bones into sub-meshes so that each + * sub-mesh has fewer or as many bones as a given limit.

+ */ + SPLIT_BY_BONE_COUNT(0x2000000), + + + /** + * This step removes bones losslessly or according to some threshold.

+ * + * In some cases (i.e. formats that require it) exporters are forced to + * assign dummy bone weights to otherwise static meshes assigned to animated + * meshes. Full, weight-based skinning is expensive while animating nodes is + * extremely cheap, so this step is offered to clean up the data in that + * regard.

+ * + * Use #AI_CONFIG_PP_DB_THRESHOLD to control this. Use + * #AI_CONFIG_PP_DB_ALL_OR_NONE if you want bones removed if and + * only if all bones within the scene qualify for removal. + */ + DEBONE(0x4000000); + + + /** + * Utility method for converting to c/c++ based integer enums from java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param set the set to convert + * @return an integer based enum value (as defined by assimp) + */ + static long toRawValue(Set set) { + long rawValue = 0L; + + for (AiPostProcessSteps step : set) { + rawValue |= step.m_rawValue; + } + + return rawValue; + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiPostProcessSteps(long rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final long m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiPrimitiveType.java b/port/jassimp/jassimp/src/jassimp/AiPrimitiveType.java new file mode 100644 index 000000000..bb8f9041d --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiPrimitiveType.java @@ -0,0 +1,113 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.util.Set; + + +/** + * Enumerates the types of geometric primitives supported by Assimp.

+ */ +public enum AiPrimitiveType { + /** + * A point primitive. + */ + POINT(0x1), + + + /** + * A line primitive. + */ + LINE(0x2), + + + /** + * A triangular primitive. + */ + TRIANGLE(0x4), + + + /** + * A higher-level polygon with more than 3 edges.

+ * + * A triangle is a polygon, but polygon in this context means + * "all polygons that are not triangles". The "Triangulate"-Step is provided + * for your convenience, it splits all polygons in triangles (which are much + * easier to handle). + */ + POLYGON(0x8); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param set the target set to fill + * @param rawValue an integer based enum value (as defined by assimp) + */ + static void fromRawValue(Set set, int rawValue) { + + for (AiPrimitiveType type : AiPrimitiveType.values()) { + if ((type.m_rawValue & rawValue) != 0) { + set.add(type); + } + } + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiPrimitiveType(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiQuaternion.java b/port/jassimp/jassimp/src/jassimp/AiQuaternion.java new file mode 100644 index 000000000..de162631b --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiQuaternion.java @@ -0,0 +1,166 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; + + +/** + * Wrapper for a quaternion.

+ * + * The wrapper is writable, i.e., changes performed via the set-methods will + * modify the underlying mesh/animation. + */ +public final class AiQuaternion { + /** + * Constructor. + * + * @param buffer the buffer to wrap + * @param offset offset into buffer + */ + public AiQuaternion(ByteBuffer buffer, int offset) { + if (null == buffer) { + throw new IllegalArgumentException("buffer may not be null"); + } + + m_buffer = buffer; + m_offset = offset; + } + + + /** + * Returns the x value. + * + * @return the x value + */ + public float getX() { + return m_buffer.getFloat(m_offset + 4); + } + + + /** + * Returns the y value. + * + * @return the y value + */ + public float getY() { + return m_buffer.getFloat(m_offset + 8); + } + + + /** + * Returns the z value. + * + * @return the z value + */ + public float getZ() { + return m_buffer.getFloat(m_offset + 12); + } + + + /** + * Returns the w value. + * + * @return the w value + */ + public float getW() { + return m_buffer.getFloat(m_offset); + } + + + /** + * Sets the x component. + * + * @param x the new value + */ + public void setX(float x) { + m_buffer.putFloat(m_offset + 4, x); + } + + + /** + * Sets the y component. + * + * @param y the new value + */ + public void setY(float y) { + m_buffer.putFloat(m_offset + 8, y); + } + + + /** + * Sets the z component. + * + * @param z the new value + */ + public void setZ(float z) { + m_buffer.putFloat(m_offset + 12, z); + } + + + /** + * Sets the z component. + * + * @param w the new value + */ + public void setW(float w) { + m_buffer.putFloat(m_offset, w); + } + + + @Override + public String toString() { + return "[" + getX() + ", " + getY() + ", " + getZ() + ", " + + getW() + "]"; + } + + + /** + * Wrapped buffer. + */ + private final ByteBuffer m_buffer; + + + /** + * Offset into m_buffer. + */ + private final int m_offset; +} \ No newline at end of file diff --git a/port/jassimp/jassimp/src/jassimp/AiScene.java b/port/jassimp/jassimp/src/jassimp/AiScene.java new file mode 100644 index 000000000..f13348dec --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiScene.java @@ -0,0 +1,251 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.util.ArrayList; +import java.util.List; + + +/** + * The root structure of the imported data.

+ * + * Everything that was imported from the given file can be accessed from here. + *

+ * Jassimp copies all data into "java memory" during import and frees + * resources allocated by native code after scene loading is completed. No + * special care has to be taken for freeing resources, unreferenced jassimp + * objects (including the scene itself) are eligible to garbage collection like + * any other java object. + */ +public final class AiScene { + /** + * Constructor. + */ + AiScene() { + /* nothing to do */ + } + + + /** + * Returns the number of meshes contained in the scene.

+ * + * This method is provided for completeness reasons. It will return the + * same value as getMeshes().size() + * + * @return the number of meshes + */ + public int getNumMeshes() { + return m_meshes.size(); + } + + + /** + * Returns the meshes contained in the scene.

+ * + * If there are no meshes in the scene, an empty collection is returned + * + * @return the list of meshes + */ + public List getMeshes() { + return m_meshes; + } + + + /** + * Returns the number of materials in the scene.

+ * + * This method is provided for completeness reasons. It will return the + * same value as getMaterials().size() + * + * @return the number of materials + */ + public int getNumMaterials() { + return m_materials.size(); + } + + + /** + * Returns the list of materials.

+ * + * Use the index given in each aiMesh structure to access this + * array. If the {@link AiSceneFlag#INCOMPLETE} flag is not set there will + * always be at least ONE material. + * + * @return the list of materials + */ + public List getMaterials() { + return m_materials; + } + + + /** + * Returns the number of animations in the scene.

+ * + * This method is provided for completeness reasons. It will return the + * same value as getAnimations().size() + * + * @return the number of materials + */ + public int getNumAnimations() { + return m_animations.size(); + } + + + /** + * Returns the list of animations. + * + * @return the list of animations + */ + public List getAnimations() { + return m_animations; + } + + + /** + * Returns the number of light sources in the scene.

+ * + * This method is provided for completeness reasons. It will return the + * same value as getLights().size() + * + * @return the number of lights + */ + public int getNumLights() { + return m_lights.size(); + } + + + /** + * Returns the list of light sources.

+ * + * Light sources are fully optional, the returned list may be empty + * + * @return a possibly empty list of lights + */ + public List getLights() { + return m_lights; + } + + + /** + * Returns the number of cameras in the scene.

+ * + * This method is provided for completeness reasons. It will return the + * same value as getCameras().size() + * + * @return the number of cameras + */ + public int getNumCameras() { + return m_cameras.size(); + } + + + /** + * Returns the list of cameras.

+ * + * Cameras are fully optional, the returned list may be empty + * + * @return a possibly empty list of cameras + */ + public List getCameras() { + return m_cameras; + } + + + /** + * Returns the scene graph root. + * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers).

+ * + * The built-in behavior is to return a {@link AiVector}. + * + * @param wrapperProvider the wrapper provider (used for type inference) + * @return the scene graph root + */ + @SuppressWarnings("unchecked") + public N getSceneRoot(AiWrapperProvider + wrapperProvider) { + + return (N) m_sceneRoot; + } + + + @Override + public String toString() { + return "AiScene (" + m_meshes.size() + " mesh/es)"; + } + + + /** + * Meshes. + */ + private final List m_meshes = new ArrayList(); + + + /** + * Materials. + */ + private final List m_materials = new ArrayList(); + + + /** + * Animations. + */ + private final List m_animations = new ArrayList(); + + + /** + * Lights. + */ + private final List m_lights = new ArrayList(); + + + /** + * Cameras. + */ + private final List m_cameras = new ArrayList(); + + + /** + * Scene graph root. + */ + private Object m_sceneRoot; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiSceneFlag.java b/port/jassimp/jassimp/src/jassimp/AiSceneFlag.java new file mode 100644 index 000000000..7f7e01ea9 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiSceneFlag.java @@ -0,0 +1,153 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.util.Set; + + +/** + * Status flags for {@link AiScene}s. + */ +public enum AiSceneFlag { + /** + * Specifies that the scene data structure that was imported is not + * complete.

+ * + * This flag bypasses some internal validations and allows the import + * of animation skeletons, material libraries or camera animation paths + * using Assimp. Most applications won't support such data. + */ + INCOMPLETE(0x1), + + + /** + * This flag is set by the validation + * ({@link AiPostProcessSteps#VALIDATE_DATA_STRUCTURE + * VALIDATE_DATA_STRUCTURE}) + * postprocess-step if the validation is successful.

+ * + * In a validated scene you can be sure that any cross references in the + * data structure (e.g. vertex indices) are valid. + */ + VALIDATED(0x2), + + + /** + * * This flag is set by the validation + * ({@link AiPostProcessSteps#VALIDATE_DATA_STRUCTURE + * VALIDATE_DATA_STRUCTURE}) + * postprocess-step if the validation is successful but some issues have + * been found.

+ * + * This can for example mean that a texture that does not exist is + * referenced by a material or that the bone weights for a vertex don't sum + * to 1.0 ... . In most cases you should still be able to use the import. + * This flag could be useful for applications which don't capture Assimp's + * log output. + */ + VALIDATION_WARNING(0x4), + + + /** + * This flag is currently only set by the + * {@link jassimp.AiPostProcessSteps#JOIN_IDENTICAL_VERTICES + * JOIN_IDENTICAL_VERTICES}.

+ * + * It indicates that the vertices of the output meshes aren't in the + * internal verbose format anymore. In the verbose format all vertices are + * unique, no vertex is ever referenced by more than one face. + */ + NON_VERBOSE_FORMAT(0x8), + + + /** + * Denotes pure height-map terrain data.

+ * + * Pure terrains usually consist of quads, sometimes triangles, in a + * regular grid. The x,y coordinates of all vertex positions refer to the + * x,y coordinates on the terrain height map, the z-axis stores the + * elevation at a specific point.

+ * + * TER (Terragen) and HMP (3D Game Studio) are height map formats. + *

+ * Assimp is probably not the best choice for loading *huge* terrains - + * fully triangulated data takes extremely much free store and should be + * avoided as long as possible (typically you'll do the triangulation when + * you actually need to render it). + */ + TERRAIN(0x10); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param set the target set to fill + * @param rawValue an integer based enum value (as defined by assimp) + */ + static void fromRawValue(Set set, int rawValue) { + + for (AiSceneFlag type : AiSceneFlag.values()) { + if ((type.m_rawValue & rawValue) != 0) { + set.add(type); + } + } + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiSceneFlag(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiShadingMode.java b/port/jassimp/jassimp/src/jassimp/AiShadingMode.java new file mode 100644 index 000000000..af90f98a1 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiShadingMode.java @@ -0,0 +1,168 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Defines all shading modes supported by the library.

+ * + * The list of shading modes has been taken from Blender. + * See Blender documentation for more information. The API does + * not distinguish between "specular" and "diffuse" shaders (thus the + * specular term for diffuse shading models like Oren-Nayar remains + * undefined).

+ * Again, this value is just a hint. Assimp tries to select the shader whose + * most common implementation matches the original rendering results of the + * 3D modeller which wrote a particular model as closely as possible. + */ +public enum AiShadingMode { + /** + * Flat shading.

+ * + * Shading is done on per-face base, diffuse only. Also known as + * 'faceted shading'. + */ + FLAT(0x1), + + + /** + * Simple Gouraud shading. + */ + GOURAUD(0x2), + + + /** + * Phong-Shading. + */ + PHONG(0x3), + + + /** + * Phong-Blinn-Shading. + */ + BLINN(0x4), + + + /** + * Toon-Shading per pixel.

+ * + * Also known as 'comic' shader. + */ + TOON(0x5), + + + /** + * OrenNayar-Shading per pixel.

+ * + * Extension to standard Lambertian shading, taking the roughness of the + * material into account + */ + OREN_NAYAR(0x6), + + + /** + * Minnaert-Shading per pixel.

+ * + * Extension to standard Lambertian shading, taking the "darkness" of the + * material into account + */ + MINNAERT(0x7), + + + /** + * CookTorrance-Shading per pixel.

+ * + * Special shader for metallic surfaces. + */ + COOK_TORRANCE(0x8), + + + /** + * No shading at all.

+ * + * Constant light influence of 1.0. + */ + NO_SHADING(0x9), + + + /** + * Fresnel shading. + */ + FRESNEL(0xa); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static AiShadingMode fromRawValue(int rawValue) { + for (AiShadingMode type : AiShadingMode.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiShadingMode(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiTextureInfo.java b/port/jassimp/jassimp/src/jassimp/AiTextureInfo.java new file mode 100644 index 000000000..bfa09397b --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiTextureInfo.java @@ -0,0 +1,224 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Data structure for texture related material properties. + */ +public final class AiTextureInfo { + + /** + * Constructor. + * + * @param type type + * @param index index + * @param file file + * @param uvIndex uv index + * @param blend blend factor + * @param texOp texture operation + * @param mmU map mode for u axis + * @param mmV map mode for v axis + * @param mmW map mode for w axis + */ + AiTextureInfo(AiTextureType type, int index, String file, + int uvIndex, float blend, AiTextureOp texOp, AiTextureMapMode mmU, + AiTextureMapMode mmV, AiTextureMapMode mmW) { + + m_type = type; + m_index = index; + m_file = file; + m_uvIndex = uvIndex; + m_blend = blend; + m_textureOp = texOp; + m_textureMapModeU = mmU; + m_textureMapModeV = mmV; + m_textureMapModeW = mmW; + } + + + /** + * Specifies the type of the texture (e.g. diffuse, specular, ...). + * + * @return the type. + */ + public AiTextureType getType() { + return m_type; + } + + + /** + * Index of the texture in the texture stack.

+ * + * Each type maintains a stack of textures, i.e., there may be a diffuse.0, + * a diffuse.1, etc + * + * @return the index + */ + public int getIndex() { + return m_index; + } + + + /** + * Returns the path to the texture file. + * + * @return the path + */ + public String getFile() { + return m_file; + } + + + /** + * Returns the index of the UV coordinate set. + * + * @return the uv index + */ + public int getUVIndex() { + return m_uvIndex; + } + + + /** + * Returns the blend factor. + * + * @return the blend factor + */ + public float getBlend() { + return m_blend; + } + + + /** + * Returns the texture operation used to combine this texture and the + * preceding texture in the stack. + * + * @return the texture operation + */ + public AiTextureOp getTextureOp() { + return m_textureOp; + } + + + /** + * Returns the texture map mode for U texture axis. + * + * @return the texture map mode + */ + public AiTextureMapMode getTextureMapModeU() { + return m_textureMapModeU; + } + + + /** + * Returns the texture map mode for V texture axis. + * + * @return the texture map mode + */ + public AiTextureMapMode getTextureMapModeV() { + return m_textureMapModeV; + } + + + /** + * Returns the texture map mode for W texture axis. + * + * @return the texture map mode + */ + public AiTextureMapMode getTextureMapModeW() { + return m_textureMapModeW; + } + + + /** + * Type. + */ + private final AiTextureType m_type; + + + /** + * Index. + */ + private final int m_index; + + + /** + * Path. + */ + private final String m_file; + + + /** + * UV index. + */ + private final int m_uvIndex; + + + /** + * Blend factor. + */ + private final float m_blend; + + + /** + * Texture operation. + */ + private final AiTextureOp m_textureOp; + + + /** + * Map mode U axis. + */ + private final AiTextureMapMode m_textureMapModeU; + + + /** + * Map mode V axis. + */ + private final AiTextureMapMode m_textureMapModeV; + + + /** + * Map mode W axis. + */ + private final AiTextureMapMode m_textureMapModeW; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiTextureMapMode.java b/port/jassimp/jassimp/src/jassimp/AiTextureMapMode.java new file mode 100644 index 000000000..f9e86dfc6 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiTextureMapMode.java @@ -0,0 +1,113 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Defines how UV coordinates outside the [0...1] range are handled.

+ * + * Commonly refered to as 'wrapping mode'. + */ +public enum AiTextureMapMode { + /** + * A texture coordinate u|v is translated to u%1|v%1. + */ + WRAP(0x0), + + + /** + * Texture coordinates outside [0...1] are clamped to the nearest + * valid value. + */ + CLAMP(0x1), + + + /** + * A texture coordinate u|v becomes u%1|v%1 if (u-(u%1))%2 is zero and + * 1-(u%1)|1-(v%1) otherwise. + */ + MIRROR(0x2), + + + /** + * If the texture coordinates for a pixel are outside [0...1] the texture + * is not applied to that pixel. + */ + DECAL(0x3); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static AiTextureMapMode fromRawValue(int rawValue) { + for (AiTextureMapMode type : AiTextureMapMode.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiTextureMapMode(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiTextureMapping.java b/port/jassimp/jassimp/src/jassimp/AiTextureMapping.java new file mode 100644 index 000000000..3112ba4bd --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiTextureMapping.java @@ -0,0 +1,78 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Defines how the mapping coords for a texture are generated.

+ * + * Real-time applications typically require full UV coordinates, so the use of + * the {@link AiPostProcessSteps#GEN_UV_COORDS} step is highly recommended. + * It generates proper UV channels for non-UV mapped objects, as long as an + * accurate description how the mapping should look like (e.g spherical) is + * given. + */ +public enum AiTextureMapping { + /** + * The mapping coordinates are taken from an UV channel. + * + * The #AI_MATKEY_UVWSRC key specifies from which UV channel + * the texture coordinates are to be taken from (remember, + * meshes can have more than one UV channel). + */ +// aiTextureMapping_UV = 0x0, +// +// /** Spherical mapping */ +// aiTextureMapping_SPHERE = 0x1, +// +// /** Cylindrical mapping */ +// aiTextureMapping_CYLINDER = 0x2, +// +// /** Cubic mapping */ +// aiTextureMapping_BOX = 0x3, +// +// /** Planar mapping */ +// aiTextureMapping_PLANE = 0x4, +// +// /** Undefined mapping. Have fun. */ +// aiTextureMapping_OTHER = 0x5, + +} diff --git a/port/jassimp/jassimp/src/jassimp/AiTextureOp.java b/port/jassimp/jassimp/src/jassimp/AiTextureOp.java new file mode 100644 index 000000000..d928167ca --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiTextureOp.java @@ -0,0 +1,137 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Defines how the Nth texture of a specific type is combined with the result + * of all previous layers.

+ * + * Example (left: key, right: value):
+ *

+ *  DiffColor0     - gray
+ *  DiffTextureOp0 - aiTextureOpMultiply
+ *  DiffTexture0   - tex1.png
+ *  DiffTextureOp0 - aiTextureOpAdd
+ *  DiffTexture1   - tex2.png
+ * 
+ * + * Written as equation, the final diffuse term for a specific pixel would be: + *
+ *  diffFinal = DiffColor0 * sampleTex(DiffTexture0,UV0) + 
+ *     sampleTex(DiffTexture1,UV0) * diffContrib;
+ * 
+ * where 'diffContrib' is the intensity of the incoming light for that pixel. + */ +public enum AiTextureOp { + /** + * T = T1 * T2. + */ + MULTIPLY(0x0), + + + /** + * T = T1 + T2. + */ + ADD(0x1), + + + /** + * T = T1 - T2. + */ + SUBTRACT(0x2), + + + /** + * T = T1 / T2. + */ + DIVIDE(0x3), + + + /** + * T = (T1 + T2) - (T1 * T2) . + */ + SMOOTH_ADD(0x4), + + + /** + * T = T1 + (T2-0.5). + */ + SIGNED_ADD(0x5); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static AiTextureOp fromRawValue(int rawValue) { + for (AiTextureOp type : AiTextureOp.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiTextureOp(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiTextureType.java b/port/jassimp/jassimp/src/jassimp/AiTextureType.java new file mode 100644 index 000000000..8756c18ee --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiTextureType.java @@ -0,0 +1,212 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +/** + * Defines the purpose of a texture.

+ * + * This is a very difficult topic. Different 3D packages support different + * kinds of textures. For very common texture types, such as bumpmaps, the + * rendering results depend on implementation details in the rendering + * pipelines of these applications. Assimp loads all texture references from + * the model file and tries to determine which of the predefined texture + * types below is the best choice to match the original use of the texture + * as closely as possible.

+ * + * In content pipelines you'll usually define how textures have to be handled, + * and the artists working on models have to conform to this specification, + * regardless which 3D tool they're using. + */ +public enum AiTextureType { + /** + * The texture is combined with the result of the diffuse + * lighting equation. + */ + DIFFUSE(0x1), + + + /** + * The texture is combined with the result of the specular + * lighting equation. + */ + SPECULAR(0x2), + + + /** + * The texture is combined with the result of the ambient + * lighting equation. + */ + AMBIENT(0x3), + + + /** + * The texture is added to the result of the lighting + * calculation. It isn't influenced by incoming light. + */ + EMISSIVE(0x4), + + + /** + * The texture is a height map.

+ * + * By convention, higher gray-scale values stand for + * higher elevations from the base height. + */ + HEIGHT(0x5), + + + /** + * The texture is a (tangent space) normal-map.

+ * + * Again, there are several conventions for tangent-space + * normal maps. Assimp does (intentionally) not distinguish here. + */ + NORMALS(0x6), + + + /** + * The texture defines the glossiness of the material.

+ * + * The glossiness is in fact the exponent of the specular + * (phong) lighting equation. Usually there is a conversion + * function defined to map the linear color values in the + * texture to a suitable exponent. Have fun. + */ + SHININESS(0x7), + + + /** + * The texture defines per-pixel opacity.

+ * + * Usually 'white' means opaque and 'black' means + * 'transparency'. Or quite the opposite. Have fun. + */ + OPACITY(0x8), + + + /** + * Displacement texture.

+ * + * The exact purpose and format is application-dependent. + * Higher color values stand for higher vertex displacements. + */ + DISPLACEMENT(0x9), + + + /** + * Lightmap texture (aka Ambient Occlusion).

+ * + * Both 'Lightmaps' and dedicated 'ambient occlusion maps' are + * covered by this material property. The texture contains a + * scaling value for the final color value of a pixel. Its + * intensity is not affected by incoming light. + */ + LIGHTMAP(0xA), + + + /** + * Reflection texture.

+ * + * Contains the color of a perfect mirror reflection. + * Rarely used, almost never for real-time applications. + */ + REFLECTION(0xB), + + + /** + * Unknown texture.

+ * + * A texture reference that does not match any of the definitions + * above is considered to be 'unknown'. It is still imported, + * but is excluded from any further postprocessing. + */ + UNKNOWN(0xC); + + + /** + * Utility method for converting from c/c++ based integer enums to java + * enums.

+ * + * This method is intended to be used from JNI and my change based on + * implementation needs. + * + * @param rawValue an integer based enum value (as defined by assimp) + * @return the enum value corresponding to rawValue + */ + static AiTextureType fromRawValue(int rawValue) { + for (AiTextureType type : AiTextureType.values()) { + if (type.m_rawValue == rawValue) { + return type; + } + } + + throw new IllegalArgumentException("unexptected raw value: " + + rawValue); + } + + + /** + * Utility method for converting from java enums to c/c++ based integer + * enums.

+ * + * @param type the type to convert, may not be null + * @return the rawValue corresponding to type + */ + static int toRawValue(AiTextureType type) { + return type.m_rawValue; + } + + + /** + * Constructor. + * + * @param rawValue maps java enum to c/c++ integer enum values + */ + private AiTextureType(int rawValue) { + m_rawValue = rawValue; + } + + + /** + * The mapped c/c++ integer enum value. + */ + private final int m_rawValue; +} \ No newline at end of file diff --git a/port/jassimp/jassimp/src/jassimp/AiVector.java b/port/jassimp/jassimp/src/jassimp/AiVector.java new file mode 100644 index 000000000..3136f3888 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiVector.java @@ -0,0 +1,195 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; + + +/** + * Wrapper for 3-dimensional vectors.

+ * + * This wrapper is also used to represent 1- and 2-dimensional vectors. In + * these cases only the x (or the x and y coordinate) will be used. + * Accessing unused components will throw UnsupportedOperationExceptions.

+ * + * The wrapper is writable, i.e., changes performed via the set-methods will + * modify the underlying mesh. + */ +public final class AiVector { + /** + * Constructor. + * + * @param buffer the buffer to wrap + * @param offset offset into buffer + * @param numComponents number vector of components + */ + public AiVector(ByteBuffer buffer, int offset, int numComponents) { + if (null == buffer) { + throw new IllegalArgumentException("buffer may not be null"); + } + + m_buffer = buffer; + m_offset = offset; + m_numComponents = numComponents; + } + + + /** + * Returns the x value. + * + * @return the x value + */ + public float getX() { + return m_buffer.getFloat(m_offset); + } + + + /** + * Returns the y value.

+ * + * May only be called on 2- or 3-dimensional vectors. + * + * @return the y value + */ + public float getY() { + if (m_numComponents <= 1) { + throw new UnsupportedOperationException( + "vector has only 1 component"); + } + + return m_buffer.getFloat(m_offset + 4); + } + + + /** + * Returns the z value.

+ * + * May only be called on 3-dimensional vectors. + * + * @return the z value + */ + public float getZ() { + if (m_numComponents <= 2) { + throw new UnsupportedOperationException( + "vector has only 2 components"); + } + + return m_buffer.getFloat(m_offset + 8); + } + + + /** + * Sets the x component. + * + * @param x the new value + */ + public void setX(float x) { + m_buffer.putFloat(m_offset, x); + } + + + /** + * Sets the y component.

+ * + * May only be called on 2- or 3-dimensional vectors. + * + * @param y the new value + */ + public void setY(float y) { + if (m_numComponents <= 1) { + throw new UnsupportedOperationException( + "vector has only 1 component"); + } + + m_buffer.putFloat(m_offset + 4, y); + } + + + /** + * Sets the z component.

+ * + * May only be called on 3-dimensional vectors. + * + * @param z the new value + */ + public void setZ(float z) { + if (m_numComponents <= 2) { + throw new UnsupportedOperationException( + "vector has only 2 components"); + } + + m_buffer.putFloat(m_offset + 8, z); + } + + + /** + * Returns the number of components in this vector. + * + * @return the number of components + */ + public int getNumComponents() { + return m_numComponents; + } + + + @Override + public String toString() { + return "[" + getX() + ", " + getY() + ", " + getZ() + "]"; + } + + + /** + * Wrapped buffer. + */ + private final ByteBuffer m_buffer; + + + /** + * Offset into m_buffer. + */ + private final int m_offset; + + + /** + * Number of components. + */ + private final int m_numComponents; +} diff --git a/port/jassimp/jassimp/src/jassimp/AiWrapperProvider.java b/port/jassimp/jassimp/src/jassimp/AiWrapperProvider.java new file mode 100644 index 000000000..e916ad260 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/AiWrapperProvider.java @@ -0,0 +1,149 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; + + +/** + * Provides wrapper objects for raw data buffers.

+ * + * It is likely that applications using Jassimp will already have a scene + * graph implementation and/ or the typical math related classes such as + * vectors, matrices, etc.

+ * + * To ease the integration with existing code, Jassimp can be customized to + * represent the scene graph and compound data structures such as vectors and + * matrices with user supplied classes.

+ * + * All methods returning wrapped objects rely on the AiWrapperProvider to + * create individual instances. Custom wrappers can be created by implementing + * AiWrapperProvider and registering the implementation via + * {@link Jassimp#setWrapperProvider(AiWrapperProvider)} before the + * scene is imported.

+ * + * The methods returning wrapped types take an AiWrapperProvider instance. This + * instance must match the instance set via + * {@link Jassimp#setWrapperProvider(AiWrapperProvider)}. The method parameter + * is used to infer the type of the returned object. The passed in wrapper + * provider is not necessarily used to actually create the wrapped object, as + * the object may be cached for performance reasons. It is not possible to + * use different AiWrapperProviders throughout the lifetime of an imported + * scene. + * + * @param the type used to represent vectors + * @param the type used to represent matrices + * @param the type used to represent colors + * @param the type used to represent scene graph nodes + * @param the type used to represent quaternions + */ +public interface AiWrapperProvider { + /** + * Wraps a vector.

+ * + * Most vectors are 3-dimensional, i.e., with 3 components. The exception + * are texture coordinates, which may be 1- or 2-dimensional. A vector + * consists of numComponents floats (x,y,z) starting from offset + * + * @param buffer the buffer to wrap + * @param offset the offset into buffer + * @param numComponents the number of components + * @return the wrapped vector + */ + V3 wrapVector3f(ByteBuffer buffer, int offset, int numComponents); + + + /** + * Wraps a 4x4 matrix of floats.

+ * + * The calling code will allocate a new array for each invocation of this + * method. It is safe to store a reference to the passed in array and + * use the array to store the matrix data. + * + * @param data the matrix data in row-major order + * @return the wrapped matrix + */ + M4 wrapMatrix4f(float[] data); + + + /** + * Wraps a RGBA color.

+ * + * A color consists of 4 float values (r,g,b,a) starting from offset + * + * @param buffer the buffer to wrap + * @param offset the offset into buffer + * @return the wrapped color + */ + C wrapColor(ByteBuffer buffer, int offset); + + + /** + * Wraps a scene graph node.

+ * + * See {@link AiNode} for a description of the scene graph structure used + * by assimp.

+ * + * The parent node is either null or an instance returned by this method. + * It is therefore safe to cast the passed in parent object to the + * implementation specific type + * + * @param parent the parent node + * @param matrix the transformation matrix + * @param meshReferences array of mesh references (indexes) + * @param name the name of the node + * @return the wrapped scene graph node + */ + N wrapSceneNode(Object parent, Object matrix, int[] meshReferences, + String name); + + + /** + * Wraps a quaternion.

+ * + * A quaternion consists of 4 float values (w,x,y,z) starting from offset + * + * @param buffer the buffer to wrap + * @param offset the offset into buffer + * @return the wrapped quaternion + */ + Q wrapQuaternion(ByteBuffer buffer, int offset); +} diff --git a/port/jassimp/jassimp/src/jassimp/JaiDebug.java b/port/jassimp/jassimp/src/jassimp/JaiDebug.java new file mode 100644 index 000000000..0f91ce662 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/JaiDebug.java @@ -0,0 +1,209 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.nio.ByteBuffer; + + +/** + * Debug/utility methods. + */ +public final class JaiDebug { + + /** + * Pure static class, no accessible constructor. + */ + private JaiDebug() { + /* nothing to do */ + } + + + /** + * Dumps vertex positions of a mesh to stdout.

+ * + * @param mesh the mesh + */ + public static void dumpPositions(AiMesh mesh) { + if (!mesh.hasPositions()) { + System.out.println("mesh has no vertex positions"); + return; + } + + for (int i = 0; i < mesh.getNumVertives(); i++) { + System.out.println("[" + + mesh.getPositionX(i) + ", " + + mesh.getPositionY(i) + ", " + + mesh.getPositionZ(i) + "]" + ); + } + } + + + /** + * Dumps faces of a mesh to stdout.

+ * + * @param mesh the mesh + */ + public static void dumpFaces(AiMesh mesh) { + if (!mesh.hasFaces()) { + System.out.println("mesh has no faces"); + return; + } + + for (int face = 0; face < mesh.getNumFaces(); face++) { + int faceNumIndices = mesh.getFaceNumIndices(face); + System.out.print(faceNumIndices + ": "); + + for (int vertex = 0; vertex < faceNumIndices; vertex++) { + int reference = mesh.getFaceVertex(face, vertex); + + System.out.print("[" + + mesh.getPositionX(reference) + ", " + + mesh.getPositionY(reference) + ", " + + mesh.getPositionZ(reference) + "] " + ); + } + + System.out.println(); + } + } + + + /** + * Dumps a vertex color set of a mesh to stdout.

+ * + * @param mesh the mesh + * @param colorset the color set + */ + public static void dumpColorset(AiMesh mesh, int colorset) { + if (!mesh.hasColors(colorset)) { + System.out.println("mesh has no vertex color set " + colorset); + return; + } + + for (int i = 0; i < mesh.getNumVertives(); i++) { + System.out.println("[" + + mesh.getColorR(i, colorset) + ", " + + mesh.getColorG(i, colorset) + ", " + + mesh.getColorB(i, colorset) + ", " + + mesh.getColorA(i, colorset) + "]" + ); + } + } + + + /** + * Dumps a texture coordinate set of a mesh to stdout. + * + * @param mesh the mesh + * @param coords the coordinates + */ + public static void dumpTexCoords(AiMesh mesh, int coords) { + if (!mesh.hasTexCoords(coords)) { + System.out.println("mesh has no texture coordinate set " + coords); + return; + } + + for (int i = 0; i < mesh.getNumVertives(); i++) { + int numComponents = mesh.getNumUVComponents(coords); + System.out.print("[" + mesh.getTexCoordU(i, coords)); + + if (numComponents > 1) { + System.out.print(", " + mesh.getTexCoordV(i, coords)); + } + + if (numComponents > 2) { + System.out.print(", " + mesh.getTexCoordW(i, coords)); + } + + System.out.println("]"); + } + } + + + /** + * Dumps a single material property to stdout. + * + * @param property the property + */ + public static void dumpMaterialProperty(AiMaterial.Property property) { + System.out.print(property.getKey() + " " + property.getSemantic() + + " " + property.getIndex() + ": "); + Object data = property.getData(); + + if (data instanceof ByteBuffer) { + ByteBuffer buf = (ByteBuffer) data; + for (int i = 0; i < buf.capacity(); i++) { + System.out.print(Integer.toHexString(buf.get(i) & 0xFF) + " "); + } + + System.out.println(); + } + else { + System.out.println(data.toString()); + } + } + + + /** + * Dumps all properties of a material to stdout. + * + * @param material the material + */ + public static void dumpMaterial(AiMaterial material) { + for (AiMaterial.Property prop : material.getProperties()) { + dumpMaterialProperty(prop); + } + } + + + /** + * Dumps an animation channel to stdout. + * + * @param nodeAnim the channel + */ + public static void dumpNodeAnim(AiNodeAnim nodeAnim) { + for (int i = 0; i < nodeAnim.getNumPosKeys(); i++) { + System.out.println(i + ": " + nodeAnim.getPosKeyTime(i) + + " ticks, " + nodeAnim.getPosKeyVector(i, Jassimp.BUILTIN)); + } + } +} diff --git a/port/jassimp/jassimp/src/jassimp/Jassimp.java b/port/jassimp/jassimp/src/jassimp/Jassimp.java new file mode 100644 index 000000000..238456c1d --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/Jassimp.java @@ -0,0 +1,256 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.EnumSet; +import java.util.Set; + + + +/** + * Entry point to the jassimp library.

+ * + * Use {@link #importFile(String, Set)} to load a file. + * + *

General Notes and Pitfalls

+ * Due to the loading via JNI, strings (for example as returned by the + * getName() methods) are not interned. You should therefore + * compare strings the way it should be done, i.e, via equals(). + * Pointer comparison will fail. + */ +public final class Jassimp { + + /** + * The default wrapper provider using built in types. + */ + public static final AiWrapperProvider BUILTIN = + new AiBuiltInWrapperProvider(); + + + /** + * Imports a file via assimp without post processing. + * + * @param filename the file to import + * @return the loaded scene + * @throws IOException if an error occurs + */ + public static AiScene importFile(String filename) throws IOException { + + return importFile(filename, EnumSet.noneOf(AiPostProcessSteps.class)); + } + + + /** + * Imports a file via assimp. + * + * @param filename the file to import + * @param postProcessing post processing flags + * @return the loaded scene, or null if an error occurred + * @throws IOException if an error occurs + */ + public static AiScene importFile(String filename, + Set postProcessing) throws IOException { + + return aiImportFile(filename, AiPostProcessSteps.toRawValue( + postProcessing)); + } + + + /** + * Returns a human readable error description.

+ * + * This method can be called when one of the import methods fails, i.e., + * throws an exception, to get a human readable error description. + * + * @return the error string + */ + public static native String getErrorString(); + + + /** + * Returns the active wrapper provider.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers). + * + * @return the active wrapper provider + */ + public static AiWrapperProvider getWrapperProvider() { + return s_wrapperProvider; + } + + + /** + * Sets a new wrapper provider.

+ * + * This method is part of the wrapped API (see {@link AiWrapperProvider} + * for details on wrappers). + * + * @param wrapperProvider the new wrapper provider + */ + public static void setWrapperProvider(AiWrapperProvider + wrapperProvider) { + + s_wrapperProvider = wrapperProvider; + } + + + /** + * Helper method for wrapping a matrix.

+ * + * Used by JNI, do not modify! + * + * @param data the matrix data + * @return the wrapped matrix + */ + static Object wrapMatrix(float[] data) { + return s_wrapperProvider.wrapMatrix4f(data); + } + + + /** + * Helper method for wrapping a color (rgb).

+ * + * Used by JNI, do not modify! + * + * @param red red component + * @param green green component + * @param blue blue component + * @return the wrapped color + */ + static Object wrapColor3(float red, float green, float blue) { + return wrapColor4(red, green, blue, 1.0f); + } + + + /** + * Helper method for wrapping a color (rgba).

+ * + * Used by JNI, do not modify! + * + * @param red red component + * @param green green component + * @param blue blue component + * @param alpha alpha component + * @return the wrapped color + */ + static Object wrapColor4(float red, float green, float blue, float alpha) { + ByteBuffer temp = ByteBuffer.allocate(4 * 4); + temp.putFloat(red); + temp.putFloat(green); + temp.putFloat(blue); + temp.putFloat(alpha); + temp.flip(); + return s_wrapperProvider.wrapColor(temp, 0); + } + + + /** + * Helper method for wrapping a vector.

+ * + * Used by JNI, do not modify! + * + * @param x x component + * @param y y component + * @param z z component + * @return the wrapped vector + */ + static Object wrapVec3(float x, float y, float z) { + ByteBuffer temp = ByteBuffer.allocate(3 * 4); + temp.putFloat(x); + temp.putFloat(y); + temp.putFloat(z); + temp.flip(); + return s_wrapperProvider.wrapVector3f(temp, 0, 3); + } + + + /** + * Helper method for wrapping a scene graph node.

+ * + * Used by JNI, do not modify! + * + * @param parent the parent node + * @param matrix the transformation matrix + * @param meshRefs array of matrix references + * @param name the name of the node + * @return the wrapped matrix + */ + static Object wrapSceneNode(Object parent, Object matrix, int[] meshRefs, + String name) { + + return s_wrapperProvider.wrapSceneNode(parent, matrix, meshRefs, name); + } + + + /** + * The native interface. + * + * @param filename the file to load + * @param postProcessing post processing flags + * @return the loaded scene, or null if an error occurred + * @throws IOException if an error occurs + */ + private static native AiScene aiImportFile(String filename, + long postProcessing) throws IOException; + + + /** + * The active wrapper provider. + */ + private static AiWrapperProvider s_wrapperProvider = + new AiBuiltInWrapperProvider(); + + + /** + * Pure static class, no accessible constructor. + */ + private Jassimp() { + /* nothing to do */ + } + + + static { + System.loadLibrary("jassimp"); + } +} diff --git a/port/jassimp/jassimp/src/jassimp/JassimpConfig.java b/port/jassimp/jassimp/src/jassimp/JassimpConfig.java new file mode 100644 index 000000000..8370bb9f0 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/JassimpConfig.java @@ -0,0 +1,66 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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 jassimp; + + +/** + * Global configuration values (limits). + */ +public final class JassimpConfig { + /** + * Maximum number of vertex color sets. + */ + public static final int MAX_NUMBER_COLORSETS = 8; + + + /** + * Maximum number of texture coordinate sets. + */ + public static final int MAX_NUMBER_TEXCOORDS = 8; + + + /** + * Pure static class, no accessible constructor. + */ + private JassimpConfig() { + /* nothing to do */ + } +} diff --git a/port/jassimp/jassimp/src/jassimp/package-info.java b/port/jassimp/jassimp/src/jassimp/package-info.java new file mode 100644 index 000000000..fa2883824 --- /dev/null +++ b/port/jassimp/jassimp/src/jassimp/package-info.java @@ -0,0 +1,45 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library - Java Binding (jassimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp 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 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. +--------------------------------------------------------------------------- +*/ + +/** + * Java binding for the Open Asset Import Library. + */ +package jassimp;