You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
2.8 KiB

using Res2tf;
using SharpGLTF.Materials;
using SharpGLTF.Schema2;
using SharpGLTF.Transforms;
using var package = new ResonitePackage("test/Test.resonitepackage");
var nodeMap = new Dictionary<DataTreeNode, Node>();
var model = ModelRoot.CreateModel();
// Initialize Data on the DataTree nodes to scene nodes.
foreach (var n in package.Tree.Root.EnumerateRecursive()) {
if (n.Parent == null) continue; // Tree root => scene root.
var parent = nodeMap.TryGetValue(n.Parent, out var parentNode)
? (IVisualNodeContainer)parentNode : model.UseScene(0);
var node = parent.CreateNode(n.Name);
node.LocalTransform = new(n.Scale, n.Rotation, n.Position);
nodeMap[n] = node;
}
package.ProcessAssets(model);
var meshRenderer = package.Tree.GetTypeId("[FrooxEngine]FrooxEngine.MeshRenderer");
var skinnedMeshRenderer = package.Tree.GetTypeId("[FrooxEngine]FrooxEngine.SkinnedMeshRenderer");
// Add meshes to the Scene hierarchy.
// (Skinned meshes need skeleton bones for this to work.)
foreach (var node in package.Tree.Root.EnumerateRecursive())
foreach (var component in node.Bson["Components"]["Data"].AsList()) {
var type = (int)component["Type"];
if (type == meshRenderer) {
var assetId = (string)component["Data"]["Mesh"]["Data"];
if (package.TryGetAsset<MeshAsset>(assetId, out var asset)) {
var materials = component["Data"]["Materials"]["Data"].AsList()
.Select(material => (MaterialBuilder)package.Assets[(string)material["Data"]]);
foreach (var (i, material) in materials.Select((m, i) => (i, m)))
asset.Mesh.Primitives[i].Material = model.CreateMaterial(material);
nodeMap[node].WithMesh(asset.Mesh);
}
} else if (type == skinnedMeshRenderer) {
var assetId = (string)component["Data"]["Mesh"]["Data"];
if (package.TryGetAsset<MeshAsset>(assetId, out var asset)) {
var materials = component["Data"]["Materials"]["Data"].AsList()
.Select(material => (MaterialBuilder)package.Assets[(string)material["Data"]]);
foreach (var (i, material) in materials.Select((m, i) => (i, m)))
asset.Mesh.Primitives[i].Material = model.CreateMaterial(material);
var bones = component["Data"]["Bones"]["Data"].AsList()
.Select(bone => nodeMap[package.Tree.Nodes[(string)bone["Data"]]]);
var inverseBoneMatrices = asset.GetInverseBindMatrices();
var joints = bones.Zip(inverseBoneMatrices).ToArray();
// Skeleton node must not have transform.
nodeMap[node].LocalTransform = AffineTransform.Identity;
nodeMap[node].WithSkinnedMesh(asset.Mesh, joints);
}
}
}
model.SaveGLB("test/scene.glb");