Ejemplo n.º 1
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);
		}
	}
}