llviewerjointattachment.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llviewerjointattachment.h"
00035 
00036 #include "llagentconstants.h"
00037 
00038 #include "llviewercontrol.h"
00039 #include "lldrawable.h"
00040 #include "llgl.h"
00041 #include "llvoavatar.h"
00042 #include "llvolume.h"
00043 #include "pipeline.h"
00044 #include "llinventorymodel.h"
00045 #include "llviewerobjectlist.h"
00046 #include "llface.h"
00047 #include "llvoavatar.h"
00048 
00049 #include "llglheaders.h"
00050 
00051 extern LLPipeline gPipeline;
00052 
00053 //-----------------------------------------------------------------------------
00054 // LLViewerJointAttachment()
00055 //-----------------------------------------------------------------------------
00056 LLViewerJointAttachment::LLViewerJointAttachment() :
00057 mJoint(NULL),
00058 mAttachedObject(NULL),
00059 mAttachmentDirty(FALSE),
00060 mVisibleInFirst(FALSE),
00061 mGroup(0),
00062 mIsHUDAttachment(FALSE),
00063 mPieSlice(-1)
00064 {
00065         mValid = FALSE;
00066         mUpdateXform = FALSE;
00067 }
00068 
00069 //-----------------------------------------------------------------------------
00070 // ~LLViewerJointAttachment()
00071 //-----------------------------------------------------------------------------
00072 LLViewerJointAttachment::~LLViewerJointAttachment()
00073 {
00074 }
00075 
00076 //-----------------------------------------------------------------------------
00077 // isTransparent()
00078 //-----------------------------------------------------------------------------
00079 BOOL LLViewerJointAttachment::isTransparent()
00080 {
00081         return FALSE;
00082 }
00083 
00084 //-----------------------------------------------------------------------------
00085 // drawShape()
00086 //-----------------------------------------------------------------------------
00087 U32 LLViewerJointAttachment::drawShape( F32 pixelArea, BOOL first_pass )
00088 {
00089         if (LLVOAvatar::sShowAttachmentPoints)
00090         {
00091                 LLGLDisable cull_face(GL_CULL_FACE);
00092                 
00093                 glColor4f(1.f, 1.f, 1.f, 1.f);
00094                 glBegin(GL_QUADS);
00095                 {
00096                         glVertex3f(-0.1f, 0.1f, 0.f);
00097                         glVertex3f(-0.1f, -0.1f, 0.f);
00098                         glVertex3f(0.1f, -0.1f, 0.f);
00099                         glVertex3f(0.1f, 0.1f, 0.f);
00100                 }glEnd();
00101         }
00102         return 0;
00103 }
00104 
00105 //-----------------------------------------------------------------------------
00106 // lazyAttach()
00107 //-----------------------------------------------------------------------------
00108 void LLViewerJointAttachment::lazyAttach()
00109 {
00110         if (!mAttachedObject)
00111         {
00112                 return;
00113         }
00114         LLDrawable *drawablep = mAttachedObject->mDrawable;
00115 
00116         if (mAttachmentDirty && drawablep)
00117         {
00118                 setupDrawable(drawablep);
00119                 mAttachmentDirty = FALSE;
00120         }
00121 }
00122 
00123 void LLViewerJointAttachment::setupDrawable(LLDrawable* drawablep)
00124 {
00125         drawablep->mXform.setParent(&mXform); // LLViewerJointAttachment::lazyAttach
00126         drawablep->makeActive();
00127         LLVector3 current_pos = mAttachedObject->getRenderPosition();
00128         LLQuaternion current_rot = mAttachedObject->getRenderRotation();
00129         LLQuaternion attachment_pt_inv_rot = ~getWorldRotation();
00130 
00131         current_pos -= getWorldPosition();
00132         current_pos.rotVec(attachment_pt_inv_rot);
00133 
00134         current_rot = current_rot * attachment_pt_inv_rot;
00135 
00136         drawablep->mXform.setPosition(current_pos);
00137         drawablep->mXform.setRotation(current_rot);
00138         gPipeline.markMoved(drawablep);
00139         gPipeline.markTextured(drawablep); // face may need to change draw pool to/from POOL_HUD
00140         drawablep->setState(LLDrawable::USE_BACKLIGHT);
00141         
00142         if(mIsHUDAttachment)
00143         {
00144                 for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
00145                 {
00146                         drawablep->getFace(face_num)->setState(LLFace::HUD_RENDER);
00147                 }
00148         }
00149 
00150         for (LLViewerObject::child_list_t::iterator iter = mAttachedObject->mChildList.begin();
00151                  iter != mAttachedObject->mChildList.end(); ++iter)
00152         {
00153                 LLViewerObject* childp = *iter;
00154                 if (childp && childp->mDrawable.notNull())
00155                 {
00156                         childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
00157                         gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
00158                         if(mIsHUDAttachment)
00159                         {
00160                                 for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
00161                                 {
00162                                         childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
00163                                 }
00164                         }
00165                 }
00166         }
00167 }
00168 
00169 //-----------------------------------------------------------------------------
00170 // addObject()
00171 //-----------------------------------------------------------------------------
00172 BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
00173 {
00174         if (mAttachedObject)
00175         {
00176                 llwarns << "Attempted to attach object where an attachment already exists!" << llendl;
00177                 return FALSE;
00178         }
00179         mAttachedObject = object;
00180         
00181         LLUUID item_id;
00182 
00183         // Find the inventory item ID of the attached object
00184         LLNameValue* item_id_nv = object->getNVPair("AttachItemID");
00185         if( item_id_nv )
00186         {
00187                 const char* s = item_id_nv->getString();
00188                 if( s )
00189                 {
00190                         item_id.set( s );
00191                         lldebugs << "getNVPair( AttachItemID ) = " << item_id << llendl;
00192                 }
00193         }
00194 
00195         mItemID = item_id;
00196 
00197         LLDrawable* drawablep = object->mDrawable;
00198 
00199         if (drawablep)
00200         {
00201                 setupDrawable(drawablep);
00202         }
00203         else
00204         {
00205                 // do lazy update once we have a drawable for this object
00206                 mAttachmentDirty = TRUE;
00207         }
00208 
00209         if (mIsHUDAttachment)
00210         {
00211                 if (object->mText.notNull())
00212                 {
00213                         object->mText->setOnHUDAttachment(TRUE);
00214                 }
00215                 for (LLViewerObject::child_list_t::iterator iter = object->mChildList.begin();
00216                         iter != object->mChildList.end(); ++iter)
00217                 {
00218                         LLViewerObject* childp = *iter;
00219                         if (childp && childp->mText.notNull())
00220                         {
00221                                 childp->mText->setOnHUDAttachment(TRUE);
00222                         }
00223                 }
00224         }
00225         calcLOD();
00226         mUpdateXform = TRUE;
00227 
00228         return TRUE;
00229 }
00230 
00231 //-----------------------------------------------------------------------------
00232 // removeObject()
00233 //-----------------------------------------------------------------------------
00234 void LLViewerJointAttachment::removeObject(LLViewerObject *object)
00235 {
00236         // force object visibile
00237         setAttachmentVisibility(TRUE);
00238 
00239         if (object->mDrawable.notNull())
00240         {
00241                 LLVector3 cur_position = object->getRenderPosition();
00242                 LLQuaternion cur_rotation = object->getRenderRotation();
00243 
00244                 object->mDrawable->mXform.setPosition(cur_position);
00245                 object->mDrawable->mXform.setRotation(cur_rotation);
00246                 gPipeline.markMoved(object->mDrawable, TRUE);
00247                 gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
00248                 object->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
00249 
00250                 if (mIsHUDAttachment)
00251                 {
00252                         for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
00253                         {
00254                                 object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
00255                         }
00256                 }
00257         }
00258 
00259         for (LLViewerObject::child_list_t::iterator iter = object->mChildList.begin();
00260                  iter != object->mChildList.end(); ++iter)
00261         {
00262                 LLViewerObject* childp = *iter;
00263                 if (childp && childp->mDrawable.notNull())
00264                 {
00265                         childp->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
00266                         gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
00267                         if (mIsHUDAttachment)
00268                         {
00269                                 for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
00270                                 {
00271                                         childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
00272                                 }
00273                         }
00274                 }
00275         } 
00276 
00277         if (mIsHUDAttachment)
00278         {
00279                 if (object->mText.notNull())
00280                 {
00281                         object->mText->setOnHUDAttachment(FALSE);
00282                 }
00283                 for (LLViewerObject::child_list_t::iterator iter = object->mChildList.begin();
00284                         iter != object->mChildList.end(); ++iter)
00285                 {
00286                         LLViewerObject* childp = *iter;
00287                         if (childp->mText.notNull())
00288                         {
00289                                 childp->mText->setOnHUDAttachment(FALSE);
00290                         }
00291                 }
00292         }
00293 
00294         mAttachedObject = NULL;
00295         mUpdateXform = FALSE;
00296         mItemID.setNull();
00297 }
00298 
00299 //-----------------------------------------------------------------------------
00300 // setAttachmentVisibility()
00301 //-----------------------------------------------------------------------------
00302 void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible)
00303 {
00304         if (!mAttachedObject || mAttachedObject->mDrawable.isNull() || 
00305                 !(mAttachedObject->mDrawable->getSpatialBridge()))
00306                 return;
00307 
00308         if (visible)
00309         {
00310                 // Hack to make attachments not visible by disabling their type mask!
00311                 // This will break if you can ever attach non-volumes! - djs 02/14/03
00312                 mAttachedObject->mDrawable->getSpatialBridge()->mDrawableType = 
00313                         mAttachedObject->isHUDAttachment() ? LLPipeline::RENDER_TYPE_HUD : LLPipeline::RENDER_TYPE_VOLUME;
00314         }
00315         else
00316         {
00317                 mAttachedObject->mDrawable->getSpatialBridge()->mDrawableType = 0;
00318         }
00319 }
00320 
00321 //-----------------------------------------------------------------------------
00322 // setOriginalPosition()
00323 //-----------------------------------------------------------------------------
00324 void LLViewerJointAttachment::setOriginalPosition(LLVector3& position)
00325 {
00326         mOriginalPos = position;
00327         setPosition(position);
00328 }
00329 
00330 //-----------------------------------------------------------------------------
00331 // clampObjectPosition()
00332 //-----------------------------------------------------------------------------
00333 void LLViewerJointAttachment::clampObjectPosition()
00334 {
00335         if (mAttachedObject)
00336         {
00337                 // *NOTE: object can drift when hitting maximum radius
00338                 LLVector3 attachmentPos = mAttachedObject->getPosition();
00339                 F32 dist = attachmentPos.normVec();
00340                 dist = llmin(dist, MAX_ATTACHMENT_DIST);
00341                 attachmentPos *= dist;
00342                 mAttachedObject->setPosition(attachmentPos);
00343         }
00344 }
00345 
00346 //-----------------------------------------------------------------------------
00347 // calcLOD()
00348 //-----------------------------------------------------------------------------
00349 void LLViewerJointAttachment::calcLOD()
00350 {
00351         F32 maxarea = mAttachedObject->getMaxScale() * mAttachedObject->getMidScale();
00352         for (LLViewerObject::child_list_t::iterator iter = mAttachedObject->mChildList.begin();
00353                  iter != mAttachedObject->mChildList.end(); ++iter)
00354         {
00355                 LLViewerObject* childp = *iter;
00356                 F32 area = childp->getMaxScale() * childp->getMidScale();
00357                 maxarea = llmax(maxarea, area);
00358         }
00359         maxarea = llclamp(maxarea, .01f*.01f, 1.f);
00360         F32 avatar_area = (4.f * 4.f); // pixels for an avatar sized attachment
00361         F32 min_pixel_area = avatar_area / maxarea;
00362         setLOD(min_pixel_area);
00363 }
00364 
00365 //-----------------------------------------------------------------------------
00366 // updateLOD()
00367 //-----------------------------------------------------------------------------
00368 BOOL LLViewerJointAttachment::updateLOD(F32 pixel_area, BOOL activate)
00369 {
00370         BOOL res = FALSE;
00371         if (!mValid)
00372         {
00373                 setValid(TRUE, TRUE);
00374                 res = TRUE;
00375         }
00376         return res;
00377 }
00378 

Generated on Thu Jul 1 06:09:28 2010 for Second Life Viewer by  doxygen 1.4.7