public void Unlock() { if (m_lock_count == 0) { return; } if (m_lock_count > 1) { --m_lock_count; return; } m_meshInterface.UnLockReadOnlyVertexBase(m_part); vertexbase = null; m_lock_count = 0; }
public virtual void ProcessNode(int nodeSubPart, int nodeTriangleIndex) { //m_triangle.Clear(); Object vertexBase; int numVerts; PHY_ScalarType type; int stride; Object indexBase; int indexStride; int numfaces; PHY_ScalarType indicesType; m_meshInterface.GetLockedReadOnlyVertexIndexBase( out vertexBase, out numVerts, out type, out stride, out indexBase, out indexStride, out numfaces, out indicesType, nodeSubPart); //unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); // force index stride to be 1 regardless. indexStride = 3; int indexIndex = nodeTriangleIndex * indexStride; Debug.Assert(indicesType == PHY_ScalarType.PHY_INTEGER || indicesType == PHY_ScalarType.PHY_SHORT); IndexedVector3 meshScaling = m_meshInterface.GetScaling(); int[] indexRaw = ((ObjectArray <int>)indexBase).GetRawArray(); if (vertexBase is ObjectArray <IndexedVector3> ) { IndexedVector3[] vertexBaseRaw = ((ObjectArray <IndexedVector3>)vertexBase).GetRawArray(); for (int j = 2; j >= 0; j--) { m_triangle[j] = vertexBaseRaw[indexRaw[indexIndex + j]]; m_triangle[j] *= meshScaling; } } else if (vertexBase is ObjectArray <Microsoft.Xna.Framework.Vector3> ) { Microsoft.Xna.Framework.Vector3[] vertexBaseRaw = ((ObjectArray <Microsoft.Xna.Framework.Vector3>)vertexBase).GetRawArray(); for (int j = 2; j >= 0; j--) { m_triangle[j] = new IndexedVector3(vertexBaseRaw[indexRaw[indexIndex + j]]); m_triangle[j] *= meshScaling; } } else if (vertexBase is ObjectArray <float> ) { float[] floats = ((ObjectArray <float>)vertexBase).GetRawArray(); for (int j = 2; j >= 0; j--) { int offset = indexRaw[indexIndex + j] * 3; m_triangle[j] = new IndexedVector3(floats[offset] * meshScaling.X, floats[offset + 1] * meshScaling.Y, floats[offset + 2] * meshScaling.Z); } } else { Debug.Assert(false, "Unsupported type."); } //FIXME - Debug here and on quantized Bvh walking #if DEBUG if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugBVHTriangleMesh) { BulletGlobals.g_streamWriter.WriteLine("BVH Triangle"); MathUtil.PrintVector3(BulletGlobals.g_streamWriter, m_triangle[0]); MathUtil.PrintVector3(BulletGlobals.g_streamWriter, m_triangle[1]); MathUtil.PrintVector3(BulletGlobals.g_streamWriter, m_triangle[2]); } #endif /* Perform ray vs. triangle collision here */ m_callback.ProcessTriangle(m_triangle, nodeSubPart, nodeTriangleIndex); m_meshInterface.UnLockReadOnlyVertexBase(nodeSubPart); }
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); } }