summaryrefslogtreecommitdiff
path: root/indra/newview/llface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llface.cpp')
-rw-r--r--indra/newview/llface.cpp139
1 files changed, 107 insertions, 32 deletions
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 7c25d14783..3fa60e9f1e 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -198,18 +198,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mHasMedia = FALSE ;
}
-static LLFastTimer::DeclareTimer FTM_DESTROY_FACE("Destroy Face");
-static LLFastTimer::DeclareTimer FTM_DESTROY_TEXTURE("Texture");
-static LLFastTimer::DeclareTimer FTM_DESTROY_DRAWPOOL("Drawpool");
-static LLFastTimer::DeclareTimer FTM_DESTROY_TEXTURE_MATRIX("Texture Matrix");
-static LLFastTimer::DeclareTimer FTM_DESTROY_DRAW_INFO("Draw Info");
-static LLFastTimer::DeclareTimer FTM_DESTROY_ATLAS("Atlas");
-static LLFastTimer::DeclareTimer FTM_FACE_DEREF("Deref");
-
void LLFace::destroy()
{
- LLFastTimer t(FTM_DESTROY_FACE);
-
if (gDebugGL)
{
gPipeline.checkReferences(this);
@@ -217,14 +207,11 @@ void LLFace::destroy()
if(mTexture.notNull())
{
- LLFastTimer t(FTM_DESTROY_TEXTURE);
mTexture->removeFace(this) ;
}
if (mDrawPoolp)
{
- LLFastTimer t(FTM_DESTROY_DRAWPOOL);
-
#if LL_MESH_ENABLED
if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
{
@@ -241,7 +228,6 @@ void LLFace::destroy()
if (mTextureMatrix)
{
- LLFastTimer t(FTM_DESTROY_TEXTURE_MATRIX);
delete mTextureMatrix;
mTextureMatrix = NULL;
@@ -256,22 +242,12 @@ void LLFace::destroy()
}
}
- {
- LLFastTimer t(FTM_DESTROY_DRAW_INFO);
- setDrawInfo(NULL);
- }
-
- {
- LLFastTimer t(FTM_DESTROY_ATLAS);
- removeAtlas();
- }
+ setDrawInfo(NULL);
+ removeAtlas();
+
+ mDrawablep = NULL;
+ mVObjp = NULL;
- {
- LLFastTimer t(FTM_FACE_DEREF);
- mDrawablep = NULL;
- mVObjp = NULL;
- }
-
ll_aligned_free_16(mExtents);
mExtents = NULL;
}
@@ -580,8 +556,36 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
}
glColor4fv(color.mV);
- mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
- mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
+
+ if (mDrawablep->isState(LLDrawable::RIGGED))
+ {
+ LLVOVolume* volume = mDrawablep->getVOVolume();
+ if (volume)
+ {
+ LLRiggedVolume* rigged = volume->getRiggedVolume();
+ if (rigged)
+ {
+ LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.f, -1.f);
+ glMultMatrixf((F32*) volume->getRelativeXform().mMatrix);
+ const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset());
+ LLVertexBuffer::unbind();
+ glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions);
+ if (vol_face.mTexCoords)
+ {
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
+ }
+ glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ }
+ else
+ {
+ mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
+ mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ }
gGL.popMatrix();
}
@@ -744,7 +748,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
//get bounding box
- if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
+ if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
{
//VECTORIZE THIS
LLMatrix4a mat_vert;
@@ -930,6 +934,77 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
return tc;
}
+// Returns scale compared to default texgen, and face orientation as calculated
+// by planarProjection(). This is needed to match planar texgen parameters.
+void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const
+{
+ const LLMatrix4& vol_mat = getWorldMatrix();
+ const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
+ const LLVector4a& normal4a = vf.mNormals[0];
+ const LLVector4a& binormal4a = vf.mBinormals[0];
+ LLVector2 projected_binormal;
+ planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
+ projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
+ *scale = projected_binormal.length();
+ // rotate binormal to match what planarProjection() thinks it is,
+ // then find rotation from that:
+ projected_binormal.normalize();
+ F32 ang = acos(projected_binormal.mV[VY]);
+ ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang;
+
+ //VECTORIZE THIS
+ LLVector3 binormal(binormal4a.getF32ptr());
+ LLVector3 normal(normal4a.getF32ptr());
+ binormal.rotVec(ang, normal);
+ LLQuaternion local_rot( binormal % normal, binormal, normal );
+ *face_rot = local_rot * vol_mat.quaternion();
+ *face_pos = vol_mat.getTranslation();
+}
+
+// Returns the necessary texture transform to align this face's TE to align_to's TE
+bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset,
+ LLVector2* res_st_scale, F32* res_st_rot) const
+{
+ if (!align_to)
+ {
+ return false;
+ }
+ const LLTextureEntry *orig_tep = align_to->getTextureEntry();
+ if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) ||
+ (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))
+ {
+ return false;
+ }
+
+ LLVector3 orig_pos, this_pos;
+ LLQuaternion orig_face_rot, this_face_rot;
+ F32 orig_proj_scale, this_proj_scale;
+ align_to->getPlanarProjectedParams(&orig_face_rot, &orig_pos, &orig_proj_scale);
+ getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale);
+
+ // The rotation of "this face's" texture:
+ LLQuaternion orig_st_rot = LLQuaternion(orig_tep->getRotation(), LLVector3::z_axis) * orig_face_rot;
+ LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot;
+ F32 x_ang, y_ang, z_ang;
+ this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang);
+ *res_st_rot = z_ang;
+
+ // Offset and scale of "this face's" texture:
+ LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot;
+ LLVector3 st_scale(orig_tep->mScaleS, orig_tep->mScaleT, 1.f);
+ st_scale *= orig_proj_scale;
+ centers_dist.scaleVec(st_scale);
+ LLVector2 orig_st_offset(orig_tep->mOffsetS, orig_tep->mOffsetT);
+
+ *res_st_offset = orig_st_offset + (LLVector2)centers_dist;
+ res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX];
+ res_st_offset->mV[VY] -= (S32)res_st_offset->mV[VY];
+
+ st_scale /= this_proj_scale;
+ *res_st_scale = (LLVector2)st_scale;
+ return true;
+}
+
void LLFace::updateRebuildFlags()
{
if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME))