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
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");
|
|
|