This commit is contained in:
Shyotl
2013-11-02 01:20:05 -05:00
parent 5e8c7264da
commit af8f8bb040
121 changed files with 8416 additions and 3292 deletions

View File

@@ -57,6 +57,8 @@
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llviewershadermgr.h"
#include "llviewertexture.h"
#include "llvoavatar.h"
#define LL_MAX_INDICES_COUNT 1000000
@@ -140,9 +142,13 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
//special value to indicate uninitialized position
mIndicesIndex = 0xFFFFFFFF;
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
mIndexInTex[i] = 0;
mTexture[i] = NULL;
}
mIndexInTex = 0;
mTexture = NULL;
mTEOffset = -1;
mTextureIndex = 255;
@@ -169,9 +175,12 @@ void LLFace::destroy()
gPipeline.checkReferences(this);
}
if(mTexture.notNull())
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
mTexture->removeFace(this) ;
if(mTexture[i].notNull())
{
mTexture[i]->removeFace(i, this) ;
}
}
if (isState(LLFace::PARTICLE))
@@ -264,47 +273,76 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
setTexture(texturep) ;
}
void LLFace::setTexture(LLViewerTexture* tex)
void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
{
if(mTexture == tex)
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mTexture[ch] == tex)
{
return ;
}
if(mTexture.notNull())
if(mTexture[ch].notNull())
{
mTexture->removeFace(this) ;
}
mTexture[ch]->removeFace(ch, this) ;
}
if(tex)
{
tex->addFace(this) ;
tex->addFace(ch, this) ;
}
mTexture = tex ;
mTexture[ch] = tex ;
}
void LLFace::setTexture(LLViewerTexture* tex)
{
setDiffuseMap(tex);
}
void LLFace::setDiffuseMap(LLViewerTexture* tex)
{
setTexture(LLRender::DIFFUSE_MAP, tex);
}
void LLFace::setNormalMap(LLViewerTexture* tex)
{
setTexture(LLRender::NORMAL_MAP, tex);
}
void LLFace::setSpecularMap(LLViewerTexture* tex)
{
setTexture(LLRender::SPECULAR_MAP, tex);
}
void LLFace::dirtyTexture()
{
LLDrawable* drawablep = getDrawable();
if (mVObjp.notNull() && mVObjp->getVolume() &&
mTexture.notNull() && mTexture->getComponents() == 4)
{ //dirty texture on an alpha object should be treated as an LoD update
LLVOVolume* vobj = drawablep->getVOVolume();
if (vobj)
if (mVObjp.notNull() && mVObjp->getVolume())
{
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
vobj->mLODChanged = TRUE;
if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
{ //dirty texture on an alpha object should be treated as an LoD update
LLVOVolume* vobj = drawablep->getVOVolume();
if (vobj)
{
vobj->mLODChanged = TRUE;
}
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
}
}
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
}
}
gPipeline.markTextured(drawablep);
}
void LLFace::switchTexture(LLViewerTexture* new_texture)
void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
{
if(mTexture == new_texture)
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mTexture[ch] == new_texture)
{
return ;
}
@@ -314,10 +352,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)
llerrs << "Can not switch to a null texture." << llendl;
return;
}
new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
setTexture(new_texture) ;
llassert(mTexture[ch].notNull());
new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
if (ch == LLRender::DIFFUSE_MAP)
{
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
}
setTexture(ch, new_texture) ;
dirtyTexture();
}
@@ -737,7 +782,7 @@ bool less_than_max_mag(const LLVector4a& vec)
}
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
const LLMatrix4& mat_vert_in, BOOL global_volume)
{
//get bounding box
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
@@ -746,16 +791,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
LLMatrix4a mat_normal;
mat_normal.loadu(mat_normal_in);
//if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
//{ //vertex buffer no longer valid
// mVertexBuffer = NULL;
// mLastVertexBuffer = NULL;
//}
//VECTORIZE THIS
LLVector4a min,max;
if (f >= volume.getNumVolumeFaces())
@@ -772,100 +807,68 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
llassert(less_than_max_mag(max));
//min, max are in volume space, convert to drawable render space
LLVector4a center;
LLVector4a t;
t.setAdd(min, max);
t.mul(0.5f);
mat_vert.affineTransform(t, center);
LLVector4a size;
size.setSub(max, min);
size.mul(0.5f);
llassert(less_than_max_mag(min));
llassert(less_than_max_mag(max));
//get 8 corners of bounding box
LLVector4Logical mask[6];
if (!global_volume)
for (U32 i = 0; i < 6; ++i)
{
//VECTORIZE THIS
LLVector4a scale;
scale.load3(mDrawablep->getVObj()->getScale().mV);
size.mul(scale);
mask[i].clear();
}
// Catch potential badness from normalization before it happens
//
//llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO));
//llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO));
//llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO));
mat_normal.mMatrix[0].normalize3fast();
mat_normal.mMatrix[1].normalize3fast();
mat_normal.mMatrix[2].normalize3fast();
mask[0].setElement<2>(); //001
mask[1].setElement<1>(); //010
mask[2].setElement<1>(); //011
mask[2].setElement<2>();
mask[3].setElement<0>(); //100
mask[4].setElement<0>(); //101
mask[4].setElement<2>();
mask[5].setElement<0>(); //110
mask[5].setElement<1>();
LLVector4a v[4];
LLVector4a v[8];
//get 4 corners of bounding box
mat_normal.rotate(size,v[0]);
v[6] = min;
v[7] = max;
//VECTORIZE THIS
LLVector4a scale;
scale.set(-1.f, -1.f, 1.f);
scale.mul(size);
mat_normal.rotate(scale, v[1]);
scale.set(1.f, -1.f, -1.f);
scale.mul(size);
mat_normal.rotate(scale, v[2]);
scale.set(-1.f, 1.f, -1.f);
scale.mul(size);
mat_normal.rotate(scale, v[3]);
for (U32 i = 0; i < 6; ++i)
{
v[i].setSelectWithMask(mask[i], min, max);
}
LLVector4a tv[8];
//transform bounding box into drawable space
for (U32 i = 0; i < 8; ++i)
{
mat_vert.affineTransform(v[i], tv[i]);
}
//find bounding box
LLVector4a& newMin = mExtents[0];
LLVector4a& newMax = mExtents[1];
newMin = newMax = center;
llassert(less_than_max_mag(center));
for (U32 i = 0; i < 4; i++)
newMin = newMax = tv[0];
for (U32 i = 1; i < 8; ++i)
{
LLVector4a delta;
delta.setAbs(v[i]);
LLVector4a min;
min.setSub(center, delta);
LLVector4a max;
max.setAdd(center, delta);
newMin.setMin(newMin,min);
newMax.setMax(newMax,max);
llassert(less_than_max_mag(newMin));
llassert(less_than_max_mag(newMax));
newMin.setMin(newMin, tv[i]);
newMax.setMax(newMax, tv[i]);
}
if (!mDrawablep->isActive())
{
{ // Shift position for region
LLVector4a offset;
offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
newMin.add(offset);
newMax.add(offset);
llassert(less_than_max_mag(newMin));
llassert(less_than_max_mag(newMax));
}
t.setAdd(newMin, newMax);
LLVector4a t;
t.setAdd(newMin,newMax);
t.mul(0.5f);
llassert(less_than_max_mag(t));
//VECTORIZE THIS
mCenterLocal.set(t.getF32ptr());
llassert(less_than_max_mag(newMin));
llassert(less_than_max_mag(newMax));
t.setSub(newMax,newMin);
mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
@@ -1273,30 +1276,34 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (tep &&
getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
{
LLMaterial* mat = tep->getMaterialParams().get();
bool shiny_in_alpha = false;
if (LLPipeline::sRenderDeferred)
{ //store shiny in alpha if we don't have a specular map
//if (!mat || mat->getSpecularID().isNull())
if (!mat || mat->getSpecularID().isNull())
{
shiny_in_alpha = true;
}
}
else
{
if(LLPipeline::sRenderBump && tep->getShiny())
if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
shiny_in_alpha = true;
}
}
if(shiny_in_alpha)
if (shiny_in_alpha)
{
GLfloat alpha[4] =
{
0.00f,
0.25f,
0.5f,
0.75f
0.00f,
0.25f,
0.5f,
0.75f
};
llassert(tep->getShiny() <= 3);
@@ -1555,11 +1562,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
if( mTexture.notNull() && mTexture->hasGLTexture())
if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
{
// Offset by approximately one texel
S32 cur_discard = mTexture->getDiscardLevel();
S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
max_size <<= cur_discard;
const F32 ARTIFICIAL_OFFSET = 2.f;
offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
@@ -1600,11 +1607,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
U8 tex_mode = 0;
bool tex_anim = false;
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
tex_mode = vobj->mTexAnimMode;
if (vobj->mTextureAnimp)
{ //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
tex_anim = true;
}
if (isState(TEXTURE_ANIM))
{
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
tex_mode = vobj->mTexAnimMode;
if (!tex_mode)
{
clearState(TEXTURE_ANIM);
@@ -1629,7 +1643,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a scalea;
scalea.load3(scale.mV);
LLMaterial* mat = tep->getMaterialParams().get();
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
if (mat && !do_bump)
{
do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
}
bool do_tex_mat = tex_mode && mTextureMatrix;
if (!do_bump)
@@ -1751,47 +1774,99 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
std::vector<LLVector2> bump_tc;
if (mat && !mat->getNormalID().isNull())
{ //writing out normal and specular texture coordinates, not bump offsets
do_bump = false;
}
LLStrider<LLVector2> dst;
mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
for (U32 ch = 0; ch < 3; ++ch)
{
switch (ch)
{
case 0:
mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
break;
case 1:
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
{
mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range);
if (mat && !tex_anim)
{
r = mat->getNormalRotation();
mat->getNormalOffset(os, ot);
mat->getNormalRepeat(ms, mt);
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
cos_ang = cos(r);
sin_ang = sin(r);
}
}
else
{
continue;
}
break;
case 2:
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
{
mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range);
if (mat && !tex_anim)
{
r = mat->getSpecularRotation();
mat->getSpecularOffset(os, ot);
mat->getSpecularRepeat(ms, mt);
cos_ang = cos(r);
sin_ang = sin(r);
}
}
else
{
continue;
}
break;
}
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
LLVector4a& norm = vf.mNormals[i];
LLVector4a& norm = vf.mNormals[i];
LLVector4a& center = *(vf.mCenter);
LLVector4a& center = *(vf.mCenter);
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
LLVector4a vec = vf.mPositions[i];
vec.mul(scalea);
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
planarProjection(tc, norm, center, vec);
LLVector4a vec = vf.mPositions[i];
vec.mul(scalea);
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
planarProjection(tc, norm, center, vec);
}
}
}
if (tex_mode && mTextureMatrix)
{
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
}
else
{
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
}
if (tex_mode && mTextureMatrix)
{
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
}
else
{
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
}
*dst++ = tc;
if (do_bump)
{
bump_tc.push_back(tc);
*dst++ = tc;
if (do_bump)
{
bump_tc.push_back(tc);
}
}
}
@@ -1800,7 +1875,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->flush();
}
if (do_bump)
if (!mat && do_bump)
{
mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
@@ -1846,20 +1921,31 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_pos)
{
LLFastTimer t(FTM_FACE_GEOM_POSITION);
LLVector4a* src = vf.mPositions;
//_mm_prefetch((char*)src, _MM_HINT_T0);
LLVector4a* end = src+num_vertices;
//LLVector4a* end_64 = end-4;
//LLFastTimer t(FTM_FACE_GEOM_POSITION);
llassert(num_vertices > 0);
mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
LLVector4a* src = vf.mPositions;
volatile F32* dst = (volatile F32*) vert.get();
F32* dst = (F32*) vert.get();
F32* end_f32 = dst+mGeomCount*4;
volatile F32* end = dst+num_vertices*4;
LLVector4a res;
//_mm_prefetch((char*)dst, _MM_HINT_NTA);
//_mm_prefetch((char*)src, _MM_HINT_NTA);
//_mm_prefetch((char*)dst, _MM_HINT_NTA);
LLVector4a res0; //,res1,res2,res3;
LLVector4a texIdx;
@@ -1880,29 +1966,53 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
texIdx.set(0,0,0,val);
{
LLFastTimer t(FTM_FACE_POSITION_STORE);
LLVector4a tmp;
LLVector4a tmp;
do
{
//LLFastTimer t2(FTM_FACE_POSITION_STORE);
/*if (num_vertices > 4)
{ //more than 64 bytes
while (src < end_64)
{
_mm_prefetch((char*)src + 64, _MM_HINT_T0);
_mm_prefetch((char*)dst + 64, _MM_HINT_T0);
mat_vert.affineTransform(*src, res0);
tmp.setSelectWithMask(mask, texIdx, res0);
tmp.store4a((F32*) dst);
mat_vert.affineTransform(*(src+1), res1);
tmp.setSelectWithMask(mask, texIdx, res1);
tmp.store4a((F32*) dst+4);
mat_vert.affineTransform(*(src+2), res2);
tmp.setSelectWithMask(mask, texIdx, res2);
tmp.store4a((F32*) dst+8);
mat_vert.affineTransform(*(src+3), res3);
tmp.setSelectWithMask(mask, texIdx, res3);
tmp.store4a((F32*) dst+12);
dst += 16;
src += 4;
}
}*/
while (src < end)
{
mat_vert.affineTransform(*src++, res);
tmp.setSelectWithMask(mask, texIdx, res);
mat_vert.affineTransform(*src++, res0);
tmp.setSelectWithMask(mask, texIdx, res0);
tmp.store4a((F32*) dst);
dst += 4;
}
while(dst < end);
}
{
LLFastTimer t(FTM_FACE_POSITION_PAD);
S32 aligned_pad_vertices = mGeomCount - num_vertices;
res.set(res[0], res[1], res[2], 0.f);
while (aligned_pad_vertices > 0)
//LLFastTimer t(FTM_FACE_POSITION_PAD);
while (dst < end_f32)
{
--aligned_pad_vertices;
res.store4a((F32*) dst);
res0.store4a((F32*) dst);
dst += 4;
}
}
@@ -1916,14 +2026,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_normal)
{
LLFastTimer t(FTM_FACE_GEOM_NORMAL);
//LLFastTimer t(FTM_FACE_GEOM_NORMAL);
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
F32* normals = (F32*) norm.get();
for (S32 i = 0; i < num_vertices; i++)
LLVector4a* src = vf.mNormals;
LLVector4a* end = src+num_vertices;
while (src < end)
{
LLVector4a normal;
mat_normal.rotate(vf.mNormals[i], normal);
normal.normalize3fast();
mat_normal.rotate(*src++, normal);
normal.store4a(normals);
normals += 4;
}
@@ -1946,14 +2058,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mask.clear();
mask.setElement<3>();
for (S32 i = 0; i < num_vertices; i++)
LLVector4a* src = vf.mTangents;
LLVector4a* end = vf.mTangents+num_vertices;
while (src < end)
{
LLVector4a tangent_out;
mat_normal.rotate(vf.mTangents[i], tangent_out);
mat_normal.rotate(*src, tangent_out);
tangent_out.normalize3fast();
tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out);
tangent_out.setSelectWithMask(mask, *src, tangent_out);
tangent_out.store4a(tangents);
src++;
tangents += 4;
}
@@ -2073,16 +2189,23 @@ BOOL LLFace::hasMedia() const
{
return TRUE ;
}
if(mTexture.notNull())
if(mTexture[LLRender::DIFFUSE_MAP].notNull())
{
return mTexture->hasParcelMedia() ; //if has a parcel media
return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
}
return FALSE ; //no media.
}
const F32 LEAST_IMPORTANCE = 0.05f ;
const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
void LLFace::resetVirtualSize()
{
setVirtualSize(0.f);
mImportanceToCamera = 0.f;
}
F32 LLFace::getTextureVirtualSize()
{
F32 radius;
@@ -2118,11 +2241,11 @@ F32 LLFace::getTextureVirtualSize()
}
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
if (/*mImportanceToCamera < 1.0f && */face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
if (mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
{
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius);
if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
{
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
}
}
@@ -2148,9 +2271,18 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
LLVector4a t;
t.load3(camera->getOrigin().mV);
lookAt.setSub(center, t);
F32 dist = lookAt.getLength3().getF32();
dist = llmax(dist-size.getLength3().getF32(), 0.001f);
lookAt.normalize3fast() ;
//ramp down distance for nearby objects
if (dist < 16.f)
{
dist /= 16.f;
dist *= dist;
dist *= 16.f;
}
lookAt.normalize3fast();
//get area of circle around node
F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
@@ -2486,9 +2618,12 @@ LLVector3 LLFace::getPositionAgent() const
return mCenterLocal * getRenderMatrix();
}
}
LLViewerTexture* LLFace::getTexture() const
LLViewerTexture* LLFace::getTexture(U32 ch) const
{
return mTexture ;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
return mTexture[ch] ;
}
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
@@ -2506,6 +2641,22 @@ void LLFace::clearVertexBuffer()
U32 LLFace::getRiggedDataMask(U32 type)
{
static const U32 rigged_data_mask[] = {
LLDrawPoolAvatar::RIGGED_MATERIAL_MASK,
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK,
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK,
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,
LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,
LLDrawPoolAvatar::RIGGED_SHINY_MASK,