public void TransformAffine(Matrix4 m) { Debug.Assert(m.IsAffine); // Do nothing if current null or infinite if (this.isNull || this.isInfinite) { return; } Vector3 centre = Center; Vector3 halfSize = HalfSize; Vector3 newCentre = m.TransformAffine(centre); var newHalfSize = new Vector3( Utility.Abs(m[0, 0]) * halfSize.x + Utility.Abs(m[0, 1]) * halfSize.y + Utility.Abs(m[0, 2]) * halfSize.z, Utility.Abs(m[1, 0]) * halfSize.x + Utility.Abs(m[1, 1]) * halfSize.y + Utility.Abs(m[1, 2]) * halfSize.z, Utility.Abs(m[2, 0]) * halfSize.x + Utility.Abs(m[2, 1]) * halfSize.y + Utility.Abs(m[2, 2]) * halfSize.z); SetExtents(newCentre - newHalfSize, newCentre + newHalfSize); }
private void _generateCurvedPlaneVertexData( HardwareVertexBuffer vbuf, int ySegments, int xSegments, float xSpace, float halfWidth, float ySpace, float halfHeight, Matrix4 transform, bool firstTime, bool normals, Matrix4 rotation, float curvature, int numTexCoordSets, float xTexCoord, float yTexCoord, SubMesh subMesh, ref Vector3 min, ref Vector3 max, ref float maxSquaredLength ) { Vector3 vec; unsafe { // lock the vertex buffer IntPtr data = vbuf.Lock( BufferLocking.Discard ); float* pData = (float*)data.ToPointer(); for ( int y = 0; y <= ySegments; y++ ) { for ( int x = 0; x <= xSegments; x++ ) { // centered on origin vec.x = ( x * xSpace ) - halfWidth; vec.y = ( y * ySpace ) - halfHeight; // Here's where curved plane is different from standard plane. Amazing, I know. Real diff_x = ( x - ( (Real)xSegments / 2 ) ) / (Real)xSegments; Real diff_y = ( y - ( (Real)ySegments / 2 ) ) / (Real)ySegments; Real dist = Utility.Sqrt( diff_x * diff_x + diff_y * diff_y ); vec.z = ( -Utility.Sin( ( 1 - dist ) * ( Utility.PI / 2 ) ) * curvature ) + curvature; // Transform by orientation and distance Vector3 pos = transform.TransformAffine( vec ); *pData++ = pos.x; *pData++ = pos.y; *pData++ = pos.z; // Build bounds as we go if ( firstTime ) { min = vec; max = vec; maxSquaredLength = vec.LengthSquared; firstTime = false; } else { min.Floor( vec ); max.Ceil( vec ); maxSquaredLength = Utility.Max( maxSquaredLength, vec.LengthSquared ); } if ( normals ) { // This part is kinda 'wrong' for curved planes... but curved planes are // very valuable outside sky planes, which don't typically need normals // so I'm not going to mess with it for now. // Default normal is along unit Z //vec = Vector3::UNIT_Z; // Rotate vec = rotation.TransformAffine( vec ); *pData++ = vec.x; *pData++ = vec.y; *pData++ = vec.z; } for ( int i = 0; i < numTexCoordSets; i++ ) { *pData++ = x * xTexCoord; *pData++ = 1 - ( y * yTexCoord ); } // for texCoords } // for x } // for y // unlock the buffer vbuf.Unlock(); subMesh.useSharedVertices = true; } // unsafe }
private void _generatePlaneVertexData( HardwareVertexBuffer vbuf, int ySegments, int xSegments, float xSpace, float halfWidth, float ySpace, float halfHeight, Matrix4 transform, bool firstTime, bool normals, Matrix4 rotation, int numTexCoordSets, float xTexCoord, float yTexCoord, SubMesh subMesh, ref Vector3 min, ref Vector3 max, ref float maxSquaredLength ) { Vector3 vec; unsafe { // lock the vertex buffer IntPtr data = vbuf.Lock( BufferLocking.Discard ); float* pData = (float*)data.ToPointer(); for ( int y = 0; y <= ySegments; y++ ) { for ( int x = 0; x <= xSegments; x++ ) { // centered on origin vec.x = ( x * xSpace ) - halfWidth; vec.y = ( y * ySpace ) - halfHeight; vec.z = 0.0f; vec = transform.TransformAffine( vec ); *pData++ = vec.x; *pData++ = vec.y; *pData++ = vec.z; // Build bounds as we go if ( firstTime ) { min = vec; max = vec; maxSquaredLength = vec.LengthSquared; firstTime = false; } else { min.Floor( vec ); max.Ceil( vec ); maxSquaredLength = Utility.Max( maxSquaredLength, vec.LengthSquared ); } if ( normals ) { vec = Vector3.UnitZ; vec = rotation.TransformAffine( vec ); *pData++ = vec.x; *pData++ = vec.y; *pData++ = vec.z; } for ( int i = 0; i < numTexCoordSets; i++ ) { *pData++ = x * xTexCoord; *pData++ = 1 - ( y * yTexCoord ); } // for texCoords } // for x } // for y // unlock the buffer vbuf.Unlock(); subMesh.useSharedVertices = true; } // unsafe }
public void TransformAffine( Matrix4 m ) { Debug.Assert( m.IsAffine ); // Do nothing if current null or infinite if ( this.isNull || this.isInfinite ) { return; } Vector3 centre = Center; Vector3 halfSize = HalfSize; Vector3 newCentre = m.TransformAffine( centre ); var newHalfSize = new Vector3( Utility.Abs( m[ 0, 0 ] )*halfSize.x + Utility.Abs( m[ 0, 1 ] )*halfSize.y + Utility.Abs( m[ 0, 2 ] )*halfSize.z, Utility.Abs( m[ 1, 0 ] )*halfSize.x + Utility.Abs( m[ 1, 1 ] )*halfSize.y + Utility.Abs( m[ 1, 2 ] )*halfSize.z, Utility.Abs( m[ 2, 0 ] )*halfSize.x + Utility.Abs( m[ 2, 1 ] )*halfSize.y + Utility.Abs( m[ 2, 2 ] )*halfSize.z ); SetExtents( newCentre - newHalfSize, newCentre + newHalfSize ); }