📄 terrlighting.cc
字号:
// generate new height step rows?
if(!xmask)
{
F32 * tmp = pTerrainHeights[0];
pTerrainHeights[0] = pTerrainHeights[1];
pTerrainHeights[1] = tmp;
bp += blockColStep;
Point2I bwalk = bp;
for(i = 0; i < TerrainBlock::BlockSize; i++, bwalk += blockRowStep)
pTerrainHeights[1][i] = fixedToFloat(getHeight(bwalk.x, bwalk.y));
// fill in the row steps
for(i = 0; i < TerrainBlock::BlockSize; i++)
{
terrainZRowStep[0][i] = (pTerrainHeights[0][(i+1) & TerrainBlock::BlockMask] - pTerrainHeights[0][i]) * heightStep;
terrainZRowStep[1][i] = (pTerrainHeights[1][(i+1) & TerrainBlock::BlockMask] - pTerrainHeights[1][i]) * heightStep;
terrainZColStep[i] = (pTerrainHeights[1][i] - pTerrainHeights[0][i]) * heightStep;
}
}
Point2I bwalk = bp - blockRowStep;
for(y = 0; y < generateDim; y++)
{
U32 ymask = y & blockMask;
if(!ymask)
bwalk += blockRowStep;
U32 bi = y >> blockShift;
U32 binext = (bi + 1) & TerrainBlock::BlockMask;
F32 height;
// 135?
if((bwalk.x ^ bwalk.y) & 1)
{
U32 xsub = blockStep - xmask;
if(xsub > ymask) // bottom
height = pTerrainHeights[0][bi] + xmask * terrainZColStep[bi] +
ymask * terrainZRowStep[0][bi];
else // top
height = pTerrainHeights[1][bi] - xsub * terrainZColStep[binext] +
ymask * terrainZRowStep[1][bi];
}
else
{
if(xmask > ymask) // bottom
height = pTerrainHeights[0][bi] + xmask * terrainZColStep[bi] +
ymask * terrainZRowStep[1][bi];
else // top
height = pTerrainHeights[0][bi] + xmask * terrainZColStep[binext] +
ymask * terrainZRowStep[0][bi];
}
F32 intHeight = heightArray[y] * oneMinusFrac + heightArray[(y + fracStep) & generateMask] * frac + zStep;
nextHeightArray[y] = getMax(height, intHeight);
}
// swap the height rows
for(y = 0; y < generateDim; y++)
heightArray[y] = nextHeightArray[y];
}
F32 squareSize = getSquareSize();
F32 squaredSquareSize = squareSize * squareSize;
F32 lexelDim = squareSize * F32(TerrainBlock::BlockSize) / F32(TerrainBlock::LightmapSize);
// calculate normal runs
Point3F normals[2][TerrainBlock::BlockSize];
Point3F * pNormals[2];
pNormals[0] = static_cast<Point3F*>(normals[0]);
pNormals[1] = static_cast<Point3F*>(normals[1]);
// calculate the normal lookup table
F32 * normTable = new F32 [blockStep * blockStep * 4];
Point2F corners[4] = {
Point2F(0.f, 0.f),
Point2F(1.f, 0.f),
Point2F(1.f, 1.f),
Point2F(0.f, 1.f)
};
U32 idx = 0;
F32 step = 1.f / blockStep;
F32 halfStep = step / 2.f;
Point2F pos(halfStep, halfStep);
// fill it
for(x = 0; x < blockStep; x++, pos.x += step, pos.y = halfStep)
for(y = 0; y < blockStep; y++, pos.y += step)
for(i = 0; i < 4; i++, idx++)
normTable[idx] = 1.f - getMin(Point2F(pos - corners[i]).len(), 1.f);
// fill first column
bp = blockFirstPos;
for(x = 0; x < TerrainBlock::BlockSize; x++)
{
terrainHeights[0][x] = fixedToFloat(getHeight(bp.x, bp.y));
Point2F pos(bp.x * squareSize, bp.y * squareSize);
getNormal(pos, &pNormals[1][x]);
bp += blockRowStep;
}
// get swapped on first pass
pTerrainHeights[0] = static_cast<F32*>(terrainHeights[1]);
pTerrainHeights[1] = static_cast<F32*>(terrainHeights[0]);
ColorF colors[TerrainBlock::LightmapSize];
F32 ratio = F32(1 << lightmapShift);
F32 inverseRatioSquared = 1.f / (ratio * ratio);
// walk it...
bp = blockFirstPos - blockColStep;
Point2I lp = lmapFirstPos - blockColStep;
for(x = 0; x < generateDim; x++)
{
U32 xmask = x & blockMask;
// process lightmap?
if(!(x & lightmapMask))
{
dMemset(colors, 0, sizeof(ColorF) * TerrainBlock::LightmapSize);
lp += blockColStep;
}
// generate new runs?
if(!xmask)
{
bp += blockColStep;
// do the normals
Point3F * temp = pNormals[0];
pNormals[0] = pNormals[1];
pNormals[1] = temp;
// fill the row
Point2I bwalk = bp + blockColStep;
for(i = 0; i < TerrainBlock::BlockSize; i++)
{
Point2F pos(bwalk.x * squareSize, bwalk.y * squareSize);
getNormal(pos, &pNormals[1][i]);
bwalk += blockRowStep;
}
// do the heights
F32 * tmp = pTerrainHeights[0];
pTerrainHeights[0] = pTerrainHeights[1];
pTerrainHeights[1] = tmp;
bwalk = bp + blockColStep;
for(i = 0; i < TerrainBlock::BlockSize; i++, bwalk += blockRowStep)
pTerrainHeights[1][i] = fixedToFloat(getHeight(bwalk.x, bwalk.y));
// fill in the row steps
for(i = 0; i < TerrainBlock::BlockSize; i++)
{
terrainZRowStep[0][i] = (pTerrainHeights[0][(i+1) & TerrainBlock::BlockMask] - pTerrainHeights[0][i]) * heightStep;
terrainZRowStep[1][i] = (pTerrainHeights[1][(i+1) & TerrainBlock::BlockMask] - pTerrainHeights[1][i]) * heightStep;
terrainZColStep[i] = (pTerrainHeights[1][i] - pTerrainHeights[0][i]) * heightStep;
}
}
Point2I bwalk = bp - blockRowStep;
for(y = 0; y < generateDim; y++)
{
U32 ymask = y & blockMask;
if(!ymask)
bwalk += blockRowStep;
U32 bi = y >> blockShift;
U32 binext = (bi + 1) & TerrainBlock::BlockMask;
F32 height;
// 135?
if((bwalk.x ^ bwalk.y) & 1)
{
U32 xsub = blockStep - xmask;
if(xsub > ymask) // bottom
height = pTerrainHeights[0][bi] + xmask * terrainZColStep[bi] +
ymask * terrainZRowStep[0][bi];
else // top
height = pTerrainHeights[1][bi] - xsub * terrainZColStep[binext] +
ymask * terrainZRowStep[1][bi];
}
else
{
if(xmask > ymask) // bottom
height = pTerrainHeights[0][bi] + xmask * terrainZColStep[bi] +
ymask * terrainZRowStep[1][bi];
else // top
height = pTerrainHeights[0][bi] + xmask * terrainZColStep[binext] +
ymask * terrainZRowStep[0][bi];
}
F32 intHeight = heightArray[y] * oneMinusFrac + heightArray[(y + fracStep) & generateMask] * frac + zStep;
ColorF & col = colors[y >> lightmapShift];
// non shadowed?
if(height >= intHeight)
{
U32 idx = (xmask + (ymask << blockShift)) << 2;
Point3F normal;
normal = pNormals[0][bi] * normTable[idx++];
normal += pNormals[0][binext] * normTable[idx++];
normal += pNormals[1][binext] * normTable[idx++];
normal += pNormals[1][bi] * normTable[idx];
normal.normalize();
nextHeightArray[y] = height;
F32 colorScale = mDot(normal, lightDir);
if(colorScale >= 0)
col += ambient;
else
col += (ambient + lightColor * -colorScale);
}
else
{
nextHeightArray[y] = intHeight;
col += ambient;
}
}
for(y = 0; y < generateDim; y++)
heightArray[y] = nextHeightArray[y];
// do some lighting stuff?
if(!((x+1) & lightmapMask))
{
Point2I lwalk = lp;
U32 mask = TerrainBlock::LightmapSize - 1;
for(i = 0; i < TerrainBlock::LightmapSize; i++)
{
U16 * ptr = (U16*)lightMap->getAddress(lp.x & mask, lp.y & mask);
*ptr = convertColor(colors[i]);
lp += blockRowStep;
}
}
}
delete [] normTable;
delete [] heightArray;
delete [] nextHeightArray;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -