예제 #1
0
 public Triangle(int i1, int i2, int i3, Vector3 v1, Vector3 v2, Vector3 v3)
 {
     this.i1 = i1;
     this.i2 = i2;
     this.i3 = i3;
     b       = new Aabb(v1);
     b.Encapsulate(v2);
     b.Encapsulate(v3);
 }
예제 #2
0
 public Edge(int i1, int i2, Vector2 v1, Vector2 v2)
 {
     this.i1 = i1;
     this.i2 = i2;
     b       = new Aabb(v1);
     b.Encapsulate(v2);
 }
예제 #3
0
파일: BIH.cs 프로젝트: EdenAlon73/ZiggyPipe
        public static BIHNode[] Build(ref IBounded[] elements, int maxDepth = 10, float maxOverlap = 0.7f)
        {
            List <BIHNode> nodes = new List <BIHNode> {
                new BIHNode(0, elements.Length)
            };

            // auxiliar variables to keep track of current tree depth:
            int depth            = 0;
            int nodesToNextLevel = 1;

            var queue = new Queue <int>();

            queue.Enqueue(0);

            while (queue.Count > 0)
            {
                // get current node:
                int index = queue.Dequeue();
                var node  = nodes[index];

                // if this node contains enough elements, split it:
                if (node.count > 2)
                {
                    int start = node.start;
                    int end   = start + (node.count - 1);

                    // calculate bounding box of all elements:
                    Aabb b = elements[start].GetBounds();
                    for (int k = start + 1; k <= end; ++k)
                    {
                        b.Encapsulate(elements[k].GetBounds());
                    }

                    // determine split axis (longest one):
                    Vector3 size = b.size;
                    int     axis = node.axis = (size.x > size.y) ?
                                               (size.x > size.z ? 0 : 2) :
                                               (size.y > size.z ? 1 : 2);

                    // place split plane at half the longest axis:
                    float pivot = b.min[axis] + size[axis] * 0.5f;

                    // partition elements according to which side of the split plane they're at:
                    int j = HoarePartition(elements, start, end, pivot, ref node, axis);

                    // create two child nodes:
                    var minChild = new BIHNode(start, j - start + 1);
                    var maxChild = new BIHNode(j + 1, end - j);

                    // calculate child overlap:
                    float overlap = size[axis] > 0 ? Mathf.Max(node.min - node.max, 0) / size[axis] : 1;

                    // guard against cases where all elements are on one side of the split plane,
                    // due to all having the same or very similar bounds as the entire group.
                    if (overlap <= maxOverlap && minChild.count > 0 && maxChild.count > 0)
                    {
                        node.firstChild = nodes.Count;
                        nodes[index]    = node;

                        queue.Enqueue(nodes.Count);
                        queue.Enqueue(nodes.Count + 1);

                        // append child nodes to list:
                        nodes.Add(minChild);
                        nodes.Add(maxChild);
                    }

                    // keep track of current depth:
                    if (--nodesToNextLevel == 0)
                    {
                        depth++;
                        if (depth >= maxDepth)
                        {
                            return(nodes.ToArray());
                        }
                        nodesToNextLevel = queue.Count;
                    }
                }
            }
            return(nodes.ToArray());
        }
예제 #4
0
파일: BIH.cs 프로젝트: Havie/BallTest
        public static List <BIHNode> Build(ref IBounded[] elements)
        {
            List <BIHNode> nodes = new List <BIHNode> {
                new BIHNode(0, elements.Length)
            };

            var queue = new Queue <int>();

            queue.Enqueue(0);

            while (queue.Count > 0)
            {
                // get current node:
                int index = queue.Dequeue();
                var node  = nodes[index];

                // if this node contains enough elements, split it:
                if (node.count > 1)
                {
                    int start = node.start;
                    int end   = start + (node.count - 1);

                    // calculate bounding box of all elements:
                    Aabb b = elements[start].GetBounds();
                    for (int k = start + 1; k <= end; ++k)
                    {
                        b.Encapsulate(elements[k].GetBounds());
                    }

                    // determine split axis (longest one):
                    Vector3 size = b.size;
                    int     axis = node.axis = (size.x > size.y) ?
                                               (size.x > size.z ? 0 : 2) :
                                               (size.y > size.z ? 1 : 2);

                    // place split plane at half the longest axis:
                    float pivot = b.min[axis] + size[axis] * 0.5f;

                    // sort elements using the split plane (Hoare's partition algorithm):
                    int  i = start - 1;
                    int  j = end + 1;
                    Aabb bi, bj;
                    while (true)
                    {
                        // iterate over left elements, while they're smaller than the pivot.
                        do
                        {
                            bi = elements[++i].GetBounds();
                            if (bi.center[axis] < pivot)
                            {
                                node.min = Mathf.Max(node.min, bi.max[axis]);
                            }
                        } while (bi.center[axis] < pivot);

                        // iterate over right elements, while they're larger than the pivot.
                        do
                        {
                            bj = elements[--j].GetBounds();
                            if (bj.center[axis] > pivot)
                            {
                                node.max = Mathf.Min(node.max, bj.min[axis]);
                            }
                        } while (bj.center[axis] > pivot);

                        // if element i is larger than the pivot, j smaller than the pivot, swap them.
                        if (i < j)
                        {
                            ObiUtils.Swap(ref elements[i], ref elements[j]);
                            node.min = Mathf.Max(node.min, bj.max[axis]);
                            node.max = Mathf.Min(node.max, bi.min[axis]);
                        }
                        else
                        {
                            break;
                        }
                    }

                    // create two child nodes:
                    var minChild = new BIHNode(start, j - start + 1);
                    var maxChild = new BIHNode(j + 1, end - j);

                    // guard against cases where all elements are on one side of the split plane,
                    // due to all having the same or very similar bounds as the entire group.
                    if (minChild.count > 0 && maxChild.count > 0)
                    {
                        node.firstChild = nodes.Count;
                        nodes[index]    = node;

                        queue.Enqueue(nodes.Count);
                        queue.Enqueue(nodes.Count + 1);

                        // append child nodes to list:
                        nodes.Add(minChild);
                        nodes.Add(maxChild);
                    }
                }
            }

            return(nodes);
        }