284 lines
8.5 KiB
C++
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;
|
||
|
}
|