// Find and return closer intersection of these two. If intersection is null then it's not really an intersection. public static MyIntersectionResultLineTriangle? GetCloserIntersection(ref MyIntersectionResultLineTriangle? a, ref MyIntersectionResultLineTriangle? b) { if (((a == null) && (b != null)) || ((a != null) && (b != null) && (b.Value.Distance < a.Value.Distance))) { // If only "b" contains valid intersection, or when it's closer than "a" return b; } else { // This will be returned also when ((a == null) && (b == null)) return a; } }
public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, MyEntity physObject, ref MyLine line) { Triangle = triangle; Entity = physObject; InputLineInObjectSpace = line; NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle); IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance; if (Entity is MyVoxelMap) { IntersectionPointInWorldSpace = IntersectionPointInObjectSpace; NormalInWorldSpace = NormalInObjectSpace; // This will move intersection point from world space into voxel map's object space IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((MyVoxelMap)Entity).PositionLeftBottomCorner; } else { Matrix worldMatrix = Entity.WorldMatrix; NormalInWorldSpace = MyUtils.GetTransformNormalNormalized(NormalInObjectSpace, ref worldMatrix); IntersectionPointInWorldSpace = MyUtils.GetTransform(IntersectionPointInObjectSpace, ref worldMatrix); } }
public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, MyEntity physObject, ref MyLine line) { Triangle = triangle; Entity = physObject; InputLineInObjectSpace = line; NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle); IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance; if (Entity is MyVoxelMap) { IntersectionPointInWorldSpace = IntersectionPointInObjectSpace; NormalInWorldSpace = NormalInObjectSpace; // This will move intersection point from world space into voxel map's object space IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((MyVoxelMap)Entity).PositionLeftBottomCorner; } else { Matrix worldMatrix = Entity.WorldMatrix; NormalInWorldSpace = MyUtils.GetTransformNormalNormalized(NormalInObjectSpace, ref worldMatrix); IntersectionPointInWorldSpace = MyUtils.GetTransform(IntersectionPointInObjectSpace, ref worldMatrix); } }
// Finds intersection between line and model, using octree for speedup the lookup. // Another speedup is, that first we check triangles that are directly in the node and then start // checking node's childs. But only if child node instersection is less than last know min distance. MyIntersectionResultLineTriangle? GetIntersectionWithLineRecursive(MyModel model, ref MyLine line, float? minDistanceUntilNow) { // Check if line intersects bounding box of this node and if distance to bounding box is less then last know min distance float? distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref line, ref m_boundingBox); if ((distanceToBoundingBox.HasValue == false) || ((minDistanceUntilNow != null) && (minDistanceUntilNow < distanceToBoundingBox.Value))) return null; // Triangles that are directly in this node MyIntersectionResultLineTriangle? foundIntersection = null; // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); MinerWars.AppCode.Game.Managers.MyPerformanceCounter.PerCameraDraw.RayCastTrianglesProcessed += m_triangleIndices.Count; for (int i = 0; i < m_triangleIndices.Count; i++) { int triangleIndex = m_triangleIndices[i]; model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); // First test intersection of triangleVertexes's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests. if (MyUtils.IsBoxIntersectingBox(triangleBoundingBox, ref line.BoundingBox) == true) { // See that we swaped vertex indices!! MyTriangle_Vertexes triangle; MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex]; triangle.Vertex0 = model.GetVertex(triangleIndices.I0); triangle.Vertex1 = model.GetVertex(triangleIndices.I2); triangle.Vertex2 = model.GetVertex(triangleIndices.I1); float? distance = MyUtils.GetLineTriangleIntersection(ref line, ref triangle); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((foundIntersection == null) || (distance.Value < foundIntersection.Value.Distance))) { Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); // We need to remember original triangleVertexes coordinates (not transformed by world matrix) foundIntersection = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value); } } } // Get intersection with childs of this node if (m_childs != null) { for (int i = 0; i < m_childs.Count; i++) { MyIntersectionResultLineTriangle? childIntersection = m_childs[i].GetIntersectionWithLineRecursive(model, ref line, (foundIntersection == null) ? (float?)null : foundIntersection.Value.Distance); // If intersection occured and if distance to intersection is closer to origin than any previous intersection foundIntersection = MyIntersectionResultLineTriangle.GetCloserIntersection(ref foundIntersection, ref childIntersection); } } return foundIntersection; }