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

📄 terrdata.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
         if(py < 0)
            py += BlockSize;

         GridSquare *sq = findSquare(0, px, py);

         sq->minHeight = 0xFFFF;
         sq->maxHeight = 0;

         getMinMax(sq->minHeight, sq->maxHeight, getHeight(x, y));
         getMinMax(sq->minHeight, sq->maxHeight, getHeight(x+1, y));
         getMinMax(sq->minHeight, sq->maxHeight, getHeight(x, y+1));
         getMinMax(sq->minHeight, sq->maxHeight, getHeight(x+1, y+1));
      }
   }

   // ok, all the level 0 grid squares are updated:
   // now update all the parent grid squares that need to be updated:

   for(S32 level = 1; level <= TerrainBlock::BlockShift; level++)
   {
      S32 size = 1 << level;
      S32 halfSize = size >> 1;
      for(S32 y = (min.y - 1) >> level; y < (max.y + size) >> level; y++)
      {
         for(S32 x = (min.x - 1) >> level; x < (max.x + size) >> level; x++)
         {
            S32 px = x << level;
            S32 py = y << level;

            GridSquare *square = findSquare(level, px, py);
            square->minHeight = 0xFFFF;
            square->maxHeight = 0;

            checkSquareMinMax(square, findSquare(level - 1, px, py));
            checkSquareMinMax(square, findSquare(level - 1, px + halfSize, py));
            checkSquareMinMax(square, findSquare(level - 1, px, py + halfSize));
            checkSquareMinMax(square, findSquare(level - 1, px + halfSize, py + halfSize));
         }
      }
   }
}


//--------------------------------------

/// TGE_Collision
bool TerrainBlock::getHeights(const Point2F &pos, F32 *pHeights)
{
		float invSquareSize = 1.0f / (float)squareSize;


		float xp = 0.;
		float yp = 0.;

	/// x,y偏移修正
#ifndef TGE_RPG /// TGE_Collision
	S32 sOffset = squareSize * (BlockSize >> 1);
		int x = (S32)mFloor((pos.x + sOffset) * invSquareSize);
		int y = (S32)mFloor((pos.y + sOffset) * invSquareSize);
#else
		int x = (S32)mFloor(pos.x * invSquareSize);
		int y = (S32)mFloor(pos.y * invSquareSize);
#endif

		S32 squareSize1 = squareSize+1;
		x &= TerrainBlock::BlockMask;
		y &= TerrainBlock::BlockMask;


	float zBottomLeft = fixedToFloat(getHeight(x, y));
	float zBottomRight = fixedToFloat(getHeight(x + 1, y));
	float zTopLeft = fixedToFloat(getHeight(x, y + 1));
	float zTopRight = fixedToFloat(getHeight(x + 1, y + 1));


	GridSquare * gs = findSquare(0, Point2I(x,y));
	if (gs->flags & GridSquare::Empty)
		return false;


	for(U32 row=0;  row < squareSize1; row++)
	{
		yp = (float)row * invSquareSize;
		U32 uBase = row * squareSize1;

		for(U32 col=0; col < squareSize1; col++)
		{
			xp = (float)col * invSquareSize;

			if(gs->flags & GridSquare::Split45)
			{
				if (xp>yp)
					// bottom half
					pHeights[uBase + col] = zBottomLeft + xp * (zBottomRight-zBottomLeft) + yp * (zTopRight-zBottomRight);
				else
					// top half
					pHeights[uBase + col] = zBottomLeft + xp * (zTopRight-zTopLeft) + yp * (zTopLeft-zBottomLeft);
			}
			else
			{
				if (1.0f-xp>yp)
					// bottom half
					pHeights[uBase + col] = zBottomRight + (1.0f-xp) * (zBottomLeft-zBottomRight) + yp * (zTopLeft-zBottomLeft);
				else
					// top half
					pHeights[uBase + col] = zBottomRight + (1.0f-xp) * (zTopLeft-zTopRight) + yp * (zTopRight-zBottomRight);
			}
		}//for
	}//for
	return true;
}


//--------------------------------------
bool TerrainBlock::getHeight(const Point2F &pos, F32 *height)
{

   float invSquareSize = 1.0f / (float)squareSize;

	/// x,y偏移修正
#ifndef TGE_RPG /// TGE_Collision
	S32 sOffset = squareSize * (BlockSize >> 1);
   float xp = (pos.x + sOffset) * invSquareSize;
   float yp = (pos.y + sOffset) * invSquareSize;
#else
   float xp = pos.x * invSquareSize;
   float yp = pos.y * invSquareSize;
#endif

   int x = (S32)mFloor(xp);
   int y = (S32)mFloor(yp);
   xp -= (float)x;
   yp -= (float)y;
   x &= BlockMask;
   y &= BlockMask;
   GridSquare * gs = findSquare(0, Point2I(x,y));

   if (gs->flags & GridSquare::Empty)
      return false;

   float zBottomLeft = fixedToFloat(getHeight(x, y));
   float zBottomRight = fixedToFloat(getHeight(x + 1, y));
   float zTopLeft = fixedToFloat(getHeight(x, y + 1));
   float zTopRight = fixedToFloat(getHeight(x + 1, y + 1));

   if(gs->flags & GridSquare::Split45)
   {
      if (xp>yp)
         // bottom half
         *height = zBottomLeft + xp * (zBottomRight-zBottomLeft) + yp * (zTopRight-zBottomRight);
      else
         // top half
         *height = zBottomLeft + xp * (zTopRight-zTopLeft) + yp * (zTopLeft-zBottomLeft);
   }
   else
   {
      if (1.0f-xp>yp)
         // bottom half
         *height = zBottomRight + (1.0f-xp) * (zBottomLeft-zBottomRight) + yp * (zTopLeft-zBottomLeft);
      else
         // top half
         *height = zBottomRight + (1.0f-xp) * (zTopLeft-zTopRight) + yp * (zTopRight-zBottomRight);
   }
   return true;
}

bool TerrainBlock::getNormal(const Point2F & pos, Point3F * normal, bool normalize)
{

	float invSquareSize = 1.0f / (float)squareSize;

	/// x,y偏移修正
#ifndef TGE_RPG /// TGE_Collision
	S32 sOffset = squareSize * (BlockSize >> 1);
   float xp = (pos.x + sOffset) * invSquareSize;
   float yp = (pos.y + sOffset) * invSquareSize;
#else
   float xp = pos.x * invSquareSize;
   float yp = pos.y * invSquareSize;
#endif

   int x = (S32)mFloor(xp);
   int y = (S32)mFloor(yp);
   xp -= (float)x;
   yp -= (float)y;
   x &= BlockMask;
   y &= BlockMask;
   GridSquare * gs = findSquare(0, Point2I(x,y));

   if (gs->flags & GridSquare::Empty)
      return false;

   float zBottomLeft = fixedToFloat(getHeight(x, y));
   float zBottomRight = fixedToFloat(getHeight(x + 1, y));
   float zTopLeft = fixedToFloat(getHeight(x, y + 1));
   float zTopRight = fixedToFloat(getHeight(x + 1, y + 1));

   if(gs->flags & GridSquare::Split45)
   {
      if (xp>yp)
         // bottom half
         normal->set(zBottomLeft-zBottomRight,zBottomRight-zTopRight,squareSize);
      else
         // top half
         normal->set(zTopLeft-zTopRight,zBottomLeft-zTopLeft,squareSize);
   }
   else
   {
      if (1.0f-xp>yp)
         // bottom half
         normal->set(zBottomLeft-zBottomRight,zBottomLeft-zTopLeft,squareSize);
      else
         // top half
         normal->set(zTopLeft-zTopRight,zBottomRight-zTopRight,squareSize);
   }
   if (normalize)
      normal->normalize();
   return true;
}

bool TerrainBlock::getNormalAndHeight(const Point2F & pos, Point3F * normal, F32 * height, bool normalize)
{
   float invSquareSize = 1.0f / (float)squareSize;

	/// x,y偏移修正
#ifndef TGE_RPG /// TGE_Collision
	//Point3F offset = getRenderPosition();
	S32 sOffset = squareSize * (BlockSize >> 1);
   float xp = (pos.x + sOffset) * invSquareSize;
   float yp = (pos.y + sOffset) * invSquareSize;
#else
   float xp = pos.x * invSquareSize;
   float yp = pos.y * invSquareSize;
#endif

	int x = (S32)mFloor(xp);
   int y = (S32)mFloor(yp);
   xp -= (float)x;
   yp -= (float)y;
   x &= BlockMask;
   y &= BlockMask;
   GridSquare * gs = findSquare(0, Point2I(x,y));

   if (gs->flags & GridSquare::Empty)
      return false;

   float zBottomLeft = fixedToFloat(getHeight(x, y));
   float zBottomRight = fixedToFloat(getHeight(x + 1, y));
   float zTopLeft = fixedToFloat(getHeight(x, y + 1));
   float zTopRight = fixedToFloat(getHeight(x + 1, y + 1));

   if(gs->flags & GridSquare::Split45)
   {
      if (xp>yp)
      {
         // bottom half
         normal->set(zBottomLeft-zBottomRight,zBottomRight-zTopRight,squareSize);
         *height = zBottomLeft + xp * (zBottomRight-zBottomLeft) + yp * (zTopRight-zBottomRight);
      }
      else
      {
         // top half
         normal->set(zTopLeft-zTopRight,zBottomLeft-zTopLeft,squareSize);
         *height = zBottomLeft + xp * (zTopRight-zTopLeft) + yp * (zTopLeft-zBottomLeft);
      }
   }
   else
   {
      if (1.0f-xp>yp)
      {
         // bottom half
         normal->set(zBottomLeft-zBottomRight,zBottomLeft-zTopLeft,squareSize);
         *height = zBottomRight + (1.0f-xp) * (zBottomLeft-zBottomRight) + yp * (zTopLeft-zBottomLeft);
      }
      else
      {
         // top half
         normal->set(zTopLeft-zTopRight,zBottomRight-zTopRight,squareSize);
         *height = zBottomRight + (1.0f-xp) * (zTopLeft-zTopRight) + yp * (zTopRight-zBottomRight);
      }
   }
   if (normalize)
      normal->normalize();
   return true;
}

//------------------------------------------------------------------------------

void TerrainBlock::setBaseMaterials(S32 argc, const char *argv[])
{
   for (S32 i = 0; i < argc; i++)
      mMaterialFileName[i] = StringTable->insert(argv[i]);
   for (S32 j = argc; j < MaterialGroups; j++)
      mMaterialFileName[j] = NULL;
}

//------------------------------------------------------------------------------

//--------------------------------------

bool TerrainBlock::buildMaterialMap()
{
   TerrainRender::flushCache();
   return initMMXBlender();
}

// This routine takes 256x256 bitmap and makes
// sure that each 128 x 128 grid has borders that
// match adjacent 128 x 128 grids.  This fixes a
// terrain blending error/defect.
void tweakTerrainBmp(GBitmap * pBitmap)
{
   AssertFatal(pBitmap->getWidth() == pBitmap->getHeight() &&
      pBitmap->getFormat()==GBitmap::RGB,
      "tweakTerrainBmp - This should have been caught before, but this is an invalid terrain texture.");

   S32 size = pBitmap->getWidth();
   for (int k = 0; k < pBitmap->getNumMipLevels() - 4; k++)
   {
      U8 * bits = pBitmap->getWritableBits(k);
      S32 offset1 = -1;
      S32 offset2 = 0;
      S32 base;
      for (base=0; base<size; base += size / 2)
      {
         S32 top1 = (base + offset1 + size) % size;
         top1 *= 3;
         S32 top2 = (base + offset2 + size) % size;
         top2 *= 3;

         // slide down column
         for (S32 i=0; i<size; i++)
         {
            for (S32 j=0; j<3; j++)
            {
               U8 val1 = bits[top1 + i*size*3 + j];
               U8 val2 = bits[top2 + i*size*3 + j];
               U8 val = (val1 >> 1) + (val2 >> 1);
               if (val1 & val2 & 1)
                  ++val;
               bits[top1 + i*size*3 + j] = bits[top2 + i*size*3 + j] = val;
            }
         }
      }

      for (base=0; base<size; base += size / 2)
      {
         S32 left1 = (base + offset1 + size) % size;
         left1 *= size * 3;
         S32 left2 = (base + offset2 + size) % size;
         left2 *= size * 3;

         // slide across row
         for (S32 i=0; i<size; i++)
         {
            for (S32 j=0; j<3; j++)
            {
               U8 val1 = bits[left1 + i*3 + j];
               U8 val2 = bits[left2 + i*3 + j];
               U8 val = (val1 >> 1) + (val2 >> 1);
               if (val1 & val2 & 1)
                  ++val;
               bits[left1+i*3 + j] = bits[left2 + i*3 + j] = val;
            }
         }
      }
      size /= 2;
   }
}

bool TerrainBlock::initMMXBlender()
{
   // DMMNOTE: come back to this
   delete mBlender;
   mBlender = NULL;

   char fileBuf[256];

   U32 validMaterials = 0;
   S32 i;
   for (i = 0; i < MaterialGroups; i++)
   {
      if (mMaterialFileName[i] && *mMaterialFileName[i])
         validMaterials++;
      else
         break;
   }

   AssertFatal(validMaterials != 0, "Error, must have SOME materials here!");

   // Submit alphamaps
   U8* alphaMaterials[MaterialGroups];
   dMemset(alphaMaterials, 0, sizeof(alphaMaterials));
   for (i = 0; i < validMaterials; i++) {
      if (getMaterialAlphaMap(i) == NULL) {
         AssertFatal(getMaterialAlphaMap(i) != NULL, "Error, need an alpha map here!");
         return false;
      }
      alphaMaterials[i] = getMaterialAlphaMap(i);
   }

   mBlender = new Blender(validMaterials, 5, alphaMaterials);

   // Ok, we have validMaterials set correctly
   bool matsValid = true;
   for(i = 0; i < validMaterials; i++)
   {
      AssertFatal(mMaterialFileName[i] && *mMaterialFileName[i], "Error, something wacky here");
      StringTableEntry fn = mMaterialFileName[i];

      GBitmap* pBitmap = TextureManager::loadBitmapInstance(fn);

      if (!pBitmap)
      {
         dStrcpyl(fileBuf, sizeof(fileBuf), mFile.getFilePath(), "/", fn, NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -