KhronosGroup的UnityGLTF插件,本体是GLTFSerialization.dll,其实就是对glTFLoader的重写,用于读写GLTF/GLB格式,它隐藏了一些细节,但是我们还是可以解析为VRM的(VRM是GLTF/GLB的拓展部分加了一点二次元的香料,本质就是glb!)
其实大厂做的类库比较简单易读,GLTFSerialization.dll的读写基本上也和glTFLoader八九不离十。
为什么不用纯C#的glTFLoader?而是UnityGLTF里面的GLTFSerialization.dll,一个是UnityGLTF占有率高,二是UnityGLTF有现成转换的代码,方便我们移植到OpenTK中!
读取的VRM模型素材是"AliciaSolid_vrm-0.51.vrm",你可以到github搜,一搜就有
GLTF/GLB或者说后面的VRM本质上内部以键值对存储,可以转换为json;
protected override async void Initialize(string name, string path, Vector3 position, Vector3 scale)
{
var bytes = System.IO.File.ReadAllBytes(this.path);
Stream stream = new MemoryStream(bytes);
GLTFRoot _gltfRoot = null;
GLTFParser.ParseJson(stream, out _gltfRoot);
GLTFScene scene=null;
if (null!= _gltfRoot)
{
if(null!=_gltfRoot.ExtensionsUsed)
{
if(_gltfRoot.Extensions.ContainsKey("VRM"))
{
Console.WriteLine("it is a vrm");
//这里try部分的代码就是对我们VRM拓展的读取
try
{
var vrmExt = _gltfRoot.Extensions["VRM"];
var clone = vrmExt.Clone(_gltfRoot);//这里不确定是否一定要拷贝一份
var obj = clone.Serialize().Value;//"VRM":{},获取这个VRM拓展的json的键值对的值
var jsonData = obj.ToString(Newtonsoft.Json.Formatting.None);
var vrmNative = Newtonsoft.Json.JsonConvert.DeserializeObject<glTF_VRM>(jsonData);//序列化到我们定义的vrm类中
if (vrmNative != null)
{
var bs = vrmNative.BlendShapeMaster;
if (null != bs.BlendShapeGroups)
{
foreach (var group in bs.BlendShapeGroups)
{
Console.WriteLine(group.PresetName);
}
}
}
Console.WriteLine("jsonData:\n"+ jsonData);
}
catch(Exception e)
{
Console.WriteLine(e);
}
}
else Console.WriteLine("it is a gltf");
}
var scenes = _gltfRoot.Scenes.Count;
if (scenes > 1)
scene = _gltfRoot.Scenes[scenes - 1];
else if (1 == scenes)
scene = _gltfRoot.GetDefaultScene();
else throw new GLTFLoadException("No default scene in gltf file.");
await ConstructScene(scene,true);
}
}
ok、如果你没有农错的话,结果是这样的
当然这个json你可以自己序列化,也可以等我后面更新,补上序列化的类
下一步,我将完整加载出VRM格式,以及VRM的动画,甚至包括是IK的设计,敬请期待!
那么我们下次再见,see you!
ref:
https://github.com/KhronosGroup/UnityGLTF
https://github.com/KhronosGroup/glTF-Sample-Models
https://github.com/KhronosGroup/glTF-CSharp-Loader