//----------------------------------------------------------------------------- // calcTargetPosition() // returns whether we successfully calculated a finite target position. //----------------------------------------------------------------------------- bool LLHUDEffectPointAt::calcTargetPosition() { LLViewerObject *targetObject = (LLViewerObject *)mTargetObject; LLVector3 local_offset; if (targetObject) { local_offset.setVec(mTargetOffsetGlobal); } else { local_offset = gAgent.getPosAgentFromGlobal(mTargetOffsetGlobal); } if (targetObject && targetObject->mDrawable.notNull()) { LLQuaternion objRot; if (targetObject->isAvatar()) { LLVOAvatar *avatarp = (LLVOAvatar *)targetObject; mTargetPos = avatarp->mHeadp->getWorldPosition(); objRot = avatarp->mPelvisp->getWorldRotation(); } else { if (targetObject->mDrawable->getGeneration() == -1) { mTargetPos = targetObject->getPositionAgent(); objRot = targetObject->getWorldRotation(); } else { mTargetPos = targetObject->getRenderPosition(); objRot = targetObject->getRenderRotation(); } } mTargetPos += (local_offset * objRot); } else { mTargetPos = local_offset; } mTargetPos -= mSourceObject->getRenderPosition(); if (!llfinite(mTargetPos.lengthSquared())) { return false; } if (mSourceObject->isAvatar()) { LLVOAvatar* avatarp = ((LLVOAvatar*)(LLViewerObject*)mSourceObject); avatarp->setAnimationData("PointAtPoint", (void *)&mTargetPos); avatarp->mIdleTimer.reset(); } return true; }
void LLFloaterPathfindingObjects::draw() { LLFloater::draw(); if (isShowBeacons()) { std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected(); if (!selectedItems.empty()) { int numSelectedItems = selectedItems.size(); S32 nameColumnIndex = getNameColumnIndex(); const LLColor4 &beaconColor = getBeaconColor(); const LLColor4 &beaconTextColor = getBeaconTextColor(); S32 beaconWidth = getBeaconWidth(); std::vector<LLViewerObject *> viewerObjects; viewerObjects.reserve(numSelectedItems); for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin(); selectedItemIter != selectedItems.end(); ++selectedItemIter) { const LLScrollListItem *selectedItem = *selectedItemIter; LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); if (viewerObject != NULL) { const std::string &objectName = selectedItem->getColumn(nameColumnIndex)->getValue().asString(); gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, beaconColor, beaconTextColor, beaconWidth); } } } } }
void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) { if (gNoRender) { return; } if (objectp->isDead()) { llwarns << "Trying to find orphans for dead obj " << objectp->mID << ":" << objectp->getPCodeString() << llendl; return; } // See if we are a parent of an orphan. // Note: This code is fairly inefficient but it should happen very rarely. // It can be sped up if this is somehow a performance issue... if (0 == mOrphanParents.count()) { // no known orphan parents return; } if (-1 == mOrphanParents.find(getIndex(objectp->mLocalID, ip, port))) { // did not find objectp in OrphanParent list return; } S32 i; U64 parent_info = getIndex(objectp->mLocalID, ip, port); BOOL orphans_found = FALSE; // Iterate through the orphan list, and set parents of matching children. for (i = 0; i < mOrphanChildren.count(); i++) { if (mOrphanChildren[i].mParentInfo != parent_info) { continue; } LLViewerObject *childp = findObject(mOrphanChildren[i].mChildInfo); if (childp) { if (childp == objectp) { llwarns << objectp->mID << " has self as parent, skipping!" << llendl; continue; } #ifdef ORPHAN_SPAM llinfos << "Reunited parent " << objectp->mID << " with child " << childp->mID << llendl; llinfos << "Glob: " << objectp->getPositionGlobal() << llendl; llinfos << "Agent: " << objectp->getPositionAgent() << llendl; addDebugBeacon(objectp->getPositionAgent(),""); #endif gPipeline.markMoved(objectp->mDrawable); objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE); // Flag the object as no longer orphaned childp->mOrphaned = FALSE; if (childp->mDrawable.notNull()) { // Make the drawable visible again and set the drawable parent childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE); childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans() } // Make certain particles, icon and HUD aren't hidden childp->hideExtraDisplayItems( FALSE ); objectp->addChild(childp); orphans_found = TRUE; } else { llinfos << "Missing orphan child, removing from list" << llendl; mOrphanChildren.remove(i); i--; } } // Remove orphan parent and children from lists now that they've been found mOrphanParents.remove(mOrphanParents.find(parent_info)); i = 0; while (i < mOrphanChildren.count()) { if (mOrphanChildren[i].mParentInfo == parent_info) { mOrphanChildren.remove(i); mNumOrphans--; } else { i++; } } if (orphans_found && objectp->isSelected()) { LLSelectNode* nodep = gSelectMgr->getSelection()->findNode(objectp); if (nodep && !nodep->mIndividualSelection) { // rebuild selection with orphans gSelectMgr->deselectObjectAndFamily(objectp); gSelectMgr->selectObjectAndFamily(objectp); } } }
void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask) { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp || !hasMouseCapture() ) return; if (objectp->isDead()) { // Bail out of drag because object has been killed setMouseCapture(FALSE); return; } LLPickInfo pick = mGrabPick; pick.mMousePt = LLCoordGL(x, y); pick.getSurfaceInfo(); // compute elapsed time F32 dt = mGrabTimer.getElapsedTimeAndResetF32(); U32 dt_milliseconds = (U32) (1000.f * dt); // i'm not a big fan of the following code - it's been culled from the physical grab case. // ideally these two would be nicely integrated - but the code in that method is a serious // mess of spaghetti. so here we go: LLVector3 grab_pos_region(0,0,0); const BOOL SUPPORT_LLDETECTED_GRAB = TRUE; if (SUPPORT_LLDETECTED_GRAB) { //-------------------------------------------------- // Toggle vertical dragging //-------------------------------------------------- if (mVerticalDragging && !(mask == MASK_VERTICAL) && !gGrabBtnVertical) { mVerticalDragging = FALSE; } else if (!mVerticalDragging && (mask == MASK_VERTICAL) ) { mVerticalDragging = TRUE; } S32 dx = x - mLastMouseX; S32 dy = y - mLastMouseY; if (dx != 0 || dy != 0) { mAccumDeltaX += dx; mAccumDeltaY += dy; S32 dist_sq = mAccumDeltaX * mAccumDeltaX + mAccumDeltaY * mAccumDeltaY; if (dist_sq > SLOP_DIST_SQ) { mOutsideSlop = TRUE; } // mouse has moved mHasMoved = TRUE; //------------------------------------------------------ // Handle grabbing //------------------------------------------------------ LLVector3d x_part; x_part.setVec(LLViewerCamera::getInstance()->getLeftAxis()); x_part.mdV[VZ] = 0.0; x_part.normVec(); LLVector3d y_part; if( mVerticalDragging ) { y_part.setVec(LLViewerCamera::getInstance()->getUpAxis()); // y_part.setVec(0.f, 0.f, 1.f); } else { // drag toward camera y_part = x_part % LLVector3d::z_axis; y_part.mdV[VZ] = 0.0; y_part.normVec(); } mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera + (x_part * (-dx * GRAB_SENSITIVITY_X)) + (y_part * ( dy * GRAB_SENSITIVITY_Y)); } // need to return offset from mGrabStartPoint LLVector3d grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera; grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global ); } LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_ObjectGrabUpdate); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ObjectData); msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() ); msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial ); msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region ); msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds ); msg->nextBlock("SurfaceInfo"); msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); msg->addVector3("Position", pick.mIntersection); msg->addVector3("Normal", pick.mNormal); msg->addVector3("Binormal", pick.mBinormal); msg->sendMessage( objectp->getRegion()->getHost() ); // update point-at / look-at if (pick.mObjectFace != -1) // if the intersection was on the surface of the obejct { LLVector3 local_edit_point = pick.mIntersection; local_edit_point -= objectp->getPositionAgent(); local_edit_point = local_edit_point * ~objectp->getRenderRotation(); gAgent.setPointAt(POINTAT_TARGET_GRAB, objectp, local_edit_point ); gAgent.setLookAt(LOOKAT_TARGET_SELECT, objectp, local_edit_point ); } gViewerWindow->setCursor(UI_CURSOR_HAND); }
void QToolAlign::align() { // no linkset parts, please LLSelectMgr::getInstance()->promoteSelectionToRoot(); std::vector<LLPointer<LLViewerObject> > objects; std::map<LLPointer<LLViewerObject>, LLBBox > original_bboxes; // cycle over the nodes in selection and collect them into an array for (LLObjectSelection::root_iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); selection_iter != LLSelectMgr::getInstance()->getSelection()->root_end(); ++selection_iter) { LLSelectNode *select_node = *selection_iter; if (select_node) { LLViewerObject* object = select_node->getObject(); if (object) { LLVector3 position = object->getPositionAgent(); LLBBox bbox = LLBBox(position, LLQuaternion(), LLVector3(), LLVector3()); bbox.addPointLocal(LLVector3()); // add the parent's bbox bbox.addBBoxAgent(object->getBoundingBoxAgent()); LLViewerObject::const_child_list_t& children = object->getChildren(); for (LLViewerObject::const_child_list_t::const_iterator i = children.begin(); i != children.end(); i++) { // add the child's bbox LLViewerObject* child = *i; bbox.addBBoxAgent(child->getBoundingBoxAgent()); } objects.push_back(object); original_bboxes[object] = bbox; } } } S32 axis = mHighlightedAxis; F32 direction = mHighlightedDirection; // sort them into positional order for proper packing BBoxCompare compare(axis, direction, original_bboxes); sort(objects.begin(), objects.end(), compare); // storage for their new position after alignment - start with original position first std::map<LLPointer<LLViewerObject>, LLBBox > new_bboxes = original_bboxes; // find new positions for (U32 i = 0; i < objects.size(); i++) { LLBBox target_bbox = mBBox; LLVector3 target_corner = target_bbox.getCenterAgent() - direction * target_bbox.getExtentLocal() / 2.0; LLViewerObject* object = objects[i]; LLBBox this_bbox = original_bboxes[object]; LLVector3 this_corner = this_bbox.getCenterAgent() - direction * this_bbox.getExtentLocal() / 2.0; // for packing, we cycle over several possible positions, taking the smallest that does not overlap F32 smallest = direction * 9999999; // 999999 guarenteed not to be the smallest for (U32 j = 0; j <= i; j++) { // how far must it move? LLVector3 delta = target_corner - this_corner; // new position moves only on one axis, please LLVector3 delta_one_axis = LLVector3(0,0,0); delta_one_axis.mV[axis] = delta.mV[axis]; LLVector3 new_position = this_bbox.getCenterAgent() + delta_one_axis; // construct the new bbox LLBBox new_bbox = LLBBox(new_position, LLQuaternion(), LLVector3(), LLVector3()); new_bbox.addPointLocal(this_bbox.getExtentLocal() / 2.0); new_bbox.addPointLocal(-1.0 * this_bbox.getExtentLocal() / 2.0); // check to see if it overlaps the previously placed objects BOOL overlap = FALSE; llwarns << "i=" << i << " j=" << j << llendl; if (!mForce) // well, don't check if in force mode { for (U32 k = 0; k < i; k++) { LLViewerObject* other_object = objects[k]; LLBBox other_bbox = new_bboxes[other_object]; BOOL overlaps_this = bbox_overlap(other_bbox, new_bbox); if (overlaps_this) { llwarns << "overlap" << new_bbox.getCenterAgent() << other_bbox.getCenterAgent() << llendl; llwarns << "extent" << new_bbox.getExtentLocal() << other_bbox.getExtentLocal() << llendl; } overlap = (overlap || overlaps_this); } } if (!overlap) { F32 this_value = (new_bbox.getCenterAgent() - direction * new_bbox.getExtentLocal() / 2.0).mV[axis]; if (direction * this_value < direction * smallest) { smallest = this_value; // store it new_bboxes[object] = new_bbox; } } // update target for next time through the loop if (j < objects.size()) { LLBBox next_bbox = new_bboxes[objects[j]]; target_corner = next_bbox.getCenterAgent() + direction * next_bbox.getExtentLocal() / 2.0; } } } // now move them in (Unsigned not Signed in 2.0) for (U32 i = 0; i < objects.size(); i++) { LLViewerObject* object = objects[i]; LLBBox original_bbox = original_bboxes[object]; LLBBox new_bbox = new_bboxes[object]; LLVector3 delta = new_bbox.getCenterAgent() - original_bbox.getCenterAgent(); LLVector3 original_position = object->getPositionAgent(); LLVector3 new_position = original_position + delta; object->setPosition(new_position); } LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); }