示例#1
0
        /// <summary>
        /// Carga de contenido gráfico
        /// </summary>
        protected override void LoadContent()
        {
            base.LoadContent();

            // Información del componente
            BuildingComponentInfo componentInfo = BuildingComponentInfo.Load(this.ComponentsDirectory + this.ComponentInfoName);

            // Modelo
            this.m_ModelName = componentInfo.Model;

            if (!g_ModelDictionary.ContainsKey(componentInfo.Model))
            {
                Model         model      = Content.Load <Model>(this.ComponentsDirectory + this.m_ModelName);
                PrimitiveInfo primitives = model.Tag as PrimitiveInfo;

                GeometryInfo geometry = new GeometryInfo()
                {
                    Model      = model,
                    Primitives = primitives,
                };

                g_ModelDictionary.Add(this.m_ModelName, geometry);
            }

            CollisionBox obb = new CollisionBox(this.TriangleInfo.AABB, 1000000f);

            this.m_CollisionPrimitive = obb;
            this.m_Offset             = Matrix.CreateTranslation(new Vector3(0f, -obb.HalfSize.Y, 0f));

            // Controles de animación
            this.m_AnimationController.AddRange(Animation.CreateAnimationList(this.Model, componentInfo.AnimationControlers));

            // Transformaciones iniciales
            this.m_BoneTransforms = new Matrix[Model.Bones.Count];
        }
        // Find the next Primitive having intersection with cur in overlapping list
        private bool FindIntersection(Geometry cur, ref int start, out PrimitiveInfo topPI, out Geometry topBounds, out Geometry inter)
        {
            topPI     = null;
            topBounds = null;
            inter     = null;

            if (_overlapping == null)
            {
                return(false);
            }

            // If not in a subtree which needs composition, igore overlapping list if all are opaque
            if (!_disjoint)
            {
                bool allopaque = true;

                for (int s = start; s < _overlapping.Count; s++)
                {
                    PrimitiveInfo pi = _commands[_overlapping[s]] as PrimitiveInfo;

                    if ((pi != null) && !pi.primitive.IsTransparent && !pi.primitive.IsOpaque)
                    {
                        allopaque = false;
                        break;
                    }
                }

                if (allopaque)
                {
                    return(false);
                }
            }

            // Search for all possible intersections
            while (start < _overlapping.Count)
            {
                topPI = _commands[_overlapping[start]] as PrimitiveInfo;

                if (!topPI.primitive.IsTransparent) // Skip primitives with nothing to draw
                {
                    topBounds = topPI.primitive.GetClippedShapeGeometry();

                    if (topBounds != null)
                    {
                        bool empty;

                        inter = Utility.Intersect(cur, topBounds, Matrix.Identity, out empty);

                        if (inter != null)
                        {
                            return(true);
                        }
                    }
                }

                start++;
            }

            return(false);
        }
示例#3
0
        /// <summary>
        /// Remove a primitive from display list
        /// </summary>
        /// <param name="i"></param>
        private void DeleteCommand(int i)
        {
#if DEBUG
            Console.WriteLine("Delete command {0}", i);
#endif

            PrimitiveInfo pi = _dl.Commands[i];

            if (pi.overlap != null)
            {
                foreach (int j in pi.overlap)
                {
                    _dl.Commands[j].underlay.Remove(i);
                }
            }

            if (pi.underlay != null)
            {
                bool trans = !pi.primitive.IsOpaque;

                foreach (int j in pi.underlay)
                {
                    if (trans)
                    {
                        _dl.Commands[j].overlapHasTransparency--;
                    }

                    _dl.Commands[j].overlap.Remove(i);
                }
            }

            _dl.Commands[i] = null;
        }
示例#4
0
        /// <summary>
        /// Optimization: If a transparent primitive is covered underneath by an opaque primitive, cut its ties with all primitives before it
        /// </summary>
        /// <param name="pi"></param>
        /// <param name="commands"></param>
        /// <param name="i"></param>
        private static void ReduceTie(PrimitiveInfo pi, List <PrimitiveInfo> commands, int i)
        {
            if ((pi.underlay != null) && !pi.primitive.IsOpaque)
            {
                int len = pi.underlay.Count;

                for (int j = len - 1; j >= 0; j--)
                {
                    PrimitiveInfo qi = commands[pi.underlay[j]];

                    if (qi.primitive.IsOpaque && qi.FullyCovers(pi))
                    {
                        for (int k = j - 1; k >= 0; k--)
                        {
                            int under = pi.underlay[k];

                            commands[under].overlap.Remove(i);
                            commands[under].overlapHasTransparency--;

                            pi.underlay.Remove(under);
                        }

                        break;
                    }
                }
            }
        }
示例#5
0
        public int GetLiteralIndex(object constant)
        {
            int index;

            if (constant is string text)
            {
                var stringInfo = new StringInfo((ushort)GetUtf8Index(text));
                if (!_stringInfos.TryGetValue(stringInfo, out index))
                {
                    index = AddConstant(stringInfo);
                    _stringInfos.Add(stringInfo, index);
                }
            }
            else
            {
                var primitiveInfo = new PrimitiveInfo(constant);
                if (!_primitiveInfos.TryGetValue(primitiveInfo, out index))
                {
                    index = AddConstant(primitiveInfo);
                    _primitiveInfos.Add(primitiveInfo, index);
                }
            }

            return(index);
        }
示例#6
0
        /// <summary>
        /// Switch commands [i] [j], when i is covered by j
        /// </summary>
        /// <param name="commands">Display list</param>
        /// <param name="i">first command</param>
        /// <param name="pi">commands[i]</param>
        /// <param name="j">second command</param>
        /// <param name="pj">command[j]</param>
        /// <param name="disconnect">Disconnect (i,j) overlap/underlay relationship</param>
        static private void SwitchCommands(List <PrimitiveInfo> commands, int i, PrimitiveInfo pi, int j, PrimitiveInfo pj, bool disconnect)
        {
            if ((pi != null) && (pj != null) && disconnect)
            {
                pi.overlap.Remove(j);

                if (!pj.primitive.IsOpaque)
                {
                    pi.overlapHasTransparency--;
                }

                pj.underlay.Remove(i);
            }

            if (pi != null)
            {
                if (pi.overlap != null)
                {
                    foreach (int k in pi.overlap)
                    {
                        commands[k].underlay.Remove(i);
                        commands[k].underlay.Add(j);
                    }
                }

                if (pi.underlay != null)
                {
                    foreach (int k in pi.underlay)
                    {
                        commands[k].overlap.Remove(i);
                        commands[k].overlap.Add(j);
                    }
                }
            }

            if (pj != null)
            {
                if (pj.overlap != null)
                {
                    foreach (int k in pj.overlap)
                    {
                        commands[k].underlay.Remove(j);
                        commands[k].underlay.Add(i);
                    }
                }

                if (pj.underlay != null)
                {
                    foreach (int k in pj.underlay)
                    {
                        commands[k].overlap.Remove(j);
                        commands[k].overlap.Add(i);
                    }
                }
            }

            commands[i] = pj;
            commands[j] = pi;
        }
示例#7
0
        /// <summary>
        /// Add a primitve to display list
        /// </summary>
        /// <param name="p"></param>
        public void RecordPrimitive(Primitive p)
        {
            if (null == _commands)
            {
                _commands = new List <PrimitiveInfo>();
            }

            int index = _commands.Count;

            PrimitiveInfo info = new PrimitiveInfo(p);

            // Skip empty and totally clipped primitive

            bool skip = !Utility.IsRenderVisible(info.bounds) || Utility.Disjoint(p.Clip, info.bounds);

            if (!skip)
            {
                if (!m_DisJoint && (index == 0))
                {
                    // Skip white objects in the front
                    skip = IsWhitePrimitive(p);
                }

                if (!skip)
                {
                    _commands.Add(info);
                }
            }

            if ((p.Clip != null) && Utility.IsRectangle(p.Clip))
            {
                Rect bounds = p.Clip.Bounds;

                if ((bounds.Left <= 0) && (bounds.Top <= 0) &&
                    (bounds.Right >= m_width) && (bounds.Bottom >= m_height))
                {
                    // Remove page full clipping
                    p.Clip = null;
                }
                else if ((bounds.Left <= info.bounds.Left) &&
                         (bounds.Top <= info.bounds.Top) &&
                         (bounds.Right >= info.bounds.Right) &&
                         (bounds.Bottom >= info.bounds.Bottom))
                {
                    // Remove clipping larger than primitive
                    p.Clip = null;
                }
            }
#if DEBUG
            if (skip && (Configuration.Verbose >= 2))
            {
                Console.Write("skip ");

                PrintPrimitive(info, index, true);
            }
#endif
        }
示例#8
0
 public bool Equals(PrimitiveInfo x, PrimitiveInfo y)
 {
     if (ReferenceEquals(x, y))
     {
         return(true);
     }
     if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
     {
         return(false);
     }
     return(x.Value == y.Value);
 }
示例#9
0
        public void ReportOverlapping(int one, int two)
        {
            if (one > two)
            {
                int t = one; one = two; two = t;
            }

            PrimitiveInfo pi = _commands[one];

            if (pi.overlap == null)
            {
                pi.overlap = new List <int>();
            }

            if (OrderedInsert(pi.overlap, two))
            {
                PrimitiveInfo qi = _commands[two];

                if (!qi.primitive.IsTransparent && !qi.primitive.IsOpaque)
                {
                    pi.overlapHasTransparency++;
                }

                // if (! qi.primitive.IsOpaque) // Remember primitves covered by a primitive having transparency
                {
                    if (qi.underlay == null)
                    {
                        qi.underlay = new List <int>();
                    }

                    OrderedInsert(qi.underlay, one);
                }
            }
#if DEBUG
            if (Configuration.Verbose >= 2)
            {
                Console.Write(" <{0} {1}>", one, two);

                overlapcount++;

                if (overlapcount >= 10)
                {
                    Console.WriteLine();
                    overlapcount = 0;
                }
            }
#endif
        }
示例#10
0
        /// <summary>
        /// Bug 1687865
        /// Special optimization for annotation type of visual: lots of glyph runs covered by a single transparency geometry
        ///    t1 ... tn g   => t1 ... tn-1 g tn'
        ///                  => g t1' ... tn'
        /// </summary>
        /// <param name="commands"></param>
        /// <param name="j"></param>
        private static void PushTransparencyDown(List <PrimitiveInfo> commands, int j)
        {
            PrimitiveInfo pj = commands[j];

            GeometryPrimitive gj = pj.primitive as GeometryPrimitive;

            if ((gj == null) || (pj.underlay == null) || (pj.underlay.Count == 0))
            {
                return;
            }

            for (int n = pj.underlay.Count - 1; n >= 0; n--)
            {
                int i = pj.underlay[n];

                PrimitiveInfo pi = commands[i];

                if (pi == null)
                {
                    continue;
                }

                GeometryPrimitive gi = pi.primitive as GeometryPrimitive;

                if ((gi != null) && (gi.Pen == null) && (pi.overlap.Count == 1) && pj.FullyCovers(pi))
                {
                    // c[i] ... c[j] => ... c[j] c[i]'
                    if (BlendCommands(pi, pj)) // pi.Brush = Blend(pi.Brush, pj.Brush)
                    {
                        pj.underlay.Remove(i);

                        pi.overlap = null;
                        pi.overlapHasTransparency = 0;

                        while (i < j)
                        {
                            SwitchCommands(commands, i, commands[i], i + 1, commands[i + 1], false);

                            i++;
                        }

                        j--;
                    }
                }
            }
        }
示例#11
0
        internal void LogInterestingPrimitives(List <PrimitiveInfo> commands, int count, List <Cluster> transparentCluster)
        {
            if (Configuration.Verbose >= 1)
            {
                // Display only interesting primitives

                DisplayList.PrintPrimitive(null, -1, false);

                Rect target = Rect.Empty;

                int vip = 0;

                for (int i = 0; i < count; i++)
                {
                    PrimitiveInfo pi = commands[i];

                    if ((pi != null) && ((pi.overlapHasTransparency != 0) || !pi.primitive.IsOpaque))
                    {
                        if (!pi.primitive.IsOpaque)
                        {
                            target.Union(pi.bounds);
                        }

                        DisplayList.PrintPrimitive(commands[i], i, false);
                        vip++;
                    }
                }

                Console.WriteLine();
                Console.WriteLine("Interesting primitives: {0}", vip);
                Console.WriteLine("Area with transparency: {0}", DisplayList.LeftPad(target, 0));
                Console.WriteLine();

                for (int i = 0; i < transparentCluster.Count; i++)
                {
                    Console.WriteLine(
                        "Cluster {0}: {1} {2} {3}",
                        i + 1,
                        DisplayList.LeftPad(transparentCluster[i].DebugBounds, 0),
                        DisplayList.LeftPad(transparentCluster[i].DebugPrimitives, 0),
                        transparentCluster[i].DebugRasterize);
                }

                Console.WriteLine();
            }
        }
示例#12
0
        private static bool BlendCommands(PrimitiveInfo pi, PrimitiveInfo pj)
        {
            GeometryPrimitive gi = pi.primitive as GeometryPrimitive;
            GeometryPrimitive gj = pj.primitive as GeometryPrimitive;

            if ((gi != null) && (gi.Brush != null) &&
                (gj != null) && (gj.Brush != null))
            {
                // get brushes in world space
                BrushProxy bi = gi.Brush.ApplyTransformCopy(gi.Transform);
                BrushProxy bj = gj.Brush.ApplyTransformCopy(gj.Transform);

                gi.Brush = bi.BlendBrush(bj);

                return(true);
            }

            return(false);
        }
示例#13
0
    public BVH(Bounds[] bounds, Matrix4x4[] transformPositions, ref List <RayTracingSubscriber> subs)
    {
        /*
         * TODO: 1) Create the primInfo for each mesh 2) create the Tree with pointer and SAH 3) Linearize
         */
        this.subs      = subs;
        primitivesInfo = new List <PrimitiveInfo>(transformPositions.Length);

        for (int i = 0; i < transformPositions.Length; i++)
        {
            PrimitiveInfo info = new PrimitiveInfo()
            {
                bounds         = bounds[i],
                primitiveIndex = i
            };

            primitivesInfo.Add(info);
        }

        for (int i = 0; i < nBuckets; i++)
        {
            buckets[i] = new BucketInfo();
        }

        List <RayTracingSubscriber> orderedInfos = new List <RayTracingSubscriber>(primitivesInfo.Count);

        root = RecursiveBuild(0, primitivesInfo.Count, ref orderedInfos);

        // primitivesInfo = orderedInfos;


        subs.Clear();
        subs.AddRange(orderedInfos);

        flatTree = new LBVH[nodeCreated];
        int offset = 0;

        FlattenTree(root, ref offset);
    }
示例#14
0
 public int GetHashCode(PrimitiveInfo obj)
 {
     return(obj.GetHashCode());
 }
        /// <summary>
        /// Calculates list of transparent clusters, returning true if clusters added or bounding rectangles changed.
        /// </summary>
        private static bool CalculateClusterCore(
            List <PrimitiveInfo> commands,
            int count,
            bool disjoint,
            List <int> [] oldUnderlay,
            List <Cluster> transparentCluster,
            bool[] addedPrimitives      // primitives added to clusters
            )
        {
            bool clusterBoundsChanged = false;

            // Build clusters of transparent primitives
            for (int i = 0; i < count; i++)
            {
                PrimitiveInfo pi = commands[i];

                // When disjoint is true (flattening a subtree), add all primitives to a single cluster
                if ((pi != null) && (disjoint || !pi.primitive.IsOpaque) && !addedPrimitives[i])
                {
                    Rect bounds = pi.GetClippedBounds();

                    Cluster home = null;

                    for (int j = 0; j < transparentCluster.Count; j++)
                    {
                        Cluster c = transparentCluster[j];

                        if (disjoint || bounds.IntersectsWith(c.m_bounds))
                        {
                            home = c;
                            break;
                        }
                    }

                    if (home == null)
                    {
                        home = new Cluster();
                        transparentCluster.Add(home);
                    }

                    Rect oldClusterBounds = home.m_bounds;

                    home.Add(i, oldUnderlay, commands, addedPrimitives);

                    if (!clusterBoundsChanged && oldClusterBounds != home.m_bounds)
                    {
                        // cluster bounds have changed
                        clusterBoundsChanged = true;
                    }
                }
            }

            // Merges clusters which touch each other
            bool changed;

            do
            {
                changed = false;

                for (int i = 0; i < transparentCluster.Count; i++)
                {
                    for (int j = i + 1; j < transparentCluster.Count; j++)
                    {
                        if (transparentCluster[i].m_bounds.IntersectsWith(transparentCluster[j].m_bounds))
                        {
                            transparentCluster[i].MergeWith(transparentCluster[j]);

                            // cluster bounds have changed since merging two clusters
                            clusterBoundsChanged = true;

                            transparentCluster.RemoveAt(j);
                            changed = true;
                            break;
                        }
                    }
                }
            }while (changed);

            return(clusterBoundsChanged);
        }
        /// <summary>
        /// Check if the whole cluster is complex enough such that rasterizing the whole thing is better than flattening it
        /// </summary>
        /// <param name="commands"></param>
        /// <returns></returns>
        private bool BetterRasterize(List <PrimitiveInfo> commands)
        {
            double clustersize = m_bounds.Width * m_bounds.Height;

            double diff = -Configuration.RasterizationCost(m_bounds.Width, m_bounds.Height);

            // Estimate cost of geometry operations (intersecting)
            double pathComplexity = 1;

            foreach (int i in m_primitives)
            {
                PrimitiveInfo pi = commands[i];

                Primitive p = pi.primitive;

                GeometryPrimitive gp = p as GeometryPrimitive;

                Rect bounds = pi.GetClippedBounds();

                bool rasterize = true;

                if (gp != null)
                {
                    double complexity = 1;

                    Geometry geo = gp.Geometry;

                    if (geo != null)
                    {
                        complexity = Utility.GetGeometryPointCount(geo);

                        // weight down the complexity of small region
                        complexity *= bounds.Width * bounds.Height / clustersize;
                    }

                    BrushProxy bp = gp.Brush;

                    if (bp == null)
                    {
                        bp = gp.Pen.StrokeBrush;

                        // Widen path would at least double the points
                        complexity *= 3;
                    }

                    if (complexity > 1)
                    {
                        pathComplexity *= complexity;

                        if (pathComplexity > 100000) // 333 x 333
                        {
                            return(true);
                        }
                    }

                    if (bp != null)
                    {
                        Brush b = bp.Brush;

                        if ((b != null) && ((b is SolidColorBrush) || (b is LinearGradientBrush)))
                        {
                            // SolidColorBrush does not need full rasterization
                            // Vertical/Horizontal linear gradient brush does not need full rasterization
                            rasterize = false;
                        }
                    }
                }

                if (rasterize)
                {
                    diff += Configuration.RasterizationCost(bounds.Width, bounds.Height);

                    if (diff > 0)
                    {
                        break;
                    }
                }
            }

            return(diff > 0);
        }
        public static List <Cluster> CalculateCluster(List <PrimitiveInfo> commands, int count, bool disjoint, List <int>[] oldUnderlay)
        {
            List <Cluster> transparentCluster = new List <Cluster>();

            // indicates which primitives have been added to any cluster
            bool[] addedPrimitives = new bool[commands.Count];

            // calculate clusters until cluster bounds stabilize
            while (true)
            {
                bool clusterBoundsChanged = CalculateClusterCore(
                    commands,
                    count,
                    disjoint,
                    oldUnderlay,
                    transparentCluster,
                    addedPrimitives
                    );

                if (!clusterBoundsChanged || GetPrimitiveIntersectAction() != PrimitiveIntersectAction.AddToCluster)
                {
                    break;
                }

                //
                // Cluster bounds have changed somewhere, need to examine all primitives that haven't
                // been added to a cluster and test for intersection with cluster. We add primitives
                // that intersect and rendered before the cluster.
                //
                // Note that here we check even opaque primitives, since they might get covered
                // by a transparent cluster, and thus need to be rasterized with a cluster if intersection
                // exists.
                //
                for (int primIndex = 0; primIndex < addedPrimitives.Length; primIndex++)
                {
                    if (!addedPrimitives[primIndex] && commands[primIndex] != null)
                    {
                        PrimitiveInfo primitive = commands[primIndex];

                        for (int clusterIndex = 0; clusterIndex < transparentCluster.Count; clusterIndex++)
                        {
                            Cluster cluster = transparentCluster[clusterIndex];

                            if (primitive.GetClippedBounds().IntersectsWith(cluster.m_bounds) &&
                                primIndex < cluster.m_lowestPrimitive)
                            {
                                // primitive intersects this cluster, add to cluster
                                cluster.Add(
                                    primIndex,
                                    oldUnderlay,
                                    commands,
                                    addedPrimitives
                                    );
                            }
                        }
                    }
                }
            }

            return(transparentCluster);
        }
        // Recursive
        // _brush must be in world space
        private void FillGeometry(
            PrimitiveInfo topPI,
            Geometry cur,
            string desp,
            Geometry curAlt,
            string despAlt,
            int start,
            Geometry inter,
            Geometry topBounds
            )
        {
            Primitive p    = topPI.primitive;
            Geometry  diff = Utility.Exclude(cur, topBounds, Matrix.Identity);

            if (diff != null)
            {
                // Render cur [- topBounds] using original brush

                if (_disjoint)
                {
#if DEBUG
                    FillGeometry(diff, Oper(desp, '-', topPI.id), null, null, start + 1);
#else
                    FillGeometry(diff, null, null, null, start + 1);
#endif
                }
                else
                {
                    // Only diff = cur - topBounds need to be rendered. But it may generate more
                    // complicated path and gaps between objects

                    if (curAlt != null)
                    {
#if DEBUG
                        FillGeometry(diff, Oper(desp, '-', topPI.id), curAlt, despAlt, start + 1);
#else
                        FillGeometry(diff, null, curAlt, despAlt, start + 1);
#endif
                    }
                    else
                    {
#if DEBUG
                        FillGeometry(diff, Oper(desp, '-', topPI.id), cur, desp, start + 1);
#else
                        FillGeometry(diff, null, cur, desp, start + 1);
#endif
                    }
                }
            }

            //if (_disjoint || ! p.IsOpaque)
            {
                if (topPI.primitive is ImagePrimitive)
                {
                    // If primitve on the top is ImagePrimitive, change it to DrawImage with blended image.
                    // An alternative will be generating an image brush

                    ImagePrimitive ip = topPI.primitive as ImagePrimitive;

                    bool empty;

                    double imageWidth  = ip.Image.Image.Width;
                    double imageHeight = ip.Image.Image.Height;

                    // Get clip in world space.
                    Geometry clip = Utility.Intersect(inter, Utility.TransformGeometry(new RectangleGeometry(ip.DstRect), ip.Transform), ip.Transform, out empty);

                    if (!empty)
                    {
                        // Get clip bounds in image space.
                        Geometry clipImageSpace = Utility.TransformGeometry(clip, ReverseMap(ip.Transform, ip.DstRect, imageWidth, imageHeight));
                        Rect     drawBounds     = clipImageSpace.Bounds;

                        // Clip image data to the intersection. Resulting draw bounds are in image space.
                        BitmapSource clippedImage = ip.Image.GetClippedImage(drawBounds, out drawBounds);
                        if (clippedImage != null)
                        {
                            // Transform draw bounds back to world space.
                            drawBounds.Scale(ip.DstRect.Width / imageWidth, ip.DstRect.Height / imageHeight);
                            drawBounds.Offset(ip.DstRect.Left, ip.DstRect.Top);

                            ImageProxy image = new ImageProxy(clippedImage);

                            // Blend image with other brush, then render composited image.
                            image.BlendOverBrush(false, _brush, ReverseMap(ip.Transform, drawBounds, image.PixelWidth, image.PixelHeight));

#if DEBUG
                            RenderImage(image, drawBounds, clip, true, start + 1, ip.Transform, Oper(desp, '*', topPI.id));
#else
                            RenderImage(image, drawBounds, clip, true, start + 1, ip.Transform, null);
#endif
                        }
                    }
                }
                else
                {
                    // -- If top primitive opaque, skip the intersection
                    // -- If current primitive is completely covered by an opaque object, skip the intersection
                    if (p.IsOpaque) // && Utility.Covers(topBounds, cur))
                    {
                        cur = null;
                    }
                    else
                    {
                        // Render the intersection using blended brush
                        BrushProxy oldbrush = _brush;

                        _brush = p.BlendBrush(_brush);

#if DEBUG
                        FillGeometry(inter, Oper(desp, '*', topPI.id), null, null, start + 1);
#else
                        FillGeometry(inter, null, null, null, start + 1);
#endif

                        _brush = oldbrush;
                    }
                }

                if (cur != null)
                {
                    bool empty;

                    Geometry geo = Utility.Intersect(cur, _clip, Matrix.Identity, out empty);

                    if (geo != null)
                    {
                        topPI.primitive.Exclude(geo); // exclude cur & _clip

#if DEBUG
                        topPI.id = Oper(topPI.id, '-', Oper(desp, '*', Oper(desp, '.', "c")));
#endif
                    }
                }
            }
        }
示例#19
0
        static internal void PrintPrimitive(PrimitiveInfo info, int index, bool verbose)
        {
            if (index < 0)
            {
                Console.WriteLine();

                Console.WriteLine(" No      Type           Und Ovr TrO           Bounding Box                   Clipping");

                if (verbose)
                {
                    Console.Write("                     Transform");
                }

                Console.WriteLine();
                return;
            }

            Primitive p = info.primitive;

            string typ = p.GetType().ToString();

            typ = typ.Substring(typ.LastIndexOf('.') + 1);

            Console.Write(LeftPad(index, 4) + LeftPad(typ, 18) + ":");

            List <int> extra = null;

            if (p.IsOpaque)
            {
                Console.Write(' ');
            }
            else
            {
                Console.Write('@');
            }

            if (info.underlay == null)
            {
                Console.Write("   ");
            }
            else
            {
                extra = info.underlay;

                Console.Write(LeftPad(info.underlay.Count, 3));
            }

            if (info.overlap != null)
            {
                Console.Write(' ' + LeftPad(info.overlap.Count, 3));

                if (info.overlapHasTransparency != 0)
                {
                    Console.Write('$');
                    Console.Write(LeftPad(info.overlapHasTransparency, 3));
                }
                else
                {
                    Console.Write("    ");
                }

                Console.Write(' ');
            }
            else
            {
                Console.Write("         ");
            }

            Console.Write(LeftPad(info.bounds, 0));

            Geometry clip = p.Clip;

            if (clip != null)
            {
                Console.Write(LeftPad(clip.Bounds, 0));
            }

            if (verbose)
            {
                Matrix m = p.Transform;

                Console.Write(" {");
                Console.Write(LeftPad(m.M11, 3) + ' ');
                Console.Write(LeftPad(m.M12, 3) + ' ');
                Console.Write(LeftPad(m.M21, 3) + ' ');
                Console.Write(LeftPad(m.M22, 3) + ' ');
                Console.Write(LeftPad(m.OffsetX, 6) + ' ');
                Console.Write(LeftPad(m.OffsetY, 6));
                Console.Write("} ");
            }

            if (verbose)
            {
                GlyphPrimitive gp = p as GlyphPrimitive;

                if (gp != null)
                {
                    IList <char> chars = gp.GlyphRun.Characters;

                    Console.Write(" \"");

                    for (int i = 0; i < chars.Count; i++)
                    {
                        Console.Write(chars[i]);
                    }

                    Console.Write('"');
                }
            }

            if (verbose)
            {
                GeometryPrimitive gp = p as GeometryPrimitive;

                if ((gp != null) && (gp.Brush != null) && (gp.Pen == null))
                {
                    Brush b = gp.Brush.Brush;

                    if (b != null)
                    {
                        SolidColorBrush sb = b as SolidColorBrush;

                        if (sb != null)
                        {
                            Console.Write(" SolidColorBrush({0})", sb.Color);
                        }
                    }
                }
            }

            if (extra != null)
            {
                Console.Write(' ');
                Console.Write(LeftPad(extra, 0));
            }

            Console.WriteLine();
        }
示例#20
0
        /// <summary>
        /// Resolve object overlapping in a primitive tree.
        /// Send broken down drawing primitives to _dc.
        /// </summary>
        /// <param name="dc"></param>
        /// <param name="disjoint">True if all output primitives need to be disjoint</param>
        public void AlphaFlatten(IProxyDrawingContext dc, bool disjoint)
        {
            List <PrimitiveInfo> commands = _dl.Commands;

            if (commands == null)
            {
                return;
            }

            int count = commands.Count;

            _dc = dc;

            bool needFlattening = true;

            if (Configuration.BlendAlphaWithWhite || Configuration.ForceAlphaOpaque)
            {
                needFlattening = false;
            }
            else if (!disjoint)
            {
                needFlattening = false;

                for (int i = 0; i < count; i++)
                {
                    PrimitiveInfo info = commands[i];

                    if (!info.primitive.IsOpaque)
                    {
                        needFlattening = true;
                        break;
                    }
                }
            }

            if (needFlattening)
            {
#if DEBUG
                Console.WriteLine();
                Console.WriteLine("Stage 2: Calculating intersections using bounding boxes");
                Console.WriteLine();
#endif
                // Still need all the primitive, for removal by opaque covering and white primitive removal
                _dl.CalculateIntersections(count);
            }

#if DEBUG
            if (Configuration.Verbose >= 2)
            {
                Console.WriteLine();
                Console.WriteLine("Original display list");
                Console.WriteLine();

                DisplayList.PrintPrimitive(null, -1, true);

                for (int i = 0; i < count; i++)
                {
                    DisplayList.PrintPrimitive(commands[i], i, true);
                }

                Console.WriteLine();

                Console.WriteLine("Primitives in display list: {0}", count);

                Console.WriteLine();
            }
#endif

            if (needFlattening)
            {
                DisplayListOptimization(commands, count, disjoint);
            }

#if DEBUG
            for (int i = 0; i < count; i++)
            {
                if (commands[i] != null)
                {
                    commands[i].SetID(i);
                }
            }

            Console.WriteLine();
            Console.WriteLine("Stage 4: Alpha flattening");
            Console.WriteLine();
#endif
            for (int i = 0; i < count; i++)
            {
                PrimitiveInfo info = commands[i];

                if (info == null)
                {
                    continue;
                }

                String desp = null;
#if DEBUG
                if (Configuration.Verbose >= 2)
                {
                    Console.Write(i);
                    Console.Write(": ");
                }

                desp = info.id;
#endif

                if (info.m_cluster != null)
                {
                    info.m_cluster.Render(commands, dc);
                }
                else
                {
                    AlphaRender(info.primitive, info.overlap, info.overlapHasTransparency, disjoint, desp);
                }

#if DEBUG
                if (Configuration.Verbose >= 2)
                {
                    Console.WriteLine("");
                }
#endif
            }

            _dc = null;
        }
示例#21
0
        /// <summary>
        /// Optimization phase
        /// </summary>
        /// <param name="commands"></param>
        /// <param name="count"></param>
        /// <param name="disjoint"></param>
        private void DisplayListOptimization(List <PrimitiveInfo> commands, int count, bool disjoint)
        {
#if DEBUG
            Console.WriteLine();
            Console.WriteLine("Start 3: Display list optimization");
            Console.WriteLine();
#endif
            List <int> [] oldUnderlay = null;

            if (!disjoint) // If not in a subtree which needs full flattening
            {
                // The following optimization may change PrimitiveInfo.underlay, but this is needed
                // for cluster calcuation. So we make a copy of it for use within this routine only
                oldUnderlay = CopyUnderlay(count, commands);

                // These optimizations need to run in a seperate pass, because they may affect other primitives
                for (int i = 0; i < count; i++)
                {
repeat:
                    PrimitiveInfo pi = commands[i];

                    if (pi == null)
                    {
                        continue;
                    }

                    // Optimization: If a primitive is covered by an opaque primtive, delete it
                    if (pi.overlap != null)
                    {
                        bool deleted = false;

                        for (int j = 0; j < pi.overlap.Count; j++)
                        {
                            PrimitiveInfo qi = commands[pi.overlap[j]];

                            if (qi.primitive.IsOpaque && qi.FullyCovers(pi))
                            {
                                DeleteCommand(i);
                                deleted = true;
                                break;
                            }
                        }

                        if (deleted)
                        {
                            continue;
                        }
                    }

                    // Optimization: If a primitive is covered by overlap[0], blend brush and switch order
                    // This results in smaller area being rendered as blending of two brushes.
                    if ((pi.overlap != null) && (pi.overlap.Count != 0))
                    {
                        int j = pi.overlap[0]; // first overlapping primitive

                        PrimitiveInfo pj = commands[j];

                        // Do not attempt to blend if both primitives cover exactly same area, since blending
                        // one into the other provides no benefits.
                        if ((pj.underlay[pj.underlay.Count - 1] == i) && pj.FullyCovers(pi) && !pi.FullyCovers(pj))
                        {
                            if (BlendCommands(pi, pj))
                            {
                                SwitchCommands(commands, i, pi, j, pj, true);
                                goto repeat; // pj at position i needs to be processed
                            }
                        }
                    }

                    // Optimization: Delete white primitives with nothing underneath
                    if ((pi.underlay == null) && DisplayList.IsWhitePrimitive(pi.primitive))
                    {
                        DeleteCommand(i);

                        continue;
                    }

                    // Optimization: If a transparent primitive is covered underneath by an opaque primitive, cut its ties with all primitives before it
                    ReduceTie(pi, commands, i);

                    // Transparent primitive
                    if (!pi.primitive.IsOpaque)
                    {
                        // Optimization: If a transparent primitive is covered underneath immediately by an opaque primitive,
                        // or has nothing underneath, convert it to opaque primitive
                        if (!ConvertTransparentOnOpaque(commands, i))
                        {
                            PushTransparencyDown(commands, i);
                        }
                    }
                }

                for (int i = 0; i < count; i++)
                {
                    PrimitiveInfo pi = commands[i];

                    if (pi == null)
                    {
                        continue;
                    }

                    // Optimization: If a primitive is covered by all opaque primitives, cut its ties with primitive on top of it.

                    // This check is also implemented in PrimitiveRender.FindIntersection,
                    // in which it is on a remaing items in overlapping list.
                    // With overlapHasTransparency flag, it can be moved forward.

                    if ((pi.overlap != null) && (pi.overlapHasTransparency == 0))
                    {
                        foreach (int j in pi.overlap)
                        {
                            commands[j].underlay.Remove(i);
                        }

                        pi.overlap = null;
                    }

                    // Optimization: If an opaque primitive is covered by all opaque primitives, cut its ties with primitives under it.
                    if ((pi.underlay != null) && (pi.overlapHasTransparency == 0) && pi.primitive.IsOpaque)
                    {
                        foreach (int j in pi.underlay)
                        {
                            commands[j].overlap.Remove(i);
                        }

                        pi.underlay = null;
                    }
                }
            }

            List <Cluster> transparentCluster = Cluster.CalculateCluster(commands, count, disjoint, oldUnderlay);

            Cluster.CheckForRasterization(transparentCluster, commands);

#if DEBUG
            if (HasUnmanagedCodePermission())
            {
                LogInterestingPrimitives(commands, count, transparentCluster);
                SaveInterestingPrimitives(commands, count, transparentCluster);
            }
#endif
        }
示例#22
0
        /// <summary>
        /// Optimization: If a transparent primitive is covered underneath immediately by an opaque primitive,
        /// or has nothing underneath, convert it to opaque primitive
        /// </summary>
        /// <param name="commands"></param>
        /// <param name="i"></param>
        private static bool ConvertTransparentOnOpaque(List <PrimitiveInfo> commands, int i)
        {
            PrimitiveInfo pi = commands[i];

            GeometryPrimitive gp = pi.primitive as GeometryPrimitive;

            if (gp != null)
            {
                PrimitiveInfo qi = null;

                if ((pi.underlay != null) && (pi.underlay.Count != 0))
                {
                    qi = commands[pi.underlay[pi.underlay.Count - 1]];
                }

                if ((qi == null) || (qi.primitive.IsOpaque && qi.FullyCovers(pi)))
                {
                    BrushProxy under = BrushProxy.CreateColorBrush(Colors.White);

                    if (qi != null)
                    {
                        GeometryPrimitive qp = qi.primitive as GeometryPrimitive;

                        if (qp != null)
                        {
                            under = qp.Brush;
                        }
                    }

                    if (under != null)
                    {
                        // Blend it with brush underneath
                        BrushProxy blendedBrush    = gp.Brush;
                        BrushProxy blendedPenBrush = gp.Pen == null ? null : gp.Pen.StrokeBrush;

                        if (blendedBrush != null)
                        {
                            blendedBrush = under.BlendBrush(blendedBrush);
                        }
                        else if (blendedPenBrush != null)
                        {
                            blendedPenBrush = under.BlendBrush(blendedPenBrush);
                        }

                        //
                        // Fix bug 1293500:
                        // Allow blending to proceed only if we did not generate pen stroke
                        // brush that is a brush list. Reason: Such a case would have to be
                        // handled during rendering by stroking the object with each brush
                        // in the list. But we're already rendering brushes of underlying
                        // objects, so the optimization is pointless.
                        //
                        bool proceedBlending = true;

                        if (blendedPenBrush != null && blendedPenBrush.BrushList != null)
                        {
                            proceedBlending = false;
                        }

                        if (proceedBlending)
                        {
                            gp.Brush = blendedBrush;
                            if (gp.Pen != null)
                            {
                                gp.Pen.StrokeBrush = blendedPenBrush;
                            }
                        }

                        if (proceedBlending && pi.primitive.IsOpaque)
                        {
#if DEBUG
                            Console.WriteLine("Make {0} opaque", i);
#endif

                            if (pi.underlay != null)
                            {
                                for (int k = 0; k < pi.underlay.Count; k++)
                                {
                                    commands[pi.underlay[k]].overlapHasTransparency--;
                                }
                            }

                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
示例#23
0
        /// <summary>
        /// Carga de contenido gráfico
        /// </summary>
        protected override void LoadContent()
        {
            base.LoadContent();

            // Información del componente
            VehicleComponentInfo componentInfo = VehicleComponentInfo.Load(Path.Combine(this.AssetsFolder, this.ComponentInfoName));

            // Modelo
            this.m_ModelName = componentInfo.Model;

            if (!g_ModelDictionary.ContainsKey(componentInfo.Model))
            {
                Model         model      = Content.Load <Model>(Path.Combine(this.AssetsFolder, this.m_ModelName));
                PrimitiveInfo primitives = model.Tag as PrimitiveInfo;

                GeometryInfo geometry = new GeometryInfo()
                {
                    Model      = model,
                    Primitives = primitives,
                };

                g_ModelDictionary.Add(this.m_ModelName, geometry);
            }

            CollisionBox box = new CollisionBox(this.TriangleInfo.AABB, 1000f);

            this.m_CollisionPrimitive = box;
            this.m_Offset             = Matrix.CreateTranslation(new Vector3(0f, -box.HalfSize.Y, 0f));

            // Integridad
            this.BaseHull = this.Hull = componentInfo.Hull;
            // Blindaje
            this.BaseArmor = this.Armor = componentInfo.Armor;

            // Altura máxima de vuelo
            this.Engine.InitialMaxFlightHeight = componentInfo.MaxFlightHeight;
            // Altura mínima de vuelo
            this.Engine.InitialMinFlightHeight = componentInfo.MinFlightHeight;

            // Velocidad máxima que puede alcanzar el vehículo hacia delante
            this.Engine.MaxForwardVelocity = componentInfo.MaxForwardVelocity;
            // Velocidad máxima que puede alcanzar el vehículo marcha atrás
            this.Engine.MaxBackwardVelocity = componentInfo.MaxBackwardVelocity;
            // Modificador de aceleración
            this.Engine.AccelerationModifier = componentInfo.AccelerationModifier;
            // Modificador de frenado
            this.Engine.BrakeModifier = componentInfo.BrakeModifier;
            // Velocidad angular
            this.Engine.AngularVelocityModifier = MathHelper.ToRadians(componentInfo.AngularVelocityModifier);
            // Vehículo volador
            this.Engine.Skimmer = componentInfo.Skimmer;
            // Altura máxima
            this.Engine.MaxFlightHeight = componentInfo.MaxFlightHeight;
            // Altura mínima
            this.Engine.MinFlightHeight = componentInfo.MinFlightHeight;
            // Rotación ascendente del morro
            this.Engine.AscendingAngle = MathHelper.ToRadians(componentInfo.AscendingAngle);
            // Rotación descendente del morro
            this.Engine.DescendingAngle = MathHelper.ToRadians(componentInfo.DescendingAngle);
            // Controles de animación
            this.m_AnimationController.AddRange(Animation.Animation.CreateAnimationList(this.Model, componentInfo.AnimationControlers));
            // Posiciones
            this.m_PlayerControlList.AddRange(Animation.PlayerPosition.CreatePlayerPositionList(this.Model, componentInfo.PlayerPositions));
            // Armas
            this.m_WeapontList.AddRange(Weapon.CreateWeaponList(this.Model, componentInfo.Weapons));
            // Emisores de partículas
            this.m_ParticleEmitterList.AddRange(ParticleEmitter.CreateParticleEmitterList(this.Model, componentInfo.ParticleEmitters));

            // Transformaciones iniciales
            this.m_BoneTransforms = new Matrix[this.Model.Bones.Count];
        }
示例#24
0
        internal void SaveInterestingPrimitives(List <PrimitiveInfo> commands, int count, List <Cluster> transparentCluster)
        {
            if (Configuration.SerializePrimitives)
            {
                // render primitives to DrawingVisual
                DrawingVisual dv = new DrawingVisual();

                using (DrawingContext ctx = dv.RenderOpen())
                {
                    Pen black = new Pen(Brushes.Black, 0.8);
                    black.DashStyle = DashStyles.Dash;

                    for (int i = 0; i < count; i++)
                    {
                        PrimitiveInfo pi = commands[i];

                        if ((pi != null) && ((pi.overlapHasTransparency != 0) || !pi.primitive.IsOpaque))
                        {
                            pi.primitive.OnRender(ctx);

                            if (!pi.primitive.IsOpaque)
                            {
                                ctx.DrawRectangle(null, black, pi.bounds);
                            }

                            //                          Rect bounds = pi.bounds;

                            //                          Console.WriteLine("<RectangleGeometry Canvas.Left=\"{0}\" Canvas.Top=\"{1}\" Width=\"{2}\" Height=\"{3}\" Fill=\"#FFFFFFFF\" />",
                            //                              bounds.Left, bounds.Top, bounds.Width, bounds.Height);
                        }
                    }

                    Pen pen = new Pen(Brushes.Blue, 0.8);

                    pen.DashStyle = DashStyles.Dot;

                    for (int i = 0; i < transparentCluster.Count; i++)
                    {
                        ctx.DrawRectangle(null, pen, transparentCluster[i].DebugBounds);
                    }
                }

                // save visual to xaml
                string name = "vip.xaml";

                for (int i = 0; (name != null) && (i < 10); i++)
                {
                    try
                    {
                        if (vipID != 0)
                        {
                            name = "vip" + vipID + ".xaml";
                        }

                        SerializeVisual(dv, _dl.m_width, _dl.m_height, name);

                        Console.WriteLine("Serialized primitives to " + name);

                        name = null;
                    }
                    catch (System.IO.IOException e)
                    {
                        Console.WriteLine(e.ToString());

                        name = "vip" + vipID + ".xaml";
                    }

                    vipID++;
                }
            }
        }