From c84c7fa1386665190f9043344d4849fade9c03a1 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Fri, 5 Nov 2010 19:38:17 -0700 Subject: Applied patch by Qarl Fizz to allow drag selection on plants. See http://www.qarl.com/qLab/?p=67 --- linden/indra/newview/llglsandbox.cpp | 10 ++- linden/indra/newview/llselectmgr.cpp | 35 +++++++-- linden/indra/newview/llviewercamera.cpp | 4 +- linden/indra/newview/llvograss.cpp | 91 +++++++++++++++++++++++ linden/indra/newview/llvograss.h | 9 +++ linden/indra/newview/llvotree.cpp | 125 ++++++++++++++++++++++++++++++++ linden/indra/newview/llvotree.h | 14 +++- 7 files changed, 279 insertions(+), 9 deletions(-) diff --git a/linden/indra/newview/llglsandbox.cpp b/linden/indra/newview/llglsandbox.cpp index a487150..98c4d06 100644 --- a/linden/indra/newview/llglsandbox.cpp +++ b/linden/indra/newview/llglsandbox.cpp @@ -275,7 +275,11 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) 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; } @@ -326,7 +330,9 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) 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 --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index 0d53e82..b0a6834 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -85,6 +85,8 @@ #include "llviewerregion.h" #include "llviewerstats.h" #include "llvoavatar.h" +#include "llvograss.h" +#include "llvotree.h" #include "llvovolume.h" #include "pipeline.h" @@ -832,7 +834,10 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) 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; } @@ -880,7 +885,10 @@ void LLSelectMgr::highlightObjectAndFamily(const std::vector& o { 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; } @@ -900,7 +908,14 @@ void LLSelectMgr::highlightObjectAndFamily(const std::vector& o 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; } @@ -5020,6 +5035,14 @@ void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_ { ((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); + } } // @@ -5355,8 +5378,10 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix); } - LLVolume *volume = objectp->getVolume(); - if (volume) + //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 (is_hud_object && gAgent.getAvatarObject()) diff --git a/linden/indra/newview/llviewercamera.cpp b/linden/indra/newview/llviewercamera.cpp index dade65f..16f6e57 100644 --- a/linden/indra/newview/llviewercamera.cpp +++ b/linden/indra/newview/llviewercamera.cpp @@ -743,7 +743,9 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) LLVolume* volume = volumep->getVolume(); if (!volume) { - return FALSE; + BOOL inside = pointInFrustum(volumep->getRenderPosition()); + + return (inside > 0); } LLVOVolume* vo_volume = (LLVOVolume*) volumep; diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index f738872..913ec33 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -48,6 +48,7 @@ #include "llviewercamera.h" #include "llviewerimagelist.h" #include "llviewerregion.h" +#include "llselectmgr.h" #include "pipeline.h" #include "llspatialpartition.h" #include "llworld.h" @@ -721,3 +722,93 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en 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 --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index 25fa04c..c76ab93 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -37,6 +37,7 @@ #include "lldarray.h" #include +class LLSelectNode; class LLSurfacePatch; class LLViewerImage; @@ -76,6 +77,8 @@ public: /*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. @@ -125,6 +128,12 @@ protected: ~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 --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index 6a59253..8c6abdc 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -47,6 +47,7 @@ #include "llagent.h" #include "lldrawable.h" #include "llface.h" +#include "llselectmgr.h" #include "llviewercamera.h" #include "llviewerimagelist.h" #include "llviewerobjectlist.h" @@ -1327,3 +1328,127 @@ LLTreePartition::LLTreePartition() 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 --git a/linden/indra/newview/llvotree.h b/linden/indra/newview/llvotree.h index 855c612..57116cc 100644 --- a/linden/indra/newview/llvotree.h +++ b/linden/indra/newview/llvotree.h @@ -39,7 +39,7 @@ class LLFace; class LLDrawPool; - +class LLSelectNode; class LLVOTree : public LLViewerObject { @@ -124,6 +124,9 @@ public: 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 @@ -200,6 +203,15 @@ protected: 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 -- cgit v1.1