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

Generated on Fri May 16 08:34:10 2008 for SecondLife by  doxygen 1.5.5