JNICalls.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. /*
  2. ---------------------------------------------------------------------------
  3. Open Asset Import Library (ASSIMP)
  4. ---------------------------------------------------------------------------
  5. Copyright (c) 2006-2008, ASSIMP Development Team
  6. All rights reserved.
  7. Redistribution and use of this software in source and binary forms,
  8. with or without modification, are permitted provided that the following
  9. conditions are met:
  10. * Redistributions of source code must retain the above
  11. copyright notice, this list of conditions and the
  12. following disclaimer.
  13. * Redistributions in binary form must reproduce the above
  14. copyright notice, this list of conditions and the
  15. following disclaimer in the documentation and/or other
  16. materials provided with the distribution.
  17. * Neither the name of the ASSIMP team, nor the names of its
  18. contributors may be used to endorse or promote products
  19. derived from this software without specific prior
  20. written permission of the ASSIMP Development Team.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. ---------------------------------------------------------------------------
  33. */
  34. /** @file Implementation of the JNI API for jAssimp */
  35. #if (defined ASSIMP_JNI_EXPORT)
  36. // include the header files generated by javah
  37. #include "assimp_Importer.h"
  38. #include "assimp_Animation.h"
  39. #include "assimp_Node.h"
  40. #include "assimp_Texture.h"
  41. #include "assimp_Mesh.h"
  42. #include "assimp_Material.h"
  43. // include assimp
  44. #include "../../include/aiTypes.h"
  45. #include "../../include/aiMesh.h"
  46. #include "../../include/aiAnim.h"
  47. #include "../../include/aiScene.h"
  48. #include "../../include/aiAssert.h"
  49. #include "../../include/aiPostProcess.h"
  50. #include "../../include/assimp.hpp"
  51. #include "../../include/DefaultLogger.h"
  52. #include "JNIEnvironment.h"
  53. #include "JNILogger.h"
  54. using namespace Assimp;
  55. #include <list>
  56. namespace Assimp {
  57. namespace JNIBridge {
  58. // used as error return code
  59. #define AI_JNI_ERROR_RETURN 0xffffffff
  60. // typedef for a jassimp context, used to uniquely identify
  61. // the Importer object which belongs to a java Importer
  62. typedef uint64_t JASSIMP_CONTEXT;
  63. #if (defined _DEBUG)
  64. typedef std::list< JASSIMP_CONTEXT > ImporterContextList;
  65. static ImporterContextList g_listActiveContexts;
  66. // ------------------------------------------------------------------------------------------------
  67. /* Used in debug builds to validate a context
  68. */
  69. bool jValidateContext (JASSIMP_CONTEXT context)
  70. {
  71. for (ImporterContextList::const_iterator
  72. i = g_listActiveContexts.begin();
  73. i != g_listActiveContexts.end();++i)
  74. {
  75. if (context == *i)return true;
  76. }
  77. DefaultLogger::get()->error("[jnibridge] Invalid context");
  78. return false;
  79. }
  80. // ------------------------------------------------------------------------------------------------
  81. /* Used in debug builds to validate a given scene
  82. */
  83. bool jValidateScene (const aiScene* scene)
  84. {
  85. if (!scene)
  86. {
  87. DefaultLogger::get()->error("[jnibridge] No asset loaded at the moment");
  88. return false;
  89. }
  90. return true;
  91. }
  92. #endif // ! ASSIMP_DEBUG
  93. // ------------------------------------------------------------------------------------------------
  94. /* Used in debug builds to validate a given scene
  95. */
  96. Assimp::Importer* jGetValidImporterScenePair (JASSIMP_CONTEXT jvmcontext)
  97. {
  98. #if (defined _DEBUG)
  99. if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext))return NULL;
  100. #endif // ! ASSIMP_DEBUG
  101. // get the importer instance from the context
  102. Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
  103. #if (defined _DEBUG)
  104. if (!jValidateScene(pcImp->GetScene()))return NULL;
  105. #endif // ! ASSIMP_DEBUG
  106. return pcImp;
  107. }
  108. // ------------------------------------------------------------------------------------------------
  109. /*
  110. * Class: assimp_Importer
  111. * Method: _NativeInitContext
  112. * Signature: ()I
  113. */
  114. JNIEXPORT jlong JNICALL Java_assimp_Importer__1NativeInitContext
  115. (JNIEnv * jvmenv, jobject jvmthis)
  116. {
  117. // 2^64-1 indicates error
  118. JASSIMP_CONTEXT context = 0xffffffffffffffffL;
  119. // create a new Importer instance
  120. Assimp::Importer* pcImp = new Assimp::Importer();
  121. context = (JASSIMP_CONTEXT)(uintptr_t)pcImp;
  122. #if (defined _DEBUG)
  123. g_listActiveContexts.push_back(context);
  124. #endif // ! ASSIMP_DEBUG
  125. // need to setup the logger
  126. JNILogDispatcher* pcLogger;
  127. if (DefaultLogger::isNullLogger())
  128. {
  129. pcLogger = new JNILogDispatcher();
  130. DefaultLogger::set (pcLogger);
  131. }
  132. else
  133. {
  134. JNILogDispatcher* pcLogger = ( JNILogDispatcher* )DefaultLogger::get();
  135. pcLogger->AddRef();
  136. }
  137. // setup the JNI environment ...
  138. // simply setup the newest JNIEnv*
  139. JNIEnvironment::Get()->AttachToCurrentThread(jvmenv);
  140. return context;
  141. }
  142. // ------------------------------------------------------------------------------------------------
  143. /*
  144. * Class: assimp_Importer
  145. * Method: _NativeFreeContext
  146. * Signature: (I)I
  147. */
  148. JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeFreeContext
  149. (JNIEnv * jvmenv, jobject jvmthis, jlong jvmcontext)
  150. {
  151. #if (defined _DEBUG)
  152. if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext))return AI_JNI_ERROR_RETURN;
  153. #endif // ! ASSIMP_DEBUG
  154. // delete the Importer instance
  155. Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
  156. delete pcImp;
  157. #if (defined _DEBUG)
  158. g_listActiveContexts.remove(jvmcontext);
  159. #endif // ! ASSIMP_DEBUG
  160. JNIEnvironment::Get()->DetachFromCurrentThread();
  161. return 0;
  162. }
  163. // ------------------------------------------------------------------------------------------------
  164. /*
  165. * Class: assimp_Importer
  166. * Method: _NativeLoad
  167. * Signature: (Ljava/lang/String;II)I
  168. */
  169. JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
  170. (JNIEnv *jvmenv, jobject jvmthis, jstring jvmpath, jint jvmflags, jlong jvmcontext)
  171. {
  172. jint iRet = 0;
  173. #if (defined _DEBUG)
  174. if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext))return AI_JNI_ERROR_RETURN;
  175. #endif // ! ASSIMP_DEBUG
  176. // get the path from the jstring
  177. const char* szPath = JNU_GetStringNativeChars(jvmenv,jvmpath);
  178. if (!szPath)
  179. {
  180. DefaultLogger::get()->error("[jnibridge] Unable to get path string from the java vm");
  181. return AI_JNI_ERROR_RETURN;
  182. }
  183. // get the importer instance from the context
  184. Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
  185. // and load the file. The aiScene object itself remains accessible
  186. // via Importer.GetScene().
  187. if(NULL == pcImp->ReadFile(std::string(szPath),(unsigned int)jvmflags))
  188. {
  189. DefaultLogger::get()->error("[jnibridge] Unable to load asset");
  190. // release the path again
  191. free((void*)szPath);
  192. return AI_JNI_ERROR_RETURN;
  193. }
  194. // release the path again
  195. free((void*)szPath);
  196. return iRet;
  197. }
  198. // ------------------------------------------------------------------------------------------------
  199. /*
  200. * Class: assimp_PostProcessStep
  201. * Method: _NativeSetVertexSplitLimit
  202. * Signature: (I)V
  203. */
  204. JNIEXPORT void JNICALL Java_assimp_PostProcessStep__1NativeSetVertexSplitLimit
  205. (JNIEnv *jvmenv, jclass jvmthis, jint jvmlimit)
  206. {
  207. aiSetVertexSplitLimit(jvmlimit);
  208. }
  209. // ------------------------------------------------------------------------------------------------
  210. /*
  211. * Class: assimp_PostProcessStep
  212. * Method: _NativeSetTriangleSplitLimit
  213. * Signature: (I)V
  214. */
  215. JNIEXPORT void JNICALL Java_assimp_PostProcessStep__1NativeSetTriangleSplitLimit
  216. (JNIEnv *jvmenv, jclass jvmthis, jint jvmlimit)
  217. {
  218. aiSetTriangleSplitLimit(jvmlimit);
  219. }
  220. // ------------------------------------------------------------------------------------------------
  221. /*
  222. * Class: assimp_Scene
  223. * Method: _NativeGetNumMeshes
  224. * Signature: (I)I
  225. */
  226. JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumMeshes
  227. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
  228. {
  229. // we need a valid scene for this
  230. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  231. if (!pcImp)return AI_JNI_ERROR_RETURN;
  232. return (jint)pcImp->GetScene()->mNumMeshes;
  233. }
  234. // ------------------------------------------------------------------------------------------------
  235. /*
  236. * Class: assimp_Scene
  237. * Method: _NativeGetNumAnimations
  238. * Signature: (I)I
  239. */
  240. JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumAnimations
  241. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
  242. {
  243. // we need a valid scene for this
  244. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  245. if (!pcImp)return AI_JNI_ERROR_RETURN;
  246. return (jint)pcImp->GetScene()->mNumAnimations;
  247. }
  248. // ------------------------------------------------------------------------------------------------
  249. /*
  250. * Class: assimp_Scene
  251. * Method: _NativeGetNumTextures
  252. * Signature: (I)I
  253. */
  254. JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumTextures
  255. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
  256. {
  257. // we need a valid scene for this
  258. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  259. if (!pcImp)return AI_JNI_ERROR_RETURN;
  260. return (jint)pcImp->GetScene()->mNumTextures;
  261. }
  262. // ------------------------------------------------------------------------------------------------
  263. /*
  264. * Class: assimp_Scene
  265. * Method: _NativeGetNumMaterials
  266. * Signature: (I)I
  267. */
  268. JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumMaterials
  269. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
  270. {
  271. // we need a valid scene for this
  272. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  273. if (!pcImp)return AI_JNI_ERROR_RETURN;
  274. return (jint)pcImp->GetScene()->mNumMaterials;
  275. }
  276. // ------------------------------------------------------------------------------------------------
  277. /*
  278. * Class: assimp_Mesh
  279. * Method: _NativeGetPresenceFlags
  280. * Signature: (JJ)I
  281. */
  282. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetPresenceFlags
  283. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
  284. {
  285. // we need a valid scene for this
  286. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  287. if (!pcImp)return AI_JNI_ERROR_RETURN;
  288. // get the corresponding mesh
  289. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  290. aiMesh* pcMesh = pcImp->GetScene()->mMeshes[jvmindex];
  291. // now build the flag list
  292. jint iRet = 0;
  293. if (pcMesh->HasPositions())
  294. iRet |= assimp_Mesh_PF_POSITION;
  295. if (pcMesh->HasBones())
  296. iRet |= assimp_Mesh_PF_BONES;
  297. if (pcMesh->HasNormals())
  298. iRet |= assimp_Mesh_PF_NORMAL;
  299. if (pcMesh->HasTangentsAndBitangents())
  300. iRet |= assimp_Mesh_PF_TANGENTBITANGENT;
  301. unsigned int i = 0;
  302. while (pcMesh->HasTextureCoords(i))
  303. iRet |= assimp_Mesh_PF_UVCOORD << i++;
  304. i = 0;
  305. while (pcMesh->HasVertexColors(i))
  306. iRet |= assimp_Mesh_PF_VERTEXCOLOR << i++;
  307. return iRet;
  308. }
  309. // ------------------------------------------------------------------------------------------------
  310. /*
  311. * Class: assimp_Mesh
  312. * Method: _NativeGetNumVertices
  313. * Signature: (JJ)I
  314. */
  315. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumVertices
  316. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
  317. {
  318. // we need a valid scene for this
  319. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  320. if (!pcImp)return AI_JNI_ERROR_RETURN;
  321. // get the corresponding mesh
  322. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  323. return pcImp->GetScene()->mMeshes[jvmindex]->mNumVertices;
  324. }
  325. // ------------------------------------------------------------------------------------------------
  326. /*
  327. * Class: assimp_Mesh
  328. * Method: _NativeGetNumFaces
  329. * Signature: (JJ)I
  330. */
  331. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumFaces
  332. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
  333. {
  334. // we need a valid scene for this
  335. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  336. if (!pcImp)return AI_JNI_ERROR_RETURN;
  337. // get the corresponding mesh
  338. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  339. return pcImp->GetScene()->mMeshes[jvmindex]->mNumFaces;
  340. }
  341. // ------------------------------------------------------------------------------------------------
  342. /*
  343. * Class: assimp_Mesh
  344. * Method: _NativeGetNumBones
  345. * Signature: (JJ)I
  346. */
  347. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumBones
  348. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
  349. {
  350. // we need a valid scene for this
  351. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  352. if (!pcImp)return AI_JNI_ERROR_RETURN;
  353. // get the corresponding mesh
  354. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  355. return pcImp->GetScene()->mMeshes[jvmindex]->mNumBones;
  356. }
  357. // ------------------------------------------------------------------------------------------------
  358. /*
  359. * Class: assimp_Mesh
  360. * Method: _NativeGetMaterialIndex
  361. * Signature: (JJ)I
  362. */
  363. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetMaterialIndex
  364. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
  365. {
  366. // we need a valid scene for this
  367. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  368. if (!pcImp)return AI_JNI_ERROR_RETURN;
  369. // get the corresponding mesh
  370. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  371. return pcImp->GetScene()->mMeshes[jvmindex]->mMaterialIndex;
  372. }
  373. // ------------------------------------------------------------------------------------------------
  374. /*
  375. * Class: assimp_Mesh
  376. * Method: _NativeGetNumUVComponents
  377. * Signature: (JJ[I)I
  378. */
  379. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumUVComponents
  380. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jintArray jvmout)
  381. {
  382. ai_assert(AI_MAX_NUMBER_OF_TEXTURECOORDS == jvmenv->GetArrayLength(jvmout) );
  383. // we need a valid scene for this
  384. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  385. if (!pcImp)return AI_JNI_ERROR_RETURN;
  386. // get the corresponding mesh
  387. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  388. const unsigned int* piArray = pcImp->GetScene()->mMeshes[jvmindex]->mNumUVComponents;
  389. jint* pArray = jvmenv->GetIntArrayElements(jvmout,NULL);
  390. if (NULL == pArray)return AI_JNI_ERROR_RETURN;
  391. for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
  392. pArray[i] = piArray[i];
  393. jvmenv->ReleaseIntArrayElements(jvmout,pArray,0);
  394. return 0;
  395. }
  396. // ------------------------------------------------------------------------------------------------
  397. void CpyVectorToFloatArray(jfloat* pDest, const aiVector3D* pSource, unsigned int iNum)
  398. {
  399. jfloat* pCursor = pDest;
  400. const aiVector3D* const pvEnd = pSource + iNum;
  401. while (pvEnd != pSource)
  402. {
  403. *pCursor++ = pSource->x;
  404. *pCursor++ = pSource->y;
  405. *pCursor++ = pSource->z;
  406. ++pSource;
  407. }
  408. return;
  409. }
  410. // ------------------------------------------------------------------------------------------------
  411. /*
  412. * Class: assimp_Mesh
  413. * Method: _NativeMapVertices
  414. * Signature: (JJ[F)I
  415. */
  416. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapVertices
  417. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
  418. {
  419. // we need a valid scene for this
  420. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  421. if (!pcImp)return AI_JNI_ERROR_RETURN;
  422. // get the corresponding mesh
  423. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  424. aiMesh* pcMesh = (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
  425. ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
  426. const aiVector3D* pcData = pcMesh->mVertices;
  427. // now copy the data to the java array
  428. jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
  429. CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
  430. jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
  431. // delete the original data
  432. delete[] pcMesh->mVertices;
  433. pcMesh->mVertices = NULL;
  434. return 0;
  435. }
  436. // ------------------------------------------------------------------------------------------------
  437. /*
  438. * Class: assimp_Mesh
  439. * Method: _NativeMapNormals
  440. * Signature: (JJ[F)I
  441. */
  442. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapNormals
  443. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
  444. {
  445. // we need a valid scene for this
  446. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  447. if (!pcImp)return AI_JNI_ERROR_RETURN;
  448. // get the corresponding mesh
  449. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  450. aiMesh* pcMesh = (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
  451. ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
  452. const aiVector3D* pcData = pcMesh->mNormals;
  453. // now copy the data to the java array
  454. jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
  455. CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
  456. jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
  457. // delete the original data
  458. delete[] pcMesh->mNormals;
  459. pcMesh->mNormals = NULL;
  460. return 0;
  461. }
  462. // ------------------------------------------------------------------------------------------------
  463. /*
  464. * Class: assimp_Mesh
  465. * Method: _NativeMapTangents
  466. * Signature: (JJ[F)I
  467. */
  468. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapTangents
  469. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
  470. {
  471. // we need a valid scene for this
  472. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  473. if (!pcImp)return AI_JNI_ERROR_RETURN;
  474. // get the corresponding mesh
  475. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  476. aiMesh* pcMesh = (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
  477. ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
  478. const aiVector3D* pcData = pcMesh->mTangents;
  479. // now copy the data to the java array
  480. jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
  481. CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
  482. jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
  483. // delete the original data
  484. delete[] pcMesh->mNormals;
  485. pcMesh->mNormals = NULL;
  486. return 0;
  487. }
  488. // ------------------------------------------------------------------------------------------------
  489. /*
  490. * Class: assimp_Mesh
  491. * Method: _NativeMapBitangents
  492. * Signature: (JJ[F)I
  493. */
  494. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapBitangents
  495. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
  496. {
  497. // we need a valid scene for this
  498. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  499. if (!pcImp)return AI_JNI_ERROR_RETURN;
  500. // get the corresponding mesh
  501. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  502. aiMesh* pcMesh = (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
  503. ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
  504. const aiVector3D* pcData = pcMesh->mBitangents;
  505. // now copy the data to the java array
  506. jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
  507. CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
  508. jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
  509. // delete the original data
  510. delete[] pcMesh->mBitangents;
  511. pcMesh->mBitangents = NULL;
  512. return 0;
  513. }
  514. // ------------------------------------------------------------------------------------------------
  515. void CpyColorToFloatArray(jfloat* pDest, const aiColor4D* pSource, unsigned int iNum)
  516. {
  517. jfloat* pCursor = pDest;
  518. const aiColor4D* const pvEnd = pSource + iNum;
  519. while (pvEnd != pSource)
  520. {
  521. *pCursor++ = pSource->r;
  522. *pCursor++ = pSource->g;
  523. *pCursor++ = pSource->b;
  524. *pCursor++ = pSource->a;
  525. ++pSource;
  526. }
  527. return;
  528. }
  529. // ------------------------------------------------------------------------------------------------
  530. void CpyVectorToFloatArray(jfloat* pDest, const aiVector3D* pSource,
  531. unsigned int iNum, unsigned int iNumComponents)
  532. {
  533. jfloat* pCursor = pDest;
  534. const aiVector3D* const pvEnd = pSource + iNum;
  535. while (pvEnd != pSource)
  536. {
  537. if (iNumComponents >= 1)*pCursor++ = pSource->x;
  538. if (iNumComponents >= 2)*pCursor++ = pSource->y;
  539. if (iNumComponents >= 3)*pCursor++ = pSource->z;
  540. ++pSource;
  541. }
  542. return;
  543. }
  544. // ------------------------------------------------------------------------------------------------
  545. /*
  546. * Class: assimp_Mesh
  547. * Method: _NativeMapUVs
  548. * Signature: (JJI[F)I
  549. */
  550. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapUVs
  551. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex,
  552. jint jvmchannel, jfloatArray jvmout)
  553. {
  554. // we need a valid scene for this
  555. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  556. if (!pcImp)return AI_JNI_ERROR_RETURN;
  557. // get the corresponding mesh
  558. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  559. aiMesh* pcMesh = (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
  560. ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices*pcMesh->mNumUVComponents[jvmchannel]);
  561. const aiVector3D* pcData = pcMesh->mTextureCoords[jvmchannel];
  562. // now copy the data to the java array
  563. jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
  564. CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices,pcMesh->mNumUVComponents[jvmchannel]);
  565. jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
  566. // delete the original data
  567. delete[] pcMesh->mTextureCoords[jvmchannel];
  568. pcMesh->mTextureCoords[jvmchannel] = NULL;
  569. return 0;
  570. }
  571. // ------------------------------------------------------------------------------------------------
  572. /*
  573. * Class: assimp_Mesh
  574. * Method: _NativeMapColors
  575. * Signature: (JJI[F)I
  576. */
  577. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapColors
  578. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex,
  579. jint jvmchannel, jfloatArray jvmout)
  580. {
  581. // we need a valid scene for this
  582. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  583. if (!pcImp)return AI_JNI_ERROR_RETURN;
  584. // get the corresponding mesh
  585. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  586. aiMesh* pcMesh = (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
  587. ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices*4);
  588. const aiColor4D* pcData = pcMesh->mColors[jvmchannel];
  589. // now copy the data to the java array
  590. jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
  591. CpyColorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
  592. jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
  593. // delete the original data
  594. delete[] pcMesh->mColors[jvmchannel];
  595. pcMesh->mColors[jvmchannel] = NULL;
  596. return 0;
  597. }
  598. // ------------------------------------------------------------------------------------------------
  599. void CpyFacesToIntArray(jint* pDest, const aiFace* pSource, unsigned int iNum)
  600. {
  601. // assume that all faces are triangles
  602. jint* pCursor = pDest;
  603. const aiFace* const pvEnd = pSource + iNum;
  604. while (pvEnd != pSource)
  605. {
  606. *pCursor++ = pSource->mIndices[0];
  607. *pCursor++ = pSource->mIndices[1];
  608. *pCursor++ = pSource->mIndices[2];
  609. ++pSource;
  610. }
  611. return;
  612. }
  613. // ------------------------------------------------------------------------------------------------
  614. /*
  615. * Class: assimp_Mesh
  616. * Method: _NativeMapFaces
  617. * Signature: (JJ[I)I
  618. */
  619. JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapFaces
  620. (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jintArray jvmout)
  621. {
  622. // we need a valid scene for this
  623. Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
  624. if (!pcImp)return AI_JNI_ERROR_RETURN;
  625. // get the corresponding mesh
  626. ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
  627. aiMesh* pcMesh = (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
  628. ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumFaces*3);
  629. const aiFace* pcData = pcMesh->mFaces;
  630. // now copy the data to the java array
  631. jint* pArray = jvmenv->GetIntArrayElements(jvmout,NULL);
  632. CpyFacesToIntArray(pArray,pcData,pcMesh->mNumFaces);
  633. jvmenv->ReleaseIntArrayElements(jvmout,pArray,0);
  634. // delete the original data
  635. for (unsigned int i = 0; i < pcMesh->mNumFaces;++i)
  636. delete[] pcMesh->mFaces[i].mIndices;
  637. delete[] pcMesh->mFaces;
  638. pcMesh->mFaces = NULL;
  639. return 0;
  640. }
  641. }; //! namespace JNIBridge
  642. }; //! namespace Assimp
  643. #endif // !ASSIMP_JNI_EXPORT