📄 mapdice.cpp
字号:
theta = PI / 2.0;
}
} else {
theta = atan2( Ny, Nx );
}
if (theta < 0.0) theta += PI*2.0;
ShiAssert( theta < PI*2.0 );
ShiAssert( theta >= 0.0 );
// Scale theta from 0 - 2 PI (360 degrees) to 0 - 255
theta *= 255.99 / (2.0 * PI);
// Scale phi from 0 - PI/2 to 0 - 255
phi *= 255.99 / (PI / 2.0);
if (phi < 0.0) phi = 0.0;
ShiAssert( theta < 256.0f );
ShiAssert( phi < 256.0f );
ShiAssert( theta >= 0.0f );
ShiAssert( phi >= 0.0f );
// Store a compressed version of theta and phi for later use with this post
NormalBuffer[dataOffset] = (((BYTE)phi) << 8) | (BYTE)(theta);
}
}
// Open a file to store the per-post normal information for use by the campaign engine
strcpy( filename, basename );
strcat( filename, "-N.RAW" );
printf( "Writing the normal inspection file %s\n", filename );
headerFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( headerFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open normal output file." );
ShiError( string );
}
// Write out the encoded representations of the normals at each post
WriteFile( headerFile, NormalBuffer, NormalBufferSize, &bytes, NULL );
ShiAssert( bytes == (DWORD)NormalBufferSize );
// Close the normal file
CloseHandle( headerFile );
// Allocate space for the texture ID buffer
texMapWidth = bufferWidth >> LAST_TEX_LEVEL;
texMapHeight = bufferHeight >> LAST_TEX_LEVEL;
TexIDBufferSize = texMapWidth*texMapHeight*sizeof(*TexIDBuffer);
TexIDBuffer = (WORD*)malloc( TexIDBufferSize );
ShiAssert( TexIDBuffer );
// Open the texture id layout file
strcpy( filename, basename );
strcat( filename, "-T.RAW" );
printf( "Reading TEXTURE ID file %s\n", filename );
textureFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( textureFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open texture id input file." );
ShiError( string );
}
// Read in the data
if ( !ReadFile( textureFile, TexIDBuffer, TexIDBufferSize, &bytes, NULL ) ) bytes=0xFFFFFFFF;
if ( bytes != TexIDBufferSize ) {
char string[256];
PutErrorString( string );
strcat( string, "Couldn't read required texture data." );
ShiError( string );
}
CloseHandle( textureFile );
// Open the map header file
strcpy( filename, basename );
strcat( filename, ".MAP" );
printf( "Writing the map header file %s\n", filename );
headerFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( headerFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open map heaader file." );
ShiError( string );
}
// Write out the number of feet between map posts at the highest detail level
LOD = MAX_LEVELS;
WriteFile( headerFile, &FeetPerPost, sizeof(FeetPerPost), &bytes, NULL );
ShiAssert( bytes == sizeof(FeetPerPost) );
// Write out the number of levels we'll be generating for this map
LOD = MAX_LEVELS;
WriteFile( headerFile, &LOD, sizeof(LOD), &bytes, NULL );
ShiAssert( bytes == sizeof(LOD) );
// Write out the number of the last level which will be textured
LOD = LAST_TEX_LEVEL;
WriteFile( headerFile, &LOD, sizeof(LOD), &bytes, NULL );
ShiAssert( bytes == sizeof(LOD) );
// Allocate the memory for each disk block as it is constructed
postBufferSize = POSTS_PER_BLOCK*sizeof(*postBuffer);
postBuffer = (TdiskPost*)malloc( postBufferSize );
ShiAssert( postBuffer );
// Write the post data for each level
for (LOD=0; LOD < MAX_LEVELS; LOD++) {
int blockStartRow;
int blockStartCol;
int blockSpan = POSTS_ACROSS_BLOCK << LOD;
int postStep = 1 << LOD;
ShiAssert( blockSpan < bufferWidth );
ShiAssert( blockSpan < bufferHeight );
// Open this level's post file
sprintf( filename, "%s.L%0d", basename, LOD );
printf( "Generating POST file %s\n", filename );
postFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( postFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open post output file." );
ShiError( string );
}
// Open this level's block offset file
sprintf( filename, "%s.O%0d", basename, LOD );
offsetFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( offsetFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open block offset file." );
ShiError( string );
}
// For each row of blocks
for ( blockStartRow = 0; blockStartRow + blockSpan <= bufferHeight; blockStartRow += blockSpan ) {
blockRow = blockStartRow / blockSpan;
// For each colomn of blocks
for ( blockStartCol = 0; blockStartCol + blockSpan <= bufferWidth; blockStartCol += blockSpan ) {
blockCol = blockStartCol / blockSpan;
// Start at the head of the post buffer
TdiskPost *post = postBuffer;
// For each row in the block
for (row=0; row < blockSpan; row+=postStep) {
// For each column in the block
for(col=0; col < blockSpan; col+=postStep) {
ShiAssert( post-postBuffer < (int)(postBufferSize/sizeof(*post)) );
int dataOffset = ((bufferHeight-1)-(row+blockStartRow))*bufferWidth + (col+blockStartCol);
int texOffset = (((bufferHeight-1)-(row+blockStartRow))>>LAST_TEX_LEVEL)*texMapWidth +
((col+blockStartCol)>>LAST_TEX_LEVEL);
// Store this point's data into the post array
post->z = ElevationBuffer[dataOffset];
post->red = ColorBuffer[(dataOffset*3)+2];
post->green = ColorBuffer[(dataOffset*3)+1];
post->blue = ColorBuffer[(dataOffset*3)+0];
post->phi = NormalBuffer[dataOffset] >> 8;
post->theta = NormalBuffer[dataOffset] & 0xFF;
// Fill in appropriate texture information
if (LOD <= LAST_TEX_LEVEL) {
int mask = ~(((~0)>>LAST_TEX_LEVEL)<<LAST_TEX_LEVEL);
// Figure out the right texture ID (includes Mipmap effects)
post->texID = TexIDBuffer[ texOffset ] | ((LAST_TEX_LEVEL-LOD)<<12);
post->u = (BYTE)((((col+blockStartCol) & mask) * 64) >> LAST_TEX_LEVEL);
post->v = (BYTE)((((row+blockStartRow) & mask) * 64) >> LAST_TEX_LEVEL);
} else {
post->texID = TexIDBuffer[ texOffset ];
post->u = 0;
post->v = 0;
}
// Move on to the next post
post++;
}
}
// Get the file offset to which we're going to write the block
fileOffset = SetFilePointer( postFile, 0, NULL, FILE_CURRENT );
ShiAssert( fileOffset != 0xFFFFFFFF );
// Write the file offset at which this block will be stored
WriteFile( offsetFile, &fileOffset, sizeof( fileOffset ), &bytes, NULL );
if ( bytes != sizeof( fileOffset) ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to write block offset information." );
ShiError( string );
}
// Now write the full block worth of posts to the post file
WriteFile( postFile, postBuffer, postBufferSize, &bytes, NULL );
if ( bytes != postBufferSize ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to write posts data." );
ShiError( string );
}
}
}
// Close the post file
CloseHandle( postFile );
// Close the block offset file
CloseHandle( offsetFile );
// Write the dimensions of this level to the map header file
int blocksWide = (bufferWidth) / (blockSpan);
int blocksHigh = (bufferHeight) / (blockSpan);
WriteFile( headerFile, &blocksWide, sizeof(blocksWide), &bytes, NULL );
ShiAssert( bytes == sizeof(blocksWide) );
WriteFile( headerFile, &blocksHigh, sizeof(blocksHigh), &bytes, NULL );
ShiAssert( bytes == sizeof(blocksHigh) );
// TODO: Down sample the color and elevation better than just decimation
}
// Close the header and post files currently open
printf( "Closing down\n" );
CloseHandle( headerFile );
// Release the color and elevation buffers
free( postBuffer );
free( TexIDBuffer );
free( NormalBuffer );
free( ElevationBuffer );
free( ColorBuffer );
// Say we're done
MessageBox( NULL, "Map Conversion Successful", "Operation Complete", MB_OK );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -