Cleaned up polymesh (mesh vectors/normals size match VBO vectors/normals size to allow memcpy). Prep for vbo testing.

This commit is contained in:
Shyotl
2011-08-04 01:38:56 -05:00
parent 4f8186b17e
commit 2c489d7741
10 changed files with 235 additions and 277 deletions

View File

@@ -769,29 +769,23 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_
}
else
{
#if 1 // Allocate memory without initializing every vector
// Allocate memory without initializing every vector
// NOTE: This makes asusmptions about the size of LLVector[234]
int nverts = mSharedData->mNumVertices;
int nfloats = nverts * (3*5 + 2 + 4);
mVertexData = new F32[nfloats];
int nfloats = nverts * (2*4 + 3*3 + 2 + 4);
//use 16 byte aligned vertex data to make LLPolyMesh SSE friendly
mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4);
int offset = 0;
mCoords = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
mNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
// these members don't need to be 16-byte aligned, but the first one might be
// read during an aligned memcpy of mTexCoords
mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
#else
mCoords = new LLVector3[mSharedData->mNumVertices];
mNormals = new LLVector3[mSharedData->mNumVertices];
mScaledNormals = new LLVector3[mSharedData->mNumVertices];
mBinormals = new LLVector3[mSharedData->mNumVertices];
mScaledBinormals = new LLVector3[mSharedData->mNumVertices];
mTexCoords = new LLVector2[mSharedData->mNumVertices];
mClothingWeights = new LLVector4[mSharedData->mNumVertices];
memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
#endif
initializeForMorph();
}
}
@@ -806,19 +800,11 @@ LLPolyMesh::~LLPolyMesh()
for (i = 0; i < mJointRenderData.count(); i++)
{
delete mJointRenderData[i];
mJointRenderData[i] = NULL;
}
#if 0 // These are now allocated as one big uninitialized chunk
delete [] mCoords;
delete [] mNormals;
delete [] mScaledNormals;
delete [] mBinormals;
delete [] mScaledBinormals;
delete [] mClothingWeights;
delete [] mTexCoords;
#else
delete [] mVertexData;
#endif
mJointRenderData[i] = NULL;
}
ll_aligned_free_16(mVertexData);
}
@@ -1242,7 +1228,7 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp)
int nfaces = mSharedData->mNumFaces;
int i;
LLVector3* coords = getWritableCoords();
LLVector4* coords = getWritableCoords();
for ( i=0; i<nverts; i++) {
std::string outstring = llformat("v %f %f %f\n",
coords[i][0],
@@ -1254,7 +1240,7 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp)
}
}
LLVector3* normals = getWritableNormals();
LLVector4* normals = getWritableNormals();
for ( i=0; i<nverts; i++) {
std::string outstring = llformat("vn %f %f %f\n",
normals[i][0],
@@ -1311,8 +1297,8 @@ BOOL LLPolyMesh::loadOBJ(LLFILE *fp)
int nnormals = 0;
int ntexcoords = 0;
LLVector3* coords = getWritableCoords();
LLVector3* normals = getWritableNormals();
LLVector4* coords = getWritableCoords();
LLVector4* normals = getWritableNormals();
LLVector3* binormals = getWritableBinormals();
LLVector2* tex = getWritableTexCoords();
LLPolyFace* faces = getFaces();
@@ -1467,8 +1453,8 @@ BOOL LLPolyMesh::setSharedFromCurrent()
LLPolyMesh delta(mSharedData, NULL);
U32 nverts = delta.getNumVertices();
LLVector3 *delta_coords = delta.getWritableCoords();
LLVector3 *delta_normals = delta.getWritableNormals();
LLVector4 *delta_coords = delta.getWritableCoords();
LLVector4 *delta_normals = delta.getWritableNormals();
LLVector3 *delta_binormals = delta.getWritableBinormals();
LLVector2 *delta_tex_coords = delta.getWritableTexCoords();
@@ -1497,8 +1483,8 @@ BOOL LLPolyMesh::setSharedFromCurrent()
LLPolyMesh* mesh = avatarp->getMesh(mSharedData);
if (mesh)
{
LLVector3 *mesh_coords = mesh->getWritableCoords();
LLVector3 *mesh_normals = mesh->getWritableNormals();
LLVector4 *mesh_coords = mesh->getWritableCoords();
LLVector4 *mesh_normals = mesh->getWritableNormals();
LLVector3 *mesh_binormals = mesh->getWritableBinormals();
LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords();
LLVector3 *mesh_scaled_normals = mesh->getScaledNormals();
@@ -1509,10 +1495,10 @@ BOOL LLPolyMesh::setSharedFromCurrent()
mesh_coords[vert_index] -= delta_coords[vert_index];
mesh_tex_coords[vert_index] -= delta_tex_coords[vert_index];
mesh_scaled_normals[vert_index] -= delta_normals[vert_index];
mesh_scaled_normals[vert_index] -= LLVector3(delta_normals[vert_index]);
LLVector3 normalized_normal = mesh_scaled_normals[vert_index];
normalized_normal.normVec();
mesh_normals[vert_index] = normalized_normal;
mesh_normals[vert_index] = LLVector4(normalized_normal);
mesh_scaled_binormals[vert_index] -= delta_binormals[vert_index];
LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal;
@@ -1616,7 +1602,7 @@ void LLPolyMesh::dumpDiagInfo(void*)
//-----------------------------------------------------------------------------
// getWritableCoords()
//-----------------------------------------------------------------------------
LLVector3 *LLPolyMesh::getWritableCoords()
LLVector4 *LLPolyMesh::getWritableCoords()
{
return mCoords;
}
@@ -1624,7 +1610,7 @@ LLVector3 *LLPolyMesh::getWritableCoords()
//-----------------------------------------------------------------------------
// getWritableNormals()
//-----------------------------------------------------------------------------
LLVector3 *LLPolyMesh::getWritableNormals()
LLVector4 *LLPolyMesh::getWritableNormals()
{
return mNormals;
}
@@ -1679,8 +1665,12 @@ void LLPolyMesh::initializeForMorph()
if (!mSharedData)
return;
memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
for (U32 i = 0; i < (U32)mSharedData->mNumVertices; ++i)
{
mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]);
mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]);
}
memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/

View File

@@ -240,15 +240,15 @@ public:
}
// Get coords
const LLVector3 *getCoords() const{
const LLVector4 *getCoords() const{
return mCoords;
}
// non const version
LLVector3 *getWritableCoords();
LLVector4 *getWritableCoords();
// Get normals
const LLVector3 *getNormals() const{
const LLVector4 *getNormals() const{
return mNormals;
}
@@ -270,7 +270,7 @@ public:
}
// intermediate morphed normals and output normals
LLVector3 *getWritableNormals();
LLVector4 *getWritableNormals();
LLVector3 *getScaledNormals();
LLVector3 *getWritableBinormals();
@@ -368,11 +368,11 @@ protected:
// Single array of floats for allocation / deletion
F32 *mVertexData;
// deformed vertices (resulting from application of morph targets)
LLVector3 *mCoords;
LLVector4 *mCoords;
// deformed normals (resulting from application of morph targets)
LLVector3 *mScaledNormals;
// output normals (after normalization)
LLVector3 *mNormals;
LLVector4 *mNormals;
// deformed binormals (resulting from application of morph targets)
LLVector3 *mScaledBinormals;
// output binormals (after normalization)

View File

@@ -282,16 +282,16 @@ BOOL LLPolyMorphData::saveOBJ(LLFILE *fp)
LLPolyMesh mesh(mMesh, NULL);
LLVector3 *coords = mesh.getWritableCoords();
LLVector3 *normals = mesh.getWritableNormals();
LLVector4 *coords = mesh.getWritableCoords();
LLVector4 *normals = mesh.getWritableNormals();
LLVector2 *tex_coords = mesh.getWritableTexCoords();
for(U32 vert_index_morph = 0; vert_index_morph < mNumIndices; vert_index_morph++)
{
S32 vert_index_mesh = mVertexIndices[vert_index_morph];
coords[vert_index_mesh] += mCoords[vert_index_morph];
normals[vert_index_mesh] += mNormals[vert_index_morph];
coords[vert_index_mesh] += LLVector4(mCoords[vert_index_morph]);
normals[vert_index_mesh] += LLVector4(mNormals[vert_index_morph]);
normals[vert_index_mesh].normVec();
tex_coords[vert_index_mesh] += mTexCoords[vert_index_morph];
}
@@ -307,8 +307,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
if (!morph)
return FALSE;
LLVector3 *morph_coords = morph->getWritableCoords();
LLVector3 *morph_normals = morph->getWritableNormals();
LLVector4 *morph_coords = morph->getWritableCoords();
LLVector4 *morph_normals = morph->getWritableNormals();
LLVector3 *morph_binormals = morph->getWritableBinormals();
LLVector2 *morph_tex_coords = morph->getWritableTexCoords();
@@ -318,8 +318,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
LLPolyMesh delta(mMesh, NULL);
U32 nverts = delta.getNumVertices();
LLVector3 *delta_coords = delta.getWritableCoords();
LLVector3 *delta_normals = delta.getWritableNormals();
LLVector4 *delta_coords = delta.getWritableCoords();
LLVector4 *delta_normals = delta.getWritableNormals();
LLVector3 *delta_binormals = delta.getWritableBinormals();
LLVector2 *delta_tex_coords = delta.getWritableTexCoords();
@@ -380,8 +380,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
{
new_vertex_indices[morph_index] = vert_index;
new_coords[morph_index] = delta_coords[vert_index];
new_normals[morph_index] = delta_normals[vert_index];
new_coords[morph_index] = LLVector3(delta_coords[vert_index]);
new_normals[morph_index] = LLVector3(delta_normals[vert_index]);
new_binormals[morph_index] = delta_binormals[vert_index];
new_tex_coords[morph_index] = delta_tex_coords[vert_index];
@@ -417,8 +417,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
{
vert_index = mVertexIndices[morph_index];
delta_coords[vert_index] -= mCoords[morph_index];
delta_normals[vert_index] -= mNormals[morph_index];
delta_coords[vert_index] -= LLVector4(mCoords[morph_index]);
delta_normals[vert_index] -= LLVector4(mNormals[morph_index]);
delta_binormals[vert_index] -= mBinormals[morph_index];
delta_tex_coords[vert_index] -= mTexCoords[morph_index];
}
@@ -456,8 +456,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
continue;
}
LLVector3 *mesh_coords = mesh->getWritableCoords();
LLVector3 *mesh_normals = mesh->getWritableNormals();
LLVector4 *mesh_coords = mesh->getWritableCoords();
LLVector4 *mesh_normals = mesh->getWritableNormals();
LLVector3 *mesh_binormals = mesh->getWritableBinormals();
LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords();
LLVector3 *mesh_scaled_normals = mesh->getScaledNormals();
@@ -468,10 +468,10 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
mesh_coords[vert_index] += delta_coords[vert_index] * weight;
mesh_tex_coords[vert_index] += delta_tex_coords[vert_index] * weight;
mesh_scaled_normals[vert_index] += delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR;
mesh_scaled_normals[vert_index] += LLVector3(delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR);
LLVector3 normalized_normal = mesh_scaled_normals[vert_index];
normalized_normal.normVec();
mesh_normals[vert_index] = normalized_normal;
mesh_normals[vert_index] = LLVector4(normalized_normal);
mesh_scaled_binormals[vert_index] += delta_binormals[vert_index] * weight * NORMAL_SOFTEN_FACTOR;
LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal;
@@ -797,10 +797,10 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
if (delta_weight != 0.f)
{
llassert(!mMesh->isLOD());
LLVector3 *coords = mMesh->getWritableCoords();
LLVector4 *coords = mMesh->getWritableCoords();
LLVector3 *scaled_normals = mMesh->getScaledNormals();
LLVector3 *normals = mMesh->getWritableNormals();
LLVector4 *normals = mMesh->getWritableNormals();
LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
LLVector3 *binormals = mMesh->getWritableBinormals();
@@ -820,7 +820,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
maskWeight = maskWeightArray[vert_index_morph];
}
coords[vert_index_mesh] += mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight;
coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight);
if (getInfo()->mIsClothingMorph && clothing_weights)
{
LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight;
@@ -835,7 +836,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
LLVector3 normalized_normal = scaled_normals[vert_index_mesh];
normalized_normal.normVec();
normals[vert_index_mesh] = normalized_normal;
normals[vert_index_mesh] = LLVector4(normalized_normal);
// calculate new binormals
scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
@@ -906,31 +907,31 @@ BOOL LLPolyMorphTarget::undoMask(BOOL delete_mask)
F32 *mask_weights = mVertMask->getMorphMaskWeights();
LLVector3 *coords = mMesh->getWritableCoords();
LLVector4 *coords = mMesh->getWritableCoords();
LLVector3 *scaled_normals = mMesh->getScaledNormals();
LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
LLVector2 *tex_coords = mMesh->getWritableTexCoords();
for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++)
{
F32 mask_weight = 1.f;
if (mask_weights)
{
mask_weight = mask_weights[vert];
}
F32 mask_weight = 1.f;
if (mask_weights)
{
mask_weight = mask_weights[vert];
}
F32 last_mask_weight = mLastWeight * mask_weight;
F32 lastMaskWeight = mLastWeight * mask_weights[vert];
S32 out_vert = mMorphData->mVertexIndices[vert];
// remove effect of existing masked morph
coords[out_vert] -= mMorphData->mCoords[vert] * last_mask_weight;
scaled_normals[out_vert] -= mMorphData->mNormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR;
scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR;
tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * last_mask_weight;
coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight;
scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight;
if (clothing_weights)
{
LLVector3 clothing_offset = mMorphData->mCoords[vert] * last_mask_weight;
LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight;
LLVector4* clothing_weight = &clothing_weights[out_vert];
clothing_weight->mV[VX] -= clothing_offset.mV[VX];
clothing_weight->mV[VY] -= clothing_offset.mV[VY];

View File

@@ -61,6 +61,7 @@
#include "v4math.h"
#include "m3math.h"
#include "m4math.h"
#include "llmatrix4a.h"
#if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS
extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
@@ -382,6 +383,7 @@ const S32 NUM_AXES = 3;
// pivot parent 0-n -- child = n+1
static LLMatrix4 gJointMatUnaligned[32];
static LLMatrix4a gJointMatAligned[32];
static LLMatrix3 gJointRotUnaligned[32];
static LLVector4 gJointPivot[32];
@@ -467,6 +469,14 @@ void LLViewerJointMesh::uploadJointMatrices()
glUniform4fvARB(gAvatarMatrixParam, 45, mat);
stop_glerror();
}
else
{
//load gJointMatUnaligned into gJointMatAligned
for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); ++joint_num)
{
gJointMatAligned[joint_num].loadu(gJointMatUnaligned[joint_num]);
}
}
}
//--------------------------------------------------------------------
@@ -516,6 +526,8 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
U32 triangle_count = 0;
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;
stop_glerror();
//----------------------------------------------------------------
@@ -531,7 +543,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
stop_glerror();
LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), gRenderForSelect ? 0.0f : mShiny && !(mFace->getPool()->getVertexShaderLevel() > 0));
LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getVertexShaderLevel() > 0 && !gRenderForSelect) ? 0.f : mShiny);
//----------------------------------------------------------------
// setup current texture
@@ -541,7 +553,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP;
if (mTestImageName)
{
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
if (mIsTransparent)
{
@@ -550,14 +562,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
else
{
glColor4f(0.7f, 0.6f, 0.3f, 1.f);
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
}
}
else if( !is_dummy && mLayerSet )
{
if( mLayerSet->hasComposite() )
{
gGL.getTexUnit(0)->bind(mLayerSet->getComposite());
gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite());
}
else
{
@@ -567,7 +579,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
{
llwarns << "Layerset without composite" << llendl;
}
gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
}
}
else
@@ -577,24 +589,25 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
{
old_mode = mTexture->getAddressMode();
}
gGL.getTexUnit(0)->bind(mTexture);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
else
{
gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR));
gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR));
}
if (gRenderForSelect)
{
if (isTransparent())
{
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA);
gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
gGL.getTexUnit(diffuse_channel)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA);
}
else
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
}
}
@@ -631,13 +644,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
if (mTestImageName)
{
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT);
}
if (mTexture.notNull() && !is_dummy)
{
gGL.getTexUnit(0)->bind(mTexture.get());
gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode);
}
return triangle_count;
@@ -648,6 +661,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
//-----------------------------------------------------------------------------
void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
{
num_vertices = (num_vertices + 0x3) & ~0x3;
// Do a pre-alloc pass to determine sizes of data.
if (mMesh && mValid)
{
@@ -676,6 +690,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
return;
}
LLDrawPool *poolp = mFace->getPool();
BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE;
if (!hardware_skinning && terse_update)
{ //no need to do terse updates if we're doing software vertex skinning
// since mMesh is being copied into mVertexBuffer every frame
return;
}
LLStrider<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> tex_coordsp;
@@ -686,111 +710,64 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
// Copy data into the faces from the polymesh data.
if (mMesh && mValid)
{
if (mMesh->getNumVertices())
const U32 num_verts = mMesh->getNumVertices();
if (num_verts)
{
stop_glerror();
face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp);
stop_glerror();
face->getVertexBuffer()->getIndexStrider(indicesp);
stop_glerror();
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)
//F32* v = (F32*) verticesp.get();
//F32* n = (F32*) normalsp.get();
//U32 words = num_verts*4;
//LLVector4a::memcpyNonAliased16(v, (F32*) mMesh->getCoords(), words*sizeof(F32));
verticesp.assignArray((U8*)mMesh->getCoords(), sizeof(mMesh->getCoords()[0]), num_verts);
//LLVector4a::memcpyNonAliased16(n, (F32*) mMesh->getNormals(), words*sizeof(F32));
normalsp.assignArray((U8*)mMesh->getNormals(), sizeof(mMesh->getNormals()[0]), num_verts);
if (!terse_update)
{
for (S32 i = num_verts; i > 0; --i)
{
//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;
}
vertex_weightsp += mMesh->mFaceVertexOffset;
clothing_weightsp += mMesh->mFaceVertexOffset;
tex_coordsp += mMesh->mFaceVertexOffset;
//F32* tc = (F32*) tex_coordsp.get();
//F32* vw = (F32*) vertex_weightsp.get();
//F32* cw = (F32*) clothing_weightsp.get();
for (S32 i = num_verts; i > 0; --i)
{
n[0] = normals[0];
n[1] = normals[1];
n[2] = normals[2];
normals += 3;
n += skip;
}
//LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32));
tex_coordsp.assignArray((U8*)mMesh->getTexCoords(), sizeof(mMesh->getTexCoords()[0]), num_verts);
//LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32));
vertex_weightsp.assignArray((U8*)mMesh->getWeights(), sizeof(mMesh->getWeights()[0]), num_verts);
//LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32));
clothing_weightsp.assignArray((U8*)mMesh->getClothingWeights(), sizeof(mMesh->getClothingWeights()[0]), num_verts);
}
else
{
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;
const U32 idx_count = mMesh->getNumFaces()*3;
indicesp += mMesh->mFaceIndexOffset;
U16* __restrict idx = indicesp.get();
S32* __restrict src_idx = (S32*) mMesh->getFaces();
U16* __restrict idx = indicesp.get();
S32* __restrict src_idx = (S32*) mMesh->getFaces();
i = 0;
const S32 offset = (S32) mMesh->mFaceVertexOffset;
const S32 offset = (S32) mMesh->mFaceVertexOffset;
do
{
*(idx++) = *(src_idx++)+offset;
}
while (++i < idx_count);
for (S32 i = 0; i < (S32)idx_count; ++i)
{
*(idx++) = *(src_idx++)+offset;
}
}
}
}
//-----------------------------------------------------------------------------
// updateLOD()
//-----------------------------------------------------------------------------
@@ -812,85 +789,45 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh)
buffer->getVertexStrider(o_vertices, 0);
buffer->getNormalStrider(o_normals, 0);
F32 last_weight = F32_MAX;
LLMatrix4 gBlendMat;
LLMatrix3 gBlendRotMat;
F32* __restrict vert = o_vertices[0].mV;
F32* __restrict norm = o_normals[0].mV;
const F32* __restrict weights = mMesh->getWeights();
const LLVector4a* __restrict coords = (LLVector4a*) mMesh->getCoords();
const LLVector4a* __restrict normals = (LLVector4a*) mMesh->getNormals();
U32 offset = mMesh->mFaceVertexOffset*4;
vert += offset;
norm += offset;
const F32* weights = mMesh->getWeights();
const LLVector3* coords = mMesh->getCoords();
const LLVector3* normals = mMesh->getNormals();
for (U32 index = 0; index < mMesh->getNumVertices(); index++)
{
U32 bidx = index + mMesh->mFaceVertexOffset;
// blend by first matrix
F32 w = weights[index];
// Maybe we don't have to change gBlendMat.
// Profiles of a single-avatar scene on a Mac show this to be a very
// common case. JC
if (w == last_weight)
// equivalent to joint = floorf(weights[index]);
S32 joint = _mm_cvtt_ss2si(_mm_load_ss(weights+index));
F32 w = weights[index] - joint;
LLMatrix4a gBlendMat;
if (w != 0.f)
{
o_vertices[bidx] = coords[index] * gBlendMat;
o_normals[bidx] = normals[index] * gBlendRotMat;
continue;
// blend between matrices and apply
gBlendMat.setLerp(gJointMatAligned[joint+0],
gJointMatAligned[joint+1], w);
LLVector4a res;
gBlendMat.affineTransform(coords[index], res);
res.store4a(vert+index*4);
gBlendMat.rotate(normals[index], res);
res.store4a(norm+index*4);
}
last_weight = w;
S32 joint = llfloor(w);
w -= joint;
// No lerp required in this case.
if (w == 1.0f)
{
gBlendMat = gJointMatUnaligned[joint+1];
o_vertices[bidx] = coords[index] * gBlendMat;
gBlendRotMat = gJointRotUnaligned[joint+1];
o_normals[bidx] = normals[index] * gBlendRotMat;
continue;
else
{ // No lerp required in this case.
LLVector4a res;
gJointMatAligned[joint].affineTransform(coords[index], res);
res.store4a(vert+index*4);
gJointMatAligned[joint].rotate(normals[index], res);
res.store4a(norm+index*4);
}
// Try to keep all the accesses to the matrix data as close
// together as possible. This function is a hot spot on the
// Mac. JC
LLMatrix4 &m0 = gJointMatUnaligned[joint+1];
LLMatrix4 &m1 = gJointMatUnaligned[joint+0];
gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w);
gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w);
gBlendMat.mMatrix[VX][VZ] = lerp(m1.mMatrix[VX][VZ], m0.mMatrix[VX][VZ], w);
gBlendMat.mMatrix[VY][VX] = lerp(m1.mMatrix[VY][VX], m0.mMatrix[VY][VX], w);
gBlendMat.mMatrix[VY][VY] = lerp(m1.mMatrix[VY][VY], m0.mMatrix[VY][VY], w);
gBlendMat.mMatrix[VY][VZ] = lerp(m1.mMatrix[VY][VZ], m0.mMatrix[VY][VZ], w);
gBlendMat.mMatrix[VZ][VX] = lerp(m1.mMatrix[VZ][VX], m0.mMatrix[VZ][VX], w);
gBlendMat.mMatrix[VZ][VY] = lerp(m1.mMatrix[VZ][VY], m0.mMatrix[VZ][VY], w);
gBlendMat.mMatrix[VZ][VZ] = lerp(m1.mMatrix[VZ][VZ], m0.mMatrix[VZ][VZ], w);
gBlendMat.mMatrix[VW][VX] = lerp(m1.mMatrix[VW][VX], m0.mMatrix[VW][VX], w);
gBlendMat.mMatrix[VW][VY] = lerp(m1.mMatrix[VW][VY], m0.mMatrix[VW][VY], w);
gBlendMat.mMatrix[VW][VZ] = lerp(m1.mMatrix[VW][VZ], m0.mMatrix[VW][VZ], w);
o_vertices[bidx] = coords[index] * gBlendMat;
LLMatrix3 &n0 = gJointRotUnaligned[joint+1];
LLMatrix3 &n1 = gJointRotUnaligned[joint+0];
gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w);
gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w);
gBlendRotMat.mMatrix[VX][VZ] = lerp(n1.mMatrix[VX][VZ], n0.mMatrix[VX][VZ], w);
gBlendRotMat.mMatrix[VY][VX] = lerp(n1.mMatrix[VY][VX], n0.mMatrix[VY][VX], w);
gBlendRotMat.mMatrix[VY][VY] = lerp(n1.mMatrix[VY][VY], n0.mMatrix[VY][VY], w);
gBlendRotMat.mMatrix[VY][VZ] = lerp(n1.mMatrix[VY][VZ], n0.mMatrix[VY][VZ], w);
gBlendRotMat.mMatrix[VZ][VX] = lerp(n1.mMatrix[VZ][VX], n0.mMatrix[VZ][VX], w);
gBlendRotMat.mMatrix[VZ][VY] = lerp(n1.mMatrix[VZ][VY], n0.mMatrix[VZ][VY], w);
gBlendRotMat.mMatrix[VZ][VZ] = lerp(n1.mMatrix[VZ][VZ], n0.mMatrix[VZ][VZ], w);
o_normals[bidx] = normals[index] * gBlendRotMat;
}
buffer->setBuffer(0);

View File

@@ -94,8 +94,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
const F32* weights = mesh->getWeights();
const LLVector3* coords = mesh->getCoords();
const LLVector3* normals = mesh->getNormals();
const LLVector4* coords = mesh->getCoords();
const LLVector4* normals = mesh->getNormals();
for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
{
if( weight != weights[index])
@@ -103,8 +103,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
S32 joint = llfloor(weight = weights[index]);
blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
}
blend_mat.multiply(coords[index], o_vertices[index]);
((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]);
((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]);
}
buffer->setBuffer(0);

View File

@@ -101,8 +101,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
const F32* weights = mesh->getWeights();
const LLVector3* coords = mesh->getCoords();
const LLVector3* normals = mesh->getNormals();
const LLVector4* coords = mesh->getCoords();
const LLVector4* normals = mesh->getNormals();
for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
{
if( weight != weights[index])
@@ -110,8 +110,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
S32 joint = llfloor(weight = weights[index]);
blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
}
blend_mat.multiply(coords[index], o_vertices[index]);
((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]);
((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]);
}
buffer->setBuffer(0);

View File

@@ -84,8 +84,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh)
buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
const F32* weights = mesh->getWeights();
const LLVector3* coords = mesh->getCoords();
const LLVector3* normals = mesh->getNormals();
const LLVector4* coords = mesh->getCoords();
const LLVector4* normals = mesh->getNormals();
for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
{
if( weight != weights[index])
@@ -93,8 +93,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh)
S32 joint = llfloor(weight = weights[index]);
blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
}
blend_mat.multiply(coords[index], o_vertices[index]);
((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]);
((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]);
}
buffer->setBuffer(0);

View File

@@ -2207,6 +2207,33 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
return mDrawable->getWorldMatrix();
}
#if MESH_ENABLED
F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
{
F32 radius = getScale().length()*0.5f;
if (isMesh())
{
LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD);
}
else
{
LLVolume* volume = getVolume();
S32 counts[4];
LLVolume::getLoDTriangleCounts(volume->getParams(), counts);
LLSD header;
header["lowest_lod"]["size"] = counts[0] * 10;
header["low_lod"]["size"] = counts[1] * 10;
header["medium_lod"]["size"] = counts[2] * 10;
header["high_lod"]["size"] = counts[3] * 10;
return LLMeshRepository::getStreamingCost(header, radius);
}
}
#endif //MESH_ENABLED
U32 LLVOVolume::getTriangleCount()
{
@@ -3403,6 +3430,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
llassert(group);
static int warningsCount = 20;
if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
{
@@ -3414,15 +3442,16 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LLDrawable* drawablep = *drawable_iter;
if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
if (drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
{
continue;
}
if (drawablep->isState(LLDrawable::REBUILD_ALL))
if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
vobj->preRebuild();
LLVolume* volume = vobj->getVolume();
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
@@ -3489,6 +3518,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
}
llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
}
struct CompareBatchBreakerModified

View File

@@ -132,7 +132,9 @@ public:
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
/*virtual*/ const LLMatrix4 getRenderMatrix() const;
#if MESH_ENABLED
/*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);
#endif //MESH_ENABLED
/*virtual*/ U32 getTriangleCount();
/*virtual*/ U32 getHighLODTriangleCount();
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,

View File

@@ -7905,17 +7905,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.pushRenderTypeMask();
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
LLPipeline::RENDER_TYPE_WL_SKY,
LLPipeline::RENDER_TYPE_WL_CLOUDS,
LLPipeline::END_RENDER_TYPES);
static LLCullResult result;
updateCull(camera, result);
stateSort(camera, result);
andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS,
LLPipeline::RENDER_TYPE_WL_CLOUDS,
LLPipeline::RENDER_TYPE_WL_SKY,
LLPipeline::END_RENDER_TYPES);
renderGeom(camera, TRUE);
gPipeline.popRenderTypeMask();
}
@@ -7925,7 +7923,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.pushRenderTypeMask();
if (detail < 4)
{
clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, END_RENDER_TYPES);
if (detail < 3)
{
clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
@@ -7940,7 +7938,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLPipeline::RENDER_TYPE_VOIDWATER,
LLPipeline::RENDER_TYPE_GROUND,
LLPipeline::RENDER_TYPE_SKY,
LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS,
LLPipeline::RENDER_TYPE_WL_CLOUDS,
LLPipeline::END_RENDER_TYPES);
static const LLCachedControl<bool> skip_distortion_updates("SkipReflectOcclusionUpdates",false);