SH-2188. Invalid VBO updates for rigged attachments.

This commit is contained in:
Shyotl
2011-08-18 00:28:42 -05:00
parent ecce8ad23a
commit 48abb8280f
5 changed files with 47 additions and 200 deletions

View File

@@ -2080,7 +2080,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mDetail = detail; mDetail = detail;
mSculptLevel = -2; mSculptLevel = -2;
#if MESH_ENABLED #if MESH_ENABLED
mIsTetrahedron = FALSE; mIsMeshAssetLoaded = FALSE;
mLODScaleBias.setVec(1,1,1); mLODScaleBias.setVec(1,1,1);
mHullPoints = NULL; mHullPoints = NULL;
mHullIndices = NULL; mHullIndices = NULL;
@@ -2103,7 +2103,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
generate(); generate();
if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE || mParams.getSculptType() == LL_SCULPT_TYPE_MESH)
{ {
createVolumeFaces(); createVolumeFaces();
} }
@@ -2712,173 +2712,21 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
return true; return true;
} }
void tetrahedron_set_normal(LLVolumeFace::VertexData* cv)
BOOL LLVolume::isMeshAssetLoaded()
{ {
LLVector4a v0; return mIsMeshAssetLoaded;
v0.setSub(cv[1].getPosition(), cv[0].getNormal());
LLVector4a v1;
v1.setSub(cv[2].getNormal(), cv[0].getPosition());
cv[0].getNormal().setCross3(v0,v1);
cv[0].getNormal().normalize3fast();
cv[1].setNormal(cv[0].getNormal());
cv[2].setNormal(cv[1].getNormal());
} }
BOOL LLVolume::isTetrahedron() void LLVolume::setMeshAssetLoaded(BOOL loaded)
{ {
return mIsTetrahedron; mIsMeshAssetLoaded = loaded;
}
void LLVolume::makeTetrahedron()
{
mVolumeFaces.clear();
LLVolumeFace face;
F32 x = 0.25f;
LLVector4a p[] =
{ //unit tetrahedron corners
LLVector4a(x,x,x),
LLVector4a(-x,-x,x),
LLVector4a(-x,x,-x),
LLVector4a(x,-x,-x)
};
face.mExtents[0].splat(-x);
face.mExtents[1].splat(x);
LLVolumeFace::VertexData cv[3];
//set texture coordinates
cv[0].mTexCoord = LLVector2(0,0);
cv[1].mTexCoord = LLVector2(1,0);
cv[2].mTexCoord = LLVector2(0.5f, 0.5f*F_SQRT3);
//side 1
cv[0].setPosition(p[1]);
cv[1].setPosition(p[0]);
cv[2].setPosition(p[2]);
tetrahedron_set_normal(cv);
face.resizeVertices(12);
face.resizeIndices(12);
LLVector4a* v = (LLVector4a*) face.mPositions;
LLVector4a* n = (LLVector4a*) face.mNormals;
LLVector2* tc = (LLVector2*) face.mTexCoords;
v[0] = cv[0].getPosition();
v[1] = cv[1].getPosition();
v[2] = cv[2].getPosition();
v += 3;
n[0] = cv[0].getNormal();
n[1] = cv[1].getNormal();
n[2] = cv[2].getNormal();
n += 3;
if(tc)
{
tc[0] = cv[0].mTexCoord;
tc[1] = cv[1].mTexCoord;
tc[2] = cv[2].mTexCoord;
tc += 3;
}
//side 2
cv[0].setPosition(p[3]);
cv[1].setPosition(p[0]);
cv[2].setPosition(p[1]);
tetrahedron_set_normal(cv);
v[0] = cv[0].getPosition();
v[1] = cv[1].getPosition();
v[2] = cv[2].getPosition();
v += 3;
n[0] = cv[0].getNormal();
n[1] = cv[1].getNormal();
n[2] = cv[2].getNormal();
n += 3;
if(tc)
{
tc[0] = cv[0].mTexCoord;
tc[1] = cv[1].mTexCoord;
tc[2] = cv[2].mTexCoord;
tc += 3;
}
//side 3
cv[0].setPosition(p[3]);
cv[1].setPosition(p[1]);
cv[2].setPosition(p[2]);
tetrahedron_set_normal(cv);
v[0] = cv[0].getPosition();
v[1] = cv[1].getPosition();
v[2] = cv[2].getPosition();
v += 3;
n[0] = cv[0].getNormal();
n[1] = cv[1].getNormal();
n[2] = cv[2].getNormal();
n += 3;
if(tc)
{
tc[0] = cv[0].mTexCoord;
tc[1] = cv[1].mTexCoord;
tc[2] = cv[2].mTexCoord;
tc += 3;
}
//side 4
cv[0].setPosition(p[2]);
cv[1].setPosition(p[0]);
cv[2].setPosition(p[3]);
tetrahedron_set_normal(cv);
v[0] = cv[0].getPosition();
v[1] = cv[1].getPosition();
v[2] = cv[2].getPosition();
v += 3;
n[0] = cv[0].getNormal();
n[1] = cv[1].getNormal();
n[2] = cv[2].getNormal();
n += 3;
if(tc)
{
tc[0] = cv[0].mTexCoord;
tc[1] = cv[1].mTexCoord;
tc[2] = cv[2].mTexCoord;
tc += 3;
}
//set index buffer
for (U16 i = 0; i < 12; i++)
{
face.mIndices[i] = i;
}
mVolumeFaces.push_back(face);
mSculptLevel = 0;
mIsTetrahedron = TRUE;
} }
void LLVolume::copyVolumeFaces(const LLVolume* volume) void LLVolume::copyVolumeFaces(const LLVolume* volume)
{ {
mVolumeFaces = volume->mVolumeFaces; mVolumeFaces = volume->mVolumeFaces;
mSculptLevel = 0; mSculptLevel = 0;
mIsTetrahedron = FALSE;
} }
void LLVolume::cacheOptimize() void LLVolume::cacheOptimize()
@@ -2889,20 +2737,12 @@ void LLVolume::cacheOptimize()
} }
} }
#endif //MESH_ENABLED #endif //MESH_ENABLED
S32 LLVolume::getNumFaces() const S32 LLVolume::getNumFaces() const
{ {
#if MESH_ENABLED
U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK);
if (sculpt_type == LL_SCULPT_TYPE_MESH)
{
return LL_SCULPT_MESH_MAX_FACES;
}
#endif //MESH_ENABLED
return (S32)mProfilep->mFaces.size(); return (S32)mProfilep->mFaces.size();
} }
void LLVolume::createVolumeFaces() void LLVolume::createVolumeFaces()
{ {
LLMemType m1(LLMemType::MTYPE_VOLUME); LLMemType m1(LLMemType::MTYPE_VOLUME);
@@ -7301,7 +7141,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
resizeVertices(num_vertices); resizeVertices(num_vertices);
resizeIndices(num_indices); resizeIndices(num_indices);
#if MESH_ENABLED #if MESH_ENABLED
if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) if (!volume->isMeshAssetLoaded())
#endif //MESH_ENABLED #endif //MESH_ENABLED
{ {
mEdge.resize(num_indices); mEdge.resize(num_indices);

View File

@@ -1085,15 +1085,15 @@ protected:
public: public:
virtual bool unpackVolumeFaces(std::istream& is, S32 size); virtual bool unpackVolumeFaces(std::istream& is, S32 size);
virtual void makeTetrahedron(); virtual void setMeshAssetLoaded(BOOL loaded);
virtual BOOL isTetrahedron(); virtual BOOL isMeshAssetLoaded();
#endif //MESH_ENABLED #endif //MESH_ENABLED
protected: protected:
BOOL mUnique; BOOL mUnique;
F32 mDetail; F32 mDetail;
S32 mSculptLevel; S32 mSculptLevel;
#if MESH_ENABLED #if MESH_ENABLED
BOOL mIsTetrahedron; BOOL mIsMeshAssetLoaded;
#endif //MESH_ENABLED #endif //MESH_ENABLED
LLVolumeParams mParams; LLVolumeParams mParams;

View File

@@ -1364,29 +1364,38 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
return; return;
} }
LLVertexBuffer* buffer = face->getVertexBuffer(); LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
U32 data_mask = face->getRiggedVertexBufferDataMask(); U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!buffer || if (buffer.isNull() ||
buffer->getTypeMask() != data_mask || buffer->getTypeMask() != data_mask ||
buffer->getRequestedVerts() != vol_face.mNumVertices) buffer->getRequestedVerts() != vol_face.mNumVertices ||
buffer->getRequestedIndices() != vol_face.mNumIndices ||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{ {
face->setGeomIndex(0); face->setGeomIndex(0);
face->setIndicesIndex(0); face->setIndicesIndex(0);
face->setSize(vol_face.mNumVertices, vol_face.mNumIndices, true);
if (buffer.isNull() || buffer->getTypeMask() != data_mask)
if (sShaderLevel > 0) { //make a new buffer
{ if (sShaderLevel > 0)
buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); {
buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
}
else
{
buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
}
buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
} }
else else //resize existing buffer
{ {
buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
} }
buffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), true); face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
face->setVertexBuffer(buffer); face->setVertexBuffer(buffer);
@@ -1488,6 +1497,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
} }
} }
} }
if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
{
drawable->clearState(LLDrawable::REBUILD_ALL);
}
} }
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
@@ -1518,7 +1532,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
LLVolume* volume = vobj->getVolume(); LLVolume* volume = vobj->getVolume();
S32 te = face->getTEOffset(); S32 te = face->getTEOffset();
if (!volume || volume->getNumVolumeFaces() <= te) if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
{ {
continue; continue;
} }

View File

@@ -1717,7 +1717,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
if (data.mModel[i].notNull()) if (data.mModel[i].notNull())
{ {
LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i)); LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
volume->copyVolumeFaces(data.mModel[i]); volume->setMeshAssetLoaded(TRUE);
} }
} }
@@ -2184,11 +2184,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
if (volume) if (volume)
{ {
if (volume->getNumVolumeFaces() == 0 && !volume->isTetrahedron())
{
volume->makeTetrahedron();
}
LLVolumeParams params = volume->getParams(); LLVolumeParams params = volume->getParams();
LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params); LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params);
@@ -2199,7 +2194,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
if (last_lod >= 0) if (last_lod >= 0)
{ {
LLVolume* lod = group->refLOD(last_lod); LLVolume* lod = group->refLOD(last_lod);
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) if (lod && !lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{ {
group->derefLOD(lod); group->derefLOD(lod);
return last_lod; return last_lod;
@@ -2211,7 +2206,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
for (S32 i = detail-1; i >= 0; --i) for (S32 i = detail-1; i >= 0; --i)
{ {
LLVolume* lod = group->refLOD(i); LLVolume* lod = group->refLOD(i);
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) if (lod && !lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{ {
group->derefLOD(lod); group->derefLOD(lod);
return i; return i;
@@ -2224,7 +2219,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
for (S32 i = detail+1; i < 4; ++i) for (S32 i = detail+1; i < 4; ++i)
{ {
LLVolume* lod = group->refLOD(i); LLVolume* lod = group->refLOD(i);
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) if (lod && !lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{ {
group->derefLOD(lod); group->derefLOD(lod);
return i; return i;
@@ -2493,7 +2488,6 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (volume->getNumVolumeFaces() <= 0) if (volume->getNumVolumeFaces() <= 0)
{ {
llwarns << "Mesh loading returned empty volume." << llendl; llwarns << "Mesh loading returned empty volume." << llendl;
volume->makeTetrahedron();
} }
{ //update system volume { //update system volume
@@ -2501,6 +2495,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (sys_volume) if (sys_volume)
{ {
sys_volume->copyVolumeFaces(volume); sys_volume->copyVolumeFaces(volume);
sys_volume->setMeshAssetLoaded(TRUE);
LLPrimitive::getVolumeManager()->unrefVolume(sys_volume); LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
} }
else else

View File

@@ -763,9 +763,6 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
{ //meshes might not have all LODs, get the force detail to best existing LOD { //meshes might not have all LODs, get the force detail to best existing LOD
LLUUID mesh_id = volume_params.getSculptID(); LLUUID mesh_id = volume_params.getSculptID();
//profile and path params don't matter for meshes
volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
lod = gMeshRepo.getActualMeshLOD(volume_params, lod); lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
if (lod == -1) if (lod == -1)
{ {
@@ -828,7 +825,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
// if it's a mesh // if it's a mesh
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
{ {
if (getVolume()->getNumVolumeFaces() == 0 || getVolume()->isTetrahedron()) if (!getVolume()->isMeshAssetLoaded())
{ {
//load request not yet issued, request pipeline load this mesh //load request not yet issued, request pipeline load this mesh
LLUUID asset_id = volume_params.getSculptID(); LLUUID asset_id = volume_params.getSculptID();
@@ -2268,7 +2265,7 @@ U32 LLVOVolume::getHighLODTriangleCount()
else if (isMesh()) else if (isMesh())
{ {
LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
if (ref->isTetrahedron() || ref->getNumVolumeFaces() == 0) if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0)
{ {
gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH); gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH);
} }
@@ -3141,7 +3138,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLVOVolume* vobj = drawablep->getVOVolume(); LLVOVolume* vobj = drawablep->getVOVolume();
#if MESH_ENABLED #if MESH_ENABLED
if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled())) if (vobj->isMesh() &&
(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
{ {
continue; continue;
} }