protected void GenerateVertices( Vector3[] offsets, Billboard bb )
{
int color = Root.Instance.ConvertColor( bb.Color );
// Texcoords
Debug.Assert( bb.UseTexcoordRect || bb.TexcoordIndex < this.textureCoords.Count );
RectangleF r = bb.UseTexcoordRect ? bb.TexcoordRect : this.textureCoords[ bb.TexcoordIndex ];
if ( this.pointRendering )
{
unsafe
{
float* posPtr = (float*)this.lockPtr.ToPointer();
int* colPtr = (int*)posPtr;
// Single vertex per billboard, ignore offsets
// position
posPtr[ this.ptrOffset++ ] = bb.Position.x;
posPtr[ this.ptrOffset++ ] = bb.Position.y;
posPtr[ this.ptrOffset++ ] = bb.Position.z;
colPtr[ this.ptrOffset++ ] = color;
// No texture coords in point rendering
}
}
else if ( this.allDefaultRotation || bb.Rotation == 0 )
{
unsafe
{
float* posPtr = (float*)this.lockPtr.ToPointer();
int* colPtr = (int*)posPtr;
float* texPtr = (float*)posPtr;
// Left-top
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Left;
texPtr[ this.ptrOffset++ ] = r.Top;
// Right-top
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 1 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 1 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 1 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Right;
texPtr[ this.ptrOffset++ ] = r.Top;
// Left-bottom
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 2 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 2 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 2 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Left;
texPtr[ this.ptrOffset++ ] = r.Bottom;
// Right-bottom
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 3 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 3 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 3 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Right;
texPtr[ this.ptrOffset++ ] = r.Bottom;
}
}
else if ( this.rotationType == BillboardRotationType.Vertex )
{
// TODO: Cache axis when billboard type is BillboardType.Point or
// BillboardType.PerpendicularCommon
Vector3 axis = ( offsets[ 3 ] - offsets[ 0 ] ).Cross( offsets[ 2 ] - offsets[ 1 ] );
axis.Normalize();
Quaternion rotation = Quaternion.FromAngleAxis( bb.rotationInRadians, axis );
Vector3 pt;
unsafe
{
float* posPtr = (float*)this.lockPtr.ToPointer();
int* colPtr = (int*)posPtr;
float* texPtr = (float*)posPtr;
// Left-top
// Positions
pt = rotation * offsets[ 0 ];
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Left;
texPtr[ this.ptrOffset++ ] = r.Top;
// Right-top
// Positions
pt = rotation * offsets[ 1 ];
posPtr[ this.ptrOffset++ ] = pt.x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = pt.y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = pt.z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Right;
texPtr[ this.ptrOffset++ ] = r.Top;
// Left-bottom
// Positions
pt = rotation * offsets[ 2 ];
posPtr[ this.ptrOffset++ ] = pt.x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = pt.y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = pt.z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Left;
texPtr[ this.ptrOffset++ ] = r.Bottom;
// Right-bottom
// Positions
pt = rotation * offsets[ 3 ];
posPtr[ this.ptrOffset++ ] = pt.x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = pt.y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = pt.z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = r.Right;
texPtr[ this.ptrOffset++ ] = r.Bottom;
}
}
else
{
float cos_rot = Utility.Cos( bb.rotationInRadians );
float sin_rot = Utility.Sin( bb.rotationInRadians );
float width = ( r.Right - r.Left ) / 2;
float height = ( r.Bottom - r.Top ) / 2;
float mid_u = r.Left + width;
float mid_v = r.Top + height;
float cos_rot_w = cos_rot * width;
float cos_rot_h = cos_rot * height;
float sin_rot_w = sin_rot * width;
float sin_rot_h = sin_rot * height;
unsafe
{
float* posPtr = (float*)this.lockPtr.ToPointer();
int* colPtr = (int*)posPtr;
float* texPtr = (float*)posPtr;
// Left-top
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 0 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = mid_u - cos_rot_w + sin_rot_h;
texPtr[ this.ptrOffset++ ] = mid_v - sin_rot_w - cos_rot_h;
// Right-top
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 1 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 1 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 1 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = mid_u + cos_rot_w + sin_rot_h;
texPtr[ this.ptrOffset++ ] = mid_v + sin_rot_w - cos_rot_h;
// Left-bottom
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 2 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 2 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 2 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = mid_u - cos_rot_w - sin_rot_h;
texPtr[ this.ptrOffset++ ] = mid_v - sin_rot_w + cos_rot_h;
// Right-bottom
// Positions
posPtr[ this.ptrOffset++ ] = offsets[ 3 ].x + bb.Position.x;
posPtr[ this.ptrOffset++ ] = offsets[ 3 ].y + bb.Position.y;
posPtr[ this.ptrOffset++ ] = offsets[ 3 ].z + bb.Position.z;
// Color
colPtr[ this.ptrOffset++ ] = color;
// Texture coords
texPtr[ this.ptrOffset++ ] = mid_u + cos_rot_w - sin_rot_h;
texPtr[ this.ptrOffset++ ] = mid_v + sin_rot_w + cos_rot_h;
}
}
}