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
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
00072
00073 LLViewerJointAttachment::~LLViewerJointAttachment()
00074 {
00075 }
00076
00077
00078
00079
00080 BOOL LLViewerJointAttachment::isTransparent()
00081 {
00082 return FALSE;
00083 }
00084
00085
00086
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);
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);
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);
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
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
00165
00166 }
00167 else {
00168 llinfos << "(objects differ, removing existing object)" << llendl;
00169
00170
00171 gObjectList.killObject(mAttachedObject);
00172
00173 }
00174 }
00175 mAttachedObject = object;
00176
00177 LLUUID item_id;
00178
00179
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
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
00230
00231 void LLViewerJointAttachment::removeObject(LLViewerObject *object)
00232 {
00233
00234 setAttachmentVisibility(TRUE);
00235
00236 if (object->mDrawable.notNull())
00237 {
00238
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);
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);
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
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
00314
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
00326
00327 void LLViewerJointAttachment::setOriginalPosition(LLVector3& position)
00328 {
00329 mOriginalPos = position;
00330 setPosition(position);
00331 }
00332
00333
00334
00335
00336 void LLViewerJointAttachment::clampObjectPosition()
00337 {
00338 if (mAttachedObject)
00339 {
00340
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
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);
00364 F32 min_pixel_area = avatar_area / maxarea;
00365 setLOD(min_pixel_area);
00366 }
00367
00368
00369
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