diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index 369b06b48..44ea80a36 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -51,7 +51,7 @@ public: void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} void skip(const U32 index) { mBytep += mSkip*index;} - + U32 getSkip() const { return mSkip; } Object* get() { return mObjectp; } Object* operator->() { return mObjectp; } Object& operator *() { return *mObjectp; } diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index c2591ac8d..8f2006b43 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -59,13 +59,9 @@ BOOL LLViewerJoint::sDisableLOD = FALSE; // Class Constructor //----------------------------------------------------------------------------- LLViewerJoint::LLViewerJoint() + : LLJoint() { - mUpdateXform = TRUE; - mValid = FALSE; - mComponents = SC_JOINT | SC_BONE | SC_AXES; - mMinPixelArea = DEFAULT_LOD; - mPickName = PN_DEFAULT; - mVisible = TRUE; + init(); } @@ -73,13 +69,21 @@ LLViewerJoint::LLViewerJoint() // LLViewerJoint() // Class Constructor //----------------------------------------------------------------------------- -LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) : - LLJoint(name, parent) +LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) + : LLJoint(name, parent) +{ + init(); +} + + +void LLViewerJoint::init() { mValid = FALSE; mComponents = SC_JOINT | SC_BONE | SC_AXES; mMinPixelArea = DEFAULT_LOD; mPickName = PN_DEFAULT; + mVisible = TRUE; + mMeshID = 0; } @@ -436,13 +440,13 @@ void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix } } -void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) +void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) { for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); ++iter) { LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->updateFaceData(face, pixel_area, damp_wind); + joint->updateFaceData(face, pixel_area, damp_wind, terse_update); } } diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index 0e993a2eb..ccfa99dd3 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -127,7 +127,7 @@ public: PickName getPickName() { return mPickName; } virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); - virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE); + virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false); virtual BOOL updateLOD(F32 pixel_area, BOOL activate); virtual void updateJointGeometry(); virtual void dump(); @@ -143,6 +143,8 @@ public: void setMeshID( S32 id ) {mMeshID = id;} protected: + void init(); + BOOL mValid; U32 mComponents; F32 mMinPixelArea; diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 747016376..5e5a98d0b 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -148,6 +148,7 @@ LLViewerJointMesh::LLViewerJointMesh() mTexture( NULL ), mLayerSet( NULL ), mTestImageName( 0 ), + mFaceIndexCount(0), mIsTransparent(FALSE) { @@ -573,7 +574,10 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else if ( !is_dummy && mTexture.notNull() ) { - old_mode = mTexture->getAddressMode(); + if(mTexture->getHasGLTexture()) + { + old_mode = mTexture->getAddressMode(); + } gGL.getTexUnit(0)->bind(mTexture.get()); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } @@ -663,7 +667,8 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 //----------------------------------------------------------------------------- // updateFaceData() //----------------------------------------------------------------------------- -void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) + +void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) { mFace = face; @@ -690,29 +695,98 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w face->mVertexBuffer->getIndexStrider(indicesp); stop_glerror(); - for (U16 i = 0; i < mMesh->getNumVertices(); i++) + verticesp += mMesh->mFaceVertexOffset; + tex_coordsp += mMesh->mFaceVertexOffset; + normalsp += mMesh->mFaceVertexOffset; + vertex_weightsp += mMesh->mFaceVertexOffset; + clothing_weightsp += mMesh->mFaceVertexOffset; + + const U32* __restrict coords = (U32*) mMesh->getCoords(); + const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords(); + const U32* __restrict normals = (U32*) mMesh->getNormals(); + const U32* __restrict weights = (U32*) mMesh->getWeights(); + const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights(); + + const U32 num_verts = mMesh->getNumVertices(); + + U32 i = 0; + + const U32 skip = verticesp.getSkip()/sizeof(U32); + + U32* __restrict v = (U32*) verticesp.get(); + U32* __restrict n = (U32*) normalsp.get(); + + if (terse_update) { - verticesp[mMesh->mFaceVertexOffset + i] = *(mMesh->getCoords() + i); - tex_coordsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getTexCoords() + i); - normalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getNormals() + i); - vertex_weightsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getWeights() + i); - if (damp_wind) + for (S32 i = num_verts; i > 0; --i) { - clothing_weightsp[mMesh->mFaceVertexOffset + i] = LLVector4(0,0,0,0); + //morph target application only, only update positions and normals + v[0] = coords[0]; + v[1] = coords[1]; + v[2] = coords[2]; + coords += 3; + v += skip; } - else + + for (S32 i = num_verts; i > 0; --i) { - clothing_weightsp[mMesh->mFaceVertexOffset + i] = (*(mMesh->getClothingWeights() + i)); + n[0] = normals[0]; + n[1] = normals[1]; + n[2] = normals[2]; + normals += 3; + n += skip; } } - - for (S32 i = 0; i < mMesh->getNumFaces(); i++) - { - for (U32 j = 0; j < 3; j++) + else { - U32 k = i*3+j+mMesh->mFaceIndexOffset; - indicesp[k] = mMesh->getFaces()[i][j] + mMesh->mFaceVertexOffset; + + U32* __restrict tc = (U32*) tex_coordsp.get(); + U32* __restrict vw = (U32*) vertex_weightsp.get(); + U32* __restrict cw = (U32*) clothing_weightsp.get(); + + do + { + v[0] = *(coords++); + v[1] = *(coords++); + v[2] = *(coords++); + v += skip; + + tc[0] = *(tex_coords++); + tc[1] = *(tex_coords++); + tc += skip; + + n[0] = *(normals++); + n[1] = *(normals++); + n[2] = *(normals++); + n += skip; + + vw[0] = *(weights++); + vw += skip; + + cw[0] = *(cloth_weights++); + cw[1] = *(cloth_weights++); + cw[2] = *(cloth_weights++); + cw[3] = *(cloth_weights++); + cw += skip; } + while (++i < num_verts); + + const U32 idx_count = mMesh->getNumFaces()*3; + + indicesp += mMesh->mFaceIndexOffset; + + U16* __restrict idx = indicesp.get(); + S32* __restrict src_idx = (S32*) mMesh->getFaces(); + + i = 0; + + const S32 offset = (S32) mMesh->mFaceVertexOffset; + + do + { + *(idx++) = *(src_idx++)+offset; + } + while (++i < idx_count); } } } diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index ee019f659..721c3f1dd 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -141,7 +141,7 @@ public: /*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy ); /*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); - /*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE); + /*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false); /*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate); /*virtual*/ void updateJointGeometry(); /*virtual*/ void dump(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f2648bb59..fcbc65a11 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2484,6 +2484,8 @@ void LLVOAvatar::updateMeshData() // resize immediately facep->setSize(num_vertices, num_indices); + bool terse_update = false; + if(facep->mVertexBuffer.isNull()) { facep->mVertexBuffer = new LLVertexBufferAvatar(); @@ -2491,7 +2493,15 @@ void LLVOAvatar::updateMeshData() } else { - facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; + if (facep->mVertexBuffer->getRequestedIndices() == num_indices && + facep->mVertexBuffer->getRequestedVerts() == num_vertices) + { + terse_update = true; + } + else + { + facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; + } } facep->setGeomIndex(0); @@ -2506,7 +2516,7 @@ void LLVOAvatar::updateMeshData() for(S32 k = j ; k < part_index ; k++) { - mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR); + mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update); } stop_glerror();