/// <summary> /// Determines if two static (non-moving) meshes interpenetrate. /// </summary> /// <param name="other">The mesh to test for intersection against.</param> /// <param name="worldMat1">The world transform matrix for this mesh.</param> /// <param name="worldMat2">The world transform matrix for 'other'.</param> /// <returns>A boolean value indicating whether interpenetration occurs.</returns> public bool Intersects( Mesh other, Matrix worldMat1, Matrix worldMat2 ) { for ( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex ) { Vector2 vertex = Vector2.TransformCoordinate( GetVertexPosition( vertexIndex ), worldMat1 ); int numAwayFacingEdges = 0; for ( int edgeIndex = 0; edgeIndex < other.NumEdges; ++edgeIndex ) { Edge edge = other.GetEdge( edgeIndex ); Vector2 edgeCenter = ( Vector2.TransformCoordinate( edge.Vertex1Pos, worldMat2 ) + Vector2.TransformCoordinate( edge.Vertex2Pos, worldMat2 ) ) * 0.5f; Vector2 vertexDir = edgeCenter - vertex; // If the edge faces away from the vertex if ( Vector2.Dot( vertexDir, edge.Normal ) >= 0.0f ) ++numAwayFacingEdges; } if ( numAwayFacingEdges == other.NumEdges ) return true; } for ( int vertexIndex = 0; vertexIndex < other.NumVertices; ++vertexIndex ) { Vector2 vertex = Vector2.TransformCoordinate( other.GetVertexPosition( vertexIndex ), worldMat2 ); int numAwayFacingEdges = 0; for ( int edgeIndex = 0; edgeIndex < NumEdges; ++edgeIndex ) { Edge edge = GetEdge( edgeIndex ); Vector2 edgeCenter = ( Vector2.TransformCoordinate( edge.Vertex1Pos, worldMat1 ) + Vector2.TransformCoordinate( edge.Vertex2Pos, worldMat1 ) ) * 0.5f; Vector2 vertexDir = edgeCenter - vertex; // If the edge faces away from the vertex if ( Vector2.Dot( vertexDir, edge.Normal ) >= 0.0f ) ++numAwayFacingEdges; } if ( numAwayFacingEdges == NumEdges ) return true; } return false; }
public static void GenerateShadow( Mesh polygonGeometry, Matrix worldMatrix, Vector2 lightPosWS, float zValue, Vector2 shadowCasterCenter) { Vector3 UVOffset = new Vector3( 0.0f, -0.5f, 0.0f ); // Transform the light position into model space Vector2 lightPos = Vector2.TransformCoordinate( lightPosWS, Matrix.Invert( worldMatrix ) ); List<Edge> contourEdges = new List<Edge>(); for ( int edgeIndex = 0; edgeIndex < polygonGeometry.NumEdges; ++edgeIndex ) { Edge edge = polygonGeometry.GetEdge( edgeIndex ); Vector2 edgeCenter = ( edge.Vertex1Pos + edge.Vertex2Pos ) * 0.5f; Vector2 incidentLightDir = edgeCenter - lightPos; // If the edge faces away from the light source if ( Vector2.Dot( incidentLightDir, edge.Normal ) >= 0.0f ) { contourEdges.Add( edge ); } } if ( contourEdges.Count < 1 || contourEdges.Count == polygonGeometry.NumEdges ) { return; } const float ExtrudeMagnitude = 1280; Shadow shadow = new Shadow(); Vector3 lightPosVec3 = new Vector3( lightPos.X, lightPos.Y, zValue ); lightPosVec3.TransformCoordinate( worldMatrix ); int quadIndex = 0; foreach ( Edge edge in contourEdges ) { Vector3 vertex1 = new Vector3( edge.Vertex1Pos.X, edge.Vertex1Pos.Y, zValue ); Vector3 vertex2 = new Vector3( edge.Vertex2Pos.X, edge.Vertex2Pos.Y, zValue ); // Transform the position data from model space to world space vertex1.TransformCoordinate( worldMatrix ); vertex2.TransformCoordinate( worldMatrix ); Quad quad = new Quad(); Color shadowColor = Color.FromArgb( 1, 0, 0, 0 ); quad.Vertices[ 2 * quadIndex + 0 ].Position = vertex1 + UVOffset - 18.0f * Vector3.Normalize( vertex1 - lightPosVec3 ); quad.Vertices[ 2 * quadIndex + 0 ].Color = shadowColor.ToArgb(); quad.Vertices[ 2 * quadIndex + 1 ].Position = vertex1 + ExtrudeMagnitude * ( vertex1 - lightPosVec3 ) + UVOffset; quad.Vertices[ 2 * quadIndex + 1 ].Color = shadowColor.ToArgb(); quad.Vertices[ 2 * quadIndex + 2 ].Position = vertex2 + UVOffset - 18.0f * Vector3.Normalize( vertex2 - lightPosVec3 ); quad.Vertices[ 2 * quadIndex + 2 ].Color = shadowColor.ToArgb(); quad.Vertices[ 2 * quadIndex + 3 ].Position = vertex2 + ExtrudeMagnitude * ( vertex2 - lightPosVec3 ) + UVOffset; quad.Vertices[ 2 * quadIndex + 3 ].Color = shadowColor.ToArgb(); shadow.Quads.Add( quad ); } shadows.Add( shadow ); }