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); }
/** * 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); }
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; }