internal NodeTemplate(Schema2.Node srcNode, int parentIdx, int[] childIndices, RuntimeOptions options) { _LogicalSourceIndex = srcNode.LogicalIndex; _ParentIndex = parentIdx; _ChildIndices = childIndices; Name = srcNode.Name; Extras = RuntimeOptions.ConvertExtras(srcNode, options); _LocalTransform = srcNode.LocalTransform; if (_LocalTransform.TryDecompose(out TRANSFORM lxform)) { _Scale = new AnimatableProperty <Vector3>(lxform.Scale); _Rotation = new AnimatableProperty <Quaternion>(lxform.Rotation); _Translation = new AnimatableProperty <Vector3>(lxform.Translation); } var mw = Transforms.SparseWeight8.Create(srcNode.MorphWeights); _Morphing = new AnimatableProperty <Transforms.SparseWeight8>(mw); var isolateMemory = options?.IsolateMemory ?? false; foreach (var anim in srcNode.LogicalParent.LogicalAnimations) { var index = anim.LogicalIndex; var curves = srcNode.GetCurveSamplers(anim); _Scale.SetCurve(index, curves.Scale?.CreateCurveSampler(isolateMemory)); _Rotation.SetCurve(index, curves.Rotation?.CreateCurveSampler(isolateMemory)); _Translation.SetCurve(index, curves.Translation?.CreateCurveSampler(isolateMemory)); _Morphing.SetCurve(index, curves.GetMorphingSampler <Transforms.SparseWeight8>()?.CreateCurveSampler(isolateMemory)); } _UseAnimatedTransforms = _Scale.IsAnimated | _Rotation.IsAnimated | _Translation.IsAnimated; if (!_UseAnimatedTransforms) { _Scale = null; _Rotation = null; _Translation = null; } }
/// <summary> /// Creates a new <see cref="SceneTemplate"/> from a given <see cref="Schema2.Scene"/>. /// </summary> /// <param name="srcScene">The source <see cref="Schema2.Scene"/> to templatize.</param> /// <param name="options">Custom processing options, or null.</param> /// <returns>A new <see cref="SceneTemplate"/> instance.</returns> public static SceneTemplate Create(Schema2.Scene srcScene, RuntimeOptions options = null) { Guard.NotNull(srcScene, nameof(srcScene)); if (options == null) { options = new RuntimeOptions(); } var armature = ArmatureTemplate.Create(srcScene, options); // gather scene nodes. var srcNodes = Schema2.Node.Flatten(srcScene) .Select((key, idx) => (key, idx)) .ToDictionary(pair => pair.key, pair => pair.idx); int indexSolver(Schema2.Node srcNode) { if (srcNode == null) { return(-1); } return(srcNodes[srcNode]); } // create drawables. var instances = srcNodes.Keys .Where(item => item.Mesh != null) .ToList(); var drawables = new List <DrawableTemplate>(); for (int i = 0; i < instances.Count; ++i) { var srcInstance = instances[i]; if (srcInstance.Skin != null) { drawables.Add(new SkinnedDrawableTemplate(srcInstance, indexSolver)); continue; } if (srcInstance.GetGpuInstancing() == null) { drawables.Add(new RigidDrawableTemplate(srcInstance, indexSolver)); continue; } switch (options.GpuMeshInstancing) { case MeshInstancing.Discard: break; case MeshInstancing.Enabled: drawables.Add(new InstancedDrawableTemplate(srcInstance, indexSolver)); break; case MeshInstancing.SingleMesh: drawables.Add(new RigidDrawableTemplate(srcInstance, indexSolver)); break; default: throw new NotImplementedException(); } } var extras = RuntimeOptions.ConvertExtras(srcScene, options); return(new SceneTemplate(srcScene.Name, extras, armature, drawables.ToArray())); }