GetAs4DVector() public method

Gets the details of this light as a 4D vector.
Getting details of a light as a 4D vector can be useful for doing general calculations between different light types; for example the vector can represent both position lights (w=1.0f) and directional lights (w=0.0f) and be used in the same calculations.
public GetAs4DVector ( ) : Vector4
return Vector4
        /// <summary>
        ///
        /// </summary>
        /// <param name="light"></param>
        /// <param name="extrusionDistance"></param>
        /// <returns></returns>
        public override AxisAlignedBox GetDarkCapBounds(Light light, float extrusionDistance)
        {
            // Extrude own light cap bounds
            // need a clone to avoid modifying the original bounding box
            worldDarkCapBounds = (AxisAlignedBox)GetLightCapBounds().Clone();

            ExtrudeBounds(worldDarkCapBounds, light.GetAs4DVector(), extrusionDistance);

            return(worldDarkCapBounds);
        }
Beispiel #2
0
            public IEnumerator GetShadowVolumeRenderableIterator(ShadowTechnique shadowTechnique, Light light,
                                                                 HardwareIndexBuffer indexBuffer, bool extrudeVertices,
                                                                 float extrusionDistance, ulong 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");

                // Calculate the object space light details
                var lightPos  = light.GetAs4DVector();
                var world2Obj = parentNode.FullTransform.Inverse();

                lightPos = world2Obj * lightPos;

                // We need to search the edge list for silhouette edges
                if (this.edgeList == null)
                {
                    throw new Exception("You enabled stencil shadows after the buid process!  In " +
                                        "Region.GetShadowVolumeRenderableIterator");
                }

                // Init shadow renderable list if required
                var init = this.shadowRenderables.Count == 0;

                RegionShadowRenderable esr = null;

                //bool updatedSharedGeomNormals = false;
                for (var i = 0; i < this.edgeList.EdgeGroups.Count; i++)
                {
                    var group = (EdgeData.EdgeGroup) this.edgeList.EdgeGroups[i];
                    if (init)
                    {
                        // Create a new renderable, create a separate light cap if
                        // we're using a vertex program (either for this model, or
                        // for extruding the shadow volume) since otherwise we can
                        // get depth-fighting on the light cap
                        esr = new RegionShadowRenderable(this, indexBuffer, group.vertexData, this.vertexProgramInUse || !extrudeVertices);
                        this.shadowRenderables.Add(esr);
                    }
                    else
                    {
                        esr = (RegionShadowRenderable)this.shadowRenderables[i];
                    }
                    // Extrude vertices in software if required
                    if (extrudeVertices)
                    {
                        ExtrudeVertices(esr.PositionBuffer, group.vertexData.vertexCount, lightPos, extrusionDistance);
                    }
                }
                return((IEnumerator)this.shadowRenderables);
            }
Beispiel #3
0
		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?" );

				var lodEnt = this.lodEntityList[ this.meshLodIndex - 1 ];

				// index - 1 as we skip index 0 (original LOD)
				if ( HasSkeleton && lodEnt.HasSkeleton )
				{
					// Copy the animation state set to lod entity, we assume the lod
					// entity only has a subset animation states
					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
				PrepareTempBlendedBuffers();
			}

			// Update any animation
			UpdateAnimation();

			// Calculate the object space light details
			var 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
			var isAnimated = HasSkeleton || this.mesh.HasVertexAnimation;
			if ( !isAnimated )
			{
				var world2Obj = parentNode.FullTransform.Inverse();

				lightPos = world2Obj*lightPos;
			}

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

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

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

			var 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 ( var i = 0; i < this.shadowRenderables.Capacity; i++ )
			{
				egi = (EdgeData.EdgeGroup)edgeList.edgeGroups[ i ];
				var data = ( isAnimated ? FindBlendedVertexData( egi.vertexData ) : egi.vertexData );
				if ( init )
				{
					// Try to find corresponding SubEntity; this allows the
					// linkage of visibility between ShadowRenderable and SubEntity
					var subEntity = 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 ( 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 )
						{
							var srcPtr = esr.PositionBuffer.Lock( BufferLocking.Normal );
							var destPtr = srcPtr + ( 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
			UpdateEdgeListLightFacing( edgeList, lightPos );

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

			return this.shadowRenderables.GetEnumerator();
		}
        /// <summary>
        ///		
        /// </summary>
        /// <param name="light"></param>
        /// <param name="extrusionDistance"></param>
        /// <returns></returns>
        public override AxisAlignedBox GetDarkCapBounds(Light light, float extrusionDistance)
        {
            // Extrude own light cap bounds
            // need a clone to avoid modifying the original bounding box
            worldDarkCapBounds = (AxisAlignedBox)GetLightCapBounds().Clone();

            ExtrudeBounds(worldDarkCapBounds, light.GetAs4DVector(), extrusionDistance);

            return worldDarkCapBounds;
        }
Beispiel #5
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="lt"></param>
		/// <param name="lightindex"></param>
		private void SetGLLightPositionDirection( Light lt, All lightindex )
		{
			// Set position / direction
			Vector4 vec = Vector4.Zero;
			// Use general 4D vector which is the same as GL's approach
			vec = lt.GetAs4DVector();
			// Must convert to float*
			float[] tmp = new float[] { vec.x, vec.y, vec.z, vec.w };
			OpenGL.Light( lightindex, All.Position, tmp );


			// Set spotlight direction
			if ( lt.Type == LightType.Spotlight )
			{
				Vector3 vec3 = lt.DerivedDirection;
				float[] tmp2 = new float[] { vec3.x, vec3.y, vec3.z, 0 };
				OpenGL.Light( lightindex, All.SpotDirection, tmp2 );
			}
		}
Beispiel #6
0
			public IEnumerator GetShadowVolumeRenderableIterator( ShadowTechnique shadowTechnique, Light light,
			                                                      HardwareIndexBuffer indexBuffer, bool extrudeVertices,
			                                                      float extrusionDistance, ulong 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" );

				// Calculate the object space light details
				var lightPos = light.GetAs4DVector();
				var world2Obj = parentNode.FullTransform.Inverse();
				lightPos = world2Obj*lightPos;

				// We need to search the edge list for silhouette edges
				if ( this.edgeList == null )
				{
					throw new Exception( "You enabled stencil shadows after the buid process!  In " +
					                     "Region.GetShadowVolumeRenderableIterator" );
				}

				// Init shadow renderable list if required
				var init = this.shadowRenderables.Count == 0;

				RegionShadowRenderable esr = null;
				//bool updatedSharedGeomNormals = false;
				for ( var i = 0; i < this.edgeList.EdgeGroups.Count; i++ )
				{
					var group = (EdgeData.EdgeGroup)this.edgeList.EdgeGroups[ i ];
					if ( init )
					{
						// Create a new renderable, create a separate light cap if
						// we're using a vertex program (either for this model, or
						// for extruding the shadow volume) since otherwise we can
						// get depth-fighting on the light cap
						esr = new RegionShadowRenderable( this, indexBuffer, group.vertexData, this.vertexProgramInUse || !extrudeVertices );
						this.shadowRenderables.Add( esr );
					}
					else
					{
						esr = (RegionShadowRenderable)this.shadowRenderables[ i ];
					}
					// Extrude vertices in software if required
					if ( extrudeVertices )
					{
						ExtrudeVertices( esr.PositionBuffer, group.vertexData.vertexCount, lightPos, extrusionDistance );
					}
				}
				return (IEnumerator)this.shadowRenderables;
			}
Beispiel #7
0
		private void SetGLLightPositionDirection( Light light, int index )
		{
			// Use general 4D vector which is the same as GL's approach
			Vector4 vec4 = light.GetAs4DVector();

			_tempLightVals[ 0 ] = vec4.x;
			_tempLightVals[ 1 ] = vec4.y;
			_tempLightVals[ 2 ] = vec4.z;
			_tempLightVals[ 3 ] = vec4.w;

			Gl.glLightfv( index, Gl.GL_POSITION, _tempLightVals );

			// set spotlight direction
			if ( light.Type == LightType.Spotlight )
			{
				var vec3 = light.DerivedDirection;
				_tempLightVals[ 0 ] = vec3.x;
				_tempLightVals[ 1 ] = vec3.y;
				_tempLightVals[ 2 ] = vec3.z;
				_tempLightVals[ 3 ] = 0.0f;

				Gl.glLightfv( index, Gl.GL_SPOT_DIRECTION, _tempLightVals );
			}
		}
Beispiel #8
0
            public override void ApplyDeltaValue(Vector4 val)
            {
                Vector4 v = light.GetAs4DVector();

                SetValue(new Vector4(v.x + val.x, v.y + val.y, v.z + val.z, v.w + val.w));
            }