/* -------------------------------------------------------------------------------- * * Open Asset Import Library (ASSIMP) (http://assimp.sourceforge.net) * Assimp2Java bridge * * Copyright (c) 2006-2009, ASSIMP Development Team * All rights reserved. See the LICENSE file for more information. * * -------------------------------------------------------------------------------- */ #include "jbridge_pch.h" using namespace Assimp; // include the header files generated by javah #include "assimp_Importer.h" #include // used as error return code #define AI_JNI_ERROR_RETURN 0xffffffff //////////////////////////////////////////////////////////////////////////////////// /* typedef for a jassimp context, used to identify the Importer object which * belongs to a particular java Importer. */ //////////////////////////////////////////////////////////////////////////////////// typedef uint64_t JASSIMP_CONTEXT; #ifdef JASSIMP_DEBUG_CHECKS typedef std::list< JASSIMP_CONTEXT > ImporterContextList; static ImporterContextList g_listActiveContexts; // ------------------------------------------------------------------------------------------------ /* DEBUG: Check the validity of a particular context. */ bool jValidateContext (JASSIMP_CONTEXT context) { ImporterContextList::const_iterator t = std::find( g_listActiveContexts.begin(),g_listActiveContexts.end(),context); if (t != g_listActiveContexts.end() { return true; } DefaultLogger::get()->error("[jnibridge] Invalid context"); return false; } // ------------------------------------------------------------------------------------------------ /* DEBUG: Check the validity of a particular scene */ bool jValidateScene (const aiScene* scene) { if (!scene) { DefaultLogger::get()->error("[jnibridge] There's not asset"); return false; } return true; } #endif // ! ASSIMP_DEBUG // ------------------------------------------------------------------------------------------------ /* Get the #Assimp::Importer for a particular JASSIMP_CONTEXT */ Assimp::Importer* jGetValidImporterScenePair (JASSIMP_CONTEXT jvmcontext) { #ifdef JASSIMP_DEBUG_CHECKS if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext)) { return NULL; } #endif // ! ASSIMP_DEBUG // get the importer instance from the context Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext; #ifdef DEBUG if (!jValidateScene(pcImp->GetScene())) { return NULL; } #endif // ! ASSIMP_DEBUG return pcImp; } // ------------------------------------------------------------------------------------------------ /* * Class: assimp_Importer * Method: _NativeInitContext * Signature: ()I */ JNIEXPORT jlong JNICALL Java_assimp_Importer__1NativeInitContext (JNIEnv * jvmenv, jobject jvmthis, jint version) { // 2^64-1 indicates error JASSIMP_CONTEXT context = 0xffffffffffffffffL; if (version != assimp_Importer_ABI_VERSION) { return context; } // create a new Importer instance Assimp::Importer* pcImp = new Assimp::Importer(); context = (JASSIMP_CONTEXT)(uintptr_t)pcImp; #ifdef JASSIMP_DEBUG_CHECKS g_listActiveContexts.push_back(context); #endif // ! ASSIMP_DEBUG // need to setup the logger ... or did we already initialize it? JNILogDispatcher* pcLogger; if (DefaultLogger::isNullLogger()) { pcLogger = new JNILogDispatcher(); DefaultLogger::set (pcLogger); } else { JNILogDispatcher* pcLogger = ( JNILogDispatcher* )DefaultLogger::get(); pcLogger->AddRef(); } // setup the JNI environment if(!JNIEnvironment::Get()->AttachToCurrentThread(jvmenv)) { return 0xffffffffffffffffL; } // return our native context handle to the caller return context; } // ------------------------------------------------------------------------------------------------ /* * Class: assimp_Importer * Method: _NativeFreeContext * Signature: (I)I */ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeFreeContext (JNIEnv * jvmenv, jobject jvmthis, jlong jvmcontext) { #ifdef JASSIMP_DEBUG_CHECKS if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext)) { return AI_JNI_ERROR_RETURN; } #endif // ! ASSIMP_DEBUG // delete the underlying Importer instance Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext; delete pcImp; #ifdef JASSIMP_DEBUG_CHECKS g_listActiveContexts.remove(jvmcontext); #endif // ! ASSIMP_DEBUG JNIEnvironment::Get()->DetachFromCurrentThread(); return 0; } // ------------------------------------------------------------------------------------------------ /* * Class: assimp_Importer * Method: _NativeLoad * Signature: (Ljava/lang/String;II)I */ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad (JNIEnv *jvmenv, jobject jvmthis, jstring jvmpath, jint jvmflags, jlong jvmcontext) { jint iRet = 0; #ifdef JASSIMP_DEBUG_CHECKS if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext)) { return AI_JNI_ERROR_RETURN; } #endif // ! ASSIMP_DEBUG // get the path from the jstring const char* szPath = JNU_GetStringNativeChars(jvmenv,jvmpath); if (!szPath) { DefaultLogger::get()->error("[jnibridge] Unable to get path string from the java vm"); return AI_JNI_ERROR_RETURN; } // get the importer instance from the context Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext; const aiScene* pcOut; // and load the file. The aiScene object itself remains accessible via Importer.GetScene(). if(!(pcOut = pcImp->ReadFile(std::string(szPath),(unsigned int)jvmflags))) { DefaultLogger::get()->error("[jnibridge] Unable to load asset"); free((void*)szPath); return AI_JNI_ERROR_RETURN; } free((void*)szPath); // allocate a new assimp.Scene object to be returned by the importer jobject jScene; if(!(jScene = jvmenv->AllocObject(AIJ_GET_HANDLE(assimp.Importer.Class)))) { DefaultLogger::get()->error("[jnibridge] Unable to allocate output scene"); return AI_JNI_ERROR_RETURN; } // fill the assimp.Scene instance with our data ... JNIEnvironment::Get()->assimp.Scene.Fill(jScene,pcOut); // ... and store it in the Importer instance jvmenv->SetObjectField(jvmthis,AIJ_GET_HANDLE(assimp.Importer.scene),jScene); // .. and finally we don't need th scene anymore pcImp->FreeScene(); return iRet; } // ------------------------------------------------------------------------------------------------ /* * Class: assimp_Importer * Method: _NativeSetPropertyInt * Signature: (Ljava/lang/String;IJ)I */ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyInt (JNIEnv * jvmenv, jobject _this, jstring name, jint value, jlong jvmcontext) { #ifdef JASSIMP_DEBUG_CHECKS if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext)) { return AI_JNI_ERROR_RETURN; } #endif // ! ASSIMP_DEBUG Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext; const char* sz = JNU_GetStringNativeChars(jvmenv,name); // set the property pcImp->SetPropertyInteger(sz,(int)value,NULL); free((void*)sz); return 0; } // ------------------------------------------------------------------------------------------------ /* * Class: assimp_Importer * Method: _NativeSetPropertyFloat * Signature: (Ljava/lang/String;FJ)I */ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyFloat (JNIEnv * jvmenv, jobject _this, jstring name, jfloat value, jlong jvmcontext) { #ifdef JASSIMP_DEBUG_CHECKS if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext)) { return AI_JNI_ERROR_RETURN; } #endif // ! ASSIMP_DEBUG Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext; const char* sz = JNU_GetStringNativeChars(jvmenv,name); // set the property pcImp->SetPropertyFloat(sz,(float)value,NULL); free((void*)sz); return 0; } // ------------------------------------------------------------------------------------------------ /* * Class: assimp_Importer * Method: _NativeSetPropertyString * Signature: (Ljava/lang/String;Ljava/lang/String;J)I */ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyString (JNIEnv * jvmenv, jobject _this, jstring name, jstring value, jlong jvmcontext) { #ifdef JASSIMP_DEBUG_CHECKS if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext)) { return AI_JNI_ERROR_RETURN; } #endif // ! ASSIMP_DEBUG Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext; const char* sz = JNU_GetStringNativeChars(jvmenv,name); const char* sc = JNU_GetStringNativeChars(jvmenv,value); // set the property pcImp->SetPropertyString(sz,sc,NULL); free((void*)sz); free((void*)sc); return 0; }