Rigged attachment integration WIP.

master
Dave Parks 2010-05-01 00:45:44 -05:00
parent d71716aa6d
commit f324787a70
16 changed files with 440 additions and 134 deletions

View File

@ -124,7 +124,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
{
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
if (mShaderLevel > 0)
if (shaderhandle > 0)
{
attachObject(shaderhandle);
}

View File

@ -13,7 +13,7 @@ void main()
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
vary_normal = normalize(gl_NormalMatrix * gl_Normal);
vary_nomral = normalize(gl_NormalMatrix * gl_Normal);
gl_FrontColor = gl_Color;
}

View File

@ -248,11 +248,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures
{
}
BOOL LLFacePool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data)
{
return TRUE;
}
// static
S32 LLFacePool::drawLoop(face_array_t& face_list)
{

View File

@ -187,8 +187,6 @@ public:
virtual void resetDrawOrders();
void resetAll();
BOOL moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data = FALSE);
void destroy();
void buildEdges();

View File

@ -39,13 +39,17 @@
#include "m3math.h"
#include "lldrawable.h"
#include "lldrawpoolbump.h"
#include "llface.h"
#include "llmeshrepository.h"
#include "llsky.h"
#include "llviewercamera.h"
#include "llviewerregion.h"
#include "noise.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
#include "llvovolume.h"
#include "llvolume.h"
#include "llappviewer.h"
#include "llrendersphere.h"
#include "llviewerpartsim.h"
@ -94,6 +98,8 @@ static BOOL sRenderingSkinned = FALSE;
S32 normal_channel = -1;
S32 specular_channel = -1;
S32 diffuse_channel = -1;
S32 cube_channel = -1;
static LLFastTimer::DeclareTimer FTM_SHADOW_AVATAR("Avatar Shadow");
@ -358,7 +364,7 @@ S32 LLDrawPoolAvatar::getNumPasses()
}
else if (getVertexShaderLevel() > 0)
{
return 4;
return 5;
}
else
{
@ -402,7 +408,10 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
beginSkinned();
break;
case 3:
beginRigged();
beginRiggedSimple();
break;
case 4:
beginRiggedShinySimple();
break;
}
}
@ -429,7 +438,10 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
endSkinned();
break;
case 3:
endRigged();
endRiggedSimple();
break;
case 4:
endRiggedShinySimple();
break;
}
}
@ -616,14 +628,15 @@ void LLDrawPoolAvatar::endSkinned()
gGL.getTexUnit(0)->activate();
}
void LLDrawPoolAvatar::beginRigged()
void LLDrawPoolAvatar::beginRiggedSimple()
{
sVertexProgram = &gSkinnedObjectSimpleProgram;
diffuse_channel = 0;
gSkinnedObjectSimpleProgram.bind();
LLVertexBuffer::sWeight4Loc = gSkinnedObjectSimpleProgram.getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
}
void LLDrawPoolAvatar::endRigged()
void LLDrawPoolAvatar::endRiggedSimple()
{
sVertexProgram = NULL;
LLVertexBuffer::unbind();
@ -631,6 +644,23 @@ void LLDrawPoolAvatar::endRigged()
LLVertexBuffer::sWeight4Loc = -1;
}
void LLDrawPoolAvatar::beginRiggedShinySimple()
{
sVertexProgram = &gSkinnedObjectShinySimpleProgram;
sVertexProgram->bind();
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, diffuse_channel, cube_channel, false);
LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
}
void LLDrawPoolAvatar::endRiggedShinySimple()
{
LLVertexBuffer::unbind();
LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, diffuse_channel, cube_channel, false);
sVertexProgram->unbind();
sVertexProgram = NULL;
LLVertexBuffer::sWeight4Loc = -1;
}
void LLDrawPoolAvatar::beginDeferredRigged()
{
sVertexProgram = &gDeferredSkinnedDiffuseProgram;
@ -790,9 +820,16 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
if (pass == 3)
{
avatarp->renderSkinnedAttachments();
renderRiggedSimple(avatarp);
return;
}
if (pass == 4)
{
renderRiggedShinySimple(avatarp);
return;
}
if (sShaderLevel > 0)
{
@ -830,13 +867,146 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
}
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face, U32 data_mask)
{
LLVertexBuffer* buff = face->mVertexBuffer;
if (!buff ||
!buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) ||
buff->getRequestedVerts() != vol_face.mVertices.size())
{
face->setGeomIndex(0);
face->setIndicesIndex(0);
face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
face->mVertexBuffer = new LLVertexBuffer(data_mask, 0);
face->mVertexBuffer->allocateBuffer(vol_face.mVertices.size(), vol_face.mIndices.size(), true);
U16 offset = 0;
LLMatrix4 mat_vert = skin->mBindShapeMatrix;
glh::matrix4f m((F32*) mat_vert.mMatrix);
m = m.inverse().transpose();
F32 mat3[] =
{ m.m[0], m.m[1], m.m[2],
m.m[4], m.m[5], m.m[6],
m.m[8], m.m[9], m.m[10] };
LLMatrix3 mat_normal(mat3);
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
buff = face->mVertexBuffer;
}
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, const U32 data_mask)
{
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
{
LLFace* face = mRiggedFace[type][i];
LLDrawable* drawable = face->getDrawable();
if (!drawable)
{
continue;
}
LLVOVolume* vobj = drawable->getVOVolume();
if (!vobj)
{
continue;
}
LLVolume* volume = vobj->getVolume();
S32 te = face->getTEOffset();
if (!volume || volume->getNumVolumeFaces() <= te)
{
continue;
}
LLUUID mesh_id = volume->getParams().getSculptID();
if (mesh_id.isNull())
{
continue;
}
const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id);
if (!skin)
{
continue;
}
const LLVolumeFace& vol_face = volume->getVolumeFace(te);
updateRiggedFaceVertexBuffer(face, skin, volume, vol_face, data_mask);
LLVertexBuffer* buff = face->mVertexBuffer;
if (buff)
{
LLMatrix4 mat[64];
for (U32 i = 0; i < skin->mJointNames.size(); ++i)
{
LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
if (joint)
{
mat[i] = skin->mInvBindMatrix[i];
mat[i] *= joint->getWorldMatrix();
}
}
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
skin->mJointNames.size(),
FALSE,
(GLfloat*) mat[0].mMatrix);
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette[0]",
skin->mJointNames.size(),
FALSE,
(GLfloat*) mat[0].mMatrix);
buff->setBuffer(data_mask);
U16 start = face->getGeomStart();
U16 end = start + face->getGeomCount()-1;
S32 offset = face->getIndicesStart();
U32 count = face->getIndicesCount();
gGL.getTexUnit(0)->bind(face->getTexture());
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
}
}
}
void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar)
{
const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4;
renderRigged(avatar, RIGGED_SIMPLE, data_mask);
}
void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar)
{
const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4;
renderRigged(avatar, RIGGED_SHINY_SIMPLE, data_mask);
}
//-----------------------------------------------------------------------------
// renderForSelect()
//-----------------------------------------------------------------------------
void LLDrawPoolAvatar::renderForSelect()
{
if (mDrawFace.empty())
{
return;
@ -930,6 +1100,64 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
return LLColor3(0.f, 1.f, 0.f);
}
void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
{
if (facep->getReferenceIndex() != -1)
{
llerrs << "Tried to add a rigged face that's referenced elsewhere." << llendl;
}
if (type >= NUM_RIGGED_PASSES)
{
llerrs << "Invalid rigged face type." << llendl;
}
facep->setReferenceIndex(mRiggedFace[type].size());
facep->mDrawPoolp = this;
mRiggedFace[type].push_back(facep);
}
void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep, U32 type)
{
S32 index = facep->getReferenceIndex();
if (index == -1)
{
llerrs << "Tried to remove rigged face with invalid index." << llendl;
}
if (type > RIGGED_UNKNOWN)
{
llerrs << "Invalid rigged face type." << llendl;
}
facep->setReferenceIndex(-1);
facep->mDrawPoolp = NULL;
if (type == RIGGED_UNKNOWN)
{
for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
{
if (mRiggedFace[i].size() > index && mRiggedFace[i][index] == facep)
{
type = i;
break;
}
}
}
if (type >= NUM_RIGGED_PASSES)
{
llerrs << "Could not find face for removal from current drawpool." << llendl;
}
mRiggedFace[type].erase(mRiggedFace[type].begin()+index);
for (S32 i = index; i < mRiggedFace[type].size(); ++i)
{ //bump indexes of currently held faces down after removal
mRiggedFace[type][i]->setReferenceIndex(i);
}
}
LLVertexBufferAvatar::LLVertexBufferAvatar()
: LLVertexBuffer(sDataMask,
GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets

View File

@ -37,6 +37,11 @@
class LLVOAvatar;
class LLGLSLShader;
class LLFace;
class LLMeshSkinInfo;
class LLVolume;
class LLVolumeFace;
class LLDrawPoolAvatar : public LLFacePool
{
@ -91,12 +96,14 @@ public:
void beginRigid();
void beginImpostor();
void beginSkinned();
void beginRigged();
void beginRiggedSimple();
void beginRiggedShinySimple();
void endRigid();
void endImpostor();
void endSkinned();
void endRigged();
void endRiggedSimple();
void endRiggedShinySimple();
void beginDeferredImpostor();
void beginDeferredRigid();
@ -108,11 +115,40 @@ public:
void endDeferredSkinned();
void endDeferredRigged();
void updateRiggedFaceVertexBuffer(LLFace* facep,
const LLMeshSkinInfo* skin,
LLVolume* volume,
const LLVolumeFace& vol_face,
U32 data_mask);
void renderRigged(LLVOAvatar* avatar, U32 type, const U32 data_mask);
void renderRiggedSimple(LLVOAvatar* avatar);
void renderRiggedShinySimple(LLVOAvatar* avatar);
/*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null.
typedef enum
{
RIGGED_SIMPLE = 0,
RIGGED_SHINY_SIMPLE,
RIGGED_SHINY_FULLBRIGHT,
RIGGED_SHINY_BUMP,
RIGGED_BUMP,
RIGGED_FULLBRIGHT,
RIGGED_ALPHA,
NUM_RIGGED_PASSES,
RIGGED_UNKNOWN,
} eRiggedPass;
void addRiggedFace(LLFace* facep, U32 type);
void removeRiggedFace(LLFace* facep, U32 type = RIGGED_UNKNOWN);
std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES];
static BOOL sSkipOpaque;
static BOOL sSkipTransparent;
static LLGLSLShader* sVertexProgram;

View File

@ -323,30 +323,43 @@ void LLDrawPoolBump::beginShiny(bool invisible)
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
}
if (LLPipeline::sUnderWaterRender)
if (getVertexShaderLevel() > 0)
{
shader = &gObjectShinyWaterProgram;
if (LLPipeline::sUnderWaterRender)
{
shader = &gObjectShinyWaterProgram;
}
else
{
shader = &gObjectShinyProgram;
}
shader->bind();
}
else
{
shader = &gObjectShinyProgram;
shader = NULL;
}
bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
}
//static
void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
{
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
if (!invisible && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0 )
if (!invisible && shader )
{
LLMatrix4 mat;
mat.initRows(LLVector4(gGLModelView+0),
LLVector4(gGLModelView+4),
LLVector4(gGLModelView+8),
LLVector4(gGLModelView+12));
shader->bind();
LLVector3 vec = LLVector3(gShinyOrigin) * mat;
LLVector4 vec4(vec, gShinyOrigin.mV[3]);
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
if (mVertexShaderLevel > 1)
if (shader_level > 1)
{
cube_map->setMatrix(1);
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
@ -408,22 +421,16 @@ void LLDrawPoolBump::renderShiny(bool invisible)
}
}
void LLDrawPoolBump::endShiny(bool invisible)
//static
void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
{
LLFastTimer t(FTM_RENDER_SHINY);
if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
(invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
{
return;
}
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
cube_map->disable();
cube_map->restoreMatrix();
if (!invisible && mVertexShaderLevel > 1)
if (!invisible && shader_level > 1)
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
@ -434,7 +441,6 @@ void LLDrawPoolBump::endShiny(bool invisible)
shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
}
shader->unbind();
}
}
gGL.getTexUnit(diffuse_channel)->disable();
@ -442,6 +448,22 @@ void LLDrawPoolBump::endShiny(bool invisible)
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
void LLDrawPoolBump::endShiny(bool invisible)
{
LLFastTimer t(FTM_RENDER_SHINY);
if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
(invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
{
return;
}
unbindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
if (shader)
{
shader->unbind();
}
diffuse_channel = -1;
cube_channel = 0;

View File

@ -41,6 +41,7 @@
class LLImageRaw;
class LLSpatialGroup;
class LLDrawInfo;
class LLGLSLShader;
class LLViewerFetchedTexture;
class LLDrawPoolBump : public LLRenderPass
@ -79,6 +80,9 @@ public:
void renderBump();
void endBump();
static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
virtual S32 getNumDeferredPasses();
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);

View File

@ -205,7 +205,12 @@ void LLFace::destroy()
if (mDrawPoolp)
{
LLFastTimer t(FTM_DESTROY_DRAWPOOL);
if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
mDrawPoolp->removeFace(this);
mDrawPoolp = NULL;
}

View File

@ -234,6 +234,7 @@ public:
private:
friend class LLGeometryManager;
friend class LLVolumeGeometryManager;
friend class LLDrawPoolAvatar;
U32 mState;
LLFacePool* mDrawPoolp;

View File

@ -5219,6 +5219,25 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif
return ;
}
//virtual
LLVOAvatar* LLViewerObject::getAvatar() const
{
if (isAttachment())
{
LLViewerObject* vobj = (LLViewerObject*) getParent();
while (vobj && !vobj->asAvatar())
{
vobj = (LLViewerObject*) vobj->getParent();
}
return (LLVOAvatar*) vobj;
}
return NULL;
}
class ObjectPhysicsProperties : public LLHTTPNode
{
public:

View File

@ -181,6 +181,7 @@ public:
void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; }
virtual BOOL isAttachment() const { return FALSE; }
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual void updateRadius() {};
virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius()

View File

@ -79,6 +79,7 @@ LLGLSLShader gObjectShinyWaterProgram;
//object hardware skinning shaders
LLGLSLShader gSkinnedObjectSimpleProgram;
LLGLSLShader gSkinnedObjectShinySimpleProgram;
//environment shaders
LLGLSLShader gTerrainProgram;
@ -154,6 +155,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gObjectFullbrightProgram);
mShaderList.push_back(&gObjectFullbrightShinyProgram);
mShaderList.push_back(&gSkinnedObjectSimpleProgram);
mShaderList.push_back(&gSkinnedObjectShinySimpleProgram);
mShaderList.push_back(&gTerrainProgram);
mShaderList.push_back(&gTerrainWaterProgram);
mShaderList.push_back(&gObjectSimpleWaterProgram);
@ -505,6 +507,9 @@ void LLViewerShaderMgr::setShaders()
if (!loadShadersDeferred())
{
gSavedSettings.setBOOL("RenderDeferred", FALSE);
reentrance = false;
setShaders();
return;
}
#endif
}
@ -557,6 +562,8 @@ void LLViewerShaderMgr::unloadShaders()
gObjectShinyWaterProgram.unload();
gSkinnedObjectSimpleProgram.unload();
gSkinnedObjectShinySimpleProgram.unload();
gWaterProgram.unload();
gUnderWaterProgram.unload();
@ -917,7 +924,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredGIProgram.unload();
gDeferredGIFinalProgram.unload();
gDeferredWaterProgram.unload();
return FALSE;
return TRUE;
}
mVertexShaderLevel[SHADER_AVATAR] = 1;
@ -1251,6 +1258,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightProgram.unload();
gObjectFullbrightWaterProgram.unload();
gSkinnedObjectSimpleProgram.unload();
gSkinnedObjectShinySimpleProgram.unload();
return FALSE;
}
@ -1376,6 +1385,22 @@ BOOL LLViewerShaderMgr::loadShadersObject()
success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL);
}
if (success)
{
gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader";
gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true;
gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true;
gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true;
gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;
gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true;
gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true;
gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectShinySimpleProgram.createShader(NULL, &mShinyUniforms);
}
if( !success )
{
mVertexShaderLevel[SHADER_OBJECT] = 0;

View File

@ -315,6 +315,7 @@ extern LLGLSLShader gObjectShinyProgram;
extern LLGLSLShader gObjectShinyWaterProgram;
extern LLGLSLShader gSkinnedObjectSimpleProgram;
extern LLGLSLShader gSkinnedObjectShinySimpleProgram;
//environment shaders
extern LLGLSLShader gTerrainProgram;

View File

@ -3642,7 +3642,7 @@ bool LLVOAvatar::shouldAlphaMask()
U32 LLVOAvatar::renderSkinnedAttachments()
{
U32 num_indices = 0;
/*U32 num_indices = 0;
const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
@ -3670,107 +3670,14 @@ U32 LLVOAvatar::renderSkinnedAttachments()
LLFace* face = drawable->getFace(i);
if (face->isState(LLFace::RIGGED))
{
LLVolume* volume = attached_object->getVolume();
if (!volume || volume->getNumVolumeFaces() <= i)
{
continue;
}
const LLVolumeFace& vol_face = volume->getVolumeFace(i);
const LLMeshSkinInfo* skin = NULL;
LLVertexBuffer* buff = face->mVertexBuffer;
LLUUID mesh_id = volume->getParams().getSculptID();;
if (!buff ||
!buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) ||
buff->getRequestedVerts() != vol_face.mVertices.size())
{
face->mVertexBuffer = NULL;
face->mLastVertexBuffer = NULL;
buff = NULL;
if (mesh_id.notNull())
{
skin = gMeshRepo.getSkinInfo(mesh_id);
if (skin)
{
face->mVertexBuffer = new LLVertexBuffer(data_mask, 0);
face->mVertexBuffer->allocateBuffer(vol_face.mVertices.size(), vol_face.mIndices.size(), true);
face->setGeomIndex(0);
face->setIndicesIndex(0);
face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
U16 offset = 0;
LLMatrix4 mat_vert = skin->mBindShapeMatrix;
glh::matrix4f m((F32*) mat_vert.mMatrix);
m = m.inverse().transpose();
F32 mat3[] =
{ m.m[0], m.m[1], m.m[2],
m.m[4], m.m[5], m.m[6],
m.m[8], m.m[9], m.m[10] };
LLMatrix3 mat_normal(mat3);
face->getGeometryVolume(*volume, i, mat_vert, mat_normal, offset, true);
buff = face->mVertexBuffer;
}
}
}
if (buff && mesh_id.notNull())
{
if (!skin)
{
skin = gMeshRepo.getSkinInfo(mesh_id);
}
if (skin)
{
LLMatrix4 mat[64];
for (U32 i = 0; i < skin->mJointNames.size(); ++i)
{
LLJoint* joint = getJoint(skin->mJointNames[i]);
if (joint)
{
mat[i] = skin->mInvBindMatrix[i];
mat[i] *= joint->getWorldMatrix();
}
}
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
skin->mJointNames.size(),
FALSE,
(GLfloat*) mat[0].mMatrix);
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette[0]",
skin->mJointNames.size(),
FALSE,
(GLfloat*) mat[0].mMatrix);
buff->setBuffer(data_mask);
U16 start = face->getGeomStart();
U16 end = start + face->getGeomCount()-1;
S32 offset = face->getIndicesStart();
U32 count = face->getIndicesCount();
gGL.getTexUnit(0)->bind(face->getTexture());
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
}
}
}
}
}
}
}
}
return num_indices;
return num_indices;*/
return 0;
}
//-----------------------------------------------------------------------------

View File

@ -52,6 +52,7 @@
#include "object_flags.h"
#include "llagentconstants.h"
#include "lldrawable.h"
#include "lldrawpoolavatar.h"
#include "lldrawpoolbump.h"
#include "llface.h"
#include "llspatialpartition.h"
@ -73,6 +74,8 @@
#include "llmeshrepository.h"
#include "llagent.h"
#include "llviewermediafocus.h"
#include "llvoavatar.h"
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
@ -3415,6 +3418,33 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
{
LLVOAvatar* avatar = vobj->getAvatar();
if (avatar)
{
LLDrawable* drawable = avatar->mDrawable;
if (drawable && drawable->getNumFaces() > 0)
{
LLFace* face = drawable->getFace(0);
if (face)
{
LLDrawPool* drawpool = face->getPool();
if (drawpool)
{
if (drawpool->getType() == LLDrawPool::POOL_AVATAR)
{
return (LLDrawPoolAvatar*) drawpool;
}
}
}
}
}
return NULL;
}
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
@ -3499,13 +3529,47 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
facep->mVertexBuffer = NULL;
facep->mLastVertexBuffer = NULL;
facep->setState(LLFace::RIGGED);
//get drawpool of avatar with rigged face
LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
if (pool)
{
const LLTextureEntry* te = facep->getTextureEntry();
//remove face from old pool if it exists
LLDrawPool* old_pool = facep->getPool();
if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
{
((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
}
//add face to new pool
if (te->getShiny())
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY_SIMPLE);
}
else
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
}
}
}
continue;
}
else
{
facep->clearState(LLFace::RIGGED);
if (facep->isState(LLFace::RIGGED))
{ //face is not rigged but used to be, remove from rigged face pool
LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
if (pool)
{
pool->removeRiggedFace(facep);
}
facep->clearState(LLFace::RIGGED);
}
}
if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)