public virtual void InternalProcessTriangleIndex(ObjectArray<Vector3> triangle, int partId, int triangleIndex) { // The partId and triangle index must fit in the same (positive) integer Debug.Assert(partId < (1<<MAX_NUM_PARTS_IN_BITS)); Debug.Assert(triangleIndex < (1 << (31 - MAX_NUM_PARTS_IN_BITS))); //negative indices are reserved for escapeIndex Debug.Assert(triangleIndex >= 0); QuantizedBvhNode node = new QuantizedBvhNode(); Vector3 aabbMin,aabbMax; aabbMin = MathUtil.MAX_VECTOR; aabbMax = MathUtil.MIN_VECTOR; Vector3 t1 = triangle[0]; Vector3 t2 = triangle[1]; Vector3 t3 = triangle[2]; MathUtil.VectorMin(ref t1, ref aabbMin); MathUtil.VectorMax(ref t1, ref aabbMax); MathUtil.VectorMin(ref t2, ref aabbMin); MathUtil.VectorMax(ref t2, ref aabbMax); MathUtil.VectorMin(ref t3, ref aabbMin); MathUtil.VectorMax(ref t3, ref aabbMax); //PCK: add these checks for zero dimensions of aabb float MIN_AABB_DIMENSION = 0.002f; float MIN_AABB_HALF_DIMENSION = 0.001f; if (aabbMax.X - aabbMin.X < MIN_AABB_DIMENSION) { aabbMax.X = (aabbMax.X + MIN_AABB_HALF_DIMENSION); aabbMin.X = (aabbMin.X - MIN_AABB_HALF_DIMENSION); } if (aabbMax.Y - aabbMin.Y < MIN_AABB_DIMENSION) { aabbMax.Y = (aabbMax.Y + MIN_AABB_HALF_DIMENSION); aabbMin.Y = (aabbMin.Y - MIN_AABB_HALF_DIMENSION); } if (aabbMax.Z - aabbMin.Z < MIN_AABB_DIMENSION) { aabbMax.Z = (aabbMax.Z + MIN_AABB_HALF_DIMENSION); aabbMin.Z = (aabbMin.Z - MIN_AABB_HALF_DIMENSION); } m_optimizedTree.Quantize(ref node.m_quantizedAabbMin,ref aabbMin,false); m_optimizedTree.Quantize(ref node.m_quantizedAabbMax,ref aabbMax,true); node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; m_triangleNodes.Add(node); }
public virtual void InternalProcessTriangleIndex(IndexedVector3[] triangle, int partId, int triangleIndex) { // The partId and triangle index must fit in the same (positive) integer Debug.Assert(partId < (1 << MAX_NUM_PARTS_IN_BITS)); Debug.Assert(triangleIndex < (1 << (31 - MAX_NUM_PARTS_IN_BITS))); //negative indices are reserved for escapeIndex Debug.Assert(triangleIndex >= 0); QuantizedBvhNode node = new QuantizedBvhNode(); IndexedVector3 aabbMin, aabbMax; aabbMin = MathUtil.MAX_VECTOR; aabbMax = MathUtil.MIN_VECTOR; MathUtil.VectorMin(ref triangle[0], ref aabbMin); MathUtil.VectorMax(ref triangle[0], ref aabbMax); MathUtil.VectorMin(ref triangle[1], ref aabbMin); MathUtil.VectorMax(ref triangle[1], ref aabbMax); MathUtil.VectorMin(ref triangle[2], ref aabbMin); MathUtil.VectorMax(ref triangle[2], ref aabbMax); //PCK: add these checks for zero dimensions of aabb float MIN_AABB_DIMENSION = 0.002f; float MIN_AABB_HALF_DIMENSION = 0.001f; if (aabbMax.X - aabbMin.X < MIN_AABB_DIMENSION) { aabbMax.X = (aabbMax.X + MIN_AABB_HALF_DIMENSION); aabbMin.X = (aabbMin.X - MIN_AABB_HALF_DIMENSION); } if (aabbMax.Y - aabbMin.Y < MIN_AABB_DIMENSION) { aabbMax.Y = (aabbMax.Y + MIN_AABB_HALF_DIMENSION); aabbMin.Y = (aabbMin.Y - MIN_AABB_HALF_DIMENSION); } if (aabbMax.Z - aabbMin.Z < MIN_AABB_DIMENSION) { aabbMax.Z = (aabbMax.Z + MIN_AABB_HALF_DIMENSION); aabbMin.Z = (aabbMin.Z - MIN_AABB_HALF_DIMENSION); } m_optimizedTree.Quantize(out node.m_quantizedAabbMin, ref aabbMin, false); m_optimizedTree.Quantize(out node.m_quantizedAabbMax, ref aabbMax, true); node.m_escapeIndexOrTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex; m_triangleNodes.Add(node); }
public void BuildTree(ref IndexedVector3 bvhAabbMin, ref IndexedVector3 bvhAabbMax) { m_optimizedAabbTree = new QuantizedBvh(); m_optimizedAabbTree.SetQuantizationValues(ref bvhAabbMin, ref bvhAabbMax); IList <QuantizedBvhNode> nodes = m_optimizedAabbTree.GetLeafNodeArray(); for (int i = 0; i < m_sapBroadphases.Count; i++) { QuantizedBvhNode node = new QuantizedBvhNode(); IndexedVector3 aabbMin; IndexedVector3 aabbMax; m_sapBroadphases[i].GetBroadphaseAabb(out aabbMin, out aabbMax); m_optimizedAabbTree.Quantize(out node.m_quantizedAabbMin, ref aabbMin, false); m_optimizedAabbTree.Quantize(out node.m_quantizedAabbMax, ref aabbMax, true); int partId = 0; node.m_escapeIndexOrTriangleIndex = (partId << (31 - QuantizedBvh.MAX_NUM_PARTS_IN_BITS)) | i; nodes.Add(node); } m_optimizedAabbTree.BuildInternal(); }
//int m_padding[3]; public void SetAabbFromQuantizeNode(QuantizedBvhNode quantizedNode) { m_quantizedAabbMin = quantizedNode.m_quantizedAabbMin; m_quantizedAabbMax = quantizedNode.m_quantizedAabbMax; }
public void UpdateBvhNodes(StridingMeshInterface meshInterface, int firstNode, int endNode, int index) { //(void)index; Debug.Assert(m_useQuantization); int curNodeSubPart = -1; //get access info to trianglemesh data Object vertexBaseObject = null; int numverts = 0; PHY_ScalarType type = PHY_ScalarType.PHY_INTEGER; int stride = 0; Object indexBaseObject = null; int indexstride = 0; int numfaces = 0; PHY_ScalarType indicestype = PHY_ScalarType.PHY_INTEGER; IndexedVector3[] triangleVerts = new IndexedVector3[3]; IndexedVector3 aabbMin, aabbMax; IndexedVector3 meshScaling = meshInterface.GetScaling(); for (int i = endNode - 1; i >= firstNode; i--) { QuantizedBvhNode curNode = m_quantizedContiguousNodes[i]; if (curNode.IsLeafNode()) { //recalc aabb from triangle data int nodeSubPart = curNode.GetPartId(); int nodeTriangleIndex = curNode.GetTriangleIndex(); if (nodeSubPart != curNodeSubPart) { if (curNodeSubPart >= 0) { meshInterface.UnLockReadOnlyVertexBase(curNodeSubPart); } meshInterface.GetLockedReadOnlyVertexIndexBase(out vertexBaseObject, out numverts, out type, out stride, out indexBaseObject, out indexstride, out numfaces, out indicestype, nodeSubPart); curNodeSubPart = nodeSubPart; Debug.Assert(indicestype == PHY_ScalarType.PHY_INTEGER); } //triangles.getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, int gfxBaseIndex = nodeTriangleIndex * indexstride; //unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); int[] indexBase = (indexBaseObject as ObjectArray <int>).GetRawArray(); if (vertexBaseObject is IList <IndexedVector3> ) { IndexedVector3[] vertexBase = (vertexBaseObject as ObjectArray <IndexedVector3>).GetRawArray(); for (int j = 2; j >= 0; j--) { int graphicsIndex = indexBase[gfxBaseIndex + j]; if (type == PHY_ScalarType.PHY_FLOAT) { triangleVerts[j] = vertexBase[graphicsIndex] * meshScaling; } else { Debug.Assert(false, "Unsupported Type"); } } } else if (vertexBaseObject is ObjectArray <float> ) { float[] vertexBase = (vertexBaseObject as ObjectArray <float>).GetRawArray(); for (int j = 2; j >= 0; j--) { //int graphicsindex = indicestype==PHY_ScalarType.PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; int graphicsIndex = indexBase[gfxBaseIndex + j]; if (type == PHY_ScalarType.PHY_FLOAT) { int graphicsBaseIndex = (graphicsIndex * stride); //IList<float> graphicsbase = (float*)(vertexbase+graphicsindex*stride); triangleVerts[j] = new IndexedVector3( vertexBase[graphicsBaseIndex] * meshScaling.X, vertexBase[graphicsBaseIndex + 1] * meshScaling.Y, vertexBase[graphicsBaseIndex + 2] * meshScaling.Z); } else { Debug.Assert(false, "Unsupported Type"); } } } else { Debug.Assert(false, "Unsupported Type"); } aabbMin = MathUtil.MAX_VECTOR; aabbMax = MathUtil.MIN_VECTOR; MathUtil.VectorMin(ref triangleVerts[0], ref aabbMin); MathUtil.VectorMax(ref triangleVerts[0], ref aabbMax); MathUtil.VectorMin(ref triangleVerts[1], ref aabbMin); MathUtil.VectorMax(ref triangleVerts[1], ref aabbMax); MathUtil.VectorMin(ref triangleVerts[2], ref aabbMin); MathUtil.VectorMax(ref triangleVerts[2], ref aabbMax); Quantize(out curNode.m_quantizedAabbMin, ref aabbMin, false); Quantize(out curNode.m_quantizedAabbMax, ref aabbMax, true); } else { //combine aabb from both children QuantizedBvhNode leftChildNode = m_quantizedContiguousNodes[i + 1]; QuantizedBvhNode rightChildNode = leftChildNode.IsLeafNode() ? m_quantizedContiguousNodes[i + 2] : m_quantizedContiguousNodes[i + 1 + leftChildNode.GetEscapeIndex()]; { curNode.m_quantizedAabbMin = leftChildNode.m_quantizedAabbMin; curNode.m_quantizedAabbMin.Min(ref rightChildNode.m_quantizedAabbMin); curNode.m_quantizedAabbMax = leftChildNode.m_quantizedAabbMax; curNode.m_quantizedAabbMax.Max(ref rightChildNode.m_quantizedAabbMax); } } } if (curNodeSubPart >= 0) { meshInterface.UnLockReadOnlyVertexBase(curNodeSubPart); } }
public void BuildTree(ref Vector3 bvhAabbMin, ref Vector3 bvhAabbMax) { m_optimizedAabbTree = new QuantizedBvh(); m_optimizedAabbTree.SetQuantizationValues(ref bvhAabbMin, ref bvhAabbMax); IList<QuantizedBvhNode> nodes = m_optimizedAabbTree.GetLeafNodeArray(); for (int i = 0; i < m_sapBroadphases.Count; i++) { QuantizedBvhNode node = new QuantizedBvhNode(); Vector3 aabbMin = Vector3.Zero, aabbMax = Vector3.Zero; m_sapBroadphases[i].GetBroadphaseAabb(ref aabbMin, ref aabbMax); m_optimizedAabbTree.Quantize(ref node.m_quantizedAabbMin, ref aabbMin, false); m_optimizedAabbTree.Quantize(ref node.m_quantizedAabbMax, ref aabbMax, true); int partId = 0; node.m_escapeIndexOrTriangleIndex = (partId << (31 - QuantizedBvh.MAX_NUM_PARTS_IN_BITS)) | i; nodes.Add(node); } m_optimizedAabbTree.BuildInternal(); }
///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal protected void WalkRecursiveQuantizedTreeAgainstQuantizedTree(QuantizedBvhNode treeNodeA, QuantizedBvhNode treeNodeB, INodeOverlapCallback nodeCallback) { // MAN - No implementation?? }
///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; QuantizedBvhNode leftChildNode = m_quantizedContiguousNodes[nodeIndex]; WalkRecursiveQuantizedTreeAgainstQueryAabb(ref leftChildNode, nodeCallback, ref quantizedQueryAabbMin, ref quantizedQueryAabbMax); int newIndex = leftChildNode.IsLeafNode() ? leftChildNode.GetTriangleIndex() + 1 : leftChildNode.GetTriangleIndex() + leftChildNode.GetEscapeIndex(); QuantizedBvhNode rightChildNode = m_quantizedContiguousNodes[newIndex]; WalkRecursiveQuantizedTreeAgainstQueryAabb(ref rightChildNode, nodeCallback, ref quantizedQueryAabbMin, ref quantizedQueryAabbMax); } } }