T3D 1.2 LOD imposter bug fix
by Dave Wagner · in Torque 3D Professional · 06/18/2012 (1:27 pm) · 1 replies
So I was adjusting the imposters for our trees in the forest which had two geometry LODs and then switched to the imposter for the third LOD. I had everything working great with no popping but when I reloaded the level the trees starting popping in and out of LOD levels, sometimes disappearing all together. If I saved each tree back out using the shape editor the popping would go away, until I reloaded the level. I figured that the shape editor was doing something that wasn't being done during the initial load of the level.
To make a long story short, the follow change fixed the problem.
Change the function in tsShapeEdit.cpp from:
To:
To make a long story short, the follow change fixed the problem.
Change the function in tsShapeEdit.cpp from:
S32 TSShape::addImposter(const String& cachePath, S32 size, S32 numEquatorSteps,
S32 numPolarSteps, S32 dl, S32 dim, bool includePoles, F32 polarAngle)
{
// Check if the desired size is already in use
bool isNewDetail = false;
S32 detIndex = findDetailBySize( size );
if ( detIndex >= 0 )
{
// Size is in use. If the detail is already an imposter, we can just change
// the settings, otherwise quit
if ( details[detIndex].subShapeNum >= 0 )
{
Con::errorf( "TSShape::addImposter: A non-billboard detail already "
"exists at size %d", size );
return -1;
}
}
else
{
// Size is not in use. If an imposter already exists, change its size, otherwise
// create a new detail
for ( detIndex = 0; detIndex < details.size(); ++detIndex )
{
if ( details[detIndex].subShapeNum < 0 )
{
// Change the imposter detail size
setDetailSize( details[detIndex].size, size );
break;
}
}
if ( detIndex == details.size() )
{
isNewDetail = true;
detIndex = addDetail( "bbDetail", size, -1 );
}
}
// Now set the billboard properties.
Detail &detail = details[detIndex];
// In prior to DTS version 26 we would pack the autobillboard
// into this single 32bit value. This was prone to overflows
// of parameters caused random bugs.
//
// Set the old autobillboard properties var to zero.
detail.objectDetailNum = 0;
// We now use the new vars.
detail.bbEquatorSteps = numEquatorSteps;
detail.bbPolarSteps = numPolarSteps;
detail.bbPolarAngle = polarAngle;
detail.bbDetailLevel = dl;
detail.bbDimension = dim;
detail.bbIncludePoles = includePoles;
// Rebuild billboard details or force an update of the modified detail
if ( isNewDetail )
{
// Add NULL meshes for this detail
for ( S32 iObj = 0; iObj < objects.size(); ++iObj )
{
if ( detIndex < objects[iObj].numMeshes )
{
objects[iObj].numMeshes++;
meshes.insert( objects[iObj].startMeshIndex + detIndex, NULL );
for (S32 j = iObj + 1; j < objects.size(); ++j )
objects[j].startMeshIndex++;
}
}
// Could be dedicated server.
if ( GFXDevice::devicePresent() )
setupBillboardDetails( cachePath );
while ( detailCollisionAccelerators.size() < details.size() )
detailCollisionAccelerators.push_back( NULL );
}
else
{
if ( billboardDetails.size() && GFXDevice::devicePresent() )
{
delete billboardDetails[detIndex];
billboardDetails[detIndex] = new TSLastDetail(
this,
cachePath,
detail.bbEquatorSteps,
detail.bbPolarSteps,
detail.bbPolarAngle,
detail.bbIncludePoles,
detail.bbDetailLevel,
detail.bbDimension );
billboardDetails[detIndex]->update( true );
}
}
return detIndex;
}To:
S32 TSShape::addImposter(const String& cachePath, S32 size, S32 numEquatorSteps,
S32 numPolarSteps, S32 dl, S32 dim, bool includePoles, F32 polarAngle)
{
// Check if the desired size is already in use
bool isNewDetail = false;
S32 detIndex = findDetailBySize( size );
if ( detIndex >= 0 )
{
// Size is in use. If the detail is already an imposter, we can just change
// the settings, otherwise quit
if ( details[detIndex].subShapeNum >= 0 )
{
Con::errorf( "TSShape::addImposter: A non-billboard detail already "
"exists at size %d", size );
return -1;
}
}
else
{
// Size is not in use. If an imposter already exists, change its size, otherwise
// create a new detail
for ( detIndex = 0; detIndex < details.size(); ++detIndex )
{
if ( details[detIndex].subShapeNum < 0 )
{
// Change the imposter detail size
setDetailSize( details[detIndex].size, size );
break;
}
}
if ( detIndex == details.size() )
{
isNewDetail = true;
detIndex = addDetail( "bbDetail", size, -1 );
}
}
// Now set the billboard properties.
Detail &detail = details[detIndex];
// In prior to DTS version 26 we would pack the autobillboard
// into this single 32bit value. This was prone to overflows
// of parameters caused random bugs.
//
// Set the old autobillboard properties var to zero.
detail.objectDetailNum = 0;
// We now use the new vars.
detail.bbEquatorSteps = numEquatorSteps;
detail.bbPolarSteps = numPolarSteps;
detail.bbPolarAngle = polarAngle;
detail.bbDetailLevel = dl;
detail.bbDimension = dim;
detail.bbIncludePoles = includePoles;
detail.polyCount = 2;
// Rebuild billboard details or force an update of the modified detail
if ( isNewDetail )
{
// Add NULL meshes for this detail
for ( S32 iObj = 0; iObj < objects.size(); ++iObj )
{
if ( detIndex < objects[iObj].numMeshes )
{
objects[iObj].numMeshes++;
meshes.insert( objects[iObj].startMeshIndex + detIndex, NULL );
for (S32 j = iObj + 1; j < objects.size(); ++j )
objects[j].startMeshIndex++;
}
}
// Could be dedicated server.
if ( GFXDevice::devicePresent() )
setupBillboardDetails( cachePath );
while ( detailCollisionAccelerators.size() < details.size() )
detailCollisionAccelerators.push_back( NULL );
}
else
{
if ( billboardDetails.size() && GFXDevice::devicePresent() )
{
delete billboardDetails[detIndex];
billboardDetails[detIndex] = new TSLastDetail(
this,
cachePath,
detail.bbEquatorSteps,
detail.bbPolarSteps,
detail.bbPolarAngle,
detail.bbIncludePoles,
detail.bbDetailLevel,
detail.bbDimension );
billboardDetails[detIndex]->update( true );
}
}
// Re-initialize the shape
init();
return detIndex;
}
Torque Owner Nils Eikelenboom
Studio DimSum