assimp/port/jAssimp/jni_bridge/jbridge_Importer.cpp

284 lines
8.5 KiB
C++

/* --------------------------------------------------------------------------------
*
* 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 <list>
// 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;
}