研究背景
體積:一個(gè).dae模型大概有1M那么大 而.fbx模型0.5M
現(xiàn)狀
xcode現(xiàn)在不能直接讀取.fbx模型
方案
1.使用assimpKit加載
2.使用Wish3D加載
結(jié)果
1.使用assimpKit--可行
2.使用Wish3D-- 官方文檔有問題,然后咨詢還不回復(fù)----直接丟棄
原理
1.讀取模型的 頂點(diǎn)坐標(biāo) 紋理坐標(biāo) 法線 骨骼頂點(diǎn) 骨骼動(dòng)畫
2.調(diào)用以下方法畫出模型
根據(jù)頂點(diǎn)坐標(biāo)和模型類型畫出模型,模型類型可以是點(diǎn)、線、三角形
為什么是三角形呢?因?yàn)槿切问亲钚∵厧缀螆D形
+ (instancetype)geometrySourceWithVertices:(const SCNVector3 *)vertices count:(NSInteger)count;
3.調(diào)用以下方法設(shè)置紋理
+ (instancetype)geometrySourceWithNormals:(const SCNVector3 *)normals count:(NSInteger)count;
用以下方法設(shè)置模型圖片 就是設(shè)置node的紋理
SCNGeometry *geo = [SCNGeometry geometryWithSources:sources elements:elements];
UIImage * image = [UIImage imageNamed:@"xy.jpg"];
SCNMaterial *mat = [SCNMaterial material];
mat.diffuse.contents = image;
geo.firstMaterial = mat;
geo.firstMaterial.doubleSided = YES;
4.調(diào)用以下方法畫出法線
+ (instancetype)geometrySourceWithTextureCoordinates:(const CGPoint *)texcoord count:(NSInteger)count;
5.調(diào)用以下方法畫出骨骼頂點(diǎn)
+ (instancetype)geometrySourceWithData:(NSData *)data semantic:(SCNGeometrySourceSemantic)semantic vectorCount:(NSInteger)vectorCount floatComponents:(BOOL)floatComponents componentsPerVector:(NSInteger)componentsPerVector bytesPerComponent:(NSInteger)bytesPerComponent dataOffset:(NSInteger)offset dataStride:(NSInteger)stride;
6.調(diào)用以下方法設(shè)置與骨骼頂點(diǎn)向連接的部分
+ (instancetype)geometrySourceWithData:(NSData *)data semantic:(SCNGeometrySourceSemantic)semantic vectorCount:(NSInteger)vectorCount floatComponents:(BOOL)floatComponents componentsPerVector:(NSInteger)componentsPerVector bytesPerComponent:(NSInteger)bytesPerComponent dataOffset:(NSInteger)offset dataStride:(NSInteger)stride;
7.調(diào)用以下方法設(shè)置骨骼動(dòng)畫皮膚那方面的
+ (instancetype)geometrySourceWithData:(NSData *)data semantic:(SCNGeometrySourceSemantic)semantic vectorCount:(NSInteger)vectorCount floatComponents:(BOOL)floatComponents componentsPerVector:(NSInteger)componentsPerVector bytesPerComponent:(NSInteger)bytesPerComponent dataOffset:(NSInteger)offset dataStride:(NSInteger)stride
8.調(diào)用以下方法設(shè)置把骨骼相信存放到一個(gè)SCNSkinner類
+ (instancetype)skinnerWithBaseGeometry:(nullable SCNGeometry *)baseGeometry bones:(NSArray<SCNNode *> *)bones boneInverseBindTransforms:(nullable NSArray<NSValue *> *)boneInverseBindTransforms boneWeights:(SCNGeometrySource *)boneWeights boneIndices:(SCNGeometrySource *)boneIndices API_AVAILABLE(macos(10.10));
9.調(diào)用以下方法設(shè)置骨骼動(dòng)畫的值和類型
+ (SCNAction *)repeatActionForever:(SCNAction *)action;
10.調(diào)用以下方法運(yùn)行骨骼動(dòng)畫
- (void)runAction:(SCNAction *)action API_AVAILABLE(macos(10.10));
把a(bǔ)ssimpKit接入項(xiàng)目
1.到 assimpKit 下載 文件
文件很大的 要找到ios的
2.把a(bǔ)ssimpKit.frame 拖入工程里

image.png
3.把下面的文件導(dǎo)入工程里

image.png

image.png
4.然后再設(shè)置動(dòng)態(tài)庫 (不是靜態(tài))

image.png
還有

image.png
如果出現(xiàn)了
"_compress", referenced from:
“_uncompress", referenced from:
"_compress2", referenced from:
"_inflateReset", referenced from:
"inflateInit", referenced from:
"_inflateEnd", referenced from:
"inflateInit2", referenced from:
有兩種解決方法

image.png
這個(gè)可以添加多個(gè)的 就是本來有其他的xxx 還是可以添加-lz的

image.png
主要是assimpKit里有.a 的壓縮文件 我們要添加壓縮的庫區(qū)解壓
5.設(shè)置bitcode為no

image.png
開發(fā)中遇到的問題
1.加載fbx模型的動(dòng)畫 只有部分節(jié)點(diǎn)有動(dòng)畫
2.控制動(dòng)畫的播放但動(dòng)畫結(jié)束的時(shí)候會(huì)很突兀
解決辦法
1.查看源碼 他是遍歷到每個(gè)子節(jié)點(diǎn)然后把動(dòng)畫添加上去 但是有一些節(jié)點(diǎn)根本加不上去 所以我們需要改一下他的源碼

image.png
當(dāng)了這個(gè)bug他們開發(fā)團(tuán)隊(duì)也知道了 并且標(biāo)為了bug

image.png
2.查看源碼 發(fā)現(xiàn)他是沒有用到fadeOutDuration這個(gè)屬性 可能是遺留了

image.png
后記
assimpKit這個(gè)庫 功能很強(qiáng) 雖然不是很成熟 但我們可以在他們基礎(chǔ)上修改一下代碼 來實(shí)現(xiàn)我們的功能 當(dāng)然了 如果發(fā)現(xiàn)bug 還可以和他們開發(fā)團(tuán)隊(duì)提一下 讓這個(gè)框架幫助更多的開發(fā)人員