V3 mesh, texture, and hover merge.

This commit is contained in:
Shyotl
2016-04-26 13:36:39 -05:00
parent be5d2f20bc
commit 55b5f60b68
39 changed files with 6860 additions and 4126 deletions

View File

@@ -93,6 +93,7 @@
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 20;
BOOL gAnimateTextures = TRUE;
//extern BOOL gHideSelectedObjects;
@@ -1564,6 +1565,65 @@ static LLFastTimer::DeclareTimer FTM_GEN_FLEX("Generate Flexies");
static LLFastTimer::DeclareTimer FTM_UPDATE_PRIMITIVES("Update Primitives");
static LLFastTimer::DeclareTimer FTM_UPDATE_RIGGED_VOLUME("Update Rigged");
bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable)
{
bool regen_faces = false;
LLVolume *old_volumep, *new_volumep;
F32 old_lod, new_lod;
S32 old_num_faces, new_num_faces ;
old_volumep = getVolume();
old_lod = old_volumep->getDetail();
old_num_faces = old_volumep->getNumFaces() ;
old_volumep = NULL ;
{
LLFastTimer ftm(FTM_GEN_VOLUME);
const LLVolumeParams &volume_params = getVolume()->getParams();
setVolume(volume_params, 0);
}
new_volumep = getVolume();
new_lod = new_volumep->getDetail();
new_num_faces = new_volumep->getNumFaces() ;
new_volumep = NULL ;
if ((new_lod != old_lod) || mSculptChanged)
{
sNumLODChanges += new_num_faces ;
if((S32)getNumTEs() != getVolume()->getNumFaces())
{
setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces.
}
drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
{
LLFastTimer t(FTM_GEN_TRIANGLES);
regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs();
if (regen_faces)
{
regenFaces();
}
if (mSculptChanged)
{ //changes in sculpt maps can thrash an object bounding box without
//triggering a spatial group bounding box update -- force spatial group
//to update bounding boxes
LLSpatialGroup* group = mDrawable->getSpatialGroup();
if (group)
{
group->unbound();
}
}
}
}
return regen_faces;
}
BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
LLFastTimer t(FTM_UPDATE_PRIMITIVES);
@@ -1595,8 +1655,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
group->dirtyMesh();
}
BOOL compiled = FALSE;
updateRelativeXform();
if (mDrawable.isNull()) // Not sure why this is happening, but it is...
@@ -1608,83 +1666,35 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
compiled = TRUE;
bool was_regen_faces = false;
if (mVolumeChanged)
{
LLFastTimer ftm(FTM_GEN_VOLUME);
LLVolumeParams volume_params = getVolume()->getParams();
setVolume(volume_params, 0);
was_regen_faces = lodOrSculptChanged(drawable);
drawable->setState(LLDrawable::REBUILD_VOLUME);
}
else if (mSculptChanged || mLODChanged)
{
was_regen_faces = lodOrSculptChanged(drawable);
}
if (!was_regen_faces) {
LLFastTimer t(FTM_GEN_TRIANGLES);
regenFaces();
genBBoxes(FALSE);
}
genBBoxes(FALSE);
}
else if ((mLODChanged) || (mSculptChanged))
else if (mLODChanged || mSculptChanged)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
lodOrSculptChanged(drawable);
genBBoxes(FALSE);
LLVolume *old_volumep, *new_volumep;
F32 old_lod, new_lod;
S32 old_num_faces, new_num_faces ;
old_volumep = getVolume();
old_lod = old_volumep->getDetail();
old_num_faces = old_volumep->getNumFaces() ;
old_volumep = NULL ;
{
LLFastTimer ftm(FTM_GEN_VOLUME);
LLVolumeParams volume_params = getVolume()->getParams();
setVolume(volume_params, 0);
}
new_volumep = getVolume();
new_lod = new_volumep->getDetail();
new_num_faces = new_volumep->getNumFaces() ;
new_volumep = NULL ;
if ((new_lod != old_lod) || mSculptChanged)
{
compiled = TRUE;
sNumLODChanges += new_num_faces ;
if((S32)getNumTEs() != getVolume()->getNumFaces())
{
setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces.
}
drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
{
LLFastTimer t(FTM_GEN_TRIANGLES);
if (new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs())
{
regenFaces();
}
genBBoxes(FALSE);
if (mSculptChanged)
{ //changes in sculpt maps can thrash an object bounding box without
//triggering a spatial group bounding box update -- force spatial group
//to update bounding boxes
LLSpatialGroup* group = mDrawable->getSpatialGroup();
if (group)
{
group->unbound();
}
}
}
}
}
// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
else
{
compiled = TRUE;
// All it did was move or we changed the texture coordinate offset
LLFastTimer t(FTM_GEN_TRIANGLES);
genBBoxes(FALSE);
@@ -1692,7 +1702,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
// Update face flags
updateFaceFlags();
mVolumeChanged = FALSE;
mLODChanged = FALSE;
mSculptChanged = FALSE;
@@ -1819,7 +1829,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
const LLTextureEntry *tep = getTE(te);
if (!tep)
{
LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
}
else if (color != tep->getColor())
{
@@ -1971,10 +1981,237 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
return res;
}
bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
{ //Ok, here we have confirmation about texture creation, check our wait-list
//and make changes, or return false
std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
typedef std::map<U8, LLMaterialPtr> map_te_material;
map_te_material new_material;
for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
{
LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
//here we just interesting in DIFFUSE_MAP only!
if(cur_material.notNull() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat())
{ //ok let's check the diffuse mode
switch(cur_material->getDiffuseAlphaMode())
{
case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
{ //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
LLMaterialPtr mat = NULL;
map_te_material::iterator it = new_material.find(range_it->second.te);
if(new_material.end() == it) {
mat = new LLMaterial(cur_material->asLLSD());
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
} else {
mat = it->second;
}
mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
} break;
} //switch
} //if
} //for
//setup new materials
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
{
LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
LLViewerObject::setTEMaterialParams(it->first, it->second);
}
//clear wait-list
mWaitingTextureInfo.erase(range.first, range.second);
return 0 != new_material.size();
}
bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
{ //Ok, here if we wait information about texture and it's missing
//then depending from the texture map (diffuse, normal, or specular)
//make changes in material and confirm it. If not return false.
std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
if(range.first == range.second) return false;
typedef std::map<U8, LLMaterialPtr> map_te_material;
map_te_material new_material;
for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
{
LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
if (cur_material.isNull())
continue;
switch(range_it->second.map)
{
case LLRender::DIFFUSE_MAP:
{
if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
LLMaterialPtr mat = NULL;
map_te_material::iterator it = new_material.find(range_it->second.te);
if(new_material.end() == it) {
mat = new LLMaterial(cur_material->asLLSD());
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
} else {
mat = it->second;
}
mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
}
} break;
case LLRender::NORMAL_MAP:
{ //missing texture => reset material texture id
LLMaterialPtr mat = NULL;
map_te_material::iterator it = new_material.find(range_it->second.te);
if(new_material.end() == it) {
mat = new LLMaterial(cur_material->asLLSD());
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
} else {
mat = it->second;
}
mat->setNormalID(LLUUID::null);
} break;
case LLRender::SPECULAR_MAP:
{ //missing texture => reset material texture id
LLMaterialPtr mat = NULL;
map_te_material::iterator it = new_material.find(range_it->second.te);
if(new_material.end() == it) {
mat = new LLMaterial(cur_material->asLLSD());
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
} else {
mat = it->second;
}
mat->setSpecularID(LLUUID::null);
} break;
case LLRender::NUM_TEXTURE_CHANNELS:
//nothing to do, make compiler happy
break;
} //switch
} //for
//setup new materials
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
{
LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
LLViewerObject::setTEMaterialParams(it->first, it->second);
}
//clear wait-list
mWaitingTextureInfo.erase(range.first, range.second);
return 0 != new_material.size();
}
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
if(pMaterialParams)
{ //check all of them according to material settings
LLViewerTexture *img_diffuse = getTEImage(te);
LLViewerTexture *img_normal = getTENormalMap(te);
LLViewerTexture *img_specular = getTESpecularMap(te);
llassert(NULL != img_diffuse);
LLMaterialPtr new_material = NULL;
//diffuse
if(NULL != img_diffuse)
{ //guard
if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
{ //ok here we don't have information about texture, let's belief and leave material settings
//but we remember this case
mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
}
else
{
bool bSetDiffuseNone = false;
if(img_diffuse->isMissingAsset())
{
bSetDiffuseNone = true;
}
else
{
switch(pMaterialParams->getDiffuseAlphaMode())
{
case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
{ //all of them modes available only for 32 bit textures
if(GL_RGBA != img_diffuse->getPrimaryFormat())
{
bSetDiffuseNone = true;
}
} break;
}
} //else
if(bSetDiffuseNone)
{ //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE
new_material = new LLMaterial(pMaterialParams->asLLSD());
new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
}
}
}
//normal
if(LLUUID::null != pMaterialParams->getNormalID())
{
if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
{
if(!new_material) {
new_material = new LLMaterial(pMaterialParams->asLLSD());
}
new_material->setNormalID(LLUUID::null);
}
else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
{ //ok here we don't have information about texture, let's belief and leave material settings
//but we remember this case
mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
}
}
//specular
if(LLUUID::null != pMaterialParams->getSpecularID())
{
if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
{
if(!new_material) {
new_material = new LLMaterial(pMaterialParams->asLLSD());
}
new_material->setSpecularID(LLUUID::null);
}
else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
{ //ok here we don't have information about texture, let's belief and leave material settings
//but we remember this case
mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
}
}
if(new_material) {
pMaterial = new_material;
LLMaterialMgr::getInstance()->put(getID(),te,*pMaterial);
}
}
S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial);
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
<< LL_ENDL;
setChanged(ALL_CHANGED);
@@ -4597,60 +4834,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//get drawpool of avatar with rigged face
LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
//Determine if we've received skininfo that contains an
//alternate bind matrix - if it does then apply the translational component
//to the joints of the avatar.
bool pelvisGotSet = false;
// FIXME should this be inside the face loop?
// doesn't seem to depend on any per-face state.
if ( pAvatarVO )
{
LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
if ( pSkinData )
{
const int bindCnt = pSkinData->mAlternateBindMatrix.size();
if ( bindCnt > 0 )
{
const int jointCnt = pSkinData->mJointNames.size();
const F32 pelvisZOffset = pSkinData->mPelvisOffset;
bool fullRig = (jointCnt>=20) ? true : false;
if ( fullRig )
{
for ( int i=0; i<jointCnt; ++i )
{
std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
//LL_INFOS() <<"joint name "<<lookingForJoint.c_str()<<LL_ENDL;
LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
if ( pJoint && pJoint->getId() != currentId )
{
pJoint->setId( currentId );
const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
//Set the joint position
pJoint->storeCurrentXform( jointPos );
//If joint is a pelvis then handle old/new pelvis to foot values
if ( lookingForJoint == "mPelvis" )
{
pJoint->storeCurrentXform( jointPos );
if ( !pAvatarVO->hasPelvisOffset() )
{
pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
//Trigger to rebuild viewer AV
pelvisGotSet = true;
}
}
}
}
}
}
}
}
//If we've set the pelvis to a new position we need to also rebuild some information that the
//viewer does at launch (e.g. body size etc.)
if ( pelvisGotSet )
{
pAvatarVO->postPelvisSetRecalc();
pAvatarVO->addAttachmentPosOverridesForObject(vobj);
}
if (pool)
@@ -5407,6 +5596,10 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
if(!drawablep)
{
continue;
}
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
LLFace* face = drawablep->getFace(i);