Пример #1
0
 public void Max(ref UShortVector3 a)
 {
     if (X < a.X)
     {
         X = a.X;
     }
     if (Y < a.Y)
     {
         Y = a.Y;
     }
     if (Z < a.Z)
     {
         Z = a.Z;
     }
 }
Пример #2
0
 public void Min(ref UShortVector3 a)
 {
     if (X > a.X)
     {
         X = a.X;
     }
     if (Y > a.Y)
     {
         Y = a.Y;
     }
     if (Z > a.Z)
     {
         Z = a.Z;
     }
 }
Пример #3
0
        public static void QuantizeClamp(out UShortVector3 output,
            ref IndexedVector3 point,
            ref IndexedVector3 min_bound,
            ref IndexedVector3 max_bound,
            ref IndexedVector3 bvhQuantization)
        {

            IndexedVector3 clampedPoint = point;
            MathUtil.VectorMax(ref min_bound, ref clampedPoint);
            MathUtil.VectorMin(ref max_bound, ref clampedPoint);

            IndexedVector3 v = (clampedPoint - min_bound) * bvhQuantization;
            output = new UShortVector3();
            output[0] = (ushort)(v.X + 0.5f);
            output[1] = (ushort)(v.Y + 0.5f);
            output[2] = (ushort)(v.Z + 0.5f);
        }
Пример #4
0
 public static IndexedVector3 Unquantize(
 ref UShortVector3 vecIn,
 ref IndexedVector3 offset,
 ref IndexedVector3 bvhQuantization)
 {
     IndexedVector3 vecOut = new IndexedVector3(
         (float)(vecIn[0]) / (bvhQuantization.X),
         (float)(vecIn[1]) / (bvhQuantization.Y),
         (float)(vecIn[2]) / (bvhQuantization.Z));
     vecOut += offset;
     return vecOut;
 }
Пример #5
0
        //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
        public static bool TestQuantizedAabbAgainstQuantizedAabb(ref UShortVector3 aabbMin1, ref UShortVector3 aabbMax1, ref UShortVector3 aabbMin2, ref UShortVector3 aabbMax2)
        {
            //return ((aabbMin1[0] <= aabbMax2[0]) && (aabbMax1[0] >= aabbMin2[0])
            //    & (aabbMin1[2] <= aabbMax2[2]) && (aabbMax1[2] >= aabbMin2[2])
            //    & (aabbMin1[1] <= aabbMax2[1]) && (aabbMax1[1] >= aabbMin2[1]));
            //return (MathUtil.select(val,1, 0));

            // MAN - Not sure why this version isn't just replaced by anding all of the above, it's still not conditional as theres a quick ref.
            bool overlap = true;
            overlap = (aabbMin1.X > aabbMax2.X || aabbMax1.X < aabbMin2.X) ? false : overlap;
            overlap = (aabbMin1.Z > aabbMax2.Z || aabbMax1.Z < aabbMin2.Z) ? false : overlap;
            overlap = (aabbMin1.Y > aabbMax2.Y || aabbMax1.Y < aabbMin2.Y) ? false : overlap;
            return overlap;
        }
        ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
        protected void WalkRecursiveQuantizedTreeAgainstQueryAabb(ref QuantizedBvhNode currentNode, INodeOverlapCallback nodeCallback, ref UShortVector3 quantizedQueryAabbMin, ref UShortVector3 quantizedQueryAabbMax)
        {
            Debug.Assert(m_useQuantization);

            bool isLeafNode;
            //PCK: unsigned instead of bool
            bool aabbOverlap = false;

            //PCK: unsigned instead of bool
            aabbOverlap = AabbUtil2.TestQuantizedAabbAgainstQuantizedAabb(ref quantizedQueryAabbMin, ref quantizedQueryAabbMax, ref currentNode.m_quantizedAabbMin, ref currentNode.m_quantizedAabbMax);
            isLeafNode = currentNode.IsLeafNode();

            //PCK: unsigned instead of bool
            if (aabbOverlap)
            {
                if (isLeafNode)
                {
                    nodeCallback.ProcessNode(currentNode.GetPartId(), currentNode.GetTriangleIndex());
                }
                else
                {
                    //process left and right children

                    //QuantizedBvhNode leftChildNode = currentNode + 1;
                    // Not sure bout thie replacement... but avoids pointer arithmetic
                    // this is broken ...
                    //int nodeIndex = currentNode.GetTriangleIndex() + 1;
                    if(currentNode.m_leftChildIndex > -1 && currentNode.m_leftChildIndex < m_quantizedContiguousNodes.Count)
                    {
                        QuantizedBvhNode leftChildNode = m_quantizedContiguousNodes[currentNode.m_leftChildIndex];
                        WalkRecursiveQuantizedTreeAgainstQueryAabb(ref leftChildNode, nodeCallback, ref quantizedQueryAabbMin, ref quantizedQueryAabbMax);
                    }

                    if(currentNode.m_rightChildIndex > -1 && currentNode.m_rightChildIndex < m_quantizedContiguousNodes.Count)
                    {
                        //int newIndex = leftChildNode.IsLeafNode() ? leftChildNode.GetTriangleIndex() + 1 : leftChildNode.GetTriangleIndex() + leftChildNode.GetEscapeIndex();
                        QuantizedBvhNode rightChildNode = m_quantizedContiguousNodes[currentNode.m_rightChildIndex];
                        WalkRecursiveQuantizedTreeAgainstQueryAabb(ref rightChildNode, nodeCallback, ref quantizedQueryAabbMin, ref quantizedQueryAabbMax);
                    }
                }
            }
        }
        ///tree traversal designed for small-memory processors like PS3 SPU
        protected void WalkStacklessQuantizedTreeCacheFriendly(INodeOverlapCallback nodeCallback, ref UShortVector3 quantizedQueryAabbMin, ref UShortVector3 quantizedQueryAabbMax)
        {
            Debug.Assert(m_useQuantization);

            for (int i = 0; i < m_SubtreeHeaders.Count; i++)
            {
                BvhSubtreeInfo subtree = m_SubtreeHeaders[i];

                //PCK: unsigned instead of bool
                bool overlap = AabbUtil2.TestQuantizedAabbAgainstQuantizedAabb(ref quantizedQueryAabbMin, ref quantizedQueryAabbMax, ref subtree.m_quantizedAabbMin, ref subtree.m_quantizedAabbMax);
                if (overlap)
                {
                    WalkStacklessQuantizedTree(nodeCallback, ref quantizedQueryAabbMin, ref quantizedQueryAabbMax,
                        subtree.m_rootNodeIndex,
                        subtree.m_rootNodeIndex + subtree.m_subtreeSize);
                }
            }

        }
        protected void WalkStacklessQuantizedTree(INodeOverlapCallback nodeCallback, ref UShortVector3 quantizedQueryAabbMin, ref UShortVector3 quantizedQueryAabbMax, int startNodeIndex, int endNodeIndex)
        {
            Debug.Assert(m_useQuantization);

            int curIndex = startNodeIndex;
            int walkIterations = 0;
            int subTreeSize = endNodeIndex - startNodeIndex;
            //(void)subTreeSize;
            QuantizedBvhNode rootNode = m_quantizedContiguousNodes[curIndex];
            int escapeIndex = 0;

            bool isLeafNode;
            //PCK: unsigned instead of bool
            bool aabbOverlap = false;

            while (curIndex < endNodeIndex)
            {

                //#define VISUALLY_ANALYZE_BVH 1
#if VISUALLY_ANALYZE_BVH
                //some code snippet to debugDraw aabb, to visually analyze bvh structure
                int drawPatch = 1;
                //need some global access to a debugDrawer
                IDebugDraw debugDrawerPtr = BulletGlobals.gDebugDraw;
                //IDebugDraw debugDrawerPtr = null;
                //if (curIndex == drawPatch&& debugDrawerPtr != null)
                if (debugDrawerPtr != null && curIndex == drawPatch)
                //if (debugDrawerPtr != null)
                {
                    IndexedVector3 aabbMin, aabbMax;
                    UnQuantize(ref rootNode.m_quantizedAabbMin, out aabbMin);
                    UnQuantize(ref rootNode.m_quantizedAabbMax, out aabbMax);
                    IndexedVector3 color = new IndexedVector3(1, 0, 0);
                    debugDrawerPtr.DrawAabb(ref aabbMin, ref aabbMax, ref color);
                    //IndexedVector3 offset = new IndexedVector3(0, 2, 0);
                    //debugDrawerPtr.DrawAabb(aabbMin+offset, aabbMax+offset, color);
                    //Console.Out.WriteLine(String.Format("min[{0},{1},{2}] max[{3},{4},{5}]\n", aabbMin.X, aabbMin.Y, aabbMin.Z, aabbMax.X, aabbMax.Y, aabbMax.Z));


                }
#endif//VISUALLY_ANALYZE_BVH

                //unQuantize version with out param


                //catch bugs in tree data
                Debug.Assert(walkIterations < subTreeSize);

                walkIterations++;

                //PCK: unsigned instead of bool
                aabbOverlap = AabbUtil2.TestQuantizedAabbAgainstQuantizedAabb(ref quantizedQueryAabbMin, ref quantizedQueryAabbMax, ref rootNode.m_quantizedAabbMin, ref rootNode.m_quantizedAabbMax);
                isLeafNode = rootNode.IsLeafNode();

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

                //PCK: unsigned instead of bool
                if ((aabbOverlap) || isLeafNode)
                {
                    curIndex++;
                }
                else
                {
                    escapeIndex = rootNode.GetEscapeIndex();
                    curIndex += escapeIndex;
                }
                rootNode = m_quantizedContiguousNodes[curIndex];

            }
            if (m_maxIterations < walkIterations)
            {
                m_maxIterations = walkIterations;
            }
        }
        //int			m_padding[3];

        public void SetAabbFromQuantizeNode(QuantizedBvhNode quantizedNode)
        {
            m_quantizedAabbMin = quantizedNode.m_quantizedAabbMin;
            m_quantizedAabbMax = quantizedNode.m_quantizedAabbMax;
        }
        //public void UnQuantize(UShortVector3 vecIn,out IndexedVector3 vecOut)
        //{
        //    UnQuantize(ref vecIn,out vecOut);
        //}

        public void UnQuantize(ref UShortVector3 vecIn, out IndexedVector3 vecOut)
        {
            vecOut = new IndexedVector3(((float)vecIn.X) / m_bvhQuantization.X,
                                        ((float)vecIn.Y) / m_bvhQuantization.Y,
                                        ((float)vecIn.Z) / m_bvhQuantization.Z);
            vecOut += m_bvhAabbMin;
        }
        //public void quantizeWithClamp(ref UShortVector3 result, ref UShortVector3 point2, bool isMax)
        //{

        //    Debug.Assert(m_useQuantization);

        //    IndexedVector3 clampedPoint = new IndexedVector3(point2.X, point2.Y, point2.Z);
        //    MathUtil.vectorMax(ref m_bvhAabbMin, ref clampedPoint);
        //    MathUtil.vectorMin(ref m_bvhAabbMax, ref clampedPoint);

        //    quantize(ref result, ref clampedPoint, isMax);
        //}

        public void QuantizeWithClamp(out UShortVector3 result, ref IndexedVector3 point2, bool isMax)
        {

            Debug.Assert(m_useQuantization);

            IndexedVector3 clampedPoint = point2;
            MathUtil.VectorMax(ref m_bvhAabbMin, ref clampedPoint);
            MathUtil.VectorMin(ref m_bvhAabbMax, ref clampedPoint);

            Quantize(out result, ref clampedPoint, isMax);
        }
        public void Quantize(out UShortVector3 result, ref IndexedVector3 point, bool isMax)
        {
            Debug.Assert(m_useQuantization);

            Debug.Assert(point.X <= m_bvhAabbMax.X);
            Debug.Assert(point.Y <= m_bvhAabbMax.Y);
            Debug.Assert(point.Z <= m_bvhAabbMax.Z);

            Debug.Assert(point.X >= m_bvhAabbMin.X);
            Debug.Assert(point.Y >= m_bvhAabbMin.Y);
            Debug.Assert(point.Z >= m_bvhAabbMin.Z);

            IndexedVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization;
            ///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative
            ///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly)
            ///@todo: double-check this

            result = new UShortVector3();
            if (isMax)
            {
                result.X = (ushort)(((ushort)(v.X + 1f) | 1));
                result.Y = (ushort)(((ushort)(v.Y + 1f) | 1));
                result.Z = (ushort)(((ushort)(v.Z + 1f) | 1));
            }
            else
            {
                result.X = (ushort)(((ushort)(v.X) & 0xfffe));
                result.Y = (ushort)(((ushort)(v.Y) & 0xfffe));
                result.Z = (ushort)(((ushort)(v.Z) & 0xfffe));
            }


#if DEBUG_CHECK_DEQUANTIZATION
            IndexedVector3 newPoint;
            UnQuantize(ref result, out newPoint);
            if (isMax)
            {
                if (newPoint.X < point.X)
                {
                    System.Console.WriteLine("unconservative X, diffX = {0}, oldX={1},newX={2}\n", newPoint.X - point.X, newPoint.X, point.X);
                }
                if (newPoint.Y < point.Y)
                {
                    System.Console.WriteLine("unconservative Y, diffY = {0}, oldY={1},newY={2}\n", newPoint.Y - point.Y, newPoint.Y, point.Y);
                }
                if (newPoint.Z < point.Z)
                {
                    System.Console.WriteLine("unconservative Z, diffZ = {0}, oldZ={1},newZ={2}\n", newPoint.Z - point.Z, newPoint.Z, point.Z);
                }
            }
            else
            {
                if (newPoint.X > point.X)
                {
                    System.Console.WriteLine("unconservative X, diffX = {0}, oldX={1},newX={2}\n", newPoint.X - point.X, newPoint.X, point.X);
                }
                if (newPoint.Y > point.Y)
                {
                    System.Console.WriteLine("unconservative Y, diffY = {0}, oldY={1},newY={2}\n", newPoint.Y - point.Y, newPoint.Y, point.Y);
                }
                if (newPoint.Z > point.Z)
                {
                    System.Console.WriteLine("unconservative Z, diffZ = {0}, oldZ={1},newZ={2}\n", newPoint.Z - point.Z, newPoint.Z, point.Z);
                }
            }
#endif //DEBUG_CHECK_DEQUANTIZATION

        }
 public void Max(ref UShortVector3 a)
 {
     if (X < a.X) X = a.X;
     if (Y < a.Y) Y = a.Y;
     if (Z < a.Z) Z = a.Z;
 }
 public void Min(ref UShortVector3 a)
 {
     if (X > a.X) X = a.X;
     if (Y > a.Y) Y = a.Y;
     if (Z > a.Z) Z = a.Z;
 }