研究背景
體積:一個.dae模型大概有1M那么大 而.fbx模型0.5M
現(xiàn)狀
xcode現(xiàn)在不能直接讀取.fbx模型
方案
1.使用assimpKit加載
2.使用Wish3D加載
結(jié)果
1.使用assimpKit--可行
2.使用Wish3D-- 官方文檔有問題因痛,然后咨詢還不回復(fù)----直接丟棄
原理
1.讀取模型的 頂點坐標(biāo) 紋理坐標(biāo) 法線 骨骼頂點 骨骼動畫
2.調(diào)用以下方法畫出模型
根據(jù)頂點坐標(biāo)和模型類型畫出模型,模型類型可以是點掺栅、線姜胖、三角形
為什么是三角形呢誉帅?因為三角形是最小邊幾何圖形
+ (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)用以下方法畫出骨骼頂點
+ (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è)置與骨骼頂點向連接的部分
+ (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è)置骨骼動畫皮膚那方面的
+ (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è)置把骨骼相信存放到一個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è)置骨骼動畫的值和類型
+ (SCNAction *)repeatActionForever:(SCNAction *)action;
10.調(diào)用以下方法運行骨骼動畫
- (void)runAction:(SCNAction *)action API_AVAILABLE(macos(10.10));
把assimpKit接入項目
1.到 assimpKit 下載 文件
文件很大的 要找到ios的
2.把assimpKit.frame 拖入工程里
image.png
3.把下面的文件導(dǎo)入工程里
image.png
image.png
4.然后再設(shè)置動態(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
這個可以添加多個的 就是本來有其他的xxx 還是可以添加-lz的
image.png
主要是assimpKit里有.a 的壓縮文件 我們要添加壓縮的庫區(qū)解壓
5.設(shè)置bitcode為no
image.png
開發(fā)中遇到的問題
1.加載fbx模型的動畫 只有部分節(jié)點有動畫
2.控制動畫的播放但動畫結(jié)束的時候會很突兀
解決辦法
1.查看源碼 他是遍歷到每個子節(jié)點然后把動畫添加上去 但是有一些節(jié)點根本加不上去 所以我們需要改一下他的源碼
image.png
當(dāng)了這個bug他們開發(fā)團隊也知道了 并且標(biāo)為了bug
image.png
2.查看源碼 發(fā)現(xiàn)他是沒有用到fadeOutDuration這個屬性 可能是遺留了
image.png
后記
assimpKit這個庫 功能很強 雖然不是很成熟 但我們可以在他們基礎(chǔ)上修改一下代碼 來實現(xiàn)我們的功能 當(dāng)然了 如果發(fā)現(xiàn)bug 還可以和他們開發(fā)團隊提一下 讓這個框架幫助更多的開發(fā)人員