예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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));
        }