diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d7a0d77a3..f3e5cd34b 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2080,7 +2080,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, 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 ¶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(); } @@ -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); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c85e43e1f..43fa23e0d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -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; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 8693ed11b..594b09456 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1364,29 +1364,38 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* return; } - LLVertexBuffer* buffer = face->getVertexBuffer(); + LLPointer 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; } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1185fea01..c55ccce10 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1717,7 +1717,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header) if (data.mModel[i].notNull()) { LLPointer 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 diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ea5af4c0e..7df4fc0f8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -763,9 +763,6 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_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 ¶ms_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; }