Summary description for TextureLight.
Inheritance: Axiom.Core.Light
Exemplo n.º 1
0
		/// <summary>
		///		Caches a face group and calculates texture lighting coordinates.
		/// </summary>
		protected int CacheLightGeometry( TextureLight light, BufferBase pIndexesBuf, BufferBase pTexLightMapsBuf,
		                                  BufferBase pVerticesBuf, BspStaticFaceGroup faceGroup )
		{
#if !AXIOM_SAFE_ONLY
			unsafe
#endif
			{
				// Skip sky always
				if ( faceGroup.isSky )
				{
					return 0;
				}

				int idxStart = 0;
				int numIdx = 0;
				int vertexStart = 0;

				if ( faceGroup.type == FaceGroup.FaceList )
				{
					idxStart = faceGroup.elementStart;
					numIdx = faceGroup.numElements;
					vertexStart = faceGroup.vertexStart;
				}
				else if ( faceGroup.type == FaceGroup.Patch )
				{
					idxStart = faceGroup.patchSurf.IndexOffset;
					numIdx = faceGroup.patchSurf.CurrentIndexCount;
					vertexStart = faceGroup.patchSurf.VertexOffset;
				}
				else
				{
					// Unsupported face type
					return 0;
				}

				var idxSize = this.level.Indexes.IndexSize;
				var idxSrc = this.level.Indexes.Lock( idxStart*idxSize, numIdx*idxSize, BufferLocking.ReadOnly );
#if SILVERLIGHT
				var src = idxSrc.ToUShortPointer();
#else
				var src = idxSrc.ToUIntPointer();
#endif

				int maxIndex = 0;
				for ( int i = 0; i < numIdx; i++ )
				{
					var index = (int)src[ i ];
					if ( index > maxIndex )
					{
						maxIndex = index;
					}
				}

				var vertexPos = new Vector3[maxIndex + 1];
				var vertexIsStored = new bool[maxIndex + 1];

				for ( int i = 0; i < numIdx; i++ )
				{
					var index = (int)src[ i ];
					var pVertices = pVerticesBuf.ToBspVertexPointer();
					if ( !vertexIsStored[ index ] )
					{
						vertexPos[ index ] = pVertices[ vertexStart + index ].position;
						vertexIsStored[ index ] = true;
					}
					pVerticesBuf.UnPin();
				}

				Vector2[] texCoors;
				ColorEx[] colors;

				bool res = light.CalculateTexCoordsAndColors( faceGroup.plane, vertexPos, out texCoors, out colors );

				if ( res )
				{
					var pTexLightMaps = pTexLightMapsBuf.ToTextureLightMapPointer();
					for ( int i = 0; i <= maxIndex; i++ )
					{
						pTexLightMaps[ vertexStart + i ] = new TextureLightMap
						                                   {
						                                   	color = Root.Instance.RenderSystem.ConvertColor( colors[ i ] ),
						                                   	textureLightMap = texCoors[ i ]
						                                   };
					}
					pTexLightMapsBuf.UnPin();

					// Offset the indexes here
					// we have to do this now rather than up-front because the
					// indexes are sometimes reused to address different vertex chunks
					if ( this.level.Indexes.Type == IndexType.Size16 )
					{
						var pIndexes = pIndexesBuf.ToUShortPointer();
						for ( int i = 0; i < numIdx; i++ )
						{
							pIndexes[ i ] = (ushort)( src[ i ] + vertexStart );
						}
					}
					else
					{
						var pIndexes = pIndexesBuf.ToUIntPointer();
						for ( int i = 0; i < numIdx; i++ )
						{
							pIndexes[ i ] = (uint)( src[ i ] + vertexStart );
						}
					}
					this.level.Indexes.Unlock();

					// return number of elements
					return numIdx;
				}
				else
				{
					this.level.Indexes.Unlock();

					return 0;
				}
			}
		}
        /// <summary>
        ///		Creates a specialised texture light.
        /// </summary>
        public override Light CreateLight(string name)
        {
            // create a new texture light and add it to our internal list
            TextureLight light = new TextureLight(name, this);

            // add the light to the list
            lightList.Add(name, light);

            // add it in the bsp tree
            NotifyObjectMoved(light, light.Position);

            return light;
        }
Exemplo n.º 3
0
		/// <summary>
		///		Caches a face group and calculates texture lighting coordinates.
		/// </summary>
		unsafe protected int CacheLightGeometry( TextureLight light, uint* pIndexes, TextureLightMap* pTexLightMaps, BspVertex* pVertices, BspStaticFaceGroup faceGroup )
		{
			// Skip sky always
			if ( faceGroup.isSky )
				return 0;

			int idxStart = 0;
			int numIdx = 0;
			int vertexStart = 0;

			if ( faceGroup.type == FaceGroup.FaceList )
			{
				idxStart = faceGroup.elementStart;
				numIdx = faceGroup.numElements;
				vertexStart = faceGroup.vertexStart;
			}
			else if ( faceGroup.type == FaceGroup.Patch )
			{
				idxStart = faceGroup.patchSurf.IndexOffset;
				numIdx = faceGroup.patchSurf.CurrentIndexCount;
				vertexStart = faceGroup.patchSurf.VertexOffset;
			}
			else
			{
				// Unsupported face type
				return 0;
			}

			uint* src = (uint*)level.Indexes.Lock(
				idxStart * sizeof( uint ),
				numIdx * sizeof( uint ),
				BufferLocking.ReadOnly );

			int maxIndex = 0;
			for ( int i = 0; i < numIdx; i++ )
			{
				int index = (int)*( src + i );
				if ( index > maxIndex )
					maxIndex = index;
			}

			Vector3[] vertexPos = new Vector3[ maxIndex + 1 ];
			bool[] vertexIsStored = new bool[ maxIndex + 1 ];

			for ( int i = 0; i < numIdx; i++ )
			{
				uint index = *( src + i );
				if ( !vertexIsStored[ index ] )
				{
					vertexPos[ index ] = ( *( pVertices + vertexStart + index ) ).position;
					vertexIsStored[ index ] = true;
				}
			}

			Vector2[] texCoors;
			ColorEx[] colors;

			bool res = light.CalculateTexCoordsAndColors( faceGroup.plane, vertexPos, out texCoors, out colors );

			if ( res )
			{
				for ( int i = 0; i <= maxIndex; i++ )
				{
					pTexLightMaps[ vertexStart + i ].color = Root.Instance.RenderSystem.ConvertColor( colors[ i ] );
					pTexLightMaps[ vertexStart + i ].textureLightMap = texCoors[ i ];
				}

				// Offset the indexes here
				// we have to do this now rather than up-front because the
				// indexes are sometimes reused to address different vertex chunks
				for ( int i = 0; i < numIdx; i++ )
					*pIndexes++ = (uint)( *src++ + vertexStart );

				level.Indexes.Unlock();

				// return number of elements
				return numIdx;
			}
			else
			{
				level.Indexes.Unlock();

				return 0;
			}
		}
        /// <summary>
        ///		Walks the BSP tree looking for the node which the camera is in, and tags any geometry 
        ///		which is in a visible leaf for later processing.
        /// </summary>
        protected BspNode WalkTree(Camera camera, bool onlyShadowCasters)
        {
            // Locate the leaf node where the camera is located
            BspNode cameraNode = level.FindLeaf(camera.DerivedPosition);

            matFaceGroupMap.Clear();
            faceGroupChecked = new bool[level.FaceGroups.Length];

            TextureLight[] lights = new TextureLight[lightList.Count];
            BspNode[] lightNodes = new BspNode[lightList.Count];
            Sphere[] lightSpheres = new Sphere[lightList.Count];

            // The base SceneManager uses this for shadows.
            // The BspSceneManager uses this for texture lighting as well.
            if (shadowTechnique == ShadowTechnique.None)
            {
                lightsAffectingFrustum.Clear();
                lightAddedToFrustum = new bool[lightList.Count];
            }

            for (int lp=0; lp < lightList.Count; lp++)
            {
                TextureLight light = (TextureLight) lightList[lp];
                lights[lp] = light;
                lightNodes[lp] = (BspNode) level.objectToNodeMap.FindFirst(light);
                if (light.Type != LightType.Directional)
                {
                    // treating spotlight as point for simplicity
                    lightSpheres[lp] = new Sphere(light.DerivedPosition, light.AttenuationRange);
                }
            }

            // Scan through all the other leaf nodes looking for visibles
            int i = level.NumNodes - level.LeafStart;
            int p = level.LeafStart;
            BspNode node;

            while(i-- > 0)
            {
                node = level.Nodes[p];

                if(level.IsLeafVisible(cameraNode, node))
                {
                    // Visible according to PVS, check bounding box against frustum
                    FrustumPlane plane;

                    if(camera.IsObjectVisible(node.BoundingBox, out plane))
                    {
                        if (!onlyShadowCasters)
                        {
                            for (int lp=0; lp < lights.Length; lp++)
                            {
                                if (lightAddedToFrustum[lp] || !lights[lp].IsVisible)
                                    continue;

                                if (level.IsLeafVisible(lightNodes[lp], node) &&
                                    (lights[lp].Type == LightType.Directional ||
                                    lightSpheres[lp].Intersects(node.BoundingBox)))
                                {
                                    // This is set so that the lights are rendered with ascending
                                    // Priority order.
                                    lights[lp].TempSquaredDist = lights[lp].Priority;

                                    lightsAffectingFrustum.Add(lights[lp]);
                                    lightAddedToFrustum[lp] = true;
                                }
                            }
                        }

                        ProcessVisibleLeaf(node, camera, onlyShadowCasters);

                        if(showNodeAABs)
                            AddBoundingBox(node.BoundingBox, true);
                    }
                }

                p++;
            }

            return cameraNode;
        }