Beispiel #1
0
        public void WalkStacklessTree(OptimizedBvhNode[] rootNodeArray, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
        {
            int              escapeIndex, curIndex = 0;
            int              walkIterations = 0;
            bool             aabbOverlap, isLeafNode;
            int              rootNodeIndex = 0;
            OptimizedBvhNode rootNode      = rootNodeArray[rootNodeIndex];

            while (curIndex < _curNodeIndex)
            {
                //catch bugs in tree data
                if (walkIterations >= _curNodeIndex)
                {
                    throw new BulletException();
                }

                walkIterations++;
                aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);
                isLeafNode  = (rootNode.LeftChild == null && rootNode.RightChild == null);

                if (isLeafNode && aabbOverlap)
                {
                    nodeCallback.ProcessNode(rootNode);
                }

                if (aabbOverlap || isLeafNode)
                {
                    rootNodeIndex++;                     // this
                    curIndex++;
                    if (rootNodeIndex < rootNodeArray.Length)
                    {
                        rootNode = rootNodeArray[rootNodeIndex];
                    }
                }
                else
                {
                    escapeIndex    = rootNode.EscapeIndex;
                    rootNodeIndex += escapeIndex;                     // and this
                    curIndex      += escapeIndex;
                    if (rootNodeIndex < rootNodeArray.Length)
                    {
                        rootNode = rootNodeArray[rootNodeIndex];
                    }
                }
            }

            if (_maxIterations < walkIterations)
            {
                _maxIterations = walkIterations;
            }
        }
Beispiel #2
0
		public void Build(StridingMeshInterface triangles)
		{
			NodeTriangleCallback callback = new NodeTriangleCallback(_leafNodes);

			Vector3 aabbMin = new Vector3(-1e30f, -1e30f, -1e30f);
			Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);

			triangles.InternalProcessAllTriangles(callback, aabbMin, aabbMax);

			//now we have an array of leafnodes in m_leafNodes
			_contiguousNodes = new OptimizedBvhNode[2 * _leafNodes.Count];
            for (int i = 0; i < _contiguousNodes.Length; i++)
                _contiguousNodes[i] = new OptimizedBvhNode();
			_curNodeIndex = 0;

			_rootNode = BuildTree(_leafNodes, 0, _leafNodes.Count);
		}
        public void ProcessNode(OptimizedBvhNode node)
        {
            List<Vector3> verts;
            List<int> indicies;
            int numtriangles;

            _meshInterface.GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, node.SubPart);
            Vector3 meshScaling = _meshInterface.Scaling;

            for (int j = 0; j < 3; j++)
            {
                _triangle[j] = verts[indicies[j + node.TriangleIndex * 3]] * meshScaling;
            }

            _callback.ProcessTriangle(_triangle, node.SubPart, node.TriangleIndex);
            _meshInterface.UnLockReadOnlyVertexBase(node.SubPart);
        }
        public void ProcessNode(OptimizedBvhNode node)
        {
            List <Vector3> verts;
            List <int>     indicies;
            int            numtriangles;

            _meshInterface.GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, node.SubPart);
            Vector3 meshScaling = _meshInterface.Scaling;

            for (int j = 0; j < 3; j++)
            {
                _triangle[j] = verts[indicies[j + node.TriangleIndex * 3]] * meshScaling;
            }

            _callback.ProcessTriangle(_triangle, node.SubPart, node.TriangleIndex);
            _meshInterface.UnLockReadOnlyVertexBase(node.SubPart);
        }
Beispiel #5
0
        public void WalkTree(OptimizedBvhNode rootNode, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
        {
            bool isLeafNode, aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);

            if (aabbOverlap)
            {
                isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null);
                if (isLeafNode)
                {
                    nodeCallback.ProcessNode(rootNode);
                }
                else
                {
                    WalkTree(rootNode.LeftChild, nodeCallback, aabbMin, aabbMax);
                    WalkTree(rootNode.RightChild, nodeCallback, aabbMin, aabbMax);
                }
            }
        }
Beispiel #6
0
        public void Build(StridingMeshInterface triangles)
        {
            NodeTriangleCallback callback = new NodeTriangleCallback(_leafNodes);

            Vector3 aabbMin = new Vector3(-1e30f, -1e30f, -1e30f);
            Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);

            triangles.InternalProcessAllTriangles(callback, aabbMin, aabbMax);

            //now we have an array of leafnodes in m_leafNodes
            _contiguousNodes = new OptimizedBvhNode[2 * _leafNodes.Count];
            for (int i = 0; i < _contiguousNodes.Length; i++)
            {
                _contiguousNodes[i] = new OptimizedBvhNode();
            }
            _curNodeIndex = 0;

            _rootNode = BuildTree(_leafNodes, 0, _leafNodes.Count);
        }
Beispiel #7
0
        public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
        {
            OptimizedBvhNode node = new OptimizedBvhNode();
            node.AabbMin = new Vector3(1e30f, 1e30f, 1e30f);
            node.AabbMax = new Vector3(-1e30f, -1e30f, -1e30f);

            node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[0]);
            node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[0]);
            node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[1]);
            node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[1]);
            node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[2]);
            node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[2]);

            node.EscapeIndex = -1;
            node.LeftChild = null;
            node.RightChild = null;

            //for child nodes
            node.SubPart = partId;
            node.TriangleIndex = triangleIndex;

            _triangleNodes.Add(node);
        }
Beispiel #8
0
        public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
        {
            OptimizedBvhNode node = new OptimizedBvhNode();

            node.AabbMin = new Vector3(1e30f, 1e30f, 1e30f);
            node.AabbMax = new Vector3(-1e30f, -1e30f, -1e30f);

            node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[0]);
            node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[0]);
            node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[1]);
            node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[1]);
            node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[2]);
            node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[2]);

            node.EscapeIndex = -1;
            node.LeftChild   = null;
            node.RightChild  = null;

            //for child nodes
            node.SubPart       = partId;
            node.TriangleIndex = triangleIndex;

            _triangleNodes.Add(node);
        }
Beispiel #9
0
		public void WalkStacklessTree(OptimizedBvhNode[] rootNodeArray, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
		{
			int escapeIndex, curIndex = 0;
			int walkIterations = 0;
			bool aabbOverlap, isLeafNode;
            int rootNodeIndex = 0;
            OptimizedBvhNode rootNode = rootNodeArray[rootNodeIndex];

			while (curIndex < _curNodeIndex)
			{
				//catch bugs in tree data
				if (walkIterations >= _curNodeIndex)
					throw new BulletException();

				walkIterations++;
				aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);
				isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null);

				if (isLeafNode && aabbOverlap)
				{
					nodeCallback.ProcessNode(rootNode);
				}

				if (aabbOverlap || isLeafNode)
				{
					rootNodeIndex++; // this
					curIndex++;
                    if (rootNodeIndex < rootNodeArray.Length)
                        rootNode = rootNodeArray[rootNodeIndex];
                }
				else
				{
					escapeIndex = rootNode.EscapeIndex;
					rootNodeIndex += escapeIndex; // and this
					curIndex += escapeIndex;
                    if (rootNodeIndex < rootNodeArray.Length)
                        rootNode = rootNodeArray[rootNodeIndex];
				}

			}

			if (_maxIterations < walkIterations)
				_maxIterations = walkIterations;
		}
Beispiel #10
0
		public void WalkTree(OptimizedBvhNode rootNode, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
		{
			bool isLeafNode, aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);
			if (aabbOverlap)
			{
				isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null);
				if (isLeafNode)
				{
					nodeCallback.ProcessNode(rootNode);
				}
				else
				{
					WalkTree(rootNode.LeftChild, nodeCallback, aabbMin, aabbMax);
					WalkTree(rootNode.RightChild, nodeCallback, aabbMin, aabbMax);
				}
			}
		}
Beispiel #11
0
        public int SortAndCalculateSplittingIndex(List <OptimizedBvhNode> leafNodes, int startIndex, int endIndex, int splitAxis)
        {
            int   splitIndex = startIndex;
            int   numIndices = endIndex - startIndex;
            float splitValue;

            Vector3 means = new Vector3();

            for (int i = startIndex; i < endIndex; i++)
            {
                Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
                means += center;
            }
            means *= (1f / (float)numIndices);

            if (splitAxis == 0)
            {
                splitValue = means.X;
            }
            else if (splitAxis == 1)
            {
                splitValue = means.Y;
            }
            else if (splitAxis == 2)
            {
                splitValue = means.Z;
            }
            else
            {
                throw new ArgumentException();
            }

            //sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
            for (int i = startIndex; i < endIndex; i++)
            {
                Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
                float   centerSplit;

                if (splitAxis == 0)
                {
                    centerSplit = means.X;
                }
                else if (splitAxis == 1)
                {
                    centerSplit = means.Y;
                }
                else if (splitAxis == 2)
                {
                    centerSplit = means.Z;
                }
                else
                {
                    throw new ArgumentException();
                }

                if (centerSplit > splitValue)
                {
                    //swap
                    OptimizedBvhNode tmp = leafNodes[i];
                    leafNodes[i]          = leafNodes[splitIndex];
                    leafNodes[splitIndex] = tmp;
                    splitIndex++;
                }
            }
            if ((splitIndex == startIndex) || (splitIndex == (endIndex - 1)))
            {
                splitIndex = startIndex + (numIndices >> 1);
            }
            return(splitIndex);
        }