//-----------------------------------------------------------------------------
// 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);
				}
			}
		}
	}
}
Example #3
0
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);
		}
	}
}
Example #4
0
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);
}