Axiom.Core.Entity.GetShadowVolumeRenderableEnumerator C# (CSharp) Метод

GetShadowVolumeRenderableEnumerator() публичный Метод

public GetShadowVolumeRenderableEnumerator ( ShadowTechnique technique, Light light, HardwareIndexBuffer indexBuffer, bool extrudeVertices, float extrusionDistance, int flags ) : IEnumerator
technique ShadowTechnique
light Light
indexBuffer Axiom.Graphics.HardwareIndexBuffer
extrudeVertices bool
extrusionDistance float
flags int
Результат IEnumerator
		public override IEnumerator GetShadowVolumeRenderableEnumerator( ShadowTechnique technique,
																		 Light light,
																		 HardwareIndexBuffer indexBuffer,
																		 bool extrudeVertices,
																		 float extrusionDistance,
																		 int flags )
		{
			Debug.Assert( indexBuffer != null, "Only external index buffers are supported right now" );
			Debug.Assert( indexBuffer.Type == IndexType.Size16, "Only 16-bit indexes supported for now" );

			// Potentially delegate to LOD entity
			if ( this.meshLodIndex > 0 && this.mesh.IsLodManual )
			{
				Debug.Assert( this.meshLodIndex - 1 < this.lodEntityList.Count,
							  "No LOD EntityList - did you build the manual LODs after creating the entity?" );

				Entity lodEnt = lodEntityList[ meshLodIndex - 1 ];

				// index - 1 as we skip index 0 (original LOD)
				if ( this.HasSkeleton && lodEnt.HasSkeleton )
				{
					// Copy the animation state set to lod entity, we assume the lod
					// entity only has a subset animation states
					this.CopyAnimationStateSubset( lodEnt.animationState, this.animationState );
				}

				return lodEnt.GetShadowVolumeRenderableEnumerator( technique,
																   light,
																   indexBuffer,
																   extrudeVertices,
																   extrusionDistance,
																   flags );
			}

			// Prep mesh if required
			// NB This seems to result in memory corruptions, having problems
			// tracking them down. For now, ensure that shadows are enabled
			// before any entities are created
			if ( !this.mesh.IsPreparedForShadowVolumes )
			{
				this.mesh.PrepareForShadowVolume();
				// reset frame last updated to force update of buffers
				this.frameAnimationLastUpdated = 0;
				// re-prepare buffers
				this.PrepareTempBlendedBuffers();
			}

			// Update any animation
			this.UpdateAnimation();

			// Calculate the object space light details
			Vector4 lightPos = light.GetAs4DVector();

			// Only use object-space light if we're not doing transforms
			// Since when animating the positions are already transformed into
			// world space so we need world space light position
			bool isAnimated = this.HasSkeleton || this.mesh.HasVertexAnimation;
			if ( !isAnimated )
			{
				Matrix4 world2Obj = this.parentNode.FullTransform.Inverse();

				lightPos = world2Obj * lightPos;
			}

			// We need to search the edge list for silhouette edges
			EdgeData edgeList = this.GetEdgeList();

			// Init shadow renderable list if required
			bool init = ( this.shadowRenderables.Count == 0 );

			if ( init )
			{
				this.shadowRenderables.Capacity = edgeList.edgeGroups.Count;
			}

			bool updatedSharedGeomNormals = false;

			EntityShadowRenderable esr = null;
			EdgeData.EdgeGroup egi;

			// note: using capacity for the loop since no items are in the list yet.
			// capacity is set to how large the collection will be in the end
			for ( int i = 0; i < this.shadowRenderables.Capacity; i++ )
			{
				egi = (EdgeData.EdgeGroup)edgeList.edgeGroups[ i ];
				VertexData data = ( isAnimated
											? this.FindBlendedVertexData( egi.vertexData )
											:
													egi.vertexData );
				if ( init )
				{
					// Try to find corresponding SubEntity; this allows the
					// linkage of visibility between ShadowRenderable and SubEntity
					SubEntity subEntity = this.FindSubEntityForVertexData( egi.vertexData );

					// Create a new renderable, create a separate light cap if
					// we're using hardware skinning since otherwise we get
					// depth-fighting on the light cap
					esr = new EntityShadowRenderable( this,
													  indexBuffer,
													  data,
													  subEntity.VertexProgramInUse || !extrudeVertices,
													  subEntity );

					this.shadowRenderables.Add( esr );
				}
				else
				{
					esr = (EntityShadowRenderable)this.shadowRenderables[ i ];

					if ( this.HasSkeleton )
					{
						// If we have a skeleton, we have no guarantee that the position
						// buffer we used last frame is the same one we used last frame
						// since a temporary buffer is requested each frame
						// therefore, we need to update the EntityShadowRenderable
						// with the current position buffer
						esr.RebindPositionBuffer( data, isAnimated );
					}
				}

				// For animated entities we need to recalculate the face normals
				if ( isAnimated )
				{
					if ( egi.vertexData != this.mesh.SharedVertexData || !updatedSharedGeomNormals )
					{
						// recalculate face normals
						edgeList.UpdateFaceNormals( egi.vertexSet, esr.PositionBuffer );

						// If we're not extruding in software we still need to update
						// the latter part of the buffer (the hardware extruded part)
						// with the latest animated positions
						if ( !extrudeVertices )
						{
							IntPtr srcPtr = esr.PositionBuffer.Lock( BufferLocking.Normal );
							IntPtr destPtr = new IntPtr( srcPtr.ToInt64() + ( egi.vertexData.vertexCount * 12 ) );

							// 12 = sizeof(float) * 3
							Memory.Copy( srcPtr, destPtr, 12 * egi.vertexData.vertexCount );

							esr.PositionBuffer.Unlock();
						}

						if ( egi.vertexData == this.mesh.SharedVertexData )
						{
							updatedSharedGeomNormals = true;
						}
					}
				}
				// Extrude vertices in software if required
				if ( extrudeVertices )
				{
					ExtrudeVertices( esr.PositionBuffer, egi.vertexData.vertexCount, lightPos, extrusionDistance );
				}

				// Stop suppressing hardware update now, if we were
				esr.PositionBuffer.SuppressHardwareUpdate( false );
			}

			// Calc triangle light facing
			this.UpdateEdgeListLightFacing( edgeList, lightPos );

			// Generate indexes and update renderables
			this.GenerateShadowVolume( edgeList, indexBuffer, light, this.shadowRenderables, flags );

			return this.shadowRenderables.GetEnumerator();
		}