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
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
00071
00072 LLViewerJointAttachment::~LLViewerJointAttachment()
00073 {
00074 }
00075
00076
00077
00078
00079 BOOL LLViewerJointAttachment::isTransparent()
00080 {
00081 return FALSE;
00082 }
00083
00084
00085
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
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);
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);
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);
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
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
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
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
00233
00234 void LLViewerJointAttachment::removeObject(LLViewerObject *object)
00235 {
00236
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);
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);
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
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
00311
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
00323
00324 void LLViewerJointAttachment::setOriginalPosition(LLVector3& position)
00325 {
00326 mOriginalPos = position;
00327 setPosition(position);
00328 }
00329
00330
00331
00332
00333 void LLViewerJointAttachment::clampObjectPosition()
00334 {
00335 if (mAttachedObject)
00336 {
00337
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
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);
00361 F32 min_pixel_area = avatar_area / maxarea;
00362 setLOD(min_pixel_area);
00363 }
00364
00365
00366
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