📄 tsshapeinstance.cc
字号:
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 + -