SH-2188 Fix for generally bad vertex buffer updates for rigged attachments and fix for viewer always thinking meshes initially have 8 texture entries.
parent
5c0df02df5
commit
f7d17cad5c
|
|
@ -2078,7 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge
|
|||
mFaceMask = 0x0;
|
||||
mDetail = detail;
|
||||
mSculptLevel = -2;
|
||||
mIsTetrahedron = FALSE;
|
||||
mIsMeshAssetLoaded = FALSE;
|
||||
mLODScaleBias.setVec(1,1,1);
|
||||
mHullPoints = NULL;
|
||||
mHullIndices = NULL;
|
||||
|
|
@ -2100,7 +2100,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, 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();
|
||||
}
|
||||
|
|
@ -2706,173 +2706,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()
|
||||
|
|
@ -2886,13 +2734,6 @@ void LLVolume::cacheOptimize()
|
|||
|
||||
S32 LLVolume::getNumFaces() const
|
||||
{
|
||||
U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK);
|
||||
|
||||
if (sculpt_type == LL_SCULPT_TYPE_MESH)
|
||||
{
|
||||
return LL_SCULPT_MESH_MAX_FACES;
|
||||
}
|
||||
|
||||
return (S32)mProfilep->mFaces.size();
|
||||
}
|
||||
|
||||
|
|
@ -7269,7 +7110,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
|
|||
resizeVertices(num_vertices);
|
||||
resizeIndices(num_indices);
|
||||
|
||||
if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
|
||||
if (!volume->isMeshAssetLoaded())
|
||||
{
|
||||
mEdge.resize(num_indices);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1058,14 +1058,14 @@ protected:
|
|||
public:
|
||||
virtual bool unpackVolumeFaces(std::istream& is, S32 size);
|
||||
|
||||
virtual void makeTetrahedron();
|
||||
virtual BOOL isTetrahedron();
|
||||
virtual void setMeshAssetLoaded(BOOL loaded);
|
||||
virtual BOOL isMeshAssetLoaded();
|
||||
|
||||
protected:
|
||||
BOOL mUnique;
|
||||
F32 mDetail;
|
||||
S32 mSculptLevel;
|
||||
BOOL mIsTetrahedron;
|
||||
BOOL mIsMeshAssetLoaded;
|
||||
|
||||
LLVolumeParams mParams;
|
||||
LLPath *mPathp;
|
||||
|
|
|
|||
|
|
@ -1283,30 +1283,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
|
||||
{
|
||||
buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
|
||||
{ //resize existing buffer
|
||||
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);
|
||||
|
||||
U16 offset = 0;
|
||||
|
|
@ -1407,6 +1415,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)
|
||||
|
|
@ -1437,7 +1450,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1701,6 +1701,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
|
|||
{
|
||||
LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
|
||||
volume->copyVolumeFaces(data.mModel[i]);
|
||||
volume->setMeshAssetLoaded(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2154,11 +2155,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);
|
||||
|
|
@ -2169,7 +2165,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;
|
||||
|
|
@ -2181,7 +2177,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;
|
||||
|
|
@ -2194,7 +2190,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;
|
||||
|
|
@ -2445,7 +2441,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
|
||||
|
|
@ -2453,6 +2448,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
|
||||
|
|
|
|||
|
|
@ -367,6 +367,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
//
|
||||
// Unpack texture entry data
|
||||
//
|
||||
|
||||
S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
|
||||
if (result & teDirtyBits)
|
||||
{
|
||||
|
|
@ -972,12 +973,8 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo
|
|||
// if it's a mesh
|
||||
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
|
||||
{ //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)
|
||||
{
|
||||
|
|
@ -1033,14 +1030,13 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo
|
|||
|
||||
updateSculptTexture();
|
||||
|
||||
|
||||
if (isSculpted())
|
||||
{
|
||||
updateSculptTexture();
|
||||
// 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();
|
||||
|
|
@ -3150,7 +3146,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);
|
||||
}
|
||||
|
|
@ -3992,7 +3988,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
|
||||
if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled()))
|
||||
if (vobj->isMesh() &&
|
||||
(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue