Beispiel #1
0
        private static SEntry BuildSEntry(tSentry sEntry)
        {
            var result = new SEntry(sEntry.name);

            if (sEntry.ifPart != null)
            {
                result.IfPart = new IfPart
                {
                    Condition = sEntry.ifPart.condition.Text.First()
                };
            }

            if (sEntry.Items != null)
            {
                foreach (var onPart in sEntry.Items)
                {
                    if (onPart is tPlanItemOnPart)
                    {
                        var planItemOnPart = onPart as tPlanItemOnPart;
                        var name           = Enum.GetName(typeof(PlanItemTransition), planItemOnPart.standardEvent);
                        var standardEvt    = (CMMNTransitions)Enum.Parse(typeof(CMMNTransitions), name, true);
                        result.PlanItemOnParts.Add(new PlanItemOnPart
                        {
                            SourceRef     = planItemOnPart.sourceRef,
                            StandardEvent = standardEvt
                        });
                    }
                    else if (onPart is tCaseFileItemOnPart)
                    {
                        var caseFileItemOnPart = onPart as tCaseFileItemOnPart;
                        var name        = Enum.GetName(typeof(CaseFileItemTransition), caseFileItemOnPart.standardEvent);
                        var standardEvt = (CMMNTransitions)Enum.Parse(typeof(CMMNTransitions), name, true);
                        result.FileItemOnParts.Add(new CaseFileItemOnPart
                        {
                            SourceRef     = caseFileItemOnPart.sourceRef,
                            StandardEvent = standardEvt
                        });
                    }
                }
            }

            return(result);
        }
Beispiel #2
0
        /**
         * Scan pruning tree for intersection with a bounding box.
         *
         * This method is a iterative implementation of the following algorithm:
         *
         * procedure scan(level, box, result)
         * for each $cell in $level
         *     $inter = intersects($cell, $box)
         *
         *     if $inter = INTERSECTS and $cell is not contained and $level != 0
         *         $inter = scan($level -1, box, $result)
         *
         *     switch on $inter
         *         case INTERSECTS
         *             return INTERSECTS
         *
         *         case CONTAINED
         *             if $result == DISJOINT
         *                 return INTERSECTS
         *             $result = CONTAINED
         *
         *         case DISJOINT
         *             if $result == CONTAINED
         *                 return INTERSECTS
         *             $result = DISJOINT
         * return $result
         */
        public ContainmentType QueryHeight(ref BoundingBox query)
        {
            // Fallback in case the user loads a bad heightmap.
            if (PruningTree == null)
            {
                return(ContainmentType.Intersects);
            }

            if (m_queryStack == null || m_queryStack.Length < PruningTree.Length)
            {
                m_queryStack = new SEntry[PruningTree.Length];
            }

            if (query.Min.Z > Root.Max)
            {
                return(ContainmentType.Disjoint);
            }
            if (query.Max.Z < Root.Min)
            {
                return(ContainmentType.Contains);
            }

            if (query.Max.X < 0 || query.Max.Y < 0 || query.Min.X > 1 || query.Min.Y > 1)
            {
                return(ContainmentType.Disjoint);
            }

            // Handle minimum size heightmaps
            if (PruningTree.Length == 0)
            {
                return(ContainmentType.Intersects);
            }

            if (query.Max.X == 1.0)
            {
                query.Max.X = .99999999f;
            }
            if (query.Max.Y == 1.0)
            {
                query.Max.Y = .99999999f;
            }

            // state variables;
            ContainmentType result = ContainmentType.Intersects;

            float maxSize = Math.Max(query.Width, query.Height);

            // If the box is really small we can be even more precise by checking the heightmap directly.
            if (maxSize < m_pixelSizeFour)
            {
                // compute an inflated box so we account for smoothing :)
                Box2I bb = new Box2I(ref query, (uint)Resolution);
                bb.Min -= 1;
                bb.Max += 1;
                bb.Intersect(ref m_bounds);

                int min = (int)(query.Min.Z * ushort.MaxValue);
                int max = (int)(query.Max.Z * ushort.MaxValue);

                ushort height;

                GetValue(bb.Min.X, bb.Min.Y, out height);

                if (height > max)
                {
                    result = ContainmentType.Contains;
                }
                else if (height < min)
                {
                    result = ContainmentType.Disjoint;
                }
                else
                {
                    return(ContainmentType.Intersects);
                }

                int mmin = ushort.MaxValue, mmax = 0;

                for (int y = bb.Min.Y; y <= bb.Max.Y; ++y)
                {
                    for (int x = bb.Min.X; x <= bb.Max.X; ++x)
                    {
                        GetValue(x, y, out height);

                        if (height > mmax)
                        {
                            mmax = height;
                        }
                        if (height < mmin)
                        {
                            mmin = height;
                        }
                    }
                }

                int diff = mmax - mmin;

                diff += diff >> 1;

                mmax += diff;

                mmin -= diff;

                if (min > mmax)
                {
                    return(ContainmentType.Disjoint);
                }
                if (max < mmin)
                {
                    return(ContainmentType.Contains);
                }

                return(ContainmentType.Intersects);
            }

            double log = Math.Log(maxSize * (Resolution / HeightmapNode.HEIGHTMAP_LEAF_SIZE)) / Math.Log(HeightmapNode.HEIGHTMAP_BRANCH_FACTOR);

            uint level = (uint)MathHelper.Clamp(log, 0, PruningTree.Length - 1);

            // stack index
            int ss = 0;
            var st = m_queryStack;

            Box2I rootBounds = new Box2I(Vector2I.Zero, new Vector2I((int)PruningTree[level].Res - 1));

            st[0].Bounds = new Box2I(ref query, PruningTree[level].Res);
            st[0].Bounds.Intersect(ref rootBounds);
            st[0].Next     = st[0].Bounds.Min;
            st[0].Level    = level;
            st[0].Result   = result;
            st[0].Continue = false;

scan:
            while (true)
            {
                SEntry state;
                if (ss == -1)
                {
                    break;
                }
                else
                {
                    state = st[ss];
                }

                for (int y = state.Next.Y; y <= state.Bounds.Max.Y; ++y)
                {
                    for (int x = state.Bounds.Min.X; x <= state.Bounds.Max.X; ++x)
                    {
                        if (!state.Continue)
                        {
                            state.Intersection = PruningTree[state.Level].Intersect(x, y, ref query);

                            if (state.Intersection == ContainmentType.Intersects && PruningTree[state.Level].IsCellNotContained(x, y, ref query) &&
                                state.Level != 0)
                            {
                                state.Next     = new Vector2I(x, y);
                                state.Continue = true;
                                st[ss]         = state;
                                ss++;
                                st[ss] = new SEntry(ref query, PruningTree[state.Level - 1].Res, new Vector2I(x, y), state.Result, state.Level - 1);
                                goto scan;
                            }
                        }
                        else
                        {
                            state.Continue = false;
                            x = state.Next.X;
                        }

                        switch (state.Intersection)
                        {
                        case ContainmentType.Intersects:
                            state.Result = ContainmentType.Intersects;
                            goto ret;
                            break;

                        case ContainmentType.Disjoint:
                            if (state.Result == ContainmentType.Contains)
                            {
                                state.Result = ContainmentType.Intersects;
                                goto ret;
                            }
                            state.Result = ContainmentType.Disjoint;
                            break;

                        case ContainmentType.Contains:
                            if (state.Result == ContainmentType.Disjoint)
                            {
                                state.Result = ContainmentType.Intersects;
                                goto ret;
                            }
                            state.Result = ContainmentType.Contains;
                            break;
                        }
                    }
                }

                ret :;
                result = state.Result;
                ss--;
                if (ss >= 0)
                {
                    st[ss].Intersection = result;
                }
            }

            return(result);
        }
Beispiel #3
0
        public unsafe ContainmentType QueryHeight(ref BoundingBox query)
        {
            ContainmentType intersects;
            int             num3;

            SEntry[] queryStack;
            SEntry   entry;
            int      y;
            int      x;

            if (this.PruningTree == null)
            {
                return(ContainmentType.Intersects);
            }
            if ((m_queryStack == null) || (m_queryStack.Length < this.PruningTree.Length))
            {
                m_queryStack = new SEntry[this.PruningTree.Length];
            }
            if (query.Min.Z > this.Root.Max)
            {
                return(ContainmentType.Disjoint);
            }
            if (query.Max.Z < this.Root.Min)
            {
                return(ContainmentType.Contains);
            }
            if (query.Max.X < 0f)
            {
                goto TR_0003;
            }
            else if (query.Max.Y < 0f)
            {
                goto TR_0003;
            }
            else if ((query.Min.X <= 1f) && (query.Min.Y <= 1f))
            {
                if (this.PruningTree.Length == 0)
                {
                    return(ContainmentType.Intersects);
                }
                if (query.Max.X == 1.0)
                {
                    query.Max.X = 1f;
                }
                if (query.Max.Y == 1.0)
                {
                    query.Max.Y = 1f;
                }
                intersects = ContainmentType.Intersects;
                float num = Math.Max(query.Width, query.Height);
                if (num < this.m_pixelSizeFour)
                {
                    ushort    num6;
                    Box2I     boxi2       = new Box2I(ref query, (uint)this.Resolution);
                    Vector2I *vectoriPtr1 = (Vector2I *)ref boxi2.Min;
                    vectoriPtr1[0] -= 1;
                    Vector2I *vectoriPtr2 = (Vector2I *)ref boxi2.Max;
                    vectoriPtr2[0] += 1;
                    boxi2.Intersect(ref this.m_bounds);
                    int num4 = (int)(query.Min.Z * 65535f);
                    int num5 = (int)(query.Max.Z * 65535f);
                    this.GetValue(boxi2.Min.X, boxi2.Min.Y, out num6);
                    if (num6 > num5)
                    {
                        intersects = ContainmentType.Contains;
                    }
                    else
                    {
                        if (num6 >= num4)
                        {
                            return(ContainmentType.Intersects);
                        }
                        intersects = ContainmentType.Disjoint;
                    }
                    int num7 = 0xffff;
                    int num8 = 0;
                    int y    = boxi2.Min.Y;
                    while (y <= boxi2.Max.Y)
                    {
                        int x = boxi2.Min.X;
                        while (true)
                        {
                            if (x > boxi2.Max.X)
                            {
                                y++;
                                break;
                            }
                            this.GetValue(x, y, out num6);
                            if (num6 > num8)
                            {
                                num8 = num6;
                            }
                            if (num6 < num7)
                            {
                                num7 = num6;
                            }
                            x++;
                        }
                    }
                    int num9 = num8 - num7;
                    num9 += num9 >> 1;
                    num7 -= num9;
                    return((num4 <= (num8 + num9)) ? ((num5 >= num7) ? ContainmentType.Intersects : ContainmentType.Contains) : ContainmentType.Disjoint);
                }
                uint index = (uint)MathHelper.Clamp(Math.Log((double)(num * (this.Resolution / HeightmapNode.HEIGHTMAP_LEAF_SIZE))) / Math.Log((double)HeightmapNode.HEIGHTMAP_BRANCH_FACTOR), 0.0, (double)(this.PruningTree.Length - 1));
                num3       = 0;
                queryStack = m_queryStack;
                Box2I other = new Box2I(Vector2I.Zero, new Vector2I(((int)this.PruningTree[index].Res) - 1));
                queryStack[0].Bounds = new Box2I(ref query, this.PruningTree[index].Res);
                queryStack[0].Bounds.Intersect(ref other);
                queryStack[0].Next     = queryStack[0].Bounds.Min;
                queryStack[0].Level    = index;
                queryStack[0].Result   = intersects;
                queryStack[0].Continue = false;
            }
            else
            {
                goto TR_0003;
            }
            goto TR_0035;
TR_0003:
            return(ContainmentType.Disjoint);

TR_001A:
            intersects = entry.Result;
            num3--;
            if (num3 >= 0)
            {
                queryStack[num3].Intersection = intersects;
            }
            goto TR_0035;
TR_001E:
            x++;
            goto TR_002E;
TR_0026:
            switch (entry.Intersection)
            {
            case ContainmentType.Disjoint:
                if (entry.Result != ContainmentType.Contains)
                {
                    entry.Result = ContainmentType.Disjoint;
                    goto TR_001E;
                }
                else
                {
                    entry.Result = ContainmentType.Intersects;
                }
                break;

            case ContainmentType.Contains:
                if (entry.Result != ContainmentType.Disjoint)
                {
                    entry.Result = ContainmentType.Contains;
                    goto TR_001E;
                }
                else
                {
                    entry.Result = ContainmentType.Intersects;
                }
                break;

            case ContainmentType.Intersects:
                entry.Result = ContainmentType.Intersects;
                break;

            default:
                goto TR_001E;
            }
            goto TR_001A;
TR_002E:
            while (true)
            {
                if (x <= entry.Bounds.Max.X)
                {
                    if (entry.Continue)
                    {
                        entry.Continue = false;
                        x = entry.Next.X;
                        goto TR_0026;
                    }
                    else
                    {
                        SEntry *entryPtr1 = (SEntry *)ref entry;
                        entryPtr1->Intersection = this.PruningTree[entry.Level].Intersect(x, y, ref query);
                        if (entry.Intersection != ContainmentType.Intersects)
                        {
                            goto TR_0026;
                        }
                        else
                        {
                            if (this.PruningTree[entry.Level].IsCellNotContained(x, y, ref query) && (entry.Level != 0))
                            {
                                entry.Next       = new Vector2I(x, y);
                                entry.Continue   = true;
                                queryStack[num3] = entry;
                                num3++;
                                queryStack[num3] = new SEntry(ref query, this.PruningTree[((int)entry.Level) - 1].Res, new Vector2I(x, y), entry.Result, entry.Level - 1);
                                break;
                            }
                            goto TR_0026;
                        }
                    }
                }
                else
                {
                    y++;
                    goto TR_0031;
                }
                break;
            }
            goto TR_0035;
TR_0031:
            while (true)
            {
                if (y <= entry.Bounds.Max.Y)
                {
                    x = entry.Bounds.Min.X;
                }
                else
                {
                    goto TR_001A;
                }
                break;
            }
            goto TR_002E;
TR_0035:
            while (true)
            {
                if (num3 == -1)
                {
                    return(intersects);
                }
                entry = queryStack[num3];
                y     = entry.Next.Y;
                break;
            }
            goto TR_0031;
        }