Axiom.Core.BillboardChain.UpdateVertexBuffer C# (CSharp) Method

UpdateVertexBuffer() protected method

protected UpdateVertexBuffer ( Camera camera ) : void
camera Camera
return void
		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();
		}