⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terrlighting.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 2 页
字号:

      // 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 + -