Windows环境下编译Assimp库生成Android可用的.so或.a文件

在做项目过程中需要使用Assimp这个3D模型读取库来读取obj格式的模型,因为项目是基于Android平台,采用NDK开发,所以就打算编译Assimp库并生成.so文件。本文使用Assimp-v.5.0.0.rc1(https://github.com/assimp/assimp/releases/tag/v.5.0.0.rc1),此版本已经支持在导入FBX的同时导入blendshape。网上的资料大多比较老,针对assimp-3.3的比较多,新版本的编译还是有些不同,特记录下。

首先我们看下Assimp中blenshape导入的代码:以FBX为例 在FBXConverter.cpp中,也就是说blendshape以顶点动画的形式 保存在了aiAnimMesh这个数据结构中,后续对bs的操作只需要操作对应的aiAnimMesh即可。

/** @brief An AnimMesh is an attachment to an #aiMesh stores per-vertex
* animations for a particular frame.


std::vector animMeshes; for (const BlendShape* blendShape : mesh.GetBlendShapes()) { for (const BlendShapeChannel* blendShapeChannel : blendShape->BlendShapeChannels()) { const std::vector& shapeGeometries = blendShapeChannel->GetShapeGeometries(); for (size_t i = 0; i < shapeGeometries.size(); i++) { aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh); const ShapeGeometry* shapeGeometry = shapeGeometries.at(i); const std::vector& vertices = shapeGeometry->GetVertices(); const std::vector& normals = shapeGeometry->GetNormals(); const std::vector& indices = shapeGeometry->GetIndices(); animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name())); for (size_t j = 0; j < indices.size(); j++) { unsigned int index = indices.at(j); aiVector3D vertex = vertices.at(j); aiVector3D normal = normals.at(j); unsigned int count = 0; const unsigned int* outIndices = mesh.ToOutputVertexIndex(index, count); for (unsigned int k = 0; k < count; k++) { unsigned int index = outIndices[k]; animMesh->mVertices[index] += vertex; if (animMesh->mNormals != nullptr) { animMesh->mNormals[index] += normal; animMesh->mNormals[index].NormalizeSafe(); } } } animMesh->mWeight = shapeGeometries.size() > 1 ? blendShapeChannel->DeformPercent() / 100.0f : 1.0f; animMeshes.push_back(animMesh); } } } const size_t numAnimMeshes = animMeshes.size(); if (numAnimMeshes > 0) { out_mesh->mNumAnimMeshes = static_cast(numAnimMeshes); out_mesh->mAnimMeshes = new aiAnimMesh*[numAnimMeshes]; for (size_t i = 0; i < numAnimMeshes; i++) { out_mesh->mAnimMeshes[i] = animMeshes.at(i); } } return static_cast(meshes.size() - 1); }

  下面正式开始编译

  • 下载Android Studio(主要是利用其带的SDK以及CMAKE)
  1. 下载并安装Python,注意安装过程中需要勾选添加到环境变量,我安装的是Python3.5,可通过命令行键入python检查Python是否已经配置好:
  2. 下载NDK, 本文使用r14b 64位(https://github.com/assimp/assimp/wiki/Android-compilation-on-Windows-%28Quick-overview%29)
  3. 下载并解压Assimp-v.5.0.0.rc1Windows环境下编译Assimp库生成Android可用的.so或.a文件_第1张图片
  4. 在NDK目录下的build/tools下,通过以下命令生成编译时所需要的交叉编译ToolChain,注意: 
  5. .make_standalone_toolchain.py --arch=arm --stl=gnustl --api=9 --install-dir=toolchain-9-arm-gnustl

     

    1. --arch 参数指定不同的架构:arm64-v8a对应arm64,armeabi-v7a对应arm等等。
    2. --stl指定使用哪种stl,本文使用gnustl
    3. --api 本文选择了9
  6. 将生成的toolchain-9-arm-gnustl整个文件夹复制到Assimp-v.5.0.0.rc1的同级目录下。
  7. 在Assimp-v.5.0.0.rc1的同级目录下,新建一个build_assimp.bat,用于编译生成.so文件,文件内容如下:

 

1.    @echo off  
2.    cls  
3.      
4.    REM *NOTE* Change these based on   
5.    SET ASSIMP_DIR=assimp-v.5.0.0.rc1  
6.    SET OUTPUT_DIR=aassimp-build-armeabi-v7a  
7.    SET ANDROID_PATH=C:/Users/xxxx/AppData/Local/Android/Sdk  
8.    SET NDK_PATH=G:/software/android-ndk-r16b  
9.    SET NDK_TOOLCHAIN=%~dp0toolchain-9-arm-gnustl10.    SET CMAKE_TOOLCHAIN=%NDK_PATH%/build/cmake/android.toolchain.cmake  
11.    SET CMAKE_PATH=%ANDROID_PATH%/cmake/3.6.4111459  
12.      
13.    REM *NOTE* Careful if you don't want rm -rf, I use it for testing purposes.  
14.      
15.    mkdir %OUTPUT_DIR%  
16.      
17.    REM pushd doesn't seem to work ):<  
18.    cd %OUTPUT_DIR%  
19.      
20.    if not defined ORIGPATH set ORIGPATH=%PATH%  
21.    SET PATH=%CMAKE_PATH%\bin;%ANDROID_PATH%\tools;%ANDROID_PATH%\platform-tools;%ORIGPATH%  
22.      
23.    cmake ^  
24.          -GNinja ^  
25.          -DCMAKE_TOOLCHAIN_FILE=%CMAKE_TOOLCHAIN% ^  
26.          -DASSIMP_ANDROID_JNIIOSYSTEM=ON ^  
27.          -DANDROID_NDK=%NDK_PATH% ^  
28.          -DCMAKE_MAKE_PROGRAM=%CMAKE_PATH%\bin\ninja.exe ^  
29.          -DCMAKE_BUILD_TYPE=Release ^  
30.          -DANDROID_ABI="armeabi-v7a" ^  
31.          -DANDROID_NATIVE_API_LEVEL=9 ^  
32.          -DANDROID_FORCE_ARM_BUILD=TRUE ^  
33.          -DCMAKE_INSTALL_PREFIX=install ^  
34.          -DANDROID_STL=gnustl_static ^  
35.          -DCMAKE_CXX_FLAGS=-Wno-c++11-narrowing ^  
36.          -DANDROID_TOOLCHAIN=clang ^  
37.      
38.          -DASSIMP_BUILD_TESTS=OFF ^  
39.      
40.          ../%ASSIMP_DIR%  
41.      
42.    cmake --build .  
43.      

  8.参数解释:

  1. ASSIMP_DIR是解压的Assimp库所在的文件夹
  2. OUTPUT_DIR是保存编译生成文件的文件夹
  3. ANDROID_PATH跟NDK_PATH需要修改为自己机器上的路径
  4. NDK_TOOLCHAIN是保存工具链的文件夹
  5. 下面的-DANDROID_ABI和-DANDROID_NATIVE_API_LEVEL参数需要改成所需的值。
  6. DANDROID_STL=gnustl_static ^  ,需要与之前生成工具链选择的c库一致。
  7. 然后双击运行.bat文件,如果没有报错,就能在< OUTPUT_DIR>/code/下找到libassimp.so文件,想要生成其他架构下的.so文件,只需修改生成toolchain和.bat文件参数(-DANDROID_ABI="armeabi-v7a" ^ ),再执行即可。
  8. 如果想生成静态库.a,需要打开assimp/CMakeList.txt,将BUILD_SHARED_LIBS关掉,并增加下面三行,然后重复上面步骤。
  9. Windows环境下编译Assimp库生成Android可用的.so或.a文件_第2张图片

     

Assimp定制化:

assimp功能强大,可以加载和导出多种3D模型,附加多种效果优化功能,但在需求中有很多功能使用不到,所以可以在编译时直接剔除已达到减小静态库的目的,需要注意的是:除了需要在编译时通过宏控制编译之外还需要直接在code/CMakeLists.txt文件中将相应的源码注释掉。【后续详细补充】

 

转载于:https://www.cnblogs.com/chenc-c/p/10737082.html

你可能感兴趣的:(Windows环境下编译Assimp库生成Android可用的.so或.a文件)