protected virtual void UpdateVertexBuffer( Camera camera )
{
this.SetupBuffers();
HardwareVertexBuffer buffer = this.vertexData.vertexBufferBinding.GetBuffer( 0 );
IntPtr bufferPtr = buffer.Lock( BufferLocking.Discard );
Vector3 camPosition = camera.DerivedPosition;
Vector3 eyePosition = ParentNode.DerivedOrientation.Inverse() * ( camPosition - ParentNode.DerivedPosition ) / ParentNode.DerivedScale;
Vector3 chainTangent;
unsafe
{
byte* bufferStart = (byte*)bufferPtr.ToPointer();
foreach ( ChainSegment segment in this.chainSegmentList )
{
// Skip 0 or 1 element segment counts
if ( segment.head != SEGMENT_EMPTY && segment.head != segment.tail )
{
int laste = segment.head;
for ( int e = segment.head; ; ++e )
{
// Wrap forwards
if ( e == this.maxElementsPerChain )
{
e = 0;
}
Element element = this.chainElementList[ e + segment.start ];
ushort baseIndex = (ushort)( ( e + segment.start ) * 2 );
// Determine base pointer to vertex #1
byte* pBase = bufferStart + buffer.VertexSize * baseIndex;
// Get index of next item
int nexte = e + 1;
if ( nexte == this.maxElementsPerChain )
{
nexte = 0;
}
if ( e == segment.head )
{
// no laste, use next item
chainTangent = this.chainElementList[ nexte + segment.start ].Position - element.Position;
}
else if ( e == segment.tail )
{
// no nexte, use only last item
chainTangent = element.Position - this.chainElementList[ laste + segment.start ].Position;
}
else
{
// a mid position, use tangent across both prev and next
chainTangent = this.chainElementList[ nexte + segment.start ].Position - this.chainElementList[ laste + segment.start ].Position;
}
Vector3 p1ToEye = eyePosition - element.Position;
Vector3 perpendicular = chainTangent.Cross( p1ToEye );
perpendicular.Normalize();
perpendicular *= ( element.Width * 0.5f );
Vector3 pos0 = element.Position - perpendicular;
Vector3 pos1 = element.Position + perpendicular;
float* pFloat = (float*)pBase;
// pos1
*pFloat++ = pos0.x;
*pFloat++ = pos0.y;
*pFloat++ = pos0.z;
pBase = (byte*)pFloat;
if ( this.useVertexColor )
{
int* pColor = (int*)pBase;
*pColor++ = Root.Instance.ConvertColor( element.Color );
pBase = (byte*)pColor;
}
if ( this.useTexCoords )
{
pFloat = (float*)pBase;
if ( this.texCoordDirection == TexCoordDirection.U )
{
*pFloat++ = element.TexCoord;
*pFloat++ = this.otherTexCoordRange[ 0 ];
}
else
{
*pFloat++ = this.otherTexCoordRange[ 0 ];
*pFloat++ = element.TexCoord;
}
pBase = (byte*)pFloat;
}
// pos2
*pFloat++ = pos1.x;
*pFloat++ = pos1.y;
*pFloat++ = pos1.z;
pBase = (byte*)pFloat;
if ( this.useVertexColor )
{
int* pColor = (int*)pBase;
*pColor++ = Root.Instance.ConvertColor( element.Color );
pBase = (byte*)pColor;
}
if ( this.useTexCoords )
{
pFloat = (float*)pBase;
if ( this.texCoordDirection == TexCoordDirection.U )
{
*pFloat++ = element.TexCoord;
*pFloat++ = this.otherTexCoordRange[ 0 ];
}
else
{
*pFloat++ = this.otherTexCoordRange[ 0 ];
*pFloat++ = element.TexCoord;
}
pBase = (byte*)pFloat;
}
if ( e == segment.tail )
{
break;
}
laste = e;
}
}
}
}
buffer.Unlock();
}