/// <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)); 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 DrawableTemplate[instances.Count]; for (int i = 0; i < drawables.Length; ++i) { var srcInstance = instances[i]; drawables[i] = srcInstance.Skin != null ? new SkinnedDrawableTemplate(srcInstance, indexSolver) : (DrawableTemplate) new RigidDrawableTemplate(srcInstance, indexSolver); } var extras = RuntimeOptions.ConvertExtras(srcScene, options); return(new SceneTemplate(srcScene.Name, extras, armature, drawables)); }
/// <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 templateize.</param> /// <param name="isolateMemory">True if we want to copy data instead of sharing it.</param> /// <returns>A new <see cref="SceneTemplate"/> instance.</returns> public static SceneTemplate Create(Schema2.Scene srcScene, bool isolateMemory) { Guard.NotNull(srcScene, nameof(srcScene)); // 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 bones. var dstNodes = new NodeTemplate[srcNodes.Count]; foreach (var srcNode in srcNodes) { var nidx = srcNode.Value; // parent index var pidx = indexSolver(srcNode.Key.VisualParent); if (pidx >= nidx) { throw new InvalidOperationException("parent indices should be below child indices"); } // child indices var cidx = srcNode.Key.VisualChildren .Select(n => indexSolver(n)) .ToArray(); dstNodes[nidx] = new NodeTemplate(srcNode.Key, pidx, cidx, isolateMemory); } // create drawables. var instances = srcNodes.Keys .Where(item => item.Mesh != null) .ToList(); var drawables = new DrawableTemplate[instances.Count]; for (int i = 0; i < drawables.Length; ++i) { var srcInstance = instances[i]; drawables[i] = srcInstance.Skin != null ? (DrawableTemplate) new SkinnedDrawableTemplate(srcInstance, indexSolver) : (DrawableTemplate) new RigidDrawableTemplate(srcInstance, indexSolver); } // gather animation durations. var dstTracks = new Collections.NamedList <float>(); foreach (var anim in srcScene.LogicalParent.LogicalAnimations) { var index = anim.LogicalIndex; var name = anim.Name; float duration = dstTracks.Count <= index ? 0 : dstTracks[index]; duration = Math.Max(duration, anim.Duration); dstTracks.SetValue(index, name, anim.Duration); } return(new SceneTemplate(srcScene.Name, dstNodes, drawables, dstTracks)); }