Beispiel #1
0
        public static OctreeChild Create(BoundingBox bounds, List <OctreeFace> faces, int depth = -1)
        {
            depth++;

            OctreeChild node        = new OctreeChild();
            Vector3     centre      = (bounds.Min + bounds.Max) * 0.5f;
            BoundingBox childBounds = new BoundingBox();
            SplitFlags  splitFlags  = 0;

            if (depth > Octree.MaxDepth || (depth > 0 && faces.Count < Octree.MaxFacesPerLeaf))
            {
                splitFlags = 0;

                if (faces.Count > Octree.MaxFacesPerLeaf / 8)
                {
                    if (bounds.Max.X - bounds.Min.X > 100.0f)
                    {
                        splitFlags |= SplitFlags.SplitInX;
                    }
                    if (bounds.Max.Z - bounds.Min.Z > 100.0f)
                    {
                        splitFlags |= SplitFlags.SplitInZ;
                    }
                }

                if (splitFlags == 0)
                {
                    node = OctreeLeaf.Create(depth, faces);
                    depth--;
                    return(node);
                }
            }
            else
            {
                DetermineSplittage(depth, faces, centre, ref splitFlags);
            }

            if (depth > 0 && splitFlags == 0)
            {
                node = OctreeLeaf.Create(depth, faces);
                depth--;
                return(node);
            }

            //numNodes++;

            node = new OctreeNode
            {
                ChildType = 0,
                Flags     = splitFlags
            };

            for (int i = 0; i < (node as OctreeNode).Children.Length; i++)
            {
                if (node.Flags.HasFlag(SplitFlags.SplitInX))
                {
                    if ((i & 1) == 1)
                    {
                        childBounds.Min.X = centre.X;
                        childBounds.Max.X = bounds.Max.X;
                    }
                    else
                    {
                        childBounds.Min.X = bounds.Min.X;
                        childBounds.Max.X = centre.X;
                    }
                }
                else
                {
                    if ((i & 1) == 1)
                    {
                        continue;
                    }
                    else
                    {
                        childBounds.Min.X = bounds.Min.X;
                        childBounds.Max.X = bounds.Max.X;
                    }
                }

                if (node.Flags.HasFlag(SplitFlags.SplitInY))
                {
                    if ((i & 2) == 2)
                    {
                        childBounds.Min.Y = centre.Y;
                        childBounds.Max.Y = bounds.Max.Y;
                    }
                    else
                    {
                        childBounds.Min.Y = bounds.Min.Y;
                        childBounds.Max.Y = centre.Y;
                    }
                }
                else
                {
                    if ((i & 2) == 2)
                    {
                        continue;
                    }
                    else
                    {
                        childBounds.Min.Y = bounds.Min.Y;
                        childBounds.Max.Y = bounds.Max.Y;
                    }
                }

                if (node.Flags.HasFlag(SplitFlags.SplitInZ))
                {
                    if ((i & 4) == 4)
                    {
                        childBounds.Min.Z = centre.Z;
                        childBounds.Max.Z = bounds.Max.Z;
                    }
                    else
                    {
                        childBounds.Min.Z = bounds.Min.Z;
                        childBounds.Max.Z = centre.Z;
                    }
                }
                else
                {
                    if ((i & 4) == 4)
                    {
                        continue;
                    }
                    else
                    {
                        childBounds.Min.Z = bounds.Min.Z;
                        childBounds.Max.Z = bounds.Max.Z;
                    }
                }

                //Logger.LogToFile(Logger.LogLevel.All, $"{depth}\t{i}\t{childBounds.Min}\t{childBounds.Max}");

                List <OctreeFace> childFaces = Octree.FindFacesFromList(faces, childBounds);
                (node as OctreeNode).Children[i] = Create(childBounds, childFaces, depth);
            }

            depth--;

            return(node);
        }
Beispiel #2
0
		public static PhpArray Split(object pattern, object data, int limit, SplitFlags flags)
		{
			if (limit == 0) // 0 does not make sense, php's behavior is as it is -1
				limit = -1;
			if (limit < -1) // for all other negative values it seems that is as limit == 1
				limit = 1;

			PerlRegExpConverter converter = ConvertPattern(pattern, null);
			if (converter == null) return null;

			string str = ConvertData(data, converter);
			Match m = converter.Regex.Match(str);

			bool offset_capture = (flags & SplitFlags.OffsetCapture) != 0;
			PhpArray result = new PhpArray();
			int last_index = 0;

			while (m.Success && (limit == -1 || --limit > 0) && last_index < str.Length)
			{
				// add part before match
				int length = m.Index - last_index;
				if (length > 0 || (flags & SplitFlags.NoEmpty) == 0)
					result.Add(NewArrayItem(str.Substring(last_index, length), last_index, offset_capture));

				if (m.Value.Length > 0)
				{
					if ((flags & SplitFlags.DelimCapture) != 0) // add all captures but not whole pattern match (start at 1)
					{
                        List<object> lastUnsucessfulGroups = null;  // value of groups that was not successful since last succesful one
						for (int i = 1; i < m.Groups.Count; i++)
						{
							Group g = m.Groups[i];
                            if (g.Length > 0 || (flags & SplitFlags.NoEmpty) == 0)
                            {
                                // the value to be added into the result:
                                object value = NewArrayItem(g.Value, g.Index, offset_capture);

                                if (g.Success)
                                {
                                    // group {i} was matched:
                                    // if there was some unsuccesfull matches before, add them now:
                                    if (lastUnsucessfulGroups != null && lastUnsucessfulGroups.Count > 0)
                                    {
                                        foreach (var x in lastUnsucessfulGroups)
                                            result.Add(x);
                                        lastUnsucessfulGroups.Clear();
                                    }
                                    // add the matched group:
                                    result.Add(value);
                                }
                                else
                                {
                                    // The match was unsuccesful, remember all the unsuccesful matches
                                    // and add them only if some succesful match will follow.
                                    // In PHP, unsuccessfully matched groups are trimmed by the end
                                    // (regexp processing stops when other groups cannot be matched):
                                    if (lastUnsucessfulGroups == null) lastUnsucessfulGroups = new List<object>();
                                    lastUnsucessfulGroups.Add(value);
                                }
                            }
						}
					}

					last_index = m.Index + m.Length;
				}
				else // regular expression match an empty string => add one character
				{
					// always not empty
					result.Add(NewArrayItem(str.Substring(last_index, 1), last_index, offset_capture));
					last_index++;
				}

				m = m.NextMatch();
			}

			// add remaining string (might be empty)
			if (last_index < str.Length || (flags & SplitFlags.NoEmpty) == 0)
				result.Add(NewArrayItem(str.Substring(last_index), last_index, offset_capture));

			return result;
		}
Beispiel #3
0
        public static void DetermineSplittage(int depth, List <OctreeFace> faces, Vector3 centre, ref SplitFlags splitFlags)
        {
            int nFacesXMin = 0, nFacesXMax = 0;
            int nFacesYMin = 0, nFacesYMax = 0;
            int nFacesZMin = 0, nFacesZMax = 0;

            for (int i = 0; i < faces.Count; i++)
            {
                OctreeFace face = faces[i];

                if (face.HitNumber == depth || face.HitNumber < 0)
                {
                    if (face.Vertices[0].X < centre.X &&
                        face.Vertices[1].X < centre.X &&
                        face.Vertices[2].X < centre.X)
                    {
                        nFacesXMin++;
                    }

                    if (face.Vertices[0].X > centre.X &&
                        face.Vertices[1].X > centre.X &&
                        face.Vertices[2].X > centre.X)
                    {
                        nFacesXMax++;
                    }

                    if (face.Vertices[0].Y < centre.Y &&
                        face.Vertices[1].Y < centre.Y &&
                        face.Vertices[2].Y < centre.Y)
                    {
                        nFacesYMin++;
                    }

                    if (face.Vertices[0].Y > centre.Y &&
                        face.Vertices[1].Y > centre.Y &&
                        face.Vertices[2].Y > centre.Y)
                    {
                        nFacesYMax++;
                    }

                    if (face.Vertices[0].Z < centre.Z &&
                        face.Vertices[1].Z < centre.Z &&
                        face.Vertices[2].Z < centre.Z)
                    {
                        nFacesZMin++;
                    }

                    if (face.Vertices[0].Z > centre.Z &&
                        face.Vertices[1].Z > centre.Z &&
                        face.Vertices[2].Z > centre.Z)
                    {
                        nFacesZMax++;
                    }
                }
            }

            splitFlags = 0;

            if (nFacesXMin + nFacesXMax > Octree.NodeSplitParameter * faces.Count)
            {
                splitFlags |= SplitFlags.SplitInX;
            }
            if (nFacesYMin + nFacesYMax > Octree.NodeSplitParameter * faces.Count)
            {
                splitFlags |= SplitFlags.SplitInY;
            }
            if (nFacesZMin + nFacesZMax > Octree.NodeSplitParameter * faces.Count)
            {
                splitFlags |= SplitFlags.SplitInZ;
            }
        }