private void _AddInstances(IVisualNodeContainer dst, Schema2SceneBuilder context) { if (_Children.Count < _GpuMinCount) { foreach (var srcChild in _Children) { if (srcChild.Content is SCHEMA2NODE srcOperator) { var dstNode = dst.CreateNode(); dstNode.Name = srcChild.Name; dstNode.Extras = srcChild.Extras.DeepClone(); dstNode.LocalTransform = srcChild.ChildTransform; srcOperator.ApplyTo(dstNode, context); System.Diagnostics.Debug.Assert(dstNode.WorldMatrix == srcChild.GetPoseWorldMatrix(), "Transform mismatch!"); } } } else { if (_Children[0].Content is SCHEMA2NODE srcOperator) { var xforms = _Children .Select(item => item.ChildTransform) .ToList(); if (!(dst is Node dstNode)) { dstNode = dst.CreateNode(); } System.Diagnostics.Debug.Assert(dstNode.Mesh == null); System.Diagnostics.Debug.Assert(dstNode.Skin == null); System.Diagnostics.Debug.Assert(dstNode.GetGpuInstancing() == null); srcOperator.ApplyTo(dstNode, context); dstNode .UseGpuInstancing() .WithInstanceAccessors(xforms); #if DEBUG var dstInstances = dstNode.GetGpuInstancing(); for (int i = 0; i < _Children.Count; ++i) { var srcXform = _Children[i].GetPoseWorldMatrix(); var dstXform = dstInstances.GetWorldMatrix(i); System.Diagnostics.Debug.Assert(srcXform == dstXform, "Transform mismatch!"); } #endif } } }
/// <summary> /// Recursively converts all the <see cref="NodeBuilder"/> instances into <see cref="Schema2.Node"/> instances. /// </summary> /// <param name="container">The target <see cref="Schema2.Scene"/> or <see cref="Schema2.Node"/>.</param> /// <param name="srcNode">The source <see cref="NodeBuilder"/> instance.</param> private void CreateArmature(IVisualNodeContainer container, NodeBuilder srcNode) { var dstNode = container.CreateNode(srcNode.Name); _Nodes[srcNode] = dstNode; if (srcNode.HasAnimations) { dstNode.LocalTransform = srcNode.LocalTransform; // Copies all the animations to the target node. if (srcNode.Scale != null) { foreach (var t in srcNode.Scale.Tracks) { dstNode.WithScaleAnimation(t.Key, t.Value); } } if (srcNode.Rotation != null) { foreach (var t in srcNode.Rotation.Tracks) { dstNode.WithRotationAnimation(t.Key, t.Value); } } if (srcNode.Translation != null) { foreach (var t in srcNode.Translation.Tracks) { dstNode.WithTranslationAnimation(t.Key, t.Value); } } } else { dstNode.LocalMatrix = srcNode.LocalMatrix; } foreach (var c in srcNode.VisualChildren) { CreateArmature(dstNode, c); } }
static void RecusiveTentacle(Scene scene, IVisualNodeContainer parent, Matrix4x4 offset, Mesh mesh, Quaternion anim, int repeat) { parent = parent .CreateNode() .WithLocalTransform(offset); parent = AddTentacleSkeleton(scene, parent as Node, mesh, anim); if (repeat == 0) { return; } var scale = Matrix4x4.CreateScale(0.2f); RecusiveTentacle(scene, parent, Matrix4x4.CreateTranslation(+15, 0, +15) * scale, mesh, Quaternion.CreateFromYawPitchRoll(0f, 0.2f, 0f), repeat - 1); RecusiveTentacle(scene, parent, Matrix4x4.CreateTranslation(-15, 0, +15) * scale, mesh, Quaternion.CreateFromYawPitchRoll(0.2f, 0f, 0f), repeat - 1); RecusiveTentacle(scene, parent, Matrix4x4.CreateTranslation(-15, 0, -15) * scale, mesh, Quaternion.CreateFromYawPitchRoll(0f, 0f, 0.2f), repeat - 1); RecusiveTentacle(scene, parent, Matrix4x4.CreateTranslation(+15, 0, -15) * scale, mesh, Quaternion.CreateFromYawPitchRoll(0.2f, 0f, 0f), repeat - 1); }