Exemple #1
0
void LLSpatialBridge::cleanupReferences()
{	
	LLDrawable::cleanupReferences();
	if (mDrawable)
	{
		/*
		
		DON'T DO THIS -- this should happen through octree destruction

		mDrawable->setSpatialGroup(NULL);
		if (mDrawable->getVObj())
		{
			LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
			for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
				 iter != child_list.end(); iter++)
			{
				LLViewerObject* child = *iter;
				LLDrawable* drawable = child->mDrawable;					
				if (drawable)
				{
					drawable->setSpatialGroup(NULL);
				}
			}
		}*/

		LLDrawable* drawablep = mDrawable;
		mDrawable = NULL;
		drawablep->setSpatialBridge(NULL);
	}
}
			virtual bool apply(LLViewerObject* vobjp)
			{
				LLDrawable* drawable = vobjp->mDrawable;
				if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
				{
					return true;
				}
				S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
				switch (result)
				{
				  case 0:
					LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					break;
				  case 1:
					// check vertices
					if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					}
					break;
				  default:
					break;
				}
				return true;
			}
Exemple #3
0
void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
{
	if (mDrawable == NULL)
	{
		markDead();
		return;
	}

	LLCamera camera = transformCamera(camera_in);
	
	mDrawable->updateDistance(camera, force_update);
	
	if (mDrawable->getVObj())
	{
		LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
			 iter != child_list.end(); iter++)
		{
			LLViewerObject* child = *iter;
			LLDrawable* drawable = child->mDrawable;					
			if (!drawable)
			{
				continue;
			}

			if (!drawable->isAvatar())
			{
				drawable->updateDistance(camera, force_update);
			}
		}
	}
}
Exemple #4
0
void LLSpatialBridge::updateDistance(LLCamera& camera_in)
{
	if (mDrawable == NULL)
	{
		markDead();
		return;
	}

	LLCamera camera = transformCamera(camera_in);
	
	mDrawable->updateDistance(camera);
	
	if (mDrawable->getVObj())
	{
		LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
			 iter != child_list.end(); iter++)
		{
			LLViewerObject* child = *iter;
			LLDrawable* drawable = child->mDrawable;					
			if (!drawable)
			{
				llwarns << "Corrupt drawable found while updating spatial bridge distance." << llendl;
				continue;
			}

			if (!drawable->isAvatar())
			{
				drawable->updateDistance(camera);
			}
		}
	}
}
void LLSpatialBridge::cleanupReferences()
{	
	LLDrawable::cleanupReferences();
	if (mDrawable)
	{
		mDrawable->setSpatialGroup(NULL);
		if (mDrawable->getVObj())
		{
			LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
			for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
				 iter != child_list.end(); iter++)
			{
				LLViewerObject* child = *iter;
				LLDrawable* drawable = child->mDrawable;					
				if (drawable)
				{
					drawable->setSpatialGroup(NULL);
				}
			}
		}

		LLDrawable* drawablep = mDrawable;
		mDrawable = NULL;
		drawablep->setSpatialBridge(NULL);
	}
}
Exemple #6
0
void LLDrawable::makeActive()
{		
#if !LL_RELEASE_FOR_DOWNLOAD
	if (mVObjp.notNull())
	{
		U32 pcode = mVObjp->getPCode();
		if (pcode == LLViewerObject::LL_VO_WATER ||
			pcode == LLViewerObject::LL_VO_VOID_WATER ||
			pcode == LLViewerObject::LL_VO_SURFACE_PATCH ||
			pcode == LLViewerObject::LL_VO_PART_GROUP ||
			pcode == LLViewerObject::LL_VO_HUD_PART_GROUP ||
#if ENABLE_CLASSIC_CLOUDS
			pcode == LLViewerObject::LL_VO_CLOUDS ||
#endif
			pcode == LLViewerObject::LL_VO_GROUND ||
			pcode == LLViewerObject::LL_VO_SKY)
		{
			LL_ERRS() << "Static viewer object has active drawable!" << LL_ENDL;
		}
	}
#endif

	if (!isState(ACTIVE)) // && mGeneration > 0)
	{
		setState(ACTIVE);
		
		//parent must be made active first
		if (!isRoot() && !mParent->isActive())
		{
			mParent->makeActive();
			//NOTE: linked set will now NEVER become static
			mParent->setState(LLDrawable::ACTIVE_CHILD);
		}

		//all child objects must also be active
		llassert_always(mVObjp);
		
		LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
			 iter != child_list.end(); iter++)
		{
			LLViewerObject* child = *iter;
			LLDrawable* drawable = child->mDrawable;
			if (drawable)
			{
				drawable->makeActive();
			}
		}

		if (mVObjp->getPCode() == LL_PCODE_VOLUME)
		{
			gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
		}
		updatePartition();
	}

	llassert(isAvatar() || isRoot() || mParent->isActive());
}
Exemple #7
0
void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
{
	if (mDrawable == NULL)
	{
		markDead();
		return;
	}

	if (gShiftFrame)
	{
		return;
	}

	if (mDrawable->getVObj())
	{
		if (mDrawable->getVObj()->isAttachment())
		{
			LLDrawable* parent = mDrawable->getParent();
			if (parent)
			{
				LLViewerObject *obj = parent->getVObj();
				if (obj && obj->isAvatar() && ((LLVOAvatar*)obj)->isImpostor())
				{
					return;
				}
			}
			else
			{
				static const LLCachedControl<bool> draw_orphans("ShyotlDrawOrphanAttachments",false);
				if(!draw_orphans)
					return;
			}
		}

		LLCamera camera = transformCamera(camera_in);
	
		mDrawable->updateDistance(camera, force_update);
	
		LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
			 iter != child_list.end(); iter++)
		{
			LLViewerObject* child = *iter;
			LLDrawable* drawable = child->mDrawable;					
			if (!drawable)
			{
				continue;
			}

			if (!drawable->isAvatar())
			{
				drawable->updateDistance(camera, force_update);
			}
		}
	}
}
Exemple #8
0
BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
{
	S32 i, num_faces;
	LLDrawable* drawablep = volumep->mDrawable;

	if (!drawablep)
	{
		return FALSE;
	}

	LLVolume* volume = volumep->getVolume();
	if (!volume)
	{
		return FALSE;
	}

	LLVOVolume* vo_volume = (LLVOVolume*) volumep;

	vo_volume->updateRelativeXform();
	LLMatrix4 mat = vo_volume->getRelativeXform();
	
	LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition()));

	LLMatrix4a render_mata;
	render_mata.loadu(render_mat);
	LLMatrix4a mata;
	mata.loadu(mat);

	num_faces = volume->getNumVolumeFaces();
	for (i = 0; i < num_faces; i++)
	{
		const LLVolumeFace& face = volume->getVolumeFace(i);
				
		for (U32 v = 0; v < face.mNumVertices; v++)
		{
			const LLVector4a& src_vec = face.mPositions[v];
			LLVector4a vec;
			mata.affineTransform(src_vec, vec);

			if (drawablep->isActive())
			{
				LLVector4a t = vec;
				render_mata.affineTransform(t, vec);
			}

			BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32ptr())) > 0;

			if (( !in_frustum && all_verts) ||
				 (in_frustum && !all_verts))
			{
				return !all_verts;
			}
		}
	}
	return all_verts;
}
void LLDrawPoolTree::renderForSelect()
{
	if (mDrawFace.empty())
	{
		return;
	}

	LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);

	LLGLSObjectSelectAlpha gls_alpha;
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

	gGL.setSceneBlendType(LLRender::BT_REPLACE);
	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);

	gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
	gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);

	if (gSavedSettings.getBOOL("RenderAnimateTrees"))
	{
		renderTree(TRUE);
	}
	else
	{
		gGL.getTexUnit(sDiffTex)->bind(mTexturep);
				
		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
		{
			LLFace *face = *iter;
			LLDrawable *drawablep = face->getDrawable();

			if (drawablep->isDead() || face->mVertexBuffer.isNull())
			{
				continue;
			}

			// Render each of the trees
			LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get();

			LLColor4U color(255,255,255,255);

			if (treep->mGLName != 0)
			{
				S32 name = treep->mGLName;
				color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255);
				
				LLFacePool::LLOverrideFaceColor col(this, color);
				
				face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
				face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); 
				gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()/3);
			}
		}
	}
Exemple #10
0
void LLDrawPoolTerrain::renderOwnership()
{
	LLGLSPipelineAlpha gls_pipeline_alpha;

	llassert(!mDrawFace.empty());

	// Each terrain pool is associated with a single region.
	// We need to peek back into the viewer's data to find out
	// which ownership overlay texture to use.
	LLFace					*facep				= mDrawFace[0];
	LLDrawable				*drawablep			= facep->getDrawable();
	const LLViewerObject	*objectp				= drawablep->getVObj();
	const LLVOSurfacePatch	*vo_surface_patchp	= (LLVOSurfacePatch *)objectp;
	LLSurfacePatch			*surface_patchp		= vo_surface_patchp->getPatch();
	LLSurface				*surfacep			= surface_patchp->getSurface();
	LLViewerRegion			*regionp			= surfacep->getRegion();
	LLViewerParcelOverlay	*overlayp			= regionp->getParcelOverlay();
	LLImageGL				*texturep			= overlayp->getTexture();

	glEnableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);

	LLViewerImage::bindTexture(texturep);

	glClientActiveTextureARB(GL_TEXTURE0_ARB);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	// *NOTE: Because the region is 256 meters wide, but has 257 pixels, the 
	// texture coordinates for pixel 256x256 is not 1,1. This makes the
	// ownership map not line up with the selection. We address this with
	// a texture matrix multiply.
	glMatrixMode(GL_TEXTURE);
	glPushMatrix();

	const F32 TEXTURE_FUDGE = 257.f / 256.f;
	glScalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f );

	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
		 iter != mDrawFace.end(); iter++)
	{
		LLFace *facep = *iter;
		facep->renderIndexed(LLVertexBuffer::MAP_VERTEX |
							LLVertexBuffer::MAP_TEXCOORD);
	}

	glMatrixMode(GL_TEXTURE);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);

	// Restore non Texture Unit specific defaults
	glDisableClientState(GL_NORMAL_ARRAY);
}
void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
{
	LLFastTimer t(FTM_RIGGED_VBO);

	//update rigged vertex buffers
	for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type)
	{
		for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
		{
			LLFace* face = mRiggedFace[type][i];
			LLDrawable* drawable = face->getDrawable();
			if (!drawable)
			{
				continue;
			}

			LLVOVolume* vobj = drawable->getVOVolume();

			if (!vobj)
			{
				continue;
			}

			LLVolume* volume = vobj->getVolume();
			S32 te = face->getTEOffset();

			if (!volume || volume->getNumVolumeFaces() <= te)
			{
				continue;
			}

			LLUUID mesh_id = volume->getParams().getSculptID();
			if (mesh_id.isNull())
			{
				continue;
			}

			const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj);
			if (!skin)
			{
				continue;
			}

			stop_glerror();

			const LLVolumeFace& vol_face = volume->getVolumeFace(te);
			updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
		}
	}
}
Exemple #12
0
BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
{
    S32 i, num_faces;
    LLDrawable* drawablep = volumep->mDrawable;

    if (!drawablep)
    {
        return FALSE;
    }

    LLVolume* volume = volumep->getVolume();
    if (!volume)
    {
        BOOL inside = pointInFrustum(volumep->getRenderPosition());

        return (inside > 0);
    }

    LLVOVolume* vo_volume = (LLVOVolume*) volumep;

    vo_volume->updateRelativeXform();
    LLMatrix4 mat = vo_volume->getRelativeXform();

    LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition()));

    num_faces = volume->getNumVolumeFaces();
    for (i = 0; i < num_faces; i++)
    {
        const LLVolumeFace& face = volume->getVolumeFace(i);

        for (U32 v = 0; v < face.mVertices.size(); v++)
        {
            LLVector4 vec = LLVector4(face.mVertices[v].mPosition) * mat;

            if (drawablep->isActive())
            {
                vec = vec * render_mat;
            }

            BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0;

            if (( !in_frustum && all_verts) ||
                    (in_frustum && !all_verts))
            {
                return !all_verts;
            }
        }
    }
    return all_verts;
}
Exemple #13
0
//static
void LLManip::rebuild(LLViewerObject* vobj)
{
	LLDrawable* drawablep = vobj->mDrawable;
	if (drawablep && drawablep->getVOVolume())
	{
		
		gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE);
		drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
		drawablep->updateMove();
		LLSpatialGroup* group = drawablep->getSpatialGroup();
		if (group)
		{
			group->dirtyGeom();
		}
	}
}
//static
void LLManip::rebuild(LLViewerObject* vobj)
{
	LLDrawable* drawablep = vobj->mDrawable;
	if (drawablep && drawablep->getVOVolume())
	{
		gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE);
		drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
		drawablep->updateMove();
		LLSpatialGroup* group = drawablep->getSpatialGroup();
		if (group)
		{
			group->dirtyGeom();
			gPipeline.markRebuild(group, TRUE);
		}

		LLViewerObject::const_child_list_t& child_list = vobj->getChildren();
		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end();
			 iter != endIter; ++iter)
		{
			LLViewerObject* child = *iter;
			rebuild(child);
		}
	}
}
void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
{
	group->mBufferUsage = mBufferUsage;

	mFaceList.clear();

	LLViewerCamera* camera = LLViewerCamera::getInstance();
	for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
	{
		LLDrawable* drawablep = *i;
		
		if (drawablep->isDead())
		{
			continue;
		}

		LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
		obj->mDepth = 0.f;
		
		if (drawablep->isAnimating())
		{
			group->mBufferUsage = GL_STREAM_DRAW_ARB;
		}

		U32 count = 0;
		for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
		{
			drawablep->updateFaceSize(j);

			LLFace* facep = drawablep->getFace(j);
			if ( !facep || !facep->hasGeometry())
			{
				continue;
			}
			
			count++;
			facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
			obj->mDepth += facep->mDistance;
			
			mFaceList.push_back(facep);
			vertex_count += facep->getGeomCount();
			index_count += facep->getIndicesCount();
			llassert(facep->getIndicesCount() < 65536);
		}
		
		obj->mDepth /= count;
	}
}
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
{
	LLVector4a* weight = vol_face.mWeights;
	if (!weight)
	{
		return;
	}

	LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
	LLDrawable* drawable = face->getDrawable();

	U32 data_mask = face->getRiggedVertexBufferDataMask();
	
	if (buffer.isNull() || 
		buffer->getTypeMask() != data_mask ||
		buffer->getNumVerts() != vol_face.mNumVertices ||
		buffer->getNumIndices() != vol_face.mNumIndices ||
		(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
	{
		if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
		{ //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
			for (S32 i = 0; i < drawable->getNumFaces(); ++i)
			{
				LLFace* facep = drawable->getFace(i);
				U32 face_data_mask = facep->getRiggedVertexBufferDataMask();
				if (face_data_mask)
				{
					LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer();
					const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i);
					getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face);
				}
			}
			drawable->clearState(LLDrawable::REBUILD_ALL);

			buffer = face->getVertexBuffer();
		}
		else
		{ //just rebuild this face
			getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
		}
	}

	if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
	{
		avatar->updateSoftwareSkinnedVertices(skin, weight, vol_face, buffer);
	}
}
Exemple #17
0
void LLVOClouds::getGeometry(S32 te, 
							LLStrider<LLVector3>& verticesp, 
							LLStrider<LLVector3>& normalsp, 
							LLStrider<LLVector2>& texcoordsp, 
							LLStrider<LLColor4U>& colorsp, 
							LLStrider<U16>& indicesp)
{

	if (te >= mCloudGroupp->getNumPuffs())
	{
		return;
	}

	LLDrawable* drawable = mDrawable;
	LLFace *facep = drawable->getFace(te);

	if (!facep->hasGeometry())
	{
		return;
	}
	
	LLVector3 normal(0.f,0.f,-1.f);

	const LLCloudPuff &puff = mCloudGroupp->getPuff(te);
	S32 index_offset = facep->getGeomIndex();
	LLColor4 float_color(LLColor3(gSky.getSunDiffuseColor() + gSky.getSunAmbientColor()),puff.getAlpha());
	LLColor4U color;
	color.setVec(float_color);
	facep->setFaceColor(float_color);
		
	
	LLVector3 up;
	LLVector3 right;
	LLVector3 at;

	const LLVector3& puff_pos_agent = facep->mCenterLocal;
	LLVector2 uvs[4];

	uvs[0].setVec(0.f, 1.f);
	uvs[1].setVec(0.f, 0.f);
	uvs[2].setVec(1.f, 1.f);
	uvs[3].setVec(1.f, 0.f);

	LLVector3 vtx[4];

	at = LLViewerCamera::getInstance()->getAtAxis();
	right = at % LLVector3(0.f, 0.f, 1.f);
	right.normVec();
	up = right % at;
	up.normVec();
	right *= 0.5f*CLOUD_PUFF_WIDTH;
	up *= 0.5f*CLOUD_PUFF_HEIGHT;;
		
	*colorsp++ = color;
	*colorsp++ = color;
	*colorsp++ = color;
	*colorsp++ = color;

	vtx[0] = puff_pos_agent - right + up;
	vtx[1] = puff_pos_agent - right - up;
	vtx[2] = puff_pos_agent + right + up;
	vtx[3] = puff_pos_agent + right - up;

	verticesp->mV[3] = 0.f;
	*verticesp++  = vtx[0];
	verticesp->mV[3] = 0.f;
	*verticesp++  = vtx[1];
	verticesp->mV[3] = 0.f;
	*verticesp++  = vtx[2];
	verticesp->mV[3] = 0.f;
	*verticesp++  = vtx[3];

	*texcoordsp++ = uvs[0];
	*texcoordsp++ = uvs[1];
	*texcoordsp++ = uvs[2];
	*texcoordsp++ = uvs[3];

	*normalsp++   = normal;
	*normalsp++   = normal;
	*normalsp++   = normal;
	*normalsp++   = normal;

	*indicesp++ = index_offset + 0;
	*indicesp++ = index_offset + 1;
	*indicesp++ = index_offset + 2;

	*indicesp++ = index_offset + 1;
	*indicesp++ = index_offset + 3;
	*indicesp++ = index_offset + 2;
}
// Returns true if you got at least one object
void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
{
// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
	// Block rectangle selection if:
	//   - prevented from editing and no exceptions are set (see below for the case where exceptions are set)
	//   - prevented from interacting at all
	if ( (rlv_handler_t::isEnabled()) && 
		 ( ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasException(RLV_BHVR_EDIT))) || 
		   (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) ) )
	{
		return;
	}
// [/RLVa:KB]

	LLVector3 av_pos = gAgent.getPositionAgent();
	F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance");
	select_dist_squared = select_dist_squared * select_dist_squared;

	BOOL deselect = (mask == MASK_CONTROL);
	S32 left =	llmin(x, mDragStartX);
	S32 right =	llmax(x, mDragStartX);
	S32 top =	llmax(y, mDragStartY);
	S32 bottom =llmin(y, mDragStartY);

	left = llround((F32) left * LLUI::getScaleFactor().mV[VX]);
	right = llround((F32) right * LLUI::getScaleFactor().mV[VX]);
	top = llround((F32) top * LLUI::getScaleFactor().mV[VY]);
	bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]);

	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();

	S32 width = right - left + 1;
	S32 height = top - bottom + 1;

	BOOL grow_selection = FALSE;
	BOOL shrink_selection = FALSE;

	if (height > mDragLastHeight || width > mDragLastWidth)
	{
		grow_selection = TRUE;
	}
	if (height < mDragLastHeight || width < mDragLastWidth)
	{
		shrink_selection = TRUE;
	}

	if (!grow_selection && !shrink_selection)
	{
		// nothing to do
		return;
	}

	mDragLastHeight = height;
	mDragLastWidth = width;

	S32 center_x = (left + right) / 2;
	S32 center_y = (top + bottom) / 2;

	// save drawing mode
	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.pushMatrix();

	BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
	if (limit_select_distance)
	{
		// ...select distance from control
		LLVector3 relative_av_pos = av_pos;
		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();

		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance");
		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance");

		new_near = llmax(new_near, 0.1f);

		LLViewerCamera::getInstance()->setFar(new_far);
		LLViewerCamera::getInstance()->setNear(new_near);
	}
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.0.0g
	if (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))
	{
		// We'll allow drag selection under fartouch, but only within the fartouch range
		// (just copy/paste the code above us to make that work, thank you Lindens!)
		LLVector3 relative_av_pos = av_pos;
		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();

		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + 1.5f;
		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - 1.5f;

		new_near = llmax(new_near, 0.1f);

		LLViewerCamera::getInstance()->setFar(new_far);
		LLViewerCamera::getInstance()->setNear(new_near);

		// Usurp these two
		limit_select_distance = TRUE;
		select_dist_squared = 1.5f * 1.5f;
	}
// [/RLVa:KB]
	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, 
							center_x-width/2, center_y-height/2, width, height, 
							limit_select_distance);

	if (shrink_selection)
	{
		struct f : public LLSelectedObjectFunctor
		{
			virtual bool apply(LLViewerObject* vobjp)
			{
				LLDrawable* drawable = vobjp->mDrawable;
				if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
				{
					return true;
				}
				S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
				switch (result)
				{
				  case 0:
					LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					break;
				  case 1:
					// check vertices
					if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					}
					break;
				  default:
					break;
				}
				return true;
			}
		} func;
		LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
	}

	if (grow_selection)
	{
		std::vector<LLDrawable*> potentials;
				
		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
		{
			LLViewerRegion* region = *iter;
			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
			{
				LLSpatialPartition* part = region->getSpatialPartition(i);
				if (part)
				{	
					part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
				}
			}
		}
		
		for (std::vector<LLDrawable*>::iterator iter = potentials.begin();
			 iter != potentials.end(); iter++)
		{
			LLDrawable* drawable = *iter;
			LLViewerObject* vobjp = drawable->getVObj();

			if (!drawable || !vobjp ||
				vobjp->getPCode() != LL_PCODE_VOLUME || 
				vobjp->isAttachment() ||
				(deselect && !vobjp->isSelected()))
			{
				continue;
			}

			if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared)
			{
				continue;
			}

// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
			if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canEdit(vobjp)) )
			{
				continue;
			}
// [/RLVa:KB]

			S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
			if (result)
			{
				switch (result)
				{
				case 1:
					// check vertices
					if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					}
					break;
				case 2:
					LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					break;
				default:
					break;
				}
			}
		}
	}

	// restore drawing mode
	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.popMatrix();
	gGL.matrixMode(LLRender::MM_MODELVIEW);

	// restore camera
	LLViewerCamera::getInstance()->setFar(old_far_plane);
	LLViewerCamera::getInstance()->setNear(old_near_plane);
	gViewerWindow->setup3DRender();
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
	if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
	{
		return;
	}

	stop_glerror();

	for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
	{
		LLFace* face = mRiggedFace[type][i];
		LLDrawable* drawable = face->getDrawable();
		if (!drawable)
		{
			continue;
		}
		LLVOVolume* vobj = drawable->getVOVolume();

		if (!vobj)
		{
			continue;
		}
	
		LLVolume* volume = vobj->getVolume();
		S32 te = face->getTEOffset();

		if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
		{
			continue;
		}

		LLUUID mesh_id = volume->getParams().getSculptID();
		if (mesh_id.isNull())
		{
			continue;
		}

		const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj);
		if (!skin)
		{
			continue;
		}

		stop_glerror();

		const LLVolumeFace& vol_face = volume->getVolumeFace(te);
		updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face, vobj);

		stop_glerror();

		U32 data_mask = LLFace::getRiggedDataMask(type);

		LLVertexBuffer* buff = face->getVertexBuffer();

		if (buff)
		{
			if (sShaderLevel > 0)
			{ //upload matrix palette to shader
				LLMatrix4 mat[64];

				for (U32 i = 0; i < skin->mJointNames.size(); ++i)
				{
					LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
					if (joint)
					{
						mat[i] = skin->mInvBindMatrix[i];
						mat[i] *= joint->getWorldMatrix();
					}
				}

				stop_glerror();

				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
																   skin->mJointNames.size(),
																   FALSE,
																   (GLfloat*) mat[0].mMatrix);

				stop_glerror();
			}
			else
			{
				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
			}

			buff->setBuffer(data_mask);

			U16 start = face->getGeomStart();
			U16 end = start + face->getGeomCount()-1;
			S32 offset = face->getIndicesStart();
			U32 count = face->getIndicesCount();

			if (glow)
			{
				glColor4f(0,0,0,face->getTextureEntry()->getGlow());
			}

			gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
			if (normal_channel > -1)
			{
				LLDrawPoolBump::bindBumpMap(face, normal_channel);
			}

			if (face->mTextureMatrix)
			{
				glMatrixMode(GL_TEXTURE);
				glLoadMatrixf((F32*) face->mTextureMatrix->mMatrix);
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
				glLoadIdentity();
				glMatrixMode(GL_MODELVIEW);
			}
			else
			{
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
			}
		}
	}
}
void LLDrawPoolTree::renderTree(BOOL selecting)
{
	LLGLState normalize(GL_NORMALIZE, TRUE);
	
	// Bind the texture for this tree.
	gGL.getTexUnit(sDiffTex)->bind(mTexturep.get(), TRUE);
		
	U32 indices_drawn = 0;

	glMatrixMode(GL_MODELVIEW);
	
	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
		 iter != mDrawFace.end(); iter++)
	{
		LLFace *face = *iter;
		LLDrawable *drawablep = face->getDrawable();

		if (drawablep->isDead() || !face->getVertexBuffer())
		{
			continue;
		}

		face->getVertexBuffer()->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
		U16* indicesp = (U16*) face->getVertexBuffer()->getIndicesPointer();

		// Render each of the trees
		LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get();

		LLColor4U color(255,255,255,255);

		if (!selecting || treep->mGLName != 0)
		{
			if (selecting)
			{
				S32 name = treep->mGLName;
				
				color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255);
			}
			
			gGLLastMatrix = NULL;
			glLoadMatrixd(gGLModelView);
			//glPushMatrix();
			F32 mat[16];
			for (U32 i = 0; i < 16; i++)
				mat[i] = (F32) gGLModelView[i];

			LLMatrix4 matrix(mat);
			
			// Translate to tree base  HACK - adjustment in Z plants tree underground
			const LLVector3 &pos_agent = treep->getPositionAgent();
			//glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
			LLMatrix4 trans_mat;
			trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
			trans_mat *= matrix;
			
			// Rotate to tree position and bend for current trunk/wind
			// Note that trunk stiffness controls the amount of bend at the trunk as 
			// opposed to the crown of the tree
			// 
			const F32 TRUNK_STIFF = 22.f;
			
			LLQuaternion rot = 
				LLQuaternion(treep->mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0)) *
				LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) *
				treep->getRotation();

			LLMatrix4 rot_mat(rot);
			rot_mat *= trans_mat;

			F32 radius = treep->getScale().magVec()*0.05f;
			LLMatrix4 scale_mat;
			scale_mat.mMatrix[0][0] = 
				scale_mat.mMatrix[1][1] =
				scale_mat.mMatrix[2][2] = radius;

			scale_mat *= rot_mat;

			const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f;
			const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f;

			F32 droop = treep->mDroop + 25.f*(1.f - treep->mTrunkBend.magVec());
			
			S32 stop_depth = 0;
			F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor;
			F32 alpha = 1.0;
			S32 trunk_LOD = LLVOTree::sMAX_NUM_TREE_LOD_LEVELS;

			for (S32 j = 0; j < 4; j++)
			{

				if (app_angle > LLVOTree::sLODAngles[j])
				{
					trunk_LOD = j;
					break;
				}
			} 
			if(trunk_LOD >= LLVOTree::sMAX_NUM_TREE_LOD_LEVELS)
			{
				continue ; //do not render.
			}

			if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD))
			{
				//
				//  Draw only the billboard 
				//
				//  Only the billboard, can use closer to normal alpha func.
				stop_depth = -1;
				LLFacePool::LLOverrideFaceColor clr(this, color); 
				indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
			}
			else // if (app_angle > (THRESH_ANGLE_FOR_BILLBOARD + BLEND_RANGE_FOR_BILLBOARD))
			{
				//
				//  Draw only the full geometry tree
				//
				//stop_depth = (app_angle < THRESH_ANGLE_FOR_RECURSION_REDUCTION);
				LLFacePool::LLOverrideFaceColor clr(this, color); 
				indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
			}
			
			//glPopMatrix();
		}
	}
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
	if ((avatar->isSelf() && !gAgent.needsRenderAvatar()) || !gMeshRepo.meshRezEnabled())
	{
		return;
	}

	stop_glerror();

	for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
	{
		LLFace* face = mRiggedFace[type][i];
		LLDrawable* drawable = face->getDrawable();
		if (!drawable)
		{
			continue;
		}

		LLVOVolume* vobj = drawable->getVOVolume();

		if (!vobj)
		{
			continue;
		}

		LLVolume* volume = vobj->getVolume();
		S32 te = face->getTEOffset();

		if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
		{
			continue;
		}

		LLUUID mesh_id = volume->getParams().getSculptID();
		if (mesh_id.isNull())
		{
			continue;
		}

		const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj);
		if (!skin)
		{
			continue;
		}

		//stop_glerror();

		//const LLVolumeFace& vol_face = volume->getVolumeFace(te);
		//updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
		
		//stop_glerror();

		U32 data_mask = LLFace::getRiggedDataMask(type);

		LLVertexBuffer* buff = face->getVertexBuffer();

		if (buff)
		{
			if (sShaderLevel > 0)
			{ //upload matrix palette to shader
				LLMatrix4 mat[JOINT_COUNT];

				U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT);

				for (U32 i = 0; i < count; ++i)
				{
					LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
					if(!joint)
					{
						joint = avatar->getJoint("mRoot");
					}
					if (joint)
					{
						LLMatrix4a tmp;
						tmp.loadu((F32*)skin->mInvBindMatrix[i].mMatrix);
						tmp.setMul(joint->getWorldMatrix(),tmp);
						mat[i] = LLMatrix4(tmp.getF32ptr());
					}
				}
				
				stop_glerror();

				F32 mp[JOINT_COUNT*12];

				for (U32 i = 0; i < count; ++i)
				{
					F32* m = (F32*) mat[i].mMatrix;

					U32 idx = i*12;

					mp[idx+0] = m[0];
					mp[idx+1] = m[1];
					mp[idx+2] = m[2];
					mp[idx+3] = m[12];

					mp[idx+4] = m[4];
					mp[idx+5] = m[5];
					mp[idx+6] = m[6];
					mp[idx+7] = m[13];

					mp[idx+8] = m[8];
					mp[idx+9] = m[9];
					mp[idx+10] = m[10];
					mp[idx+11] = m[14];
				}

				LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, 
					count,
					FALSE,
					(GLfloat*) mp);

				LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(count-1));
				
				stop_glerror();
			}
			else
			{
				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
			}

			U16 start = face->getGeomStart();
			U16 end = start + face->getGeomCount()-1;
			S32 offset = face->getIndicesStart();
			U32 count = face->getIndicesCount();

			/*if (glow)
			{
				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
			}*/

			const LLTextureEntry* te = face->getTextureEntry();
			LLMaterial* mat = te->getMaterialParams().get();

			if (mat && is_deferred_render)
			{
				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP));
				gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
				gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP));

				LLColor4 col = mat->getSpecularLightColor();
				F32 spec = llmax(0.0001f, mat->getSpecularLightExponent() / 255.f);

				F32 env = mat->getEnvironmentIntensity()/255.f;

				if (mat->getSpecularID().isNull())
				{
					env = te->getShiny()*0.25f;
					col.set(env,env,env,0);
					spec = env;
				}
		
				BOOL fullbright = te->getFullbright();

				sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);

				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
				{
					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
				}
				else
				{
					sVertexProgram->setMinimumAlpha(0.004f);
				}

				for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
				{
					LLViewerTexture* tex = face->getTexture(i);
					if (tex)
					{
						tex->addTextureStats(avatar->getPixelArea());
					}
				}
			}
			else
			{
				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());

				if(sVertexProgram)
				{
					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
					{
						sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
					}
					else
					{
						sVertexProgram->setMinimumAlpha(0.004f);
					}
				}

				if (normal_channel > -1)
				{
					LLDrawPoolBump::bindBumpMap(face, normal_channel);
				}
			}

			if (face->mTextureMatrix && vobj->mTexAnimMode)
			{
				gGL.matrixMode(LLRender::MM_TEXTURE);
				gGL.loadMatrix(*face->mTextureMatrix);
				buff->setBuffer(data_mask);
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
				gGL.loadIdentity();
				gGL.matrixMode(LLRender::MM_MODELVIEW);
			}
			else
			{
				buff->setBuffer(data_mask);
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);		
			}

			gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
		}
	}
}
void LLDrawable::makeActive()
{		
#if !LL_RELEASE_FOR_DOWNLOAD
	if (mVObjp.notNull())
	{
		U32 pcode = mVObjp->getPCode();
		if (pcode == LLViewerObject::LL_VO_WATER ||
			pcode == LLViewerObject::LL_VO_VOID_WATER ||
			pcode == LLViewerObject::LL_VO_SURFACE_PATCH ||
			pcode == LLViewerObject::LL_VO_PART_GROUP ||
			pcode == LLViewerObject::LL_VO_HUD_PART_GROUP ||
			pcode == LLViewerObject::LL_VO_GROUND ||
			pcode == LLViewerObject::LL_VO_SKY)
		{
			llerrs << "Static viewer object has active drawable!" << llendl;
		}
	}
#endif

	if (!isState(ACTIVE)) // && mGeneration > 0)
	{
		setState(ACTIVE);
		
		//parent must be made active first
		if (!isRoot() && !mParent->isActive())
		{
			mParent->makeActive();
		}

		//all child objects must also be active
		llassert_always(mVObjp);
		
		LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
			 iter != child_list.end(); iter++)
		{
			LLViewerObject* child = *iter;
			LLDrawable* drawable = child->mDrawable;
			if (drawable)
			{
				drawable->makeActive();
			}
		}

		if (mVObjp->getPCode() == LL_PCODE_VOLUME)
		{
			if (mVObjp->isFlexible())
			{
				return;
			}
		}
	
		if (mVObjp->getPCode() == LL_PCODE_VOLUME)
		{
			gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
		}
		updatePartition();
	}

	if (isRoot())
	{
		mQuietCount = 0;
	}
	else
	{
		getParent()->mQuietCount = 0;
	}
}
// Returns true if you got at least one object
void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
{
	LLVector3 av_pos = gAgent.getPositionAgent();
	F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance");
	select_dist_squared = select_dist_squared * select_dist_squared;

	BOOL deselect = (mask == MASK_CONTROL);
	S32 left =	llmin(x, mDragStartX);
	S32 right =	llmax(x, mDragStartX);
	S32 top =	llmax(y, mDragStartY);
	S32 bottom =llmin(y, mDragStartY);

	left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
	right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
	top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
	bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);

	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();

	S32 width = right - left + 1;
	S32 height = top - bottom + 1;

	BOOL grow_selection = FALSE;
	BOOL shrink_selection = FALSE;

	if (height > mDragLastHeight || width > mDragLastWidth)
	{
		grow_selection = TRUE;
	}
	if (height < mDragLastHeight || width < mDragLastWidth)
	{
		shrink_selection = TRUE;
	}

	if (!grow_selection && !shrink_selection)
	{
		// nothing to do
		return;
	}

	mDragLastHeight = height;
	mDragLastWidth = width;

	S32 center_x = (left + right) / 2;
	S32 center_y = (top + bottom) / 2;

	// save drawing mode
	glMatrixMode(GL_PROJECTION);
	gGL.pushMatrix();

	BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
	if (limit_select_distance)
	{
		// ...select distance from control
		LLVector3 relative_av_pos = av_pos;
		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();

		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance");
		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance");

		new_near = llmax(new_near, 0.1f);

		LLViewerCamera::getInstance()->setFar(new_far);
		LLViewerCamera::getInstance()->setNear(new_near);
	}
	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, 
							center_x-width/2, center_y-height/2, width, height, 
							limit_select_distance);

	if (shrink_selection)
	{
		struct f : public LLSelectedObjectFunctor
		{
			virtual bool apply(LLViewerObject* vobjp)
			{
				LLDrawable* drawable = vobjp->mDrawable;
				if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
				{
					return true;
				}
				S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
				switch (result)
				{
				  case 0:
					LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					break;
				  case 1:
					// check vertices
					if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					}
					break;
				  default:
					break;
				}
				return true;
			}
		} func;
		LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
	}

	if (grow_selection)
	{
		std::vector<LLDrawable*> potentials;
				
		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
		{
			LLViewerRegion* region = *iter;
			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
			{
				LLSpatialPartition* part = region->getSpatialPartition(i);
				if (part)
				{	
					part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
				}
			}
		}
		
		for (std::vector<LLDrawable*>::iterator iter = potentials.begin();
			 iter != potentials.end(); iter++)
		{
			LLDrawable* drawable = *iter;
			LLViewerObject* vobjp = drawable->getVObj();

			if (!drawable || !vobjp ||
				vobjp->getPCode() != LL_PCODE_VOLUME || 
				vobjp->isAttachment() ||
				(deselect && !vobjp->isSelected()))
			{
				continue;
			}

			if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared)
			{
				continue;
			}

			S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
			if (result)
			{
				switch (result)
				{
				case 1:
					// check vertices
					if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					}
					break;
				case 2:
					LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					break;
				default:
					break;
				}
			}
		}
	}

	// restore drawing mode
	glMatrixMode(GL_PROJECTION);
	gGL.popMatrix();
	glMatrixMode(GL_MODELVIEW);

	// restore camera
	LLViewerCamera::getInstance()->setFar(old_far_plane);
	LLViewerCamera::getInstance()->setNear(old_near_plane);
	gViewerWindow->setup3DRender();
}
void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results, BOOL for_select)
{
	if (!gPipeline.hasRenderType(mDrawableType))
	{
		return;
	}


	//HACK don't draw attachments for avatars that haven't been visible in more than a frame
	LLViewerObject *vobj = mDrawable->getVObj();
	if (vobj && vobj->isAttachment() && !vobj->isHUDAttachment())
	{
		LLDrawable* av;
		LLDrawable* parent = mDrawable->getParent();

		if (parent)
		{
			LLViewerObject* objparent = parent->getVObj();
			av = objparent->mDrawable;
			LLSpatialGroup* group = av->getSpatialGroup();

			BOOL impostor = FALSE;
			BOOL loaded = FALSE;
			if (objparent->isAvatar())
			{
				LLVOAvatar* avatarp = (LLVOAvatar*) objparent;
				if (avatarp->isVisible())
				{
					impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
					loaded   = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
				}
				else
				{
					return;
				}
			}

			if (!group ||
				LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
				impostor ||
				!loaded)
			{
				return;
			}
		}
	}
	

	LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
	group->rebound();
	
	LLVector4a center;
	center.setAdd(mExtents[0], mExtents[1]);
	center.mul(0.5f);
	LLVector4a size;
	size.setSub(mExtents[1], mExtents[0]);
	size.mul(0.5f);

	if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) ||
		LLPipeline::sImpostorRender ||
		(camera_in.AABBInFrustumNoFarClip(center, size) && 
		AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))
	{
		if (!LLPipeline::sImpostorRender &&
			!LLPipeline::sShadowRender && 
			LLPipeline::calcPixelArea(center, size, camera_in) < FORCE_INVISIBLE_AREA)
		{
			return;
		}

		LLDrawable::setVisible(camera_in);
		
		if (for_select)
		{
			results->push_back(mDrawable);
			if (mDrawable->getVObj())
			{
				LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
					 iter != child_list.end(); iter++)
				{
					LLViewerObject* child = *iter;
					LLDrawable* drawable = child->mDrawable;					
					results->push_back(drawable);
				}
			}
		}
		else 
		{
			LLCamera trans_camera = transformCamera(camera_in);
			LLOctreeMarkNotCulled culler(&trans_camera);
			culler.traverse(mOctree);
		}		
	}
}
//-----------------------------------------------------------------------------
// addObject()
//-----------------------------------------------------------------------------
BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
{
	if (mAttachedObject)
	{
		llwarns << "Attempted to attach object where an attachment already exists!" << llendl;
		
		if (mAttachedObject == object) {
			llinfos << "(same object re-attached)" << llendl;
			removeObject(mAttachedObject);
			// Pass through anyway to let setupDrawable()
			// re-connect object to the joint correctly
		}
		else {
			llinfos << "(objects differ, removing existing object)" << llendl;
			// Rather hacky, but no-one can think of something
			// better to do for this case.
			gObjectList.killObject(mAttachedObject);
			// Proceed with new object attachment
		}
	}
	mAttachedObject = object;
	
	LLUUID item_id;

	// Find the inventory item ID of the attached object
	LLNameValue* item_id_nv = object->getNVPair("AttachItemID");
	if( item_id_nv )
	{
		const char* s = item_id_nv->getString();
		if( s )
		{
			item_id.set( s );
			lldebugs << "getNVPair( AttachItemID ) = " << item_id << llendl;
		}
	}

	mItemID = item_id;

	LLDrawable* drawablep = object->mDrawable;

	if (drawablep)
	{
		//if object is active, make it static
		if(drawablep->isActive())
		{
			drawablep->makeStatic(FALSE) ;
		}

		setupDrawable(drawablep);
	}

	if (mIsHUDAttachment)
	{
		if (object->mText.notNull())
		{
			object->mText->setOnHUDAttachment(TRUE);
		}
		LLViewerObject::const_child_list_t& child_list = object->getChildren();
		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
			 iter != child_list.end(); iter++)
		{
			LLViewerObject* childp = *iter;
			if (childp && childp->mText.notNull())
			{
				childp->mText->setOnHUDAttachment(TRUE);
			}
		}
	}
	calcLOD();
	mUpdateXform = TRUE;

	return TRUE;
}
void LLViewerObjectList::generatePickList(LLCamera &camera)
{
		LLViewerObject *objectp;
		S32 i;
		// Reset all of the GL names to zero.
		for (i = 0; i < mObjects.count(); i++)
		{
			objectp = mObjects[i];
			objectp->mGLName = 0;
		}

		mSelectPickList.clear();

		std::vector<LLDrawable*> pick_drawables;

		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
		{
			LLViewerRegion* region = *iter;
			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
			{
				LLSpatialPartition* part = region->getSpatialPartition(i);
				if (part)
				{	
					part->cull(camera, &pick_drawables, TRUE);
				}
			}
		}

		for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin();
			iter != pick_drawables.end(); iter++)
		{
			LLDrawable* drawablep = *iter;
			if( !drawablep )
				continue;

			LLViewerObject* last_objectp = NULL;
			for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
			{
				LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject();

				if (objectp && objectp != last_objectp)
				{
					mSelectPickList.insert(objectp);
					last_objectp = objectp;
				}
			}
		}

		LLHUDText::addPickable(mSelectPickList);

		for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
			iter != LLCharacter::sInstances.end(); ++iter)
		{
			objectp = (LLVOAvatar*) *iter;
			if (!objectp->isDead())
			{
				if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible())
				{
					mSelectPickList.insert(objectp);
				}
			}
		}

		// add all hud objects to pick list
		LLVOAvatar* avatarp = gAgent.getAvatarObject();
		if (avatarp)
		{
			for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); 
				 iter != avatarp->mAttachmentPoints.end(); )
			{
				LLVOAvatar::attachment_map_t::iterator curiter = iter++;
				LLViewerJointAttachment* attachmentp = curiter->second;
				if (attachmentp->getIsHUDAttachment())
				{
					LLViewerObject* objectp = attachmentp->getObject();
					if (objectp)
					{
						mSelectPickList.insert(objectp);		
						LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
						for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
							 iter != child_list.end(); iter++)
						{
							LLViewerObject* childp = *iter;
							if (childp)
							{
								mSelectPickList.insert(childp);
							}
						}
					}
				}
			}
		}
		
		S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances();

		if (num_pickables != 0)
		{
			S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables;

			std::set<LLViewerObject*>::iterator pick_it;
			i = 0;
			for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();)
			{
				LLViewerObject* objp = (*pick_it);
				if (!objp || objp->isDead() || !objp->mbCanSelect)
				{
					mSelectPickList.erase(pick_it++);
					continue;
				}
				
				objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET;
				i++;
				++pick_it;
			}

			LLHUDIcon::generatePickIDs(i * step, step);
	}
}
void LLVOClouds::getGeometry(S32 idx,
								LLStrider<LLVector4a>& verticesp,
								LLStrider<LLVector3>& normalsp, 
								LLStrider<LLVector2>& texcoordsp,
								LLStrider<LLColor4U>& colorsp, 
								LLStrider<U16>& indicesp)
{

	if (idx >= mCloudGroupp->getNumPuffs())
	{
		return;
	}

	LLDrawable* drawable = mDrawable;
	LLFace *facep = drawable->getFace(idx);

	if (!facep->hasGeometry())
	{
		return;
	}
	

	const LLCloudPuff &puff = mCloudGroupp->getPuff(idx);

	LLColor4 float_color(LLColor3(gSky.getSunDiffuseColor() + gSky.getSunAmbientColor()),puff.getAlpha());
	LLColor4U color;
	color.setVec(float_color);
	facep->setFaceColor(float_color);
	
	U32 vert_offset = facep->getGeomIndex();
		
	LLVector4a part_pos_agent;
	part_pos_agent.load3(facep->mCenterLocal.mV);	
	LLVector4a at;
	at.load3(LLViewerCamera::getInstance()->getAtAxis().mV);
	LLVector4a up(0, 0, 1);
	LLVector4a right;

	right.setCross3(at, up);
	right.normalize3fast();
	up.setCross3(right, at);
	up.normalize3fast();
	right.mul(0.5f*CLOUD_PUFF_WIDTH);
	up.mul(0.5f*CLOUD_PUFF_HEIGHT);
		

	LLVector3 normal(0.f,0.f,-1.f);

	//HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should)
	// this works because there is actually a 4th float stored after the vertex position which is used as a texture index
	// also, somebody please VECTORIZE THIS

	LLVector4a ppapu;
	LLVector4a ppamu;
	
	ppapu.setAdd(part_pos_agent, up);
	ppamu.setSub(part_pos_agent, up);
	
	verticesp->setSub(ppapu, right);
	(*verticesp++).getF32ptr()[3] = 0.f;
	verticesp->setSub(ppamu, right);
	(*verticesp++).getF32ptr()[3] = 0.f;
	verticesp->setAdd(ppapu, right);
	(*verticesp++).getF32ptr()[3] = 0.f;
	verticesp->setAdd(ppamu, right);
	(*verticesp++).getF32ptr()[3] = 0.f;

	// *verticesp++ = puff_pos_agent - right + up;
	// *verticesp++ = puff_pos_agent - right - up;
	// *verticesp++ = puff_pos_agent + right + up;
	// *verticesp++ = puff_pos_agent + right - up;

	*colorsp++ = color;
	*colorsp++ = color;
	*colorsp++ = color;
	*colorsp++ = color;

	*texcoordsp++ = LLVector2(0.f, 1.f);
	*texcoordsp++ = LLVector2(0.f, 0.f);
	*texcoordsp++ = LLVector2(1.f, 1.f);
	*texcoordsp++ = LLVector2(1.f, 0.f);

	*normalsp++   = normal;
	*normalsp++   = normal;
	*normalsp++   = normal;
	*normalsp++   = normal;

	*indicesp++ = vert_offset + 0;
	*indicesp++ = vert_offset + 1;
	*indicesp++ = vert_offset + 2;

	*indicesp++ = vert_offset + 1;
	*indicesp++ = vert_offset + 3;
	*indicesp++ = vert_offset + 2;
}
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, 
													const LLMeshSkinInfo* skin, LLVolume* volume, 
													const LLVolumeFace& vol_face, LLVOVolume* vobj)
{
	LLVector4a* weight = vol_face.mWeights;
	if (!weight)
	{
		return;
	}

	LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
	LLDrawable* drawable = face->getDrawable();

	U32 data_mask = face->getRiggedVertexBufferDataMask();

	if (buffer.isNull() || buffer->getTypeMask() != data_mask ||
		buffer->getRequestedVerts() != vol_face.mNumVertices ||
		buffer->getRequestedIndices() != vol_face.mNumIndices ||
		(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
	{
		face->setGeomIndex(0);
		face->setIndicesIndex(0);

		if (buffer.isNull() || buffer->getTypeMask() != data_mask)
		{	//make a new buffer
			if (sShaderLevel > 0)
			{
				buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
			}
			else
			{
				buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
			}
			buffer->allocateBuffer(vol_face.mNumVertices,
								   vol_face.mNumIndices, true);
		}
		else
		{	//resize existing buffer
			buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
		}

		face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
		face->setVertexBuffer(buffer);

		U16 offset = 0;

		LLMatrix4 mat_vert = skin->mBindShapeMatrix;
		glh::matrix4f m((F32*) mat_vert.mMatrix);
		m = m.inverse().transpose();

		F32 mat3[] = {	m.m[0], m.m[1], m.m[2],
						m.m[4], m.m[5], m.m[6],
						m.m[8], m.m[9], m.m[10] };

		LLMatrix3 mat_normal(mat3);

		static LLCachedControl<bool> mesh_enable_deformer(gSavedSettings, "MeshEnableDeformer");
		if (mesh_enable_deformer)
		{
			LLDeformedVolume* deformed_volume = vobj->getDeformedVolume();
			deformed_volume->deform(volume, avatar, skin, face->getTEOffset());
			face->getGeometryVolume(*deformed_volume, face->getTEOffset(), mat_vert,
									mat_normal, offset, true);
		}
		else
		{
			face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert,
 									mat_normal, offset, true);
		}
	}

	if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
	{ //perform software vertex skinning for this face
		LLStrider<LLVector3> position;
		LLStrider<LLVector3> normal;

		bool has_normal = buffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
		buffer->getVertexStrider(position);

		if (has_normal)
		{
			buffer->getNormalStrider(normal);
		}
		LLVector4a* pos = (LLVector4a*) position.get();

		LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;

		//build matrix palette
		LLMatrix4a mp[64];
		LLMatrix4* mat = (LLMatrix4*) mp;

		for (U32 j = 0; j < skin->mJointNames.size(); ++j)
		{
			LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
			if (joint)
			{
				mat[j] = skin->mInvBindMatrix[j];
				mat[j] *= joint->getWorldMatrix();
			}
		}

		LLMatrix4a bind_shape_matrix;
		bind_shape_matrix.loadu(skin->mBindShapeMatrix);

		for (U32 j = 0; j < buffer->getRequestedVerts(); ++j)
		{
			LLMatrix4a final_mat;
			final_mat.clear();

			S32 idx[4];

			LLVector4 wght;

			F32 scale = 0.f;
			for (U32 k = 0; k < 4; k++)
		{
				F32 w = weight[j][k];

				idx[k] = llclamp((S32) floorf(w), 0, 63);
				wght[k] = w - floorf(w);
				scale += wght[k];
			}

			wght *= 1.f/scale;

			for (U32 k = 0; k < 4; k++)
			{
				F32 w = wght[k];

				LLMatrix4a src;
				src.setMul(mp[idx[k]], w);

				final_mat.add(src);
			}

			LLVector4a& v = vol_face.mPositions[j];
			LLVector4a t;
			LLVector4a dst;
			bind_shape_matrix.affineTransform(v, t);
			final_mat.affineTransform(t, dst);
			pos[j] = dst;

			if (norm)
			{
				LLVector4a& n = vol_face.mNormals[j];
				bind_shape_matrix.rotate(n, t);
				final_mat.rotate(t, dst);
				norm[j] = dst;
			}
		}
	}

	if (drawable && face->getTEOffset() == drawable->getNumFaces() - 1)
	{
		drawable->clearState(LLDrawable::REBUILD_ALL);
	}
}
Exemple #29
0
U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parcel_wall, BOOL keep_pick_list)
{
	gRenderForSelect = TRUE;

	//	LLTimer pick_timer;
	if (!keep_pick_list)
	{
		LLViewerObject *objectp;
		S32 i;
		// Reset all of the GL names to zero.
		for (i = 0; i < mObjects.count(); i++)
		{
			objectp = mObjects[i];
			objectp->mGLName = 0;
		}

		mSelectPickList.clear();

		std::vector<LLDrawable*> pick_drawables;

		for (i = 0; i < LLPipeline::NUM_PARTITIONS-1; i++)
		{
			LLSpatialPartition* part = gPipeline.getSpatialPartition(i);
			if (part)
			{
				part->cull(camera, &pick_drawables, TRUE);
			}
		}

		for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin();
			iter != pick_drawables.end(); iter++)
		{
			LLDrawable* drawablep = *iter;
			if( !drawablep )
				continue;

			LLViewerObject* last_objectp = NULL;
			for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
			{
				LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject();

				if (objectp && objectp != last_objectp)
				{
					mSelectPickList.insert(objectp);
					last_objectp = objectp;
				}
			}
		}

		LLHUDText::addPickable(mSelectPickList);

		for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
			iter != LLCharacter::sInstances.end(); ++iter)
		{
			objectp = (LLVOAvatar*) *iter;
			if (!objectp->isDead())
			{
				if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible())
				{
					mSelectPickList.insert(objectp);
				}
			}
		}

		// add all hud objects to pick list
		LLVOAvatar* avatarp = gAgent.getAvatarObject();
		if (avatarp)
		{
			LLViewerJointAttachment* attachmentp;
			for (attachmentp = avatarp->mAttachmentPoints.getFirstData();
				attachmentp;
				attachmentp = avatarp->mAttachmentPoints.getNextData())
			{
				if (attachmentp->getIsHUDAttachment())
				{
					LLViewerObject* objectp = attachmentp->getObject();
					if (objectp)
					{
						mSelectPickList.insert(objectp);		
						for (U32 i = 0; i < objectp->mChildList.size(); i++)
						{
							LLViewerObject* childp = objectp->mChildList[i];
							if (childp)
							{
								mSelectPickList.insert(childp);
							}
						}
					}
				}
			}
		}
		
		S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances();

		if (num_pickables != 0)
		{
			S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables;

			std::set<LLViewerObject*>::iterator pick_it;
			i = 0;
			for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();)
			{
				LLViewerObject* objp = (*pick_it);
				if (!objp || objp->isDead() || !objp->mbCanSelect)
				{
					mSelectPickList.erase(pick_it++);
					continue;
				}
				
				objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET;
				i++;
				++pick_it;
			}

			LLHUDIcon::generatePickIDs(i * step, step);
		
			// At this point, we should only have live drawables/viewer objects
			gPipeline.renderForSelect(mSelectPickList);
		}
	}

	//
	// Render pass for selected objects
	//
	gViewerWindow->renderSelections( TRUE, pick_parcel_wall, FALSE );

	// render pickable ui elements, like names, etc.
	LLHUDObject::renderAllForSelect();

	gRenderForSelect = FALSE;

	//llinfos << "Rendered " << count << " for select" << llendl;
	//llinfos << "Took " << pick_timer.getElapsedTimeF32()*1000.f << "ms to pick" << llendl;
	return 0;
}
Exemple #30
0
void LLVOClouds::getGeometry(S32 te, 
							LLStrider<LLVector3>& verticesp, 
							LLStrider<LLVector3>& normalsp, 
							LLStrider<LLVector2>& texcoordsp, 
							LLStrider<LLColor4U>& colorsp, 
							LLStrider<U32>& indicesp)
{

	if (te >= mCloudGroupp->getNumPuffs())
	{
		return;
	}

	LLDrawable* drawable = mDrawable;
	LLFace *facep = drawable->getFace(te);

	if (!facep->hasGeometry())
	{
		return;
	}
	
	LLVector3 normal(0.f,0.f,-1.f);

	const LLCloudPuff &puff = mCloudGroupp->getPuff(te);
	S32 index_offset = facep->getGeomIndex();
	LLColor4U color(255, 255, 255, (U8) (puff.getAlpha()*255));
	facep->setFaceColor(LLColor4(color));
		
	
	if (isParticle())
	{
		*verticesp++ = facep->mCenterLocal;
		*texcoordsp++ = LLVector2(0.5f, 0.5f);
		*colorsp++ = color;
		*normalsp++ = normal;
		*indicesp++ = facep->getGeomIndex();
	}
	else
	{
		LLVector3 up;
		LLVector3 right;
		LLVector3 at;

		const LLVector3& puff_pos_agent = facep->mCenterLocal;
		LLVector2 uvs[4];

		uvs[0].setVec(0.f, 1.f);
		uvs[1].setVec(0.f, 0.f);
		uvs[2].setVec(1.f, 1.f);
		uvs[3].setVec(1.f, 0.f);

		LLVector3 vtx[4];

		at = gCamera->getAtAxis();
		right = at % LLVector3(0.f, 0.f, 1.f);
		right.normVec();
		up = right % at;
		up.normVec();
		right *= 0.5f*CLOUD_PUFF_WIDTH;
		up *= 0.5f*CLOUD_PUFF_HEIGHT;;
		
		*colorsp++ = color;
		*colorsp++ = color;
		*colorsp++ = color;
		*colorsp++ = color;

		vtx[0] = puff_pos_agent - right + up;
		vtx[1] = puff_pos_agent - right - up;
		vtx[2] = puff_pos_agent + right + up;
		vtx[3] = puff_pos_agent + right - up;

		*verticesp++  = vtx[0];
		*verticesp++  = vtx[1];
		*verticesp++  = vtx[2];
		*verticesp++  = vtx[3];

		*texcoordsp++ = uvs[0];
		*texcoordsp++ = uvs[1];
		*texcoordsp++ = uvs[2];
		*texcoordsp++ = uvs[3];

		*normalsp++   = normal;
		*normalsp++   = normal;
		*normalsp++   = normal;
		*normalsp++   = normal;

		*indicesp++ = index_offset + 0;
		*indicesp++ = index_offset + 1;
		*indicesp++ = index_offset + 2;

		*indicesp++ = index_offset + 1;
		*indicesp++ = index_offset + 3;
		*indicesp++ = index_offset + 2;
	}
}