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

📄 tsshapeinstance.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
      return;
   mMaterialList = new TSMaterialList(mMaterialList);
   mOwnMaterialList = true;
}

static bool makeSkinPath(char* buffer, U32 bufferLength, const char* resourcePath,
                         const char* oldSkin, const char* oldRoot, const char* newRoot)
{
   bool replacedRoot = true;

   dsize_t oldRootLen = 0;
   char* rootStart = NULL;

   if (oldRoot == NULL) {
      // Not doing any replacing.
      replacedRoot = false;
   }
   else {
      // See if original name has the old root in it.
      oldRootLen = dStrlen(oldRoot);
      AssertFatal((oldRootLen + 1) < bufferLength, "makeSkinPath: Error, skin root name too long");
      dStrcpy(buffer, oldRoot);
      dStrcat(buffer, ".");
      rootStart = dStrstr(oldSkin, buffer);
      if (rootStart == NULL) {
         replacedRoot = false;
      }
   }

   // Find out how long the total pathname will be.
   const dsize_t oldLen = dStrlen(oldSkin);
   dsize_t pathLen = 0;
   if (resourcePath != NULL) {
      pathLen = dStrlen(resourcePath);
   }
   if (replacedRoot) {
      const dsize_t newRootLen = dStrlen(newRoot);
      AssertFatal((pathLen + 1 + oldLen + newRootLen - oldRootLen) < bufferLength, "makeSkinPath: Error, pathname too long");
   }
   else {
      AssertFatal((pathLen + 1 + oldLen) < bufferLength, "makeSkinPath: Error, pathname too long");
   }

   // OK, now make the pathname.

   // Start with the resource path:
   if (resourcePath != NULL) {
      dStrcpy(buffer, resourcePath);
      dStrcat(buffer, "/");
   }
   else {
      buffer[0] = '\0';
   }
   if (replacedRoot) {
      // Then the pre-root part of the old name:
      dsize_t rootStartPos = rootStart - oldSkin;
      if (rootStartPos != 0) {
         dStrncat(buffer, oldSkin, rootStartPos);
      }
      // Then the new root:
      dStrcat(buffer, newRoot);
      dStrcat(buffer, ".");
      // Then the post-root part of the old name:
      dStrcat(buffer, oldSkin + rootStartPos + oldRootLen + 1);
   }
   else {
      // Then the old name:
      dStrcat(buffer, oldSkin);
   }

   return replacedRoot;
}


void TSShapeInstance::reSkin(StringHandle& newBaseHandle)
{
#define NAME_BUFFER_LENGTH 256
   static char pathName[NAME_BUFFER_LENGTH];
   const char* defaultBaseName = "base";
   const char* newBaseName;

   if (newBaseHandle.isValidString()) {
      newBaseName = newBaseHandle.getString();
      if (newBaseName == NULL) {
         return;
      }
   }
   else {
      newBaseName = defaultBaseName;
   }

   // Make our own copy of the materials list from the resource
   // if necessary.
   if (ownMaterialList() == false) {
      cloneMaterialList();
   }

   const char* resourcePath = hShape.getFilePath();

   // Cycle through the materials.
   TSMaterialList* pMatList = getMaterialList();
   for (S32 j = 0; j < pMatList->mMaterialNames.size(); j++) {
      // Get the name of this material.
      const char* pName = pMatList->mMaterialNames[j];
      // Bail if no name.
      if (pName == NULL) {
         continue;
      }
      // Make a texture file pathname with the new root if this name
      // has the old root in it; otherwise just make a path with the
      // original name.
      bool replacedRoot = makeSkinPath(pathName, NAME_BUFFER_LENGTH, resourcePath,
                          pName, defaultBaseName, newBaseName);

      if (!replacedRoot) {
         // If this wasn't in the desired format, set the material's
         // texture handle (since that wasn't copied over in the
         // cloning) and continue.

			//skin modifier
		  //pMatList->mMaterials[j] = TextureHandle(pathName, MeshTexture, false);
         pMatList->mMaterials[j] = getSkinTexutre(pName,pathName);
         continue;
      }

	  //skin modifier
      // OK, it is a skin texture.  Get the handle.
      //TextureHandle skinHandle = TextureHandle(pathName, MeshTexture, false);
      TextureHandle skinHandle = getSkinTexutre(pName,pathName);

      // Do a sanity check; if it fails, use the original skin instead.
      if (skinHandle.getGLName() != 0) {
         pMatList->mMaterials[j] = skinHandle;
      }
      else {
         makeSkinPath(pathName, NAME_BUFFER_LENGTH, resourcePath, pName, NULL, NULL);
		 //skin modifier
         //pMatList->mMaterials[j] = TextureHandle(pathName, MeshTexture, false);
         pMatList->mMaterials[j] = getSkinTexutre(pName,pathName);
      }
   }
}



//-------------------------------------------------------------------------------------
// skin modifier methods
void TSShapeInstance::addSkinModifier(U32 slot, StringTableEntry skinName, StringTableEntry printName)
{
   if(skinName == NULL || skinName[0] == 0 || printName == NULL || printName[0] == 0)
      return;

	//removeSkinModifier(slot);
	if(mSkinModifiers[slot].skinName	!= skinName)
	{
		removeSkinModifier(slot);
	}

	mSkinModifiers[slot].skinName			= skinName;
	mSkinModifiers[slot].hModTexture		= TextureHandle(printName, MeshTexture);

	if(!bool(mSkinModifiers[slot].hBakTexture))
	{	
		mSkinModifiers[slot].hBakTexture		= getShapeSkinTexture(skinName, &mSkinModifiers[slot].nBakIndex);
	}
	updateModifier(slot);
}



void TSShapeInstance::removeSkinModifier(U32 slot)
{
	if(bool(mSkinModifiers[slot].hModTexture) )
		mSkinModifiers[slot].hModTexture = TextureHandle();

	if(bool(mSkinModifiers[slot].hBakTexture) )
	{	
		TSMaterialList*	pMatList = getMaterialList();
		pMatList->mMaterials[mSkinModifiers[slot].nBakIndex] = mSkinModifiers[slot].hBakTexture;
		//updateModifier(SkinModifiers[slot].skinName, mSkinModifiers[slot].hBakTexture);
	}

	mSkinModifiers[slot].skinName	= StringTable->getBlank();
}


void TSShapeInstance::clearSkinModifiers()
{
   for (U32 ss=0; ss<MaxSkinModifiers; ss++)
   {
      removeSkinModifier(ss);
   }
}



void TSShapeInstance::updateModifiers()
{
	char skinName[512];

	// Make our own copy of the materials list from the resource
	// if necessary.
	if (!ownMaterialList()) 
	{
		cloneMaterialList();
	}


	TSMaterialList*	pMatList = getMaterialList();
	StringTableEntry	baseSkinName;
	StringTableEntry	pFilePath;

	for (U32 mm=0; mm < pMatList->mMaterialNames.size(); mm++)
	{
		// Get the name of this material.
		pFilePath		= pMatList->mMaterials[mm].getName();
		baseSkinName	= StringTable->insert(pMatList->mMaterialNames[mm]);

		if(pFilePath)
			pFilePath		= StringTable->insert(pFilePath);
		else
			pFilePath		= StringTable->getBlank();
		
		pMatList->mMaterials[mm]	= getSkinTexutre(baseSkinName,pFilePath);
	}
}


void TSShapeInstance::updateModifier(U32 slot/*, TextureHandle* pTexture*/)
{
	U32 n;
	//StringTableEntry	baseSkinName;
	
	if(!bool(mSkinModifiers[slot].hModTexture))
		return;
	
	TSMaterialList*	pMatList = getMaterialList();
	//for (n=0; n < pMatList->mMaterialNames.size(); n++)
	//{
	//	// Get the name of this material.
	//	baseSkinName	= StringTable->insert(pMatList->mMaterialNames[n]);

	//	if(baseSkinName == mSkinModifiers[slot].skinName)
	//	{
	n = mSkinModifiers[slot].nBakIndex;
	
	pMatList->mMaterials[n]	= mSkinModifiers[slot].hModTexture;
			//return;
	//	}
	//}
}

void TSShapeInstance::updateModifier(StringTableEntry skinName/*,TextureHandle* pTexture*/)
{
	U32 n;
	for (n=0; n < MaxSkinModifiers; n++)
	{
		if(mSkinModifiers[n].skinName == skinName)
		{
			updateModifier(n/*, pTexture*/);
			break;
		}
	}

}


TextureHandle TSShapeInstance::getShapeSkinTexture(StringTableEntry skinName,U32* pRet)
{
	U32 n;
	StringTableEntry	baseSkinName;

	TSMaterialList*	pMatList = getMaterialList();
	for (n=0; n < pMatList->mMaterialNames.size(); n++)
	{
		// Get the name of this material.
		baseSkinName	= StringTable->insert(pMatList->mMaterialNames[n]);

		if(baseSkinName == skinName)
		{
			if(pRet)
				*pRet = n;
			return pMatList->mMaterials[n];
		}
	}

	if(pRet)
		*pRet = -1;
	return TextureHandle();
}


TextureHandle TSShapeInstance::getSkinTexutre(StringTableEntry baseSkinName, StringTableEntry skinName)
{
   char modTextureName[512];

	if(baseSkinName == NULL || baseSkinName[0] == 0)
		return TextureHandle();

	if(skinName == NULL || skinName[0] == 0)
		return TextureHandle();


   // check all skin modifier slots
   for (U32 n=0; n<MaxSkinModifiers; n++)
   {
      if(mSkinModifiers[n].skinName != baseSkinName)
			continue;

		if(!bool(mSkinModifiers[n].hModTexture))
		{	
			mSkinModifiers[n].hModTexture = TextureHandle(skinName, MeshTexture, false);
		}
		return mSkinModifiers[n].hModTexture;
   }


   return TextureHandle(skinName,MeshTexture,false);

}




//-------------------------------------------------------------------------------------
// Render & detail selection
//-------------------------------------------------------------------------------------
void TSShapeInstance::render(const Point3F * objectScale)
{
   if (mCurrentDetailLevel<0)
      return;
   PROFILE_START(TSShapeInstanceRender);
   dglSetRenderPrimType(3);

   // alphaIn:  we start to alpha-in next detail level when intraDL > 1-alphaIn-alphaOut
   //           (finishing when intraDL = 1-alphaOut)
   // alphaOut: start to alpha-out this detail level when intraDL > 1-alphaOut
   // NOTE:
   //   intraDL is at 1 when if shape were any closer to us we'd be at dl-1,
   //   intraDL is at 0 when if shape were any farther away we'd be at dl+1
   F32 alphaOut = mShape->alphaOut[mCurrentDetailLevel];
   F32 alphaIn  = mShape->alphaIn[mCurrentDetailLevel];
   F32 saveAA = mAlphaAlways ? mAlphaAlwaysValue : 1.0f;

   if (mCurrentIntraDetailLevel>alphaIn+alphaOut)
      render(mCurrentDetailLevel,mCurrentIntraDetailLevel,objectScale);
   else if (mCurrentIntraDetailLevel>alphaOut)
   {
      // draw this detail level w/ alpha=1 and next detail level w/
      // alpha=1-(intraDl-alphaOut)/alphaIn

      // first draw next detail level
      if (mCurrentDetailLevel+1<mShape->details.size() && mShape->details[mCurrentDetailLevel+1].size>0.0f)
      {
         setAlphaAlways(saveAA * (alphaIn+alphaOut-mCurrentIntraDetailLevel)/alphaIn);
         render(mCurrentDetailLevel+1,0.0f,objectScale);
      }

      setAlphaAlways(saveAA);
      render(mCurrentDetailLevel,mCurrentIntraDetailLevel,objectScale);
   }
   else
   {
      // draw next detail level w/ alpha=1 and this detail level w/
      // alpha = 1-intraDL/alphaOut

      // first draw next detail level
      if (mCurrentDetailLevel+1<mShape->details.size() && mShape->details[mCurrentDetailLevel+1].size>0.0f)
         render(mCurrentDetailLevel+1,0.0f,objectScale);

      setAlphaAlways(saveAA * mCurrentIntraDetailLevel / alphaOut);
      render(mCurrentDetailLevel,mCurrentIntraDetailLevel,objectScale);
      setAlphaAlways(saveAA);
   }
   dglSetRenderPrimType(0);
   PROFILE_END();
}

bool TSShapeInstance::hasTranslucency()
{
   if(!mShape->details.size())
      return false;

   const TSDetail * detail = &mShape->details[0];
   S32 ss = detail->subShapeNum;

   return mShape->subShapeFirstTranslucentObject[ss] != mShape->subShapeFirstObject[ss] + mShape->subShapeNumObjects[ss];
}

bool TSShapeInstance::hasSolid()
{
   if(!mShape->details.size())
      return false;

   const TSDetail * detail = &mShape->details[0];
   S32 ss = detail->subShapeNum;

   return mShape->subShapeFirstTranslucentObject[ss] != mShape->subShapeFirstObject[ss];
}

⌨️ 快捷键说明

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