void LLDrawPoolTerrain::drawLoop()
{
	if (!mDrawFace.empty())
	{
		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
		{
			LLFace *facep = *iter;

			LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix);

			if (model_matrix != gGLLastMatrix)
			{
				llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
				gGLLastMatrix = model_matrix;
				gGL.loadMatrix(gGLModelView);
				if (model_matrix)
				{
					gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
				}
				gPipeline.mMatrixOpCount++;
			}

			facep->renderIndexed();
		}
	}
}
Example #2
0
void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
{
	//precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this
	llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this));

	//precondition: groupp MUST be null or groupp MUST contain this
	llassert(!groupp || groupp->hasElement(this));

/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
	{
		mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY);
	}*/

	if (mSpatialGroupp != groupp && getVOVolume())
	{ //NULL out vertex buffer references for volumes on spatial group change to maintain
		//requirement that every face vertex buffer is either NULL or points to a vertex buffer
		//contained by its drawable's spatial group
		for (S32 i = 0; i < getNumFaces(); ++i)
		{
			LLFace* facep = getFace(i);
			if (facep)
			{
				facep->clearVertexBuffer();
			}
		}
	}

	//postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1
	//postcondition: if next group is NOT NULL, binIndex must not be -1
	llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 :
							getBinIndex() != -1);

	mSpatialGroupp = groupp;
}
Example #3
0
void LLDrawable::shiftPos(const LLVector3 &shift_vector)
{
	if (isDead())
	{
		llwarns << "Shifting dead drawable" << llendl;
		return;
	}

	if (mParent)
	{
		mXform.setPosition(mVObjp->getPosition());
	}
	else
	{
		mXform.setPosition(mVObjp->getPositionAgent());
	}

	mXform.setRotation(mVObjp->getRotation());
	mXform.setScale(1,1,1);
	mXform.updateMatrix();

	if (isStatic())
	{
		LLVOVolume* volume = getVOVolume();
		if (!volume)
		{
			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
		}

		for (S32 i = 0; i < getNumFaces(); i++)
		{
			LLFace *facep = getFace(i);
			facep->mCenterAgent += shift_vector;
			facep->mExtents[0] += shift_vector;
			facep->mExtents[1] += shift_vector;
			
			if (!volume && facep->hasGeometry())
			{
				facep->mVertexBuffer = NULL;
				facep->mLastVertexBuffer = NULL;
			}
		}
		
		mExtents[0] += shift_vector;
		mExtents[1] += shift_vector;
		mPositionGroup += LLVector3d(shift_vector);
	}
	else if (mSpatialBridge)
	{
		mSpatialBridge->shiftPos(shift_vector);
	}
	else if (isAvatar())
	{
		mExtents[0] += shift_vector;
		mExtents[1] += shift_vector;
		mPositionGroup += LLVector3d(shift_vector);
	}
	
	mVObjp->onShift(shift_vector);
}
void LLDrawPoolGround::render(S32 pass)
{
	if (mDrawFace.empty() || !gSavedSettings.getBOOL("RenderGround"))
	{
		return;
	}	
	
	LLGLSPipelineSkyBox gls_skybox;
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

	LLGLClampToFarClip far_clip(glh_get_current_projection());

	F32 water_height = gAgent.getRegion()->getWaterHeight();
	glPushMatrix();
	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
	glTranslatef(origin.mV[0], origin.mV[1], llmax(origin.mV[2], water_height));

	LLFace *facep = mDrawFace[0];

	gPipeline.disableLights();

	LLOverrideFaceColor col(this, gSky.mVOSkyp->getGLFogColor());
	facep->renderIndexed();
	
	glPopMatrix();
}
	virtual bool apply(LLViewerObject* object, S32 te)
	{
		LLFace* facep = object->mDrawable->getFace(te);
		if (!facep)
		{
			return false;
		}
		if (facep == mCenterFace)
		{
			return true;
		}
		
		LLVector2 aligned_st_offset, aligned_st_scale;
		F32 aligned_st_rot;
		if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) )
		{
			const LLTextureEntry* tep = facep->getTextureEntry();
			LLVector2 st_offset, st_scale;
			tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
			tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
			F32 st_rot = tep->getRotation();
			// needs a fuzzy comparison, because of fp errors
			if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 16) && 
				is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 16) && 
				is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 16) &&
				is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 16) &&
				is_approx_equal_fraction(st_rot, aligned_st_rot, 14))
			{
				return true;
			}
		}
		return false;
	}
	virtual bool apply(LLViewerObject* object, S32 te)
	{
		LLFace* facep = object->mDrawable->getFace(te);
		if (!facep)
		{
			return true;
		}

		bool set_aligned = true;
		if (facep == mCenterFace)
		{
			set_aligned = false;
		}
		if (set_aligned)
		{
			LLVector2 uv_offset, uv_scale;
			F32 uv_rot;
			set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot);
			if (set_aligned)
			{
				object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]);
				object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
				object->setTERotation(te, uv_rot);
			}
		}
		if (!set_aligned)
		{
			LLPanelFaceSetTEFunctor setfunc(mPanel);
			setfunc.apply(object, te);
		}
		return true;
	}
void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,
								LLStrider<LLVector3> &normalsp,
								LLStrider<LLVector2> &texCoords0p,
								LLStrider<LLVector2> &texCoords1p,
								LLStrider<U16> &indicesp)
{
	LLFace* facep = mDrawable->getFace(0);
	if (facep)
	{
		U32 index_offset = facep->getGeomIndex();

		updateMainGeometry(facep, 
						verticesp,
						normalsp,
						texCoords0p,
						texCoords1p,
						indicesp,
						index_offset);
		updateNorthGeometry(facep, 
							verticesp,
							normalsp,
							texCoords0p,
							texCoords1p,
							indicesp,
							index_offset);
		updateEastGeometry(facep, 
							verticesp,
							normalsp,
							texCoords0p,
							texCoords1p,
							indicesp,
							index_offset);
	}
}
Example #8
0
BOOL LLVOTextBubble::updateGeometry(LLDrawable *drawable)
{
 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOLUME)))
		return TRUE;
	
	if (mVolumeChanged)
	{
		LLVolumeParams volume_params = getVolume()->getParams();
		setVolume(volume_params, 0);

		LLPipeline::sCompiles++;

		drawable->setNumFaces(getVolume()->getNumFaces(), drawable->getFace(0)->getPool(), getTEImage(0));
	}

	LLMatrix4 identity4;
	LLMatrix3 identity3;
	for (S32 i = 0; i < drawable->getNumFaces(); i++)
	{
		LLFace *face = drawable->getFace(i);
		face->setTEOffset(i);
		face->setTexture(LLViewerFetchedTexture::sSmokeImagep);
		face->setState(LLFace::FULLBRIGHT);
	}

	mVolumeChanged = FALSE;

	mDrawable->movePartition();
	return TRUE;
}
void LLDrawPoolTree::render(S32 pass)
{
	LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES);

	if (mDrawFace.empty())
	{
		return;
	}

	LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1);
	LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);

	gGL.getTexUnit(sDiffTex)->bind(mTexturep);
				
	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
		 iter != mDrawFace.end(); iter++)
	{
		LLFace *face = *iter;
		LLVertexBuffer* buff = face->getVertexBuffer();
		if(buff)
		{
			buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
			buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); 
			gPipeline.addTrianglesDrawn(buff->getNumIndices());
		}
	}
}
Example #10
0
LLFace*	LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
	
	LLFace *face;
	{
		LLFastTimer t(FTM_ALLOCATE_FACE);
		face = new LLFace(this, mVObjp);
	}

	if (!face) LL_ERRS() << "Allocating new Face: " << mFaces.size() << LL_ENDL;
	
	if (face)
	{
		mFaces.push_back(face);

		if (poolp)
		{
			face->setPool(poolp, texturep);
		}

		if (isState(UNLIT))
		{
			face->setState(LLFace::FULLBRIGHT);
		}
	}
	return face;
}
void LLDrawPoolTree::render(S32 pass)
{
	LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES);

	if (mDrawFace.empty())
	{
		return;
	}

	LLGLEnable test(GL_ALPHA_TEST);
	LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);

	if (gSavedSettings.getBOOL("RenderAnimateTrees"))
	{
		renderTree();
	}
	else
	{
		gGL.getTexUnit(sDiffTex)->bind(mTexturep);
					
		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
		{
			LLFace *face = *iter;
			LLVertexBuffer* buff = face->getVertexBuffer();
			if(buff)
			{
				buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
				buff->drawRange(LLRender::TRIANGLES, 0, buff->getRequestedVerts()-1, buff->getRequestedIndices(), 0); 
				gPipeline.addTrianglesDrawn(buff->getRequestedIndices());
			}
		}
	}
}
void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
	if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
	{
		llwarns << "Attempted to update distance for non-world camera." << llendl;
		return;
	}

	//switch LOD with the spatial group to avoid artifacts
	//LLSpatialGroup* sg = getSpatialGroup();

	LLVector3 pos;

	//if (!sg || sg->changeLOD())
	{
		LLVOVolume* volume = getVOVolume();
		if (volume)
		{
			if (getSpatialGroup())
			{
				pos.set(getPositionGroup().getF32ptr());
			}
			else
			{
				pos = getPositionAgent();
			}
			
			if (isState(LLDrawable::HAS_ALPHA))
			{
				for (S32 i = 0; i < getNumFaces(); i++)
				{
					LLFace* facep = getFace(i);
					if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
					{
						LLVector4a box;
						box.setSub(facep->mExtents[1], facep->mExtents[0]);
						box.mul(0.25f);
						LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
						const LLVector3& at = camera.getAtAxis();
						for (U32 j = 0; j < 3; j++)
						{
							v.mV[j] -= box[j] * at.mV[j];
						}
						facep->mDistance = v * camera.getAtAxis();
					}
				}
			}	
		}
		else
		{
			pos = LLVector3(getPositionGroup().getF32ptr());
		}

		pos -= camera.getOrigin();	
		mDistanceWRTCamera = llround(pos.magVec(), 0.01f);
		mVObjp->updateLOD();
	}
}
Example #13
0
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);
			}
		}
	}
void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerImage*>& textures)
{
	if (textures.find(mTexturep) != textures.end())
	{
		for (std::vector<LLFace*>::iterator iter = mReferences.begin();
			 iter != mReferences.end(); iter++)
		{
			LLFace *facep = *iter;
			gPipeline.markTextured(facep->getDrawable());
		}
	}
}
Example #15
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 LLDrawable::mergeFaces(LLDrawable* src)
{
	U32 face_count = mFaces.size() + src->mFaces.size();

	mFaces.reserve(face_count);
	for (U32 i = 0; i < src->mFaces.size(); i++)
	{
		LLFace* facep = src->mFaces[i];
		facep->setDrawable(this);
		mFaces.push_back(facep);
	}
	src->mFaces.clear();
}
void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
    LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ;
    if (tex && textures.find(tex) != textures.end())
    {
        for (std::vector<LLFace*>::iterator iter = mReferences.begin();
                iter != mReferences.end(); iter++)
        {
            LLFace *facep = *iter;
            gPipeline.markTextured(facep->getDrawable());
        }
    }
}
void LLVOSurfacePatch::dirtyGeom()
{
	if (mDrawable)
	{
		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
		LLFace* facep = mDrawable->getFace(0);
		if (facep)
		{
			facep->setVertexBuffer(NULL);
		}
		mDrawable->movePartition();
	}
}
Example #19
0
std::vector<LLFace*> LocalBitmap::getFaceUsesThis(LLDrawable* drawable)
{
	std::vector<LLFace*> matching_faces;

	for ( S32 face_iter = 0; face_iter <= drawable->getNumFaces(); face_iter++ )
	{
		LLFace* newface = drawable->getFace(face_iter);

		if ( this->id == newface->getTexture()->getID() )
		{ matching_faces.push_back(newface); }
	}

	return matching_faces;
}
Example #20
0
void LLFacePool::removeFaceReference(LLFace *facep)
{
	if (facep->getReferenceIndex() != -1)
	{
		if (facep->getReferenceIndex() != (S32)mReferences.size())
		{
			LLFace *back = mReferences.back();
			mReferences[facep->getReferenceIndex()] = back;
			back->setReferenceIndex(facep->getReferenceIndex());
		}
		mReferences.pop_back();
	}
	facep->setReferenceIndex(-1);
}
Example #21
0
void LLVOTextBubble::updateFaceSize(S32 idx)
{
	LLFace* face = mDrawable->getFace(idx);
	
	if (idx == 0 || idx == 2)
	{
		face->setSize(0,0);
	}
	else
	{
		const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
		face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
	}
}
Example #22
0
// static
S32 LLFacePool::drawLoop(face_array_t& face_list)
{
	S32 res = 0;
	if (!face_list.empty())
	{
		for (std::vector<LLFace*>::iterator iter = face_list.begin();
			 iter != face_list.end(); iter++)
		{
			LLFace *facep = *iter;
			res += facep->renderIndexed();
		}
	}
	return res;
}
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);
		}
	}
}
void LLDrawPoolTree::render(S32 pass)
{
	LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES);

	if (mDrawFace.empty())
	{
		return;
	}

	LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1);
	LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);

	static LLCachedControl<bool> sRenderAnimateTrees("RenderAnimateTrees", false);
	if (sRenderAnimateTrees)
	{
		renderTree();
	}
	else
	gGL.getTexUnit(sDiffTex)->bind(mTexturep);
					
	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
	{
		LLFace *face = *iter;
		LLVertexBuffer* buff = face->getVertexBuffer();

		if(buff)
		{
			LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix);

			if (model_matrix != gGLLastMatrix)
			{
				gGLLastMatrix = model_matrix;
				gGL.loadMatrix(gGLModelView);
				if (model_matrix)
				{
					llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
					gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
				}
				gPipeline.mMatrixOpCount++;
			}

			buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
			buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); 
			gPipeline.addTrianglesDrawn(buff->getNumIndices());
		}
	}
}
Example #25
0
void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
	//switch LOD with the spatial group to avoid artifacts
	//LLSpatialGroup* sg = getSpatialGroup();

	LLVector3 pos;

	//if (!sg || sg->changeLOD())
	{
		LLVOVolume* volume = getVOVolume();
		if (volume)
		{
			volume->updateRelativeXform();
			pos = volume->getRelativeXform().getTranslation();
			if (isStatic())
			{
				pos += volume->getRegion()->getOriginAgent();
			}

			if (isState(LLDrawable::HAS_ALPHA))
			{
				for (S32 i = 0; i < getNumFaces(); i++)
				{
					LLFace* facep = getFace(i);
					if (facep->getPoolType() == LLDrawPool::POOL_ALPHA)
					{
						LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f;
						LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
						const LLVector3& at = camera.getAtAxis();
						for (U32 j = 0; j < 3; j++)
						{
							v.mV[j] -= box.mV[j] * at.mV[j];
						}
						facep->mDistance = v * camera.getAtAxis();
					}
				}
			}
		}
		else
		{
			pos = LLVector3(getPositionGroup());
		}

		pos -= camera.getOrigin();	
		mDistanceWRTCamera = llround(pos.magVec(), 0.01f);
		mVObjp->updateLOD();
	}
}
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;
	}
}
Example #27
0
// static
S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
{
	S32 res = 0;
	if (!face_list.empty())
	{
		for (std::vector<LLFace*>::iterator iter = face_list.begin();
			 iter != face_list.end(); iter++)
		{
			LLFace *facep = *iter;
			gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE);
			gGL.getTexUnit(0)->activate();
			res += facep->renderIndexed();
		}
	}
	return res;
}
//-----------------------------------------------------------------------------
// getDebugTexture()
//-----------------------------------------------------------------------------
LLViewerTexture *LLDrawPoolAvatar::getDebugTexture()
{
	if (mReferences.empty())
	{
		return NULL;
	}
	LLFace *face = mReferences[0];
	if (!face->getDrawable())
	{
		return NULL;
	}
	const LLViewerObject *objectp = face->getDrawable()->getVObj();

	// Avatar should always have at least 1 (maybe 3?) TE's.
	return objectp->getTEImage(0);
}
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);
	}
}
Example #30
0
LLDrawable* LLVOTree::createDrawable(LLPipeline *pipeline)
{
	pipeline->allocDrawable(this);
	mDrawable->setLit(FALSE);

	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TREE);

	LLDrawPoolTree *poolp = (LLDrawPoolTree*) gPipeline.getPool(LLDrawPool::POOL_TREE, mTreeImagep);

	// Just a placeholder for an actual object...
	LLFace *facep = mDrawable->addFace(poolp, mTreeImagep);
	facep->setSize(1, 3);

	updateRadius();

	return mDrawable;
}