在做项目过程中需要使用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<aiAnimMesh*> animMeshes;
for (const BlendShape* blendShape : mesh.GetBlendShapes()) {
for (const BlendShapeChannel* blendShapeChannel : blendShape->BlendShapeChannels()) {
const std::vector<const ShapeGeometry*>& 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<aiVector3D>& vertices = shapeGeometry->GetVertices();
const std::vector<aiVector3D>& normals = shapeGeometry->GetNormals();
const std::vector<unsigned int>& 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<unsigned int>(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<unsigned int>(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.rc1
  4. 在NDK目录下的build/tools下,通过以下命令生成编译时所需要的交叉编译ToolChain,注意: 
  5. .make_standalone_toolchain.py --arch=arm --stl=gnustl --api= --install-dir=toolchain--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文件,文件内容如下:
.    @echo off
. cls
.
. REM *NOTE* Change these based on
. SET ASSIMP_DIR=assimp-v.5.0..rc1
. SET OUTPUT_DIR=aassimp-build-armeabi-v7a
. SET ANDROID_PATH=C:/Users/xxxx/AppData/Local/Android/Sdk
. SET NDK_PATH=G:/software/android-ndk-r16b
. SET NDK_TOOLCHAIN=%~dp0toolchain-9-arm-gnustl. SET CMAKE_TOOLCHAIN=%NDK_PATH%/build/cmake/android.toolchain.cmake
. SET CMAKE_PATH=%ANDROID_PATH%/cmake/3.6.
.
. REM *NOTE* Careful if you don't want rm -rf, I use it for testing purposes.
.
. mkdir %OUTPUT_DIR%
.
. REM pushd doesn't seem to work ):<
. cd %OUTPUT_DIR%
.
. if not defined ORIGPATH set ORIGPATH=%PATH%
. SET PATH=%CMAKE_PATH%\bin;%ANDROID_PATH%\tools;%ANDROID_PATH%\platform-tools;%ORIGPATH%
.
. cmake ^
. -GNinja ^
. -DCMAKE_TOOLCHAIN_FILE=%CMAKE_TOOLCHAIN% ^
. -DASSIMP_ANDROID_JNIIOSYSTEM=ON ^
. -DANDROID_NDK=%NDK_PATH% ^
. -DCMAKE_MAKE_PROGRAM=%CMAKE_PATH%\bin\ninja.exe ^
. -DCMAKE_BUILD_TYPE=Release ^
. -DANDROID_ABI="armeabi-v7a" ^
. -DANDROID_NATIVE_API_LEVEL= ^
. -DANDROID_FORCE_ARM_BUILD=TRUE ^
. -DCMAKE_INSTALL_PREFIX=install ^
. -DANDROID_STL=gnustl_static ^
. -DCMAKE_CXX_FLAGS=-Wno-c++-narrowing ^
. -DANDROID_TOOLCHAIN=clang ^
.
. -DASSIMP_BUILD_TESTS=OFF ^
.
. ../%ASSIMP_DIR%
.
. cmake --build .
.

  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关掉,并增加下面三行,然后重复上面步骤。

Assimp定制化:

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

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

  1. 在Ubuntu下编译Assimp库

    在Ubuntu下编译Assimp库 怎样在Ubuntu下编译Assimp库?这是我曾经编译成功后做的笔记,供參考. 1.去以下的站点去下载Assimp库: http://assimp.sourcefo ...

  2. Openstack 二次开发之:在windows 环境下编译Openstack-java-sdk

    在windows环境下使用maven对openstack-java-sdk进行编译 编译源文件 下载源代码 git clonehttps://github.com/woorea/openstack-j ...

  3. 在Windows 环境下编译Qt静态库(QT5.32)

    参考链接 Qt5.3 Tools and Versions MinGW ICU ActivePerl Qt 安装MinGW工具链环境 这里在Win32环境下要安装一个MinGW工具链,这里最好是先安装 ...

  4. 在windows环境下编译hadoop

    1.环境准备 1.1 JDK的安装 下载jdk1.6.0_43(这里务必要使用jdk的1.6版本,因为使用JDK1.7版本编译hadoop的时候,很多Maven依赖下载不完整,最终会报错)解压到,并将 ...

  5. 【Code::Blocks】windows 环境下编译 Code::Blocks(已修正)

    Code::Blocks 在2012-11-25发布了最新的12.11版本,相比上一个版本(10.05),Code::Blocks 进行了许多改进和更新(Change log). 引用 Wikiped ...

  6. 【转】Windows环境下Android NDK环境搭建

    原文网址:http://www.metsky.com/archives/525.html 前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员 ...

  7. Windows环境下Android NDK环境搭建

    前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员来讲,基本够用了,由于Linux系统的权限限制和Android封装架构限制,很多涉及底层设 ...

  8. Android 环境下编译FFmpeg

    Android 环境下编译FFmpeg 开发环境:Ubuntu 12.04.2 LTS , android-sdk-linux, android-ndk-r8e 一 .X264 编译 1.    X2 ...

  9. Windows环境下使用VS2005编译OpenSSL

    如何Windows环境下,使用VS2005编译OpenSSL,虽然这个问题在Baidu.Google上一堆,但安装中还是遇到些问题,在这里 记录下来希望能帮助大家不要在走弯路.注:我是在WinXP S ...

随机推荐

  1. [面试] Java GC (未整理完)

    Java GC简介 什么是 GC ? Java程序不用像C++程序在程序中自行处理内存的回收释放.这是因为Java在JVM虚拟机上增加了垃圾回收(GC)机制,用以在合适的时间触发垃圾回收. 你都了解哪 ...

  2. http和https协议的区别

    内容摘自:转载注明Wosign 尊重知识产权 一 什么是HTTPS HTTPS全称为 安全超文本传输协议(Secure Hypertext Transfer Protocol)),是一个安全通信通道, ...

  3. 第三节:Windows平台部署Asp.Net Core应用(基于IIS和Windows服务两种模式)

    一. 简介 二. 文件系统发布至IIS 三. Web部署发布至IIS 四. FTP发布至IIS 五. Windows服务的形式发布 ! 作       者 : Yaopengfei(姚鹏飞) 博客地址 ...

  4. 网络&协议目录

    HTTP [基础] HTTP入门学习 网络基础 数据传输 网站架构演化 连接管理 缓存 [组成] URL 报文起始行 报文首部 [结构] Web服务器 代理 网关.隧道和中继 [安全] Web攻击技术 ...

  5. iTOP-i.MX6Q开发板支持安卓Android6.0系统

    迅为IMX6开发板: Android4.4/6.0系统  Linux + Qt5.7系统  Ubuntu12.04系统 部分案例:HMI:3D打印机:医疗设备:工控机:触控一体机:车载终端 核心板兼容 ...

  6. 初始化仓库(git init)

    创建新的仓库 首先进入需要初始化的目录,然后输入git init D:\Git\test λ git init Initialized empty Git repository in D:/Git/t ...

  7. window C/C++ 简单的IDE编译器

    C-Free 官网链接: http://www.programarts.com/cfree_ch/download.htm

  8. Scrapy+Scrapy-redis+Scrapyd+Gerapy 分布式爬虫框架整合

    简介:给正在学习的小伙伴们分享一下自己的感悟,如有理解不正确的地方,望指出,感谢~ 首先介绍一下这个标题吧~ 1. Scrapy:是一个基于Twisted的异步IO框架,有了这个框架,我们就不需要等待 ...

  9. Theano.tensor.round函数学习,同时解决输出Elemwise{xxx,no_inplace}.0的问题

    1. 出现Elemwise{xxx,no_inplace}.0   这是因为没有定义theano.function所致,参考下面错误示范: y = np.random.normal(size=(2,2 ...

  10. mysql性能优化分析 --- 下篇

    概要回顾 之前看过<高性能mysql>对mysql数据库有了系统化的理解,虽然没能达到精通,但有了概念,遇到问题时会有逻辑条理的分析; 这回继上次sql分析结果的一个继续延伸分析,我拿了; ...