diff -r bda5610cbea6 indra/newview/llglsandbox.cpp --- a/indra/newview/llglsandbox.cpp Fri Jun 25 09:59:20 2010 -0500 +++ b/indra/newview/llglsandbox.cpp Mon Oct 25 10:51:14 2010 -0500 @@ -149,7 +149,11 @@ virtual bool apply(LLViewerObject* vobjp) { LLDrawable* drawable = vobjp->mDrawable; - if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment()) + if (!drawable || + ((vobjp->getPCode() != LL_PCODE_VOLUME) && + (vobjp->getPCode() != LL_PCODE_LEGACY_TREE) && + (vobjp->getPCode() != LL_PCODE_LEGACY_GRASS) )|| + vobjp->isAttachment()) { return true; } @@ -200,7 +204,9 @@ LLViewerObject* vobjp = drawable->getVObj(); if (!drawable || !vobjp || - vobjp->getPCode() != LL_PCODE_VOLUME || + ((vobjp->getPCode() != LL_PCODE_VOLUME) && + (vobjp->getPCode() != LL_PCODE_LEGACY_TREE) && + (vobjp->getPCode() != LL_PCODE_LEGACY_GRASS) )|| vobjp->isAttachment() || (deselect && !vobjp->isSelected())) { diff -r bda5610cbea6 indra/newview/llselectmgr.cpp --- a/indra/newview/llselectmgr.cpp Fri Jun 25 09:59:20 2010 -0500 +++ b/indra/newview/llselectmgr.cpp Mon Oct 25 10:51:14 2010 -0500 @@ -91,6 +91,8 @@ #include "llviewerregion.h" #include "llviewerstats.h" #include "llvoavatarself.h" +#include "llvograss.h" +#include "llvotree.h" #include "llvovolume.h" #include "pipeline.h" @@ -857,7 +859,10 @@ return; } - if (objectp->getPCode() != LL_PCODE_VOLUME) + if ((objectp->getPCode() != LL_PCODE_VOLUME) && + (objectp->getPCode() != LL_PCODE_LEGACY_TREE) && + (objectp->getPCode() != LL_PCODE_LEGACY_GRASS)) + { return; } @@ -905,7 +910,10 @@ { continue; } - if (object->getPCode() != LL_PCODE_VOLUME) + + if ((object->getPCode() != LL_PCODE_VOLUME) && + (object->getPCode() != LL_PCODE_LEGACY_TREE) && + (object->getPCode() != LL_PCODE_LEGACY_GRASS)) { continue; } @@ -925,7 +933,14 @@ void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp) { - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + if (!objectp) + { + return; + } + + if ((objectp->getPCode() != LL_PCODE_VOLUME) && + (objectp->getPCode() != LL_PCODE_LEGACY_TREE) && + (objectp->getPCode() != LL_PCODE_LEGACY_GRASS)) { return; } @@ -5046,6 +5061,14 @@ { ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point); } + else if (objectp && objectp->getPCode() == LL_PCODE_LEGACY_GRASS) + { + ((LLVOGrass*)objectp)->generateSilhouette(nodep, view_point); + } + else if (objectp && objectp->getPCode() == LL_PCODE_LEGACY_TREE) + { + ((LLVOTree*)objectp)->generateSilhouette(nodep, view_point); + } } // @@ -5395,8 +5418,8 @@ glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix); } - LLVolume *volume = objectp->getVolume(); - if (volume) + // we used to only call this for volumes. but let's render silhouettes for any node that has them. + if (1) { F32 silhouette_thickness; if (isAgentAvatarValid() && is_hud_object) diff -r bda5610cbea6 indra/newview/llviewercamera.cpp --- a/indra/newview/llviewercamera.cpp Fri Jun 25 09:59:20 2010 -0500 +++ b/indra/newview/llviewercamera.cpp Mon Oct 25 10:51:14 2010 -0500 @@ -777,7 +777,9 @@ LLVolume* volume = volumep->getVolume(); if (!volume) { - return FALSE; + BOOL inside = pointInFrustum(volumep->getRenderPosition()); + + return (inside > 0); } LLVOVolume* vo_volume = (LLVOVolume*) volumep; diff -r bda5610cbea6 indra/newview/llvograss.cpp --- a/indra/newview/llvograss.cpp Fri Jun 25 09:59:20 2010 -0500 +++ b/indra/newview/llvograss.cpp Mon Oct 25 10:51:14 2010 -0500 @@ -49,6 +49,7 @@ #include "llviewertexturelist.h" #include "llviewerregion.h" #include "pipeline.h" +#include "llselectmgr.h" #include "llspatialpartition.h" #include "llworld.h" #include "lldir.h" @@ -708,3 +709,94 @@ return ret; } +void LLVOGrass::generateSilhouetteVertices(std::vector &vertices, + std::vector &normals, + std::vector &segments, + const LLVector3& obj_cam_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat) +{ + vertices.clear(); + normals.clear(); + segments.clear(); + + F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; + F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; + + for (S32 i = 0; i < mNumBlades; i++) + { + F32 x = exp_x[i] * mScale.mV[VX]; + F32 y = exp_y[i] * mScale.mV[VY]; + F32 xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i]; + F32 yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i]; + F32 dzx = dz_x [i]; + F32 dzy = dz_y [i]; + + F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; + + LLVector3 position1; + + position1.mV[0] = mPosition.mV[VX] + x + xf; + position1.mV[1] = mPosition.mV[VY] + y + yf; + position1.mV[2] = mRegionp->getLand().resolveHeightRegion(position1); + + LLVector3 position2 = position1; + + position2.mV[0] += dzx; + position2.mV[1] += dzy; + position2.mV[2] += blade_height; + + LLVector3 position3; + + position3.mV[0] = mPosition.mV[VX] + x - xf; + position3.mV[1] = mPosition.mV[VY] + y - xf; + position3.mV[2] = mRegionp->getLand().resolveHeightRegion(position3); + + LLVector3 position4 = position3; + + position4.mV[0] += dzx; + position4.mV[1] += dzy; + position4.mV[2] += blade_height; + + + LLVector3 normal = (position1-position2) % (position2 - position3); + normal.normalize(); + + vertices.push_back(position1 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position2 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position2 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position4 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position4 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position3 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position3 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position1 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + } +} + + + +void LLVOGrass::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) +{ + generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, + nodep->mSilhouetteSegments, + LLVector3(0,0,0), LLMatrix4(), LLMatrix3()); + + nodep->mSilhouetteExists = TRUE; + +} + diff -r bda5610cbea6 indra/newview/llvograss.h --- a/indra/newview/llvograss.h Fri Jun 25 09:59:20 2010 -0500 +++ b/indra/newview/llvograss.h Mon Oct 25 10:51:14 2010 -0500 @@ -37,6 +37,7 @@ #include "lldarray.h" #include +class LLSelectNode; class LLSurfacePatch; class LLViewerTexture; @@ -76,6 +77,8 @@ /*virtual*/ BOOL updateLOD(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area + void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); + void plantBlades(); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. @@ -121,6 +124,12 @@ ~LLVOGrass(); private: + void generateSilhouetteVertices(std::vector &vertices, + std::vector &normals, + std::vector &segments, + const LLVector3& view_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat); void updateSpecies(); F32 mLastHeight; // For cheap update hack S32 mNumBlades; diff -r bda5610cbea6 indra/newview/llvotree.cpp --- a/indra/newview/llvotree.cpp Fri Jun 25 09:59:20 2010 -0500 +++ b/indra/newview/llvotree.cpp Mon Oct 25 10:51:14 2010 -0500 @@ -47,6 +47,7 @@ #include "llagentcamera.h" #include "lldrawable.h" #include "llface.h" +#include "llselectmgr.h" #include "llviewercamera.h" #include "llviewertexturelist.h" #include "llviewerobjectlist.h" @@ -1315,3 +1316,127 @@ mLODPeriod = 1; } + + +void LLVOTree::generateSilhouetteVertices(std::vector &vertices, + std::vector &normals, + std::vector &segments, + const LLVector3& obj_cam_vec, + const LLMatrix4& local_matrix, + const LLMatrix3& normal_matrix) +{ + vertices.clear(); + normals.clear(); + segments.clear(); + + F32 height = mBillboardScale; // *mBillboardRatio * 0.5; + F32 width = height * mTrunkAspect; + + LLVector3 position1 = LLVector3(-width * 0.5,0,0) * local_matrix; + LLVector3 position2 = LLVector3(-width * 0.5,0,height) * local_matrix; + LLVector3 position3 = LLVector3(+width * 0.5,0,height) * local_matrix; + LLVector3 position4 = LLVector3(+width * 0.5,0,0) * local_matrix; + + LLVector3 position5 = LLVector3(0,-width * 0.5,0) * local_matrix; + LLVector3 position6 = LLVector3(0,-width * 0.5,height) * local_matrix; + LLVector3 position7 = LLVector3(0,+width * 0.5,height) * local_matrix; + LLVector3 position8 = LLVector3(0,+width * 0.5,0) * local_matrix; + + + LLVector3 normal = (position1-position2) % (position2-position3); + normal.normalize(); + + vertices.push_back(position1); + normals.push_back(normal); + vertices.push_back(position2); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position2); + normals.push_back(normal); + vertices.push_back(position3); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position3); + normals.push_back(normal); + vertices.push_back(position4); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position4); + normals.push_back(normal); + vertices.push_back(position1); + normals.push_back(normal); + segments.push_back(vertices.size()); + + normal = (position5-position6) % (position6-position7); + normal.normalize(); + + vertices.push_back(position5); + normals.push_back(normal); + vertices.push_back(position6); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position6); + normals.push_back(normal); + vertices.push_back(position7); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position7); + normals.push_back(normal); + vertices.push_back(position8); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position8); + normals.push_back(normal); + vertices.push_back(position5); + normals.push_back(normal); + segments.push_back(vertices.size()); + +} + + +void LLVOTree::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) +{ + LLVector3 position; + LLQuaternion rotation; + + if (mDrawable->isActive()) + { + if (mDrawable->isSpatialRoot()) + { + position = LLVector3(); + rotation = LLQuaternion(); + } + else + { + position = mDrawable->getPosition(); + rotation = mDrawable->getRotation(); + } + } + else + { + position = getPosition() + getRegion()->getOriginAgent();; + rotation = getRotation(); + } + + // trees have bizzare scaling rules... because it's cool to make needless exceptions + // PS: the trees are the last remaining tidbit of Philip's code. take a look sometime. + F32 radius = getScale().length() * 0.05f; + LLVector3 scale = LLVector3(1,1,1) * radius; + + // compose final matrix + LLMatrix4 local_matrix; + local_matrix.initAll(scale, rotation, position); + + + generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, + nodep->mSilhouetteSegments, + LLVector3(0,0,0), local_matrix, LLMatrix3()); + + nodep->mSilhouetteExists = TRUE; +} diff -r bda5610cbea6 indra/newview/llvotree.h --- a/indra/newview/llvotree.h Fri Jun 25 09:59:20 2010 -0500 +++ b/indra/newview/llvotree.h Mon Oct 25 10:51:14 2010 -0500 @@ -40,6 +40,7 @@ class LLFace; class LLDrawPool; class LLViewerFetchedTexture; +class LLSelectNode; class LLVOTree : public LLViewerObject { @@ -124,6 +125,9 @@ LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); + void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); + + static S32 sMaxTreeSpecies; struct TreeSpeciesData @@ -197,6 +201,15 @@ static S32 sLODVertexCount[4]; static S32 sLODSlices[4]; static F32 sLODAngles[4]; + +private: + void generateSilhouetteVertices(std::vector &vertices, + std::vector &normals, + std::vector &segments, + const LLVector3& view_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat); + }; #endif