Example #1
0
        private void CreateChildBox(ref AlignedBox box, int sector, out AlignedBox output)
        {
            Vector3 size;

            Vector3.Subtract(ref box.Maximum, ref box.Minimum, out size);
            Vector3.Multiply(ref size, 0.5f, out size);

            Vector3 p;

            switch (sector % 4)
            {
            case 0: p = new Vector3(0f, 0f, 0f); break;

            case 1: p = new Vector3(0f, 1f, 0f); break;

            case 2: p = new Vector3(1f, 1f, 0f); break;

            case 3: p = new Vector3(1f, 0f, 0f); break;

            default: throw new Exception("Internal error: invalid bounding box section.");
            }
            if (sector > 3)
            {
                p.Z = 1f;
            }

            Vector3.Multiply(ref p, ref size, out output.Minimum);
            Vector3.Add(ref output.Minimum, ref box.Minimum, out output.Minimum);
            Vector3.Add(ref output.Minimum, ref size, out output.Maximum);
        }
Example #2
0
        internal void ProcessTriangles(TriangleFunctor tf)
        {
            Triangle tri;
            int      stackIdx = 0, stackSize = tf.Stack.Length;
            int      bufIdx = 0, bufSize = tf.Buffer.Length;

            var box = tf.BoundingBox;

            if (AlignedBox.Intersect(ref box, ref _nodes[0].BoundingBox) == BoxIntersectType.None)
            {
                return;
            }

            tf.Stack[0] = 0;
            while (stackIdx >= 0)
            {
                int nodeIdx = tf.Stack[stackIdx];
                if (AlignedBox.Intersect(ref box, ref _nodes[nodeIdx].BoundingBox) != BoxIntersectType.None)
                {
                    for (int i = 0; i < _nodes[nodeIdx].Triangles.Length; i++)
                    {
                        if (AlignedBox.Intersect(ref box, ref _triangleBoxes[_nodes[nodeIdx].Triangles[i]]) != BoxIntersectType.None)
                        {
                            int[] vertices = _triangles[_nodes[nodeIdx].Triangles[i]];
                            tri.V1              = _body[vertices[0]];
                            tri.V2              = _body[vertices[1]];
                            tri.V3              = _body[vertices[2]];
                            tri.Normal          = _normals[_nodes[nodeIdx].Triangles[i]];
                            tf.Buffer[bufIdx++] = tri;
                            if (bufIdx == bufSize)
                            {
                                tf.Process(bufSize);
                                bufIdx = 0;
                            }
                        }
                    }
                }
                stackIdx--;
                for (int i = 0; i < _nodes[nodeIdx].Children.Length; i++)
                {
                    if (stackIdx == stackSize - 2)
                    {
                        stackSize = tf.GrowStack();
                    }
                    tf.Stack[++stackIdx] = _nodes[nodeIdx].Children[i];
                }
            }
            if (bufIdx > 0)
            {
                tf.Process(bufIdx);
            }
        }
Example #3
0
            public void Initialize(CollisionFunctor cf, PolyhedronPart a, MeshPart b, Vector3 delta)
            {
                _cf           = cf;
                _a            = a;
                _b            = b;
                _delta        = delta;
                _useSweptTest = _delta != Vector3.Zero;
                Depth         = float.MaxValue;
                a.Center(out _center);

                // transform bounding box to body space
                b.BoundingBox(out BoundingBox);
                AlignedBox.Transform(ref BoundingBox, ref b.TransformInverse, out BoundingBox);
            }
Example #4
0
            public void Initialize(CollisionFunctor cf, CapsulePart a, MeshPart b, Vector3 offset)
            {
                _cf            = cf;
                _b             = b;
                _radius        = a.World.Radius * b.TransformInverse.Scale;
                _radiusSquared = _radius * _radius;
                _offset        = offset;
                _hasCollision  = false;
                Vector3.Add(ref a.World.P1, ref _offset, out _cap.P1);
                Vector3.Add(ref a.World.P2, ref _offset, out _cap.P2);

                // calculate points and bounding box in body space
                var radius = new Vector3(_radius);

                Vector3.Transform(ref _cap.P1, ref b.TransformInverse.Combined, out _cap.P1);
                Vector3.Transform(ref _cap.P2, ref b.TransformInverse.Combined, out _cap.P2);
                AlignedBox.Fit(ref _cap.P1, ref _cap.P2, out BoundingBox);
                Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
                Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
            }
Example #5
0
            public void Initialize(CollisionFunctor cf, SpherePart a, MeshPart b, Vector3 delta)
            {
                _cf            = cf;
                _a             = a;
                _b             = b;
                _radius        = a.World.Radius * b.TransformInverse.Scale;
                _radiusSquared = _radius * _radius;

                Vector3.Transform(ref a.World.Center, ref b.TransformInverse.Combined, out _path.P1);
                Vector3.Transform(ref delta, ref b.TransformInverse.Orientation, out delta);
                Vector3.Multiply(ref delta, b.TransformInverse.Scale, out delta);
                Vector3.Add(ref _path.P1, ref delta, out _path.P2);

                AlignedBox.Fit(ref _path.P1, ref _path.P2, out BoundingBox);

                var radius = new Vector3(_radius);

                Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
                Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
            }
Example #6
0
        private void BuildOctree()
        {
            var tempNodes = new List <TempNode>();
            var root      = new TempNode();

            tempNodes.Add(root);

            // create bounding boxes for all triangles
            _triangleBoxes = new AlignedBox[_triangles.Length];
            for (int i = 0; i < _triangles.Length; i++)
            {
                AlignedBox.Fit(ref _body[_triangles[i][0]], ref _body[_triangles[i][1]], ref _body[_triangles[i][2]], out _triangleBoxes[i]);
                AlignedBox.Merge(ref root.BoundingBox, ref _triangleBoxes[i], out root.BoundingBox);
            }

            var subBoxes = new AlignedBox[8];

            // add each triangle to the bounding box
            for (int i = 0; i < _triangles.Length; i++)
            {
                int idx = 0;
                var box = root.BoundingBox;

                while (AlignedBox.Intersect(ref tempNodes[idx].BoundingBox, ref _triangleBoxes[i]) == BoxIntersectType.AContainsB)
                {
                    int sector = -1;
                    for (int j = 0; j < 8; j++)
                    {
                        CreateChildBox(ref tempNodes[idx].BoundingBox, j, out subBoxes[j]);
                        if (AlignedBox.Intersect(ref subBoxes[j], ref _triangleBoxes[i]) == BoxIntersectType.AContainsB)
                        {
                            sector = j;
                            break;
                        }
                    }
                    if (sector == -1)
                    {
                        tempNodes[idx].Triangles.Add(i);
                        break;
                    }
                    else
                    {
                        if (tempNodes[idx].Children[sector] > 0)
                        {
                            idx = tempNodes[idx].Children[sector];
                        }
                        else
                        {
                            var child = new TempNode();
                            child.BoundingBox = subBoxes[sector];
                            tempNodes.Add(child);

                            idx = tempNodes[idx].Children[sector] = tempNodes.Count - 1;
                        }
                    }
                }
            }

            _nodes = (from node in tempNodes
                      select new Node()
            {
                Children = (from i in node.Children where i > 0 select(ushort) i).ToArray(),
                Triangles = (from i in node.Triangles select(ushort) i).ToArray(),
                BoundingBox = node.BoundingBox
            }).ToArray();
        }