public MyIntersectionResultLineTriangle(ref MyTriangle_Vertices triangle, ref MyTriangle_BoneIndicesWeigths? boneWeigths, ref Vector3 triangleNormal, double distance) { InputTriangle = triangle; InputTriangleNormal = triangleNormal; Distance = distance; BoneWeights = boneWeigths; }
public MyIntersectionResultLineTriangle(ref MyTriangle_Vertices triangle, ref MyTriangle_BoneIndicesWeigths?boneWeigths, ref Vector3 triangleNormal, double distance) { InputTriangle = triangle; InputTriangleNormal = triangleNormal; Distance = distance; BoneWeights = boneWeigths; }
public MyIntersectionResultLineTriangle(int triangleIndex, ref MyTriangle_Vertices triangle, ref Vector3 triangleNormal, double distance) { InputTriangle = triangle; InputTriangleNormal = triangleNormal; Distance = distance; BoneWeights = null; TriangleIndex = triangleIndex; }
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(); } }
/// <summary> /// Return true if point is inside the triangle. /// </summary> public static bool GetInsidePolygonForSphereCollision(ref Vector3 point, ref MyTriangle_Vertices triangle) { const float MATCH_FACTOR = 0.99f; // Used to cover up the error in floating point float angle = 0.0f; // Initialize the angle // Spocitame uhol medzi bodmi trojuholnika a intersection bodu (ale na vypocet uhlov pouzivame funkciu ktora je // bezpecna aj pre sphere coldet, problem so SafeACos()) angle += GetAngleBetweenVectorsForSphereCollision(triangle.Vertex0 - point, triangle.Vertex1 - point); // Find the angle between the 2 vectors and add them all up as we go along angle += GetAngleBetweenVectorsForSphereCollision(triangle.Vertex1 - point, triangle.Vertex2 - point); // Find the angle between the 2 vectors and add them all up as we go along angle += GetAngleBetweenVectorsForSphereCollision(triangle.Vertex2 - point, triangle.Vertex0 - point); // Find the angle between the 2 vectors and add them all up as we go along if (angle >= (MATCH_FACTOR * (2.0 * MathHelper.Pi))) // If the angle is greater than 2 PI, (360 degrees) { return(true); // The point is inside of the polygon } return(false); // If you get here, it obviously wasn't inside the polygon, so Return FALSE }
/// <summary> /// Return true if point is inside the triangle. /// </summary> public static bool GetInsidePolygonForSphereCollision(ref Vector3 point, ref MyTriangle_Vertices triangle) { const float MATCH_FACTOR = 0.99f; // Used to cover up the error in floating point float angle = 0.0f; // Initialize the angle // Spocitame uhol medzi bodmi trojuholnika a intersection bodu (ale na vypocet uhlov pouzivame funkciu ktora je // bezpecna aj pre sphere coldet, problem so SafeACos()) angle += GetAngleBetweenVectorsForSphereCollision(triangle.Vertex0 - point, triangle.Vertex1 - point); // Find the angle between the 2 vectors and add them all up as we go along angle += GetAngleBetweenVectorsForSphereCollision(triangle.Vertex1 - point, triangle.Vertex2 - point); // Find the angle between the 2 vectors and add them all up as we go along angle += GetAngleBetweenVectorsForSphereCollision(triangle.Vertex2 - point, triangle.Vertex0 - point); // Find the angle between the 2 vectors and add them all up as we go along if (angle >= (MATCH_FACTOR * (2.0 * MathHelper.Pi))) // If the angle is greater than 2 PI, (360 degrees) { return true; // The point is inside of the polygon } return false; // If you get here, it obviously wasn't inside the polygon, so Return FALSE }
/// <summary> /// Returns intersection point between sphere and its edges. But only if there is intersection between sphere and one of the edges. /// If sphere intersects somewhere inside the triangle, this method will not detect it. /// </summary> public static Vector3? GetEdgeSphereCollision(ref Vector3D sphereCenter, float sphereRadius, ref MyTriangle_Vertices triangle) { Vector3 intersectionPoint; // This returns the closest point on the current edge to the center of the sphere. intersectionPoint = GetClosestPointOnLine(ref triangle.Vertex0, ref triangle.Vertex1, ref sphereCenter); // Now, we want to calculate the distance between the closest point and the center float distance1 = Vector3.Distance(intersectionPoint, sphereCenter); // If the distance is less than the radius, there must be a collision so return true if (distance1 < sphereRadius) { return intersectionPoint; } // This returns the closest point on the current edge to the center of the sphere. intersectionPoint = GetClosestPointOnLine(ref triangle.Vertex1, ref triangle.Vertex2, ref sphereCenter); // Now, we want to calculate the distance between the closest point and the center float distance2 = Vector3.Distance(intersectionPoint, sphereCenter); // If the distance is less than the radius, there must be a collision so return true if (distance2 < sphereRadius) { return intersectionPoint; } // This returns the closest point on the current edge to the center of the sphere. intersectionPoint = GetClosestPointOnLine(ref triangle.Vertex2, ref triangle.Vertex0, ref sphereCenter); // Now, we want to calculate the distance between the closest point and the center float distance3 = Vector3.Distance(intersectionPoint, sphereCenter); // If the distance is less than the radius, there must be a collision so return true if (distance3 < sphereRadius) { return intersectionPoint; } // The was no intersection of the sphere and the edges of the polygon return null; }
public override void DebugDraw() { Vector3D positionLeftBottomCorner = this.m_planet.PositionLeftBottomCorner; if (MyDebugDrawSettings.DEBUG_DRAW_VOXEL_MAP_AABB) { this.m_planet.Components.Get <MyPlanetEnvironmentComponent>().DebugDraw(); this.m_planet.DebugDrawPhysics(); MyRenderProxy.DebugDrawAABB(this.m_planet.PositionComp.WorldAABB, Color.White, 1f, 1f, true, false, false); MyRenderProxy.DebugDrawLine3D(positionLeftBottomCorner, positionLeftBottomCorner + new Vector3(1f, 0f, 0f), Color.Red, Color.Red, true, false); MyRenderProxy.DebugDrawLine3D(positionLeftBottomCorner, positionLeftBottomCorner + new Vector3(0f, 1f, 0f), Color.Green, Color.Green, true, false); MyRenderProxy.DebugDrawLine3D(positionLeftBottomCorner, positionLeftBottomCorner + new Vector3(0f, 0f, 1f), Color.Blue, Color.Blue, true, false); MyRenderProxy.DebugDrawAxis(this.m_planet.PositionComp.WorldMatrix, 2f, false, false, false); MyRenderProxy.DebugDrawSphere(this.m_planet.PositionComp.GetPosition(), 1f, Color.OrangeRed, 1f, false, false, true, false); } if (MyDebugDrawSettings.DEBUG_DRAW_VOXEL_GEOMETRY_CELL) { MyIntersectionResultLineTriangleEx?nullable; MyCamera mainCamera = MySector.MainCamera; LineD line = new LineD(mainCamera.Position, mainCamera.Position + (25f * mainCamera.ForwardVector)); if (this.m_planet.GetIntersectionWithLine(ref line, out nullable, IntersectionFlags.ALL_TRIANGLES)) { Vector3I vectori; Vector3I vectori2; BoundingBoxD xd2; MyTriangle_Vertices inputTriangle = nullable.Value.Triangle.InputTriangle; MyRenderProxy.DebugDrawTriangle(inputTriangle.Vertex0 + positionLeftBottomCorner, inputTriangle.Vertex1 + positionLeftBottomCorner, inputTriangle.Vertex2 + positionLeftBottomCorner, Color.Red, true, false, false); Vector3D intersectionPointInWorldSpace = nullable.Value.IntersectionPointInWorldSpace; MyVoxelCoordSystems.WorldPositionToVoxelCoord(positionLeftBottomCorner, ref intersectionPointInWorldSpace, out vectori2); MyVoxelCoordSystems.VoxelCoordToWorldAABB(positionLeftBottomCorner, ref vectori2, out xd2); MyRenderProxy.DebugDrawAABB(xd2, Vector3.UnitY, 1f, 1f, true, false, false); MyVoxelCoordSystems.WorldPositionToGeometryCellCoord(positionLeftBottomCorner, ref intersectionPointInWorldSpace, out vectori); MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(positionLeftBottomCorner, ref vectori, out xd2); MyRenderProxy.DebugDrawAABB(xd2, Vector3.UnitZ, 1f, 1f, true, false, false); } } }
public MyPlane(ref MyTriangle_Vertices triangle) { Point = triangle.Vertex0; Normal = MyUtils.Normalize(Vector3.Cross((triangle.Vertex1 - triangle.Vertex0), (triangle.Vertex2 - triangle.Vertex0))); }
/// <summary> /// Method returns intersection point between sphere and triangle (which is defined by vertexes and plane). /// If no intersection found, method returns null. /// See below how intersection point can be calculated, because it's not so easy - for example sphere vs. triangle will /// hardly generate just intersection point... more like intersection area or something. /// </summary> public static Vector3?GetSphereTriangleIntersection(ref BoundingSphereD sphere, ref PlaneD trianglePlane, ref MyTriangle_Vertices triangle) { // Vzdialenost gule od roviny trojuholnika double distance; // Zistim, ci sa gula nachadza pred alebo za rovinou trojuholnika, alebo ju presekava MySpherePlaneIntersectionEnum spherePlaneIntersection = GetSpherePlaneIntersection(ref sphere, ref trianglePlane, out distance); // Ak gula presekava rovinu, tak hladam pseudo-priesecnik if (spherePlaneIntersection == MySpherePlaneIntersectionEnum.INTERSECTS) { // Offset ktory pomoze vypocitat suradnicu stredu gule premietaneho na rovinu trojuholnika Vector3D offset = trianglePlane.Normal * distance; // Priesecnik na rovine trojuholnika, je to premietnuty stred gule na rovine trojuholnika Vector3D intersectionPoint; intersectionPoint.X = sphere.Center.X - offset.X; intersectionPoint.Y = sphere.Center.Y - offset.Y; intersectionPoint.Z = sphere.Center.Z - offset.Z; if (GetInsidePolygonForSphereCollision(ref intersectionPoint, ref triangle)) // Ak priesecnik nachadza v trojuholniku { // Toto je pripad, ked sa podarilo premietnut stred gule na rovinu trojuholnika a tento priesecnik sa // nachadza vnutri trojuholnika (tzn. sedia uhly) return((Vector3)intersectionPoint); } else // Ak sa priesecnik nenachadza v trojuholniku, este stale sa moze nachadzat na hrane trojuholnika { Vector3?edgeIntersection = GetEdgeSphereCollision(ref sphere.Center, (float)sphere.Radius / 1.0f, ref triangle); if (edgeIntersection != null) { // Toto je pripad, ked sa priemietnuty stred gule nachadza mimo trojuholnika, ale intersection gule a trojuholnika tam // je, pretoze gula presekava jednu z hran trojuholnika. Takze vratim suradnice priesecnika na jednej z hran. return(edgeIntersection.Value); } } } // Sphere doesn't collide with any triangle return(null); }
public static Vector3 GetNormalVectorFromTriangle(ref MyTriangle_Vertices inputTriangle) { //return MyVRageUtils.Normalize(Vector3.Cross(inputTriangle.Vertex2 - inputTriangle.Vertex0, inputTriangle.Vertex1 - inputTriangle.Vertex0)); return(Vector3.Normalize(Vector3.Cross(inputTriangle.Vertex2 - inputTriangle.Vertex0, inputTriangle.Vertex1 - inputTriangle.Vertex0))); }
/// <summary> /// Checks whether a ray intersects a triangleVertexes. This uses the algorithm /// developed by Tomas Moller and Ben Trumbore, which was published in the /// Journal of Graphics Tools, pitch 2, "Fast, Minimum Storage Ray-Triangle /// Intersection". /// /// This method is implemented using the pass-by-reference versions of the /// XNA math functions. Using these overloads is generally not recommended, /// because they make the code less readable than the normal pass-by-value /// versions. This method can be called very frequently in a tight inner loop, /// however, so in this particular case the performance benefits from passing /// everything by reference outweigh the loss of readability. /// </summary> public static float?GetLineTriangleIntersection(ref Line line, ref MyTriangle_Vertices triangle) { // Compute vectors along two edges of the triangleVertexes. Vector3 edge1, edge2; Vector3.Subtract(ref triangle.Vertex1, ref triangle.Vertex0, out edge1); Vector3.Subtract(ref triangle.Vertex2, ref triangle.Vertex0, out edge2); // Compute the determinant. Vector3 directionCrossEdge2; Vector3.Cross(ref line.Direction, ref edge2, out directionCrossEdge2); float determinant; Vector3.Dot(ref edge1, ref directionCrossEdge2, out determinant); // If the ray is parallel to the triangleVertexes plane, there is no collision. if (determinant > -float.Epsilon && determinant < float.Epsilon) { return(null); } float inverseDeterminant = 1.0f / determinant; // Calculate the U parameter of the intersection point. Vector3 distanceVector; Vector3.Subtract(ref line.From, ref triangle.Vertex0, out distanceVector); float triangleU; Vector3.Dot(ref distanceVector, ref directionCrossEdge2, out triangleU); triangleU *= inverseDeterminant; // Make sure it is inside the triangleVertexes. if (triangleU < 0 || triangleU > 1) { return(null); } // Calculate the V parameter of the intersection point. Vector3 distanceCrossEdge1; Vector3.Cross(ref distanceVector, ref edge1, out distanceCrossEdge1); float triangleV; Vector3.Dot(ref line.Direction, ref distanceCrossEdge1, out triangleV); triangleV *= inverseDeterminant; // Make sure it is inside the triangleVertexes. if (triangleV < 0 || triangleU + triangleV > 1) { return(null); } // Compute the distance along the ray to the triangleVertexes. float rayDistance; Vector3.Dot(ref edge2, ref distanceCrossEdge1, out rayDistance); rayDistance *= inverseDeterminant; // Is the triangleVertexes behind the ray origin? if (rayDistance < 0) { return(null); } // Does the intersection point lie on the line (ray hasn't end, but line does) if (rayDistance > line.Length) { return(null); } return(rayDistance); }
/// <summary> /// Returns intersection point between sphere and its edges. But only if there is intersection between sphere and one of the edges. /// If sphere intersects somewhere inside the triangle, this method will not detect it. /// </summary> public static Vector3?GetEdgeSphereCollision(ref Vector3D sphereCenter, float sphereRadius, ref MyTriangle_Vertices triangle) { Vector3 intersectionPoint; // This returns the closest point on the current edge to the center of the sphere. intersectionPoint = GetClosestPointOnLine(ref triangle.Vertex0, ref triangle.Vertex1, ref sphereCenter); // Now, we want to calculate the distance between the closest point and the center float distance1 = Vector3.Distance(intersectionPoint, sphereCenter); // If the distance is less than the radius, there must be a collision so return true if (distance1 < sphereRadius) { return(intersectionPoint); } // This returns the closest point on the current edge to the center of the sphere. intersectionPoint = GetClosestPointOnLine(ref triangle.Vertex1, ref triangle.Vertex2, ref sphereCenter); // Now, we want to calculate the distance between the closest point and the center float distance2 = Vector3.Distance(intersectionPoint, sphereCenter); // If the distance is less than the radius, there must be a collision so return true if (distance2 < sphereRadius) { return(intersectionPoint); } // This returns the closest point on the current edge to the center of the sphere. intersectionPoint = GetClosestPointOnLine(ref triangle.Vertex2, ref triangle.Vertex0, ref sphereCenter); // Now, we want to calculate the distance between the closest point and the center float distance3 = Vector3.Distance(intersectionPoint, sphereCenter); // If the distance is less than the radius, there must be a collision so return true if (distance3 < sphereRadius) { return(intersectionPoint); } // The was no intersection of the sphere and the edges of the polygon 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(); } }
/// <summary> /// Checks whether a ray intersects a triangleVertexes. This uses the algorithm /// developed by Tomas Moller and Ben Trumbore, which was published in the /// Journal of Graphics Tools, pitch 2, "Fast, Minimum Storage Ray-Triangle /// Intersection". /// /// This method is implemented using the pass-by-reference versions of the /// XNA math functions. Using these overloads is generally not recommended, /// because they make the code less readable than the normal pass-by-value /// versions. This method can be called very frequently in a tight inner loop, /// however, so in this particular case the performance benefits from passing /// everything by reference outweigh the loss of readability. /// </summary> public static float? GetLineTriangleIntersection(ref Line line, ref MyTriangle_Vertices triangle) { // Compute vectors along two edges of the triangleVertexes. Vector3 edge1, edge2; Vector3.Subtract(ref triangle.Vertex1, ref triangle.Vertex0, out edge1); Vector3.Subtract(ref triangle.Vertex2, ref triangle.Vertex0, out edge2); // Compute the determinant. Vector3 directionCrossEdge2; Vector3.Cross(ref line.Direction, ref edge2, out directionCrossEdge2); float determinant; Vector3.Dot(ref edge1, ref directionCrossEdge2, out determinant); // If the ray is parallel to the triangleVertexes plane, there is no collision. if (determinant > -float.Epsilon && determinant < float.Epsilon) { return null; } float inverseDeterminant = 1.0f / determinant; // Calculate the U parameter of the intersection point. Vector3 distanceVector; Vector3.Subtract(ref line.From, ref triangle.Vertex0, out distanceVector); float triangleU; Vector3.Dot(ref distanceVector, ref directionCrossEdge2, out triangleU); triangleU *= inverseDeterminant; // Make sure it is inside the triangleVertexes. if (triangleU < 0 || triangleU > 1) { return null; } // Calculate the V parameter of the intersection point. Vector3 distanceCrossEdge1; Vector3.Cross(ref distanceVector, ref edge1, out distanceCrossEdge1); float triangleV; Vector3.Dot(ref line.Direction, ref distanceCrossEdge1, out triangleV); triangleV *= inverseDeterminant; // Make sure it is inside the triangleVertexes. if (triangleV < 0 || triangleU + triangleV > 1) { return null; } // Compute the distance along the ray to the triangleVertexes. float rayDistance; Vector3.Dot(ref edge2, ref distanceCrossEdge1, out rayDistance); rayDistance *= inverseDeterminant; // Is the triangleVertexes behind the ray origin? if (rayDistance < 0) { return null; } // Does the intersection point lie on the line (ray hasn't end, but line does) if (rayDistance > line.Length) return null; return rayDistance; }
public static Vector3 GetNormalVectorFromTriangle(ref MyTriangle_Vertices inputTriangle) { //return MyVRageUtils.Normalize(Vector3.Cross(inputTriangle.Vertex2 - inputTriangle.Vertex0, inputTriangle.Vertex1 - inputTriangle.Vertex0)); return Vector3.Normalize(Vector3.Cross(inputTriangle.Vertex2 - inputTriangle.Vertex0, inputTriangle.Vertex1 - inputTriangle.Vertex0)); }
/// <summary> /// Method returns intersection point between sphere and triangle (which is defined by vertexes and plane). /// If no intersection found, method returns null. /// See below how intersection point can be calculated, because it's not so easy - for example sphere vs. triangle will /// hardly generate just intersection point... more like intersection area or something. /// </summary> public static Vector3? GetSphereTriangleIntersection(ref BoundingSphereD sphere, ref PlaneD trianglePlane, ref MyTriangle_Vertices triangle) { // Vzdialenost gule od roviny trojuholnika double distance; // Zistim, ci sa gula nachadza pred alebo za rovinou trojuholnika, alebo ju presekava MySpherePlaneIntersectionEnum spherePlaneIntersection = GetSpherePlaneIntersection(ref sphere, ref trianglePlane, out distance); // Ak gula presekava rovinu, tak hladam pseudo-priesecnik if (spherePlaneIntersection == MySpherePlaneIntersectionEnum.INTERSECTS) { // Offset ktory pomoze vypocitat suradnicu stredu gule premietaneho na rovinu trojuholnika Vector3D offset = trianglePlane.Normal * distance; // Priesecnik na rovine trojuholnika, je to premietnuty stred gule na rovine trojuholnika Vector3D intersectionPoint; intersectionPoint.X = sphere.Center.X - offset.X; intersectionPoint.Y = sphere.Center.Y - offset.Y; intersectionPoint.Z = sphere.Center.Z - offset.Z; if (GetInsidePolygonForSphereCollision(ref intersectionPoint, ref triangle)) // Ak priesecnik nachadza v trojuholniku { // Toto je pripad, ked sa podarilo premietnut stred gule na rovinu trojuholnika a tento priesecnik sa // nachadza vnutri trojuholnika (tzn. sedia uhly) return (Vector3)intersectionPoint; } else // Ak sa priesecnik nenachadza v trojuholniku, este stale sa moze nachadzat na hrane trojuholnika { Vector3? edgeIntersection = GetEdgeSphereCollision(ref sphere.Center, (float)sphere.Radius / 1.0f, ref triangle); if (edgeIntersection != null) { // Toto je pripad, ked sa priemietnuty stred gule nachadza mimo trojuholnika, ale intersection gule a trojuholnika tam // je, pretoze gula presekava jednu z hran trojuholnika. Takze vratim suradnice priesecnika na jednej z hran. return edgeIntersection.Value; } } } // Sphere doesn't collide with any triangle return null; }