📄 terrdata.cc
字号:
//--------------------------------------
void TerrainBlock::initPersistFields()
{
Parent::initPersistFields();
addGroup("Media");
addField("detailTexture", TypeFilename, Offset(mDetailTextureName, TerrainBlock));
#ifdef TGE_RPG /// TGE_TerrainScene
addField("sceneFile", TypeFilename, Offset(mSceneFileName, TerrainBlock));
#endif
addField("terrainFile", TypeFilename, Offset(mTerrFileName, TerrainBlock));
addField("bumpTexture", TypeFilename, Offset(mBumpTextureName, TerrainBlock));
endGroup("Media");
addGroup("Misc");
addField("squareSize", TypeS32, Offset(squareSize, TerrainBlock));
addField("emptySquares", TypeS32Vector, Offset(mEmptySquareRuns, TerrainBlock));
addField("bumpScale", TypeF32, Offset(mBumpScale, TerrainBlock));
addField("bumpOffset", TypeF32, Offset(mBumpOffset, TerrainBlock));
addField("zeroBumpScale", TypeS32, Offset(mZeroBumpScale, TerrainBlock));
addField("tile", TypeBool, Offset(mTile, TerrainBlock));
endGroup("Misc");
removeField("position");
}
void TerrainBlock::inspectPostApply()
{
Parent::inspectPostApply();
if(isServerObject())
setMaskBits(InitMask);
}
//--------------------------------------
U32 TerrainBlock::packUpdate(NetConnection *, U32 mask, BitStream *stream)
{
if(stream->writeFlag(mask & InitMask))
{
stream->write(mCRC);
stream->writeFlag(mTile);
stream->writeString(mTerrFileName);
#ifdef TGE_RPG /// TGE_TerrainScene
stream->writeString(mSceneFileName);
#endif
stream->writeString(mDetailTextureName);
stream->writeString(mBumpTextureName);
//don't have negative bump scale and don't have one too small
if (mBumpScale <= 0)
{
Con::errorf("Bump scale cannot be less than or equal to 0. Setting to 0.0001.");
mBumpScale = 0.0001;
}
stream->write(mBumpScale);
stream->write(mBumpOffset);
stream->write(mZeroBumpScale);
stream->write(squareSize);
// write out the empty rle vector
stream->write(mEmptySquareRuns.size());
for(U32 i = 0; i < mEmptySquareRuns.size(); i++)
stream->write(mEmptySquareRuns[i]);
}
else // normal update
{
if(stream->writeFlag(mask & EmptyMask))
{
// write out the empty rle vector
stream->write(mEmptySquareRuns.size());
for(U32 i = 0; i < mEmptySquareRuns.size(); i++)
stream->write(mEmptySquareRuns[i]);
}
if(stream->writeFlag(mask & TextureMask))
{
stream->writeString(mDetailTextureName);
stream->writeString(mBumpTextureName);
}
}
return 0;
}
void TerrainBlock::unpackUpdate(NetConnection *, BitStream *stream)
{
if(stream->readFlag()) // init
{
stream->read(&mCRC);
mTile = stream->readFlag();
mTerrFileName = stream->readSTString();
#ifdef TGE_RPG /// TGE_TerrainScene
mSceneFileName = stream->readSTString();
#endif
mDetailTextureName = stream->readSTString();
//CW - bump mapping stuff
mBumpTextureName = stream->readSTString();
stream->read(&mBumpScale);
stream->read(&mBumpOffset);
stream->read(&mZeroBumpScale);
//CW - end bump mapping stuff
stream->read(&squareSize);
// read in the empty rle
U32 size;
stream->read(&size);
mEmptySquareRuns.setSize(size);
for(U32 i = 0; i < size; i++)
stream->read(&mEmptySquareRuns[i]);
// make sure detail and bump textures are set correctly
if((mDetailTextureName && mDetailTextureName[0]) || (mBumpTextureName && mBumpTextureName[0]))
{
mDetailTextureHandle = TextureHandle(mDetailTextureName, DetailTexture);
mBumpTextureHandle = TextureHandle(mBumpTextureName, BumpTexture);
mInvertedBumpTextureHandle = TextureHandle(mBumpTextureName, InvertedBumpTexture);
}
else
{
mDetailTextureHandle = NULL;
mBumpTextureHandle = NULL;
mInvertedBumpTextureHandle = NULL;
}
}
else // normal update
{
if(stream->readFlag()) // empty
{
// read in the empty rle
U32 size;
stream->read(&size);
mEmptySquareRuns.setSize(size);
for(U32 i = 0; i < size; i++)
stream->read(&mEmptySquareRuns[i]);
//
if(materialMap)
unpackEmptySquares();
}
/// TextureMask
if(stream->readFlag()) // empty
{
mDetailTextureName = stream->readSTString();
mBumpTextureName = stream->readSTString();
// make sure detail and bump textures are set correctly
if((mDetailTextureName && mDetailTextureName[0]) || (mBumpTextureName && mBumpTextureName[0]))
{
mDetailTextureHandle = TextureHandle(mDetailTextureName, DetailTexture);
mBumpTextureHandle = TextureHandle(mBumpTextureName, BumpTexture);
mInvertedBumpTextureHandle = TextureHandle(mBumpTextureName, InvertedBumpTexture);
}
else
{
mDetailTextureHandle = NULL;
mBumpTextureHandle = NULL;
mInvertedBumpTextureHandle = NULL;
}
}
}
}
//--------------------------------------
ConsoleFunction(createTerrain, void, 1, 10, "(string fileName,bool bCreateHeight, ...) - makes a test terrain file - arguments after the fileName are the names of the initial terrain materials.")
{
//createTerrain("GWGame/scenes/test.ter","GWGame/terrains/textures/floor1.jpg","GWGame/terrains/textures/floor2.jpg");
TerrainFile *file = new TerrainFile;
S32 nMaterialTypes;
S32 mArgc = argc-2;
bool bCreateHeight = false;
if (argc > 1)
bCreateHeight = dAtob(argv[2]);
bCreateHeight = true;
// Load materials
if (mArgc > 2)
{
nMaterialTypes = mArgc;
for (S32 i=0; i<TerrainBlock::MaterialGroups && i < mArgc; i++)
{
char material[256];
char *ext;
/// TGE_Map
Con::expandScriptFilename(material,256, argv[i+3]);
//dStrcpy(material, argv[i+3]);
ext = dStrrchr(material, '.');
if (ext)
*ext = 0;
file->mMaterialFileName[i] = StringTable->insert(material);
/// TGE_Map
file->mMaterialAlphaMap[i] = new U8[TerrainBlock::BlockSize * TerrainBlock::BlockSize];
for(S32 j = 0; j <TerrainBlock::BlockSize* TerrainBlock::BlockSize; j++)
file->mMaterialAlphaMap[i][j] = 1;//j&255;
// dMemset(file->mMaterialAlphaMap[i], 0, TerrainBlock::BlockSize * TerrainBlock::BlockSize);
}
}
else
{
nMaterialTypes = 1;
file->mMaterialFileName[0] = StringTable->insert("terrains/textures/tile1.jpg");
/// TGE_Map
file->mMaterialAlphaMap[0] = new U8[TerrainBlock::BlockSize * TerrainBlock::BlockSize];
for(S32 j = 0; j <TerrainBlock::BlockSize* TerrainBlock::BlockSize; j++)
file->mMaterialAlphaMap[0][j] = 1;//j&255;
//dMemset(file->mMaterialAlphaMap[0], 0, TerrainBlock::BlockSize * TerrainBlock::BlockSize);
}
// create circular cone in the middle of the map:
S32 i, j;
for(i = 0; i < TerrainBlock::BlockSize; i++)
{
for(j = 0; j < TerrainBlock::BlockSize; j++)
{
U32 offset = i + (j << TerrainBlock::BlockShift);
if(bCreateHeight)
{
S32 x = i & 0x7f;
S32 y = j & 0x7f;
F32 dist = mSqrt((64 - x) * (64 - x) + (64 - y) * (64 - y));
dist /= 64.0f;
if(dist > 1)
dist = 1;
file->mHeightMap[offset] = (U16)((1 - dist) * (1 - dist) * 2000);
}
else
file->mHeightMap[offset] = 0;
file->mBaseMaterialMap[offset] = 0;
}
}
//
char filename[256];
/// TGE_Map
if(argc <2 || !argv[1][0])
dSprintf(filename,256,"_scenes/new_%d.ter",Platform::getTime());
else
{
/// TGE_Map
Con::expandScriptFilename(filename,256, argv[1]);
}
//dStrcpy(filename,argv[1]);
char* ext = dStrrchr(filename, '.');
if (!ext || dStricmp(ext, ".ter") != 0)
dStrcat(filename, ".ter");
file->save(filename);
delete file;
}
//--------------------------------------
ConsoleMethod(TerrainBlock, save, bool, 3, 3, "(string fileName) - saves the terrain block's terrain file to the specified file name.")
{
char filename[256];
dStrcpy(filename,argv[2]);
char *ext = dStrrchr(filename, '.');
if (!ext || dStricmp(ext, ".ter") != 0)
dStrcat(filename, ".ter");
return object->save(filename);
}
ConsoleMethod(TerrainBlock, getSquareSize, F32, 1, 1, "Return the square size of the terrain.")
{
return object->getSquareSize();
}
ConsoleFunction(getTerrainHeight, F32, 2, 2, "(Point2I pos) - gets the terrain height at the specified position.")
{
Point2F pos;
F32 height = 0.0f;
dSscanf(argv[1],"%g %g",&pos.x,&pos.y);
TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(Sim::findObject("Terrain"));
if(terrain)
if(terrain->isServerObject())
{
Point3F offset;
terrain->getTransform().getColumn(3, &offset);
pos -= Point2F(offset.x, offset.y);
terrain->getHeight(pos, &height);
}
return height;
}
ConsoleMethod(TerrainBlock, setTextureScript, void, 3, 3, "(string script) - sets the texture script associated with this terrain file.")
{
object->getFile()->setTextureScript(argv[2]);
}
ConsoleMethod(TerrainBlock, setHeightfieldScript, void, 3, 3, "(string script) - sets the heightfield script associated with this terrain file.")
{
object->getFile()->setHeightfieldScript(argv[2]);
}
ConsoleMethod(TerrainBlock, getTextureScript, const char *, 2, 2, "() - gets the texture script associated with the terrain file.")
{
return object->getFile()->getTextureScript();
}
ConsoleMethod(TerrainBlock, getHeightfieldScript, const char *, 2, 2, "() - gets the heightfield script associated with the terrain file.")
{
return object->getFile()->getHeightfieldScript();
}
#ifdef TGE_RPG /// TGE_Map
/// TGE_Map
ConsoleMethod(TerrainBlock, setDetailTextureHandle, void, 3, 3, "setDetailTextureHandle(sFileName) - 设置detailTexture.")
{
argc;
char sFilename[256];
Con::expandScriptFilename(sFilename,256,argv[2]);
return object->setDetailTextureHandle(StringTable->insert(sFilename));
}
/// TGE_Map
ConsoleMethod(TerrainBlock, setBumpTextureHandle, void, 3, 3, "setBumpTextureHandle(sFileName) - 设置bumpTexture.")
{
argc;
char sFilename[256];
Con::expandScriptFilename(sFilename,256,argv[2]);
return object->setBumpTextureHandle(StringTable->insert(sFilename));
}
#endif
void TerrainBlock::flushCache()
{
TerrainRender::flushCache();
}
//--------------------------------------
TerrainFile::TerrainFile()
{
for(S32 i=0; i < TerrainBlock::MaterialGroups; i++)
{
mMaterialFileName[i] = NULL;
mMaterialAlphaMap[i] = NULL;
}
mTextureScript = 0;
mHeightfieldScript = 0;
}
TerrainFile::~TerrainFile()
{
for(S32 i=0; i < TerrainBlock::MaterialGroups; i++) {
delete[] mMaterialAlphaMap[i];
mMaterialAlphaMap[i] = NULL;
}
dFree(mTextureScript);
dFree(mHeightfieldScript);
}
void TerrainFile::setTextureScript(const char *script)
{
dFree(mTextureScript);
mTextureScript = dStrdup(script);
}
void TerrainFile::setHeightfieldScript(const char *script)
{
dFree(mHeightfieldScript);
mHeightfieldScript = dStrdup(script);
}
const char *TerrainFile::getTextureScript()
{
return mTextureScript ? mTextureScript : "";
}
const char *TerrainFile::getHeightfieldScript()
{
return mHeightfieldScript ? mHeightfieldScript : "";
}
//--------------------------------------
bool TerrainFile::save(const char *filename)
{
FileStream writeFile;
if (!ResourceManager->openFileForWrite(writeFile, filename))
return false;
// write the VERSION and HeightField
writeFile.write((U8)FILE_VERSION);
for (S32 i=0; i < (TerrainBlock::BlockSize * TerrainBlock::BlockSize); i++)
writeFile.write(mHeightMap[i]);
// write the material group map, after merging the flags...
TerrainBlock::Material * materialMap = (TerrainBlock::Material*)mMaterialMap;
for (S32 j=0; j < (TerrainBlock::BlockSize * TerrainBlock::BlockSize); j++)
{
U8 val = mBaseMaterialMap[j];
val |= materialMap[j].flags & TerrainBlock::Material::PersistMask;
writeFile.write(val);
}
// write the MaterialList Info
S32 k;
for(k=0; k < TerrainBlock::MaterialGroups; k++)
{
// ok, only write out the material string if there is a non-zero
// alpha material:
if(mMaterialFileName[k] && mMaterialFileName[k][0])
{
S32 n;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -