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;
mSculptLevel = -2;
#if MESH_ENABLED
mIsTetrahedron = FALSE;
mIsMeshAssetLoaded = FALSE;
mLODScaleBias.setVec(1,1,1);
mHullPoints = NULL;
mHullIndices = NULL;
@@ -2103,7 +2103,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
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();
}
@@ -2712,173 +2712,21 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
return true;
}
void tetrahedron_set_normal(LLVolumeFace::VertexData* cv)
BOOL LLVolume::isMeshAssetLoaded()
{
LLVector4a v0;
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());
return mIsMeshAssetLoaded;
}
BOOL LLVolume::isTetrahedron()
void LLVolume::setMeshAssetLoaded(BOOL loaded)
{
return mIsTetrahedron;
}
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;
mIsMeshAssetLoaded = loaded;
}
void LLVolume::copyVolumeFaces(const LLVolume* volume)
{
mVolumeFaces = volume->mVolumeFaces;
mSculptLevel = 0;
mIsTetrahedron = FALSE;
}
void LLVolume::cacheOptimize()
@@ -2889,20 +2737,12 @@ void LLVolume::cacheOptimize()
}
}
#endif //MESH_ENABLED
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();
}
void LLVolume::createVolumeFaces()
{
LLMemType m1(LLMemType::MTYPE_VOLUME);
@@ -7301,7 +7141,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
resizeVertices(num_vertices);
resizeIndices(num_indices);
#if MESH_ENABLED
if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
if (!volume->isMeshAssetLoaded())
#endif //MESH_ENABLED
{
mEdge.resize(num_indices);

View File

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

View File

@@ -1364,29 +1364,38 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
return;
}
LLVertexBuffer* buffer = face->getVertexBuffer();
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!buffer ||
if (buffer.isNull() ||
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->setIndicesIndex(0);
face->setSize(vol_face.mNumVertices, vol_face.mNumIndices, true);
if (sShaderLevel > 0)
{
buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
if (buffer.isNull() || buffer->getTypeMask() != data_mask)
{ //make a new buffer
if (sShaderLevel > 0)
{
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);
@@ -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)
@@ -1518,7 +1532,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
LLVolume* volume = vobj->getVolume();
S32 te = face->getTEOffset();
if (!volume || volume->getNumVolumeFaces() <= te)
if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
{
continue;
}

View File

@@ -1717,7 +1717,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
if (data.mModel[i].notNull())
{
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->getNumVolumeFaces() == 0 && !volume->isTetrahedron())
{
volume->makeTetrahedron();
}
LLVolumeParams params = volume->getParams();
LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params);
@@ -2199,7 +2194,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
if (last_lod >= 0)
{
LLVolume* lod = group->refLOD(last_lod);
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
if (lod && !lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{
group->derefLOD(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)
{
LLVolume* lod = group->refLOD(i);
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
if (lod && !lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{
group->derefLOD(lod);
return i;
@@ -2224,7 +2219,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
for (S32 i = detail+1; i < 4; ++i)
{
LLVolume* lod = group->refLOD(i);
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
if (lod && !lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
{
group->derefLOD(lod);
return i;
@@ -2493,7 +2488,6 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (volume->getNumVolumeFaces() <= 0)
{
llwarns << "Mesh loading returned empty volume." << llendl;
volume->makeTetrahedron();
}
{ //update system volume
@@ -2501,6 +2495,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (sys_volume)
{
sys_volume->copyVolumeFaces(volume);
sys_volume->setMeshAssetLoaded(TRUE);
LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
}
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
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);
if (lod == -1)
{
@@ -828,7 +825,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
// if it's a 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
LLUUID asset_id = volume_params.getSculptID();
@@ -2268,7 +2265,7 @@ U32 LLVOVolume::getHighLODTriangleCount()
else if (isMesh())
{
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);
}
@@ -3141,7 +3138,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLVOVolume* vobj = drawablep->getVOVolume();
#if MESH_ENABLED
if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled()))
if (vobj->isMesh() &&
(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
{
continue;
}