研究背景
體積:一個(gè).dae模型大概有1M那么大 而.fbx模型0.5M
現(xiàn)狀
xcode現(xiàn)在不能直接讀取.fbx模型
方案
1.使用assimpKit加載
2.使用Wish3D加載
結(jié)果
1.使用assimpKit--可行
2.使用Wish3D-- 官方文檔有問(wèn)題,然后咨詢(xún)還不回復(fù)----直接丟棄
原理
1.讀取模型的 頂點(diǎn)坐標(biāo) 紋理坐標(biāo) 法線 骨骼頂點(diǎn) 骨骼動(dòng)畫(huà)
2.調(diào)用以下方法畫(huà)出模型
根據(jù)頂點(diǎn)坐標(biāo)和模型類(lèi)型畫(huà)出模型,模型類(lèi)型可以是點(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)用以下方法畫(huà)出法線
+ (instancetype)geometrySourceWithTextureCoordinates:(const CGPoint *)texcoord count:(NSInteger)count;
5.調(diào)用以下方法畫(huà)出骨骼頂點(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)畫(huà)皮膚那方面的
+ (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類(lèi)
+ (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)畫(huà)的值和類(lèi)型
+ (SCNAction *)repeatActionForever:(SCNAction *)action;
10.調(diào)用以下方法運(yùn)行骨骼動(dòng)畫(huà)
- (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)庫(kù) (不是靜態(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è)的 就是本來(lái)有其他的xxx 還是可以添加-lz的
image.png
主要是assimpKit里有.a 的壓縮文件 我們要添加壓縮的庫(kù)區(qū)解壓
5.設(shè)置bitcode為no
image.png
開(kāi)發(fā)中遇到的問(wèn)題
1.加載fbx模型的動(dòng)畫(huà) 只有部分節(jié)點(diǎn)有動(dòng)畫(huà)
2.控制動(dòng)畫(huà)的播放但動(dòng)畫(huà)結(jié)束的時(shí)候會(huì)很突兀
解決辦法
1.查看源碼 他是遍歷到每個(gè)子節(jié)點(diǎn)然后把動(dòng)畫(huà)添加上去 但是有一些節(jié)點(diǎn)根本加不上去 所以我們需要改一下他的源碼
image.png
當(dāng)了這個(gè)bug他們開(kāi)發(fā)團(tuán)隊(duì)也知道了 并且標(biāo)為了bug
image.png
2.查看源碼 發(fā)現(xiàn)他是沒(méi)有用到fadeOutDuration這個(gè)屬性 可能是遺留了
image.png
后記
assimpKit這個(gè)庫(kù) 功能很強(qiáng) 雖然不是很成熟 但我們可以在他們基礎(chǔ)上修改一下代碼 來(lái)實(shí)現(xiàn)我們的功能 當(dāng)然了 如果發(fā)現(xiàn)bug 還可以和他們開(kāi)發(fā)團(tuán)隊(duì)提一下 讓這個(gè)框架幫助更多的開(kāi)發(fā)人員