?? incremental.cpp
字號:
{
unsigned short flCurValue = (unsigned short)pValues[i].m_Dot;
if( i == 0 )
{
flLastValue = flCurValue;
runLength = 1;
}
else if( flCurValue == flLastValue && runLength < 255 )
{
++runLength;
}
else
{
pBuf->PutUnsignedChar( runLength );
EncodeCharOrShort( pBuf, flLastValue );
flLastValue = flCurValue;
runLength = 1;
}
}
// Write the end..
if( runLength )
{
pBuf->PutUnsignedChar( runLength );
EncodeCharOrShort( pBuf, flLastValue );
}
}
#ifdef _WIN32
#pragma warning (default:4701)
#endif
void MultiplyValues( CUtlVector<CLightValue> &values, float scale )
{
for( int i=0; i < values.Count(); i++ )
values[i].m_Dot *= scale;
}
void CIncremental::FinishFace(
IncrementalLightID lightID,
int iFace,
int iThread )
{
CIncLight *pLight = m_Lights[lightID];
// Check for the 99.99% case in which the face already exists.
CLightFace *pFace;
if( pLight->m_pCachedFaces[iThread] && pLight->m_pCachedFaces[iThread]->m_FaceIndex == iFace )
{
pFace = pLight->m_pCachedFaces[iThread];
// Compress the data.
MultiplyValues( pFace->m_LightValues, pLight->m_flMaxIntensity );
pFace->m_CompressedData.SeekPut( CUtlBuffer::SEEK_HEAD, 0 );
CompressLightData(
pFace->m_LightValues.Base(),
pFace->m_LightValues.Count(),
&pFace->m_CompressedData );
#if 0
// test decompression
CUtlVector<CLightValue> test;
test.SetSize( 2048 );
pFace->m_CompressedData.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
DecompressLightData( &pFace->m_CompressedData, &test );
#endif
if( pFace->m_CompressedData.TellPut() == 0 )
{
// No contribution.. delete this face from the light.
EnterCriticalSection( &pLight->m_CS );
pLight->m_LightFaces.Remove( pFace->m_LightFacesIndex );
delete pFace;
LeaveCriticalSection( &pLight->m_CS );
}
else
{
// Discard the uncompressed data.
pFace->m_LightValues.Purge();
m_FacesTouched[ pFace->m_FaceIndex ] = 1;
}
}
}
bool CIncremental::Finalize()
{
// If we're not being used, don't do anything.
if( !m_pIncrementalFilename || !m_pBSPFilename )
return false;
CUtlVector<CFaceLightList> faceLights;
LinkLightsToFaces( faceLights );
Vector faceLight[(MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2) * (MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2)];
CUtlVector<CLightValue> faceLightValues;
faceLightValues.SetSize( (MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2) * (MAX_LIGHTMAP_DIM_WITHOUT_BORDER+2) );
// Only update the faces we've touched.
for( int facenum = 0; facenum < numfaces; facenum++ )
{
if( !m_FacesTouched[facenum] || !faceLights[facenum].Count() )
continue;
int w = dfaces[facenum].m_LightmapTextureSizeInLuxels[0]+1;
int h = dfaces[facenum].m_LightmapTextureSizeInLuxels[1]+1;
int nLuxels = w * h;
assert( nLuxels <= sizeof(faceLight) / sizeof(faceLight[0]) );
// Clear the lighting for this face.
memset( faceLight, 0, nLuxels * sizeof(Vector) );
// Composite all the light contributions.
for( int iFace=0; iFace < faceLights[facenum].Count(); iFace++ )
{
CLightFace *pFace = faceLights[facenum][iFace];
pFace->m_CompressedData.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
DecompressLightData( &pFace->m_CompressedData, &faceLightValues );
for( int iSample=0; iSample < nLuxels; iSample++ )
{
float flDot = faceLightValues[iSample].m_Dot;
if( flDot )
{
VectorMA(
faceLight[iSample],
flDot / pFace->m_pLight->m_flMaxIntensity,
pFace->m_pLight->m_Light.intensity,
faceLight[iSample] );
}
}
}
// Convert to the floating-point representation in the BSP file.
Vector *pSrc = faceLight;
unsigned char *pDest = &dlightdata[ dfaces[facenum].lightofs ];
for( int iSample=0; iSample < nLuxels; iSample++ )
{
extern void Vec3toColorRGBExp32( Vector& v, colorRGBExp32 *c );
Vec3toColorRGBExp32( *pSrc, ( colorRGBExp32 *)pDest );
pDest += 4;
pSrc++;
}
}
m_bSuccessfulRun = true;
return true;
}
void CIncremental::GetFacesTouched( CUtlVector<unsigned char> &touched )
{
touched.CopyArray( m_FacesTouched.Base(), m_FacesTouched.Count() );
}
bool CIncremental::Serialize()
{
if( !SaveIncrementalFile() )
return false;
WriteBSPFile( (char*)m_pBSPFilename );
return true;
}
void CIncremental::Term()
{
m_Lights.PurgeAndDeleteElements();
m_TotalMemory = 0;
}
void CIncremental::AddLightsForActiveLights()
{
// Create our lights.
for( directlight_t *dl=activelights; dl != NULL; dl = dl->next )
{
CIncLight *pLight = new CIncLight;
dl->m_IncrementalID = m_Lights.AddToTail( pLight );
// Copy the light information.
pLight->m_Light = dl->light;
pLight->m_flMaxIntensity = max( dl->light.intensity[0], max( dl->light.intensity[1], dl->light.intensity[2] ) );
}
}
bool CIncremental::LoadIncrementalFile()
{
Term();
if( !IsIncrementalFileValid() )
return false;
long fp = FileOpen( m_pIncrementalFilename, true );
if( !fp )
return false;
// Read the header.
CIncrementalHeader hdr;
if( !ReadIncrementalHeader( fp, &hdr ) )
{
FileClose( fp );
return false;
}
// Read the lights.
int nLights;
FileRead( fp, nLights );
for( int iLight=0; iLight < nLights; iLight++ )
{
CIncLight *pLight = new CIncLight;
m_Lights.AddToTail( pLight );
FileRead( fp, pLight->m_Light );
pLight->m_flMaxIntensity =
max( pLight->m_Light.intensity.x,
max( pLight->m_Light.intensity.y, pLight->m_Light.intensity.z ) );
int nFaces;
FileRead( fp, nFaces );
assert( nFaces < 70000 );
for( int iFace=0; iFace < nFaces; iFace++ )
{
CLightFace *pFace = new CLightFace;
pLight->m_LightFaces.AddToTail( pFace );
pFace->m_pLight = pLight;
FileRead( fp, pFace->m_FaceIndex );
int dataSize;
FileRead( fp, dataSize );
pFace->m_CompressedData.SeekPut( CUtlBuffer::SEEK_HEAD, 0 );
while( dataSize )
{
--dataSize;
unsigned char ucData;
FileRead( fp, ucData );
pFace->m_CompressedData.PutUnsignedChar( ucData );
}
}
}
FileClose( fp );
return !FileError();
}
bool CIncremental::SaveIncrementalFile()
{
long fp = FileOpen( m_pIncrementalFilename, false );
if( !fp )
return false;
if( !WriteIncrementalHeader( fp ) )
{
FileClose( fp );
return false;
}
// Write the lights.
int nLights = m_Lights.Count();
FileWrite( fp, nLights );
for( int iLight=m_Lights.Head(); iLight != m_Lights.InvalidIndex(); iLight = m_Lights.Next( iLight ) )
{
CIncLight *pLight = m_Lights[iLight];
FileWrite( fp, pLight->m_Light );
int nFaces = pLight->m_LightFaces.Count();
FileWrite( fp, nFaces );
for( int iFace=pLight->m_LightFaces.Head(); iFace != pLight->m_LightFaces.InvalidIndex(); iFace = pLight->m_LightFaces.Next( iFace ) )
{
CLightFace *pFace = pLight->m_LightFaces[iFace];
FileWrite( fp, pFace->m_FaceIndex );
int dataSize = pFace->m_CompressedData.TellPut();
FileWrite( fp, dataSize );
pFace->m_CompressedData.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
while( dataSize )
{
--dataSize;
FileWrite( fp, pFace->m_CompressedData.GetUnsignedChar() );
}
}
}
FileClose( fp );
return !FileError();
}
void CIncremental::LinkLightsToFaces( CUtlVector<CFaceLightList> &faceLights )
{
faceLights.SetSize( numfaces );
for( int iLight=m_Lights.Head(); iLight != m_Lights.InvalidIndex(); iLight = m_Lights.Next( iLight ) )
{
CIncLight *pLight = m_Lights[iLight];
for( int iFace=pLight->m_LightFaces.Head(); iFace != pLight->m_LightFaces.InvalidIndex(); iFace = pLight->m_LightFaces.Next( iFace ) )
{
CLightFace *pFace = pLight->m_LightFaces[iFace];
if( m_FacesTouched[pFace->m_FaceIndex] )
faceLights[ pFace->m_FaceIndex ].AddToTail( pFace );
}
}
}
// ------------------------------------------------------------------ //
// CIncLight
// ------------------------------------------------------------------ //
CIncLight::CIncLight()
{
memset( m_pCachedFaces, 0, sizeof(m_pCachedFaces) );
InitializeCriticalSection( &m_CS );
}
CIncLight::~CIncLight()
{
m_LightFaces.PurgeAndDeleteElements();
DeleteCriticalSection( &m_CS );
}
CLightFace* CIncLight::FindOrCreateLightFace( int iFace, int lmSize, bool *bNew )
{
if( bNew )
*bNew = false;
// Look for it.
for( int i=m_LightFaces.Head(); i != m_LightFaces.InvalidIndex(); i=m_LightFaces.Next(i) )
{
CLightFace *pFace = m_LightFaces[i];
if( pFace->m_FaceIndex == iFace )
{
assert( pFace->m_LightValues.Count() == lmSize );
return pFace;
}
}
// Ok, create one.
CLightFace *pFace = new CLightFace;
pFace->m_LightFacesIndex = m_LightFaces.AddToTail( pFace );
pFace->m_pLight = this;
pFace->m_FaceIndex = iFace;
pFace->m_LightValues.SetSize( lmSize );
memset( pFace->m_LightValues.Base(), 0, sizeof( CLightValue ) * lmSize );
if( bNew )
*bNew = true;
return pFace;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -