/// <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; } } }