private float?ProcessTriangle(int triangleIndex) { System.Diagnostics.Debug.Assert((int)m_flags != 0); MyTriangle_Vertexes triangle; MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex]; m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2); Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); //We dont want backside intersections if (((int)(m_flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) && Vector3.Dot(m_line.Direction, calculatedTriangleNormal) > 0) { return(null); } Line lineF = (Line)m_line; float?distance = MyUtils.GetLineTriangleIntersection(ref lineF, ref triangle); if (distance.HasValue) { MyTriangle_BoneWeigths?boneWeights = m_model.GetBoneWeights(triangleIndex); var result = new MyIntersectionResultLineTriangle(ref triangle, ref boneWeights, ref calculatedTriangleNormal, distance.Value); m_result.Add(result); } return(distance); }
private float?ProcessTriangle(int triangleIndex) { System.Diagnostics.Debug.Assert((int)m_flags != 0); MyTriangle_Vertexes triangle; MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex]; m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2); Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); //We dont want backside intersections if (((int)(m_flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) && Vector3.Dot(m_line.Direction, calculatedTriangleNormal) > 0) { return(null); } Line lineF = (Line)m_line; float?distance = MyUtils.GetLineTriangleIntersection(ref lineF, ref triangle); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((m_result == null) || (distance.Value < m_result.Value.Distance))) { // We need to remember original triangleVertexes coordinates (not transformed by world matrix) MyTriangle_BoneWeigths?boneWeights = m_model.GetBoneWeights(triangleIndex); m_result = new MyIntersectionResultLineTriangle(ref triangle, ref boneWeights, ref calculatedTriangleNormal, distance.Value); return(distance.Value); } return(null); }
public void GetTrianglesIntersectingAABB(ref BoundingBoxD aabb, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles) { BoundingBox boxF = (BoundingBox)aabb; IndexedVector3 min = boxF.Min.ToBullet(); IndexedVector3 max = boxF.Max.ToBullet(); AABB gi_aabb = new AABB(ref min, ref max); m_overlappedTriangles.Clear(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.BoxQuery"); bool res = m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (res) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_overlappedTriangles"); //foreach (var triangleIndex in m_overlappedTriangles) for (int i = 0; i < m_overlappedTriangles.Count; i++) { var triangleIndex = m_overlappedTriangles[i]; // If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow. if (retTriangles.Count == maxNeighbourTriangles) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); return; } MyTriangleVertexIndices triangle = m_model.Triangles[triangleIndex]; MyTriangle_Vertices triangleVertices = new MyTriangle_Vertices(); m_model.GetVertex(triangle.I0, triangle.I1, triangle.I2, out triangleVertices.Vertex0, out triangleVertices.Vertex1, out triangleVertices.Vertex2); IndexedVector3 iv0 = triangleVertices.Vertex0.ToBullet(); IndexedVector3 iv1 = triangleVertices.Vertex1.ToBullet(); IndexedVector3 iv2 = triangleVertices.Vertex2.ToBullet(); MyTriangle_Vertex_Normal retTriangle; retTriangle.Vertexes = triangleVertices; retTriangle.Normal = Vector3.Forward; retTriangles.Add(retTriangle); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
public bool GetIntersectionWithSphere(IMyEntity entity, ref BoundingSphereD sphere) { // Transform sphere from world space to object space MatrixD worldInv = entity.PositionComp.WorldMatrixNormalizedInv; Vector3 positionInObjectSpace = (Vector3)Vector3D.Transform(sphere.Center, ref worldInv); BoundingSphereD sphereInObjectSpace = new BoundingSphereD(positionInObjectSpace, (float)sphere.Radius); var aabb = BoundingBox.CreateInvalid(); BoundingSphere sphereF = (BoundingSphere)sphereInObjectSpace; aabb.Include(ref sphereF); AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet()); m_overlappedTriangles.Clear(); if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles)) { // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); // Triangles that are directly in this node for (int i = 0; i < m_overlappedTriangles.Count; i++) { var triangleIndex = m_overlappedTriangles[i]; m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); // First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests. if (triangleBoundingBox.Intersects(ref sphereInObjectSpace)) { // See that we swaped vertex indices!! MyTriangle_Vertices triangle; MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex]; triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0); triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2); triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1); PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2); if (MyUtils.GetSphereTriangleIntersection(ref sphereInObjectSpace, ref trianglePlane, ref triangle) != null) { // If we found intersection we can stop and dont need to look further return(true); } } } } return(false); }
public MyTriangle_BoneIndicesWeigths?GetBoneIndicesWeights(int triangleIndex) { if (m_bonesIndicesWeights == null) { return(null); } MyTriangleVertexIndices indices = Triangles[triangleIndex]; MyCompressedBoneIndicesWeights boneIndicesWeightsV0 = m_bonesIndicesWeights[indices.I0]; MyCompressedBoneIndicesWeights boneIndicesWeightsV1 = m_bonesIndicesWeights[indices.I1]; MyCompressedBoneIndicesWeights boneIndicesWeightsV2 = m_bonesIndicesWeights[indices.I2]; Vector4UByte indicesV0 = boneIndicesWeightsV0.Indices.ToVector4UByte(); Vector4 weightsV0 = boneIndicesWeightsV0.Weights.ToVector4(); Vector4UByte indicesV1 = boneIndicesWeightsV1.Indices.ToVector4UByte(); Vector4 weightsV1 = boneIndicesWeightsV1.Weights.ToVector4(); Vector4UByte indicesV2 = boneIndicesWeightsV2.Indices.ToVector4UByte(); Vector4 weightsV2 = boneIndicesWeightsV2.Weights.ToVector4(); MyTriangle_BoneIndicesWeigths ret = new MyTriangle_BoneIndicesWeigths() { Vertex0 = new MyVertex_BoneIndicesWeights() { Indices = indicesV0, Weights = weightsV0 }, Vertex1 = new MyVertex_BoneIndicesWeights() { Indices = indicesV1, Weights = weightsV1 }, Vertex2 = new MyVertex_BoneIndicesWeights() { Indices = indicesV2, Weights = weightsV2 } }; return(ret); }
public MyTriangle_BoneWeigths?GetBoneWeights(int triangleIndex) { if (m_bonesWeights == null) { return(null); } MyTriangleVertexIndices indices = Triangles[triangleIndex]; MyCompressedBoneWeights boneWeightV0 = m_bonesWeights[indices.I0]; MyCompressedBoneWeights boneWeightV1 = m_bonesWeights[indices.I1]; MyCompressedBoneWeights boneWeightV2 = m_bonesWeights[indices.I2]; Vector4 indicesV0 = boneWeightV0.Indices.ToVector4(); Vector4 weightsV0 = boneWeightV0.Weights.ToVector4(); Vector4 indicesV1 = boneWeightV1.Indices.ToVector4(); Vector4 weightsV1 = boneWeightV1.Weights.ToVector4(); Vector4 indicesV2 = boneWeightV2.Indices.ToVector4(); Vector4 weightsV2 = boneWeightV2.Weights.ToVector4(); MyTriangle_BoneWeigths ret = new MyTriangle_BoneWeigths() { Vertex0 = new MyVertex_BoneWeight() { Indices = new Vector3(indicesV0), Weights = new Vector3(weightsV0) }, Vertex1 = new MyVertex_BoneWeight() { Indices = new Vector3(indicesV1), Weights = new Vector3(weightsV1) }, Vertex2 = new MyVertex_BoneWeight() { Indices = new Vector3(indicesV2), Weights = new Vector3(weightsV2) } }; return(ret); }
void CopyTriangleIndices() { Triangles = new MyTriangleVertexIndices[GetNumberOfTrianglesForColDet()]; int triangleIndex = 0; foreach (MyMesh mesh in m_meshContainer) { mesh.TriStart = triangleIndex; if (m_Indices != null) { for (int i = 0; i < mesh.TriCount; i++) { // Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order. // But because of this, I did similar swaping in my col/det functions Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices[mesh.IndexStart + i * 3 + 0], m_Indices[mesh.IndexStart + i * 3 + 2], m_Indices[mesh.IndexStart + i * 3 + 1]); triangleIndex++; } } else if (m_Indices_16bit != null) { for (int i = 0; i < mesh.TriCount; i++) { // Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order. // But because of this, I did similar swaping in my col/det functions Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices_16bit[mesh.IndexStart + i * 3 + 0], m_Indices_16bit[mesh.IndexStart + i * 3 + 2], m_Indices_16bit[mesh.IndexStart + i * 3 + 1]); triangleIndex++; } } else { throw new InvalidBranchException(); // Neither 32bit or 16bit indices are set, probably already called mesh.DisposeIndices() } } CheckTriangles(triangleIndex); }
void CopyTriangleIndices() { Triangles = new MyTriangleVertexIndices[GetNumberOfTrianglesForColDet()]; int triangleIndex = 0; foreach (MyMesh mesh in m_meshContainer) { mesh.TriStart = triangleIndex; if (m_Indices != null) { for (int i = 0; i < mesh.TriCount; i++) { // Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order. // But because of this, I did similar swaping in my col/det functions Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices[mesh.IndexStart + i * 3 + 0], m_Indices[mesh.IndexStart + i * 3 + 2], m_Indices[mesh.IndexStart + i * 3 + 1]); triangleIndex++; } } else if (m_Indices_16bit != null) { for (int i = 0; i < mesh.TriCount; i++) { // Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order. // But because of this, I did similar swaping in my col/det functions Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices_16bit[mesh.IndexStart + i * 3 + 0], m_Indices_16bit[mesh.IndexStart + i * 3 + 2], m_Indices_16bit[mesh.IndexStart + i * 3 + 1]); triangleIndex++; } } else throw new InvalidBranchException(); // Neither 32bit or 16bit indices are set, probably already called mesh.DisposeIndices() } CheckTriangles(triangleIndex); }
public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles) { Vector3?referenceNormalVector = null; float? maxAngle = null; var aabb = BoundingBox.CreateInvalid(); BoundingSphere sphereF = (BoundingSphere)sphere; aabb.Include(ref sphereF); AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet()); m_overlappedTriangles.Clear(); // VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.BoxQuery"); // This code is called recursively and cause profiler to lag bool res = m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles); // VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (res) { //VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_overlappedTriangles"); // This code is called recursively and cause profiler to lag // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); for (int i = 0; i < m_overlappedTriangles.Count; i++) { var triangleIndex = m_overlappedTriangles[i]; // If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow. if (retTriangles.Count == maxNeighbourTriangles) { return; } m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); //gi_aabb.CollideTriangleExact // First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests. if (triangleBoundingBox.Intersects(ref sphere)) { //if (m_triangleIndices[value] != ignoreTriangleWithIndex) { // See that we swaped vertex indices!! MyTriangle_Vertices triangle; MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex]; triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0); triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2); triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1); Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2); if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null) { Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) || ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle))) { MyTriangle_Vertex_Normal retTriangle; retTriangle.Vertexes = triangle; retTriangle.Normal = calculatedTriangleNormal; retTriangles.Add(retTriangle); } } } } } //VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles) { var aabb = BoundingBox.CreateInvalid(); BoundingSphere sphereF = (BoundingSphere)sphere; aabb.Include(ref sphereF); AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet()); m_overlappedTriangles.Clear(); if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles)) { // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); for (int i = 0; i < m_overlappedTriangles.Count; i++) { var triangleIndex = m_overlappedTriangles[i]; // If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow. if (retTriangles.Count == maxNeighbourTriangles) { return; } m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); // First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests. if (triangleBoundingBox.Intersects(ref sphere)) { //if (m_triangleIndices[value] != ignoreTriangleWithIndex) { // See that we swaped vertex indices!! MyTriangle_Vertices triangle; MyTriangle_Normals triangleNormals; //MyTriangle_Normals triangleTangents; MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex]; m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2); /* * triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0); * triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2); * triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1); */ triangleNormals.Normal0 = m_model.GetVertexNormal(triangleIndices.I0); triangleNormals.Normal1 = m_model.GetVertexNormal(triangleIndices.I2); triangleNormals.Normal2 = m_model.GetVertexNormal(triangleIndices.I1); PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2); if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null) { Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) || ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle))) { MyTriangle_Vertex_Normals retTriangle; retTriangle.Vertices = triangle; retTriangle.Normals = triangleNormals; retTriangles.Add(retTriangle); } } } } } } }