BOOL LLVOClouds::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_CLOUDS);
	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)))
	{
		return TRUE;
	}
	
	dirtySpatialGroup();

	LLFace *facep;
	
	S32 num_faces = mCloudGroupp->getNumPuffs();

	if (num_faces > drawable->getNumFaces())
	{
		drawable->setNumFacesFast(num_faces, NULL, getTEImage(0));
	}

	mDepth = (getPositionAgent()-LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis();

	S32 face_indx = 0;
	for ( ;	face_indx < num_faces; face_indx++)
	{
		facep = drawable->getFace(face_indx);
		if (!facep)
		{
			llwarns << "No facep for index " << face_indx << llendl;
			continue;
		}

		facep->setSize(4, 6);
		
		facep->setTEOffset(face_indx);
		facep->setTexture(getTEImage(0));
		const LLCloudPuff &puff = mCloudGroupp->getPuff(face_indx);
		const LLVector3 puff_pos_agent = gAgent.getPosAgentFromGlobal(puff.getPositionGlobal());
		facep->mCenterLocal = puff_pos_agent;
		/// Update cloud color based on sun color.
		LLColor4 float_color(LLColor3(gSky.getSunDiffuseColor() + gSky.getSunAmbientColor()),puff.getAlpha());
		facep->setFaceColor(float_color);
	}
	for ( ; face_indx < drawable->getNumFaces(); face_indx++)
	{
		facep = drawable->getFace(face_indx);
		if (!facep)
		{
			llwarns << "No facep for index " << face_indx << llendl;
			continue;
		}

		facep->setTEOffset(face_indx);
		facep->setSize(0,0);
	}

	drawable->movePartition();

	return TRUE;
}
Exemple #2
0
BOOL LLVOClouds::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_CLOUDS);
 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)))
		return TRUE;
	
	LLFace *facep;
	
	S32 num_faces = mCloudGroupp->getNumPuffs();

	if (num_faces > drawable->getNumFaces())
	{
		drawable->setNumFacesFast(num_faces, NULL, getTEImage(0));
	}

	mDepth = (getPositionAgent()-gCamera->getOrigin())*gCamera->getAtAxis();

	S32 face_indx = 0;
	for ( ;	face_indx < num_faces; face_indx++)
	{
		facep = drawable->getFace(face_indx);
		if (!facep)
		{
			llwarns << "No facep for index " << face_indx << llendl;
			continue;
		}

		if (isParticle())
		{
			facep->setSize(1,1);
		}
		else
		{
			facep->setSize(4, 6);
		}
		facep->setTEOffset(face_indx);
		facep->setTexture(getTEImage(0));
		const LLCloudPuff &puff = mCloudGroupp->getPuff(face_indx);
		const LLVector3 puff_pos_agent = gAgent.getPosAgentFromGlobal(puff.getPositionGlobal());
		facep->mCenterLocal = puff_pos_agent;
	}
	for ( ; face_indx < drawable->getNumFaces(); face_indx++)
	{
		facep = drawable->getFace(face_indx);
		if (!facep)
		{
			llwarns << "No facep for index " << face_indx << llendl;
			continue;
		}

		facep->setTEOffset(face_indx);
		facep->setSize(0,0);
	}

	drawable->movePartition();

	return TRUE;
}
Exemple #3
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());
	}
}
Exemple #4
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;
}
Exemple #5
0
void LLVOSurfacePatch::updateFaceSize(S32 idx)
{
	if (idx != 0)
	{
		llwarns << "Terrain partition requested invalid face!!!" << llendl;
		return;
	}

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

	S32 num_vertices = 0;
	S32 num_indices = 0;
	
	if (mLastStride)
	{
		getGeomSizesMain(mLastStride, num_vertices, num_indices);
		getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
		getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
	}

	facep->setSize(num_vertices, num_indices);	
}
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(FTM_UPDATE_PARTICLES);

	dirtySpatialGroup();
	
	S32 num_parts = mViewerPartGroupp->getCount();
	LLFace *facep;
	LLSpatialGroup* group = drawable->getSpatialGroup();
	if (!group && num_parts)
	{
		drawable->movePartition();
		group = drawable->getSpatialGroup();
	}

	if (group && group->isVisible())
	{
		dirtySpatialGroup(TRUE);
	}

	if (!num_parts)
	{
		if (group && drawable->getNumFaces())
		{
			group->setState(LLSpatialGroup::GEOM_DIRTY);
		}
		drawable->setNumFaces(0, NULL, getTEImage(0));
		return TRUE;
	}

 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
	{
		return TRUE;
	}

	if (num_parts > drawable->getNumFaces())
	{
		drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0));
	}

	F32 tot_area = 0;

	F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; 
	F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
	pixel_meter_ratio *= pixel_meter_ratio;

	LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ;

	S32 count=0;
	mDepth = 0.f;
	S32 i = 0 ;
	LLVector3 camera_agent = getCameraPosition();
	
	F32 max_scale = 0.f;


	for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)
	{
		const LLViewerPart *part = mViewerPartGroupp->mParticles[i];


		//remember the largest particle
		max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]);

		if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK)
		{ //include ribbon segment length in scale
			const LLVector3* pos_agent = NULL;
			if (part->mParent)
			{
				pos_agent = &(part->mParent->mPosAgent);
			}
			else if (part->mPartSourcep.notNull())
			{
				pos_agent = &(part->mPartSourcep->mPosAgent);
			}

			if (pos_agent)
			{
				F32 dist = (*pos_agent-part->mPosAgent).length();

				max_scale = llmax(max_scale, dist);
			}
		}

		LLVector3 part_pos_agent(part->mPosAgent);
		LLVector3 at(part_pos_agent - camera_agent);

		
		F32 camera_dist_squared = at.lengthSquared();
		F32 inv_camera_dist_squared;
		if (camera_dist_squared > 1.f)
			inv_camera_dist_squared = 1.f / camera_dist_squared;
		else
			inv_camera_dist_squared = 1.f;

		llassert(llfinite(inv_camera_dist_squared));
		llassert(!llisnan(inv_camera_dist_squared));

		F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
		tot_area = llmax(tot_area, area);
 		
		if (tot_area > max_area)
		{
			break;
		}
	
		count++;

		facep = drawable->getFace(i);
		if (!facep)
		{
			LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL;
			continue;
		}

		facep->setTEOffset(i);
		const F32 NEAR_PART_DIST_SQ = 5.f*5.f;  // Only discard particles > 5 m from the camera
		const F32 MIN_PART_AREA = .005f*.005f;  // only less than 5 mm x 5 mm at 1 m from camera
		
		if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA)
		{
			facep->setSize(0, 0);
			continue;
		}

		facep->setSize(4, 6);
		
		facep->setViewerObject(this);

		if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
		{
			facep->setState(LLFace::FULLBRIGHT);
		}
		else
		{
			facep->clearState(LLFace::FULLBRIGHT);
		}

		facep->mCenterLocal = part->mPosAgent;
		facep->setFaceColor(part->mColor);
		facep->setTexture(part->mImagep);
			
		//check if this particle texture is replaced by a parcel media texture.
		if(part->mImagep.notNull() && part->mImagep->hasParcelMedia()) 
		{
			part->mImagep->getParcelMedia()->addMediaToFace(facep) ;
		}

		mPixelArea = tot_area * pixel_meter_ratio;
		const F32 area_scale = 10.f; // scale area to increase priority a bit
		facep->setVirtualSize(mPixelArea*area_scale);
	}
	for (i = count; i < drawable->getNumFaces(); i++)
	{
		LLFace* facep = drawable->getFace(i);
		if (!facep)
		{
			LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL;
			continue;
		}
		facep->setTEOffset(i);
		facep->setSize(0, 0);
	}

	//record max scale (used to stretch bounding box for visibility culling)
	
	mScale.set(max_scale, max_scale, max_scale);

	mDrawable->movePartition();
	return TRUE;
}
Exemple #7
0
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_PARTICLES);

	dirtySpatialGroup();
	
	S32 num_parts = mViewerPartGroupp->getCount();
	LLFace *facep;
	LLSpatialGroup* group = drawable->getSpatialGroup();
	if (!group && num_parts)
	{
		drawable->movePartition();
		group = drawable->getSpatialGroup();
	}

	if (!num_parts)
	{
		if (group && drawable->getNumFaces())
		{
			group->setState(LLSpatialGroup::GEOM_DIRTY);
		}
		drawable->setNumFaces(0, NULL, getTEImage(0));
		LLPipeline::sCompiles++;
		return TRUE;
	}

 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
	{
		return TRUE;
	}

	if (num_parts > drawable->getNumFaces())
	{
		drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0));
	}

	F32 tot_area = 0;

	F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; 
	F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
	pixel_meter_ratio *= pixel_meter_ratio;

	LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ;

	S32 count=0;
	mDepth = 0.f;
	S32 i = 0 ;
	LLVector3 camera_agent = getCameraPosition();
	for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)
	{
		const LLViewerPart *part = mViewerPartGroupp->mParticles[i];

		LLVector3 part_pos_agent(part->mPosAgent);
		LLVector3 at(part_pos_agent - camera_agent);

		F32 camera_dist_squared = at.lengthSquared();
		F32 inv_camera_dist_squared;
		if (camera_dist_squared > 1.f)
			inv_camera_dist_squared = 1.f / camera_dist_squared;
		else
			inv_camera_dist_squared = 1.f;
		F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
		tot_area = llmax(tot_area, area);
 		
		if (tot_area > max_area)
		{
			break;
		}
	
		count++;

		facep = drawable->getFace(i);
		if (!facep)
		{
			llwarns << "No face found for index " << i << "!" << llendl;
			continue;
		}

		facep->setTEOffset(i);
		const F32 NEAR_PART_DIST_SQ = 5.f*5.f;  // Only discard particles > 5 m from the camera
		const F32 MIN_PART_AREA = .005f*.005f;  // only less than 5 mm x 5 mm at 1 m from camera
		
		if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA)
		{
			facep->setSize(0, 0);
			continue;
		}

		facep->setSize(4, 6);
		
		facep->setViewerObject(this);

		if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
		{
			facep->setState(LLFace::FULLBRIGHT);
		}
		else
		{
			facep->clearState(LLFace::FULLBRIGHT);
		}

		facep->mCenterLocal = part->mPosAgent;
		facep->setFaceColor(part->mColor);
		facep->setTexture(part->mImagep);

		mPixelArea = tot_area * pixel_meter_ratio;
		const F32 area_scale = 10.f; // scale area to increase priority a bit
		facep->setVirtualSize(mPixelArea*area_scale);
	}
	for (i = count; i < drawable->getNumFaces(); i++)
	{
		LLFace* facep = drawable->getFace(i);
		if (!facep)
		{
			llwarns << "No face found for index " << i << "!" << llendl;
			continue;
		}
		facep->setTEOffset(i);
		facep->setSize(0, 0);
	}

	mDrawable->movePartition();
	LLPipeline::sCompiles++;
	return TRUE;
}
BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER);
	LLFace *face;

	if (drawable->getNumFaces() < 1)
	{
		LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
		drawable->addFace(poolp, NULL);
	}
	face = drawable->getFace(0);

//	LLVector2 uvs[4];
//	LLVector3 vtx[4];

	LLStrider<LLVector3> verticesp, normalsp;
	LLStrider<LLVector2> texCoordsp;
	LLStrider<U16> indicesp;
	U16 index_offset;


	// A quad is 4 vertices and 6 indices (making 2 triangles)
	static const unsigned int vertices_per_quad = 4;
	static const unsigned int indices_per_quad = 6;

	static const LLCachedControl<bool> render_transparent_water("RenderTransparentWater",false);
	const S32 size = (render_transparent_water && !LLGLSLShader::sNoFixedFunction) ? 16 : 1;
	const S32 num_quads = size * size;
	face->setSize(vertices_per_quad * num_quads,
				  indices_per_quad * num_quads);
	
	LLVertexBuffer* buff = face->getVertexBuffer();
	if (!buff)
	{
		buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
		buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
		face->setIndicesIndex(0);
		face->setGeomIndex(0);
		face->setVertexBuffer(buff);
	}
	else
	{
		buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount());
	}
		
	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
		
	LLVector3 position_agent;
	position_agent = getPositionAgent();
	face->mCenterAgent = position_agent;
	face->mCenterLocal = position_agent;

	S32 x, y;
	F32 step_x = getScale().mV[0] / size;
	F32 step_y = getScale().mV[1] / size;

	const LLVector3 up(0.f, step_y * 0.5f, 0.f);
	const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
	const LLVector3 normal(0.f, 0.f, 1.f);

	F32 size_inv = 1.f / size;

	for (y = 0; y < size; y++)
	{
		for (x = 0; x < size; x++)
		{
			S32 toffset = index_offset + 4*(y*size + x);
			position_agent = getPositionAgent() - getScale() * 0.5f;
			position_agent.mV[VX] += (x + 0.5f) * step_x;
			position_agent.mV[VY] += (y + 0.5f) * step_y;

			*verticesp++  = position_agent - right + up;
			*verticesp++  = position_agent - right - up;
			*verticesp++  = position_agent + right + up;
			*verticesp++  = position_agent + right - up;

			*texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2(x*size_inv, y*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv);
			
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;

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

			*indicesp++ = toffset + 1;
			*indicesp++ = toffset + 3;
			*indicesp++ = toffset + 2;
		}
	}
	
	buff->flush();

	mDrawable->movePartition();
	LLPipeline::sCompiles++;
	return TRUE;
}
Exemple #9
0
void LLSprite::updateFace(LLFace &face)
{
	LLViewerCamera &camera = *LLViewerCamera::getInstance();

	// First, figure out how many vertices/indices we need.
	U32 num_vertices, num_indices;
	U32 vertex_count = 0;
	
	// Get the total number of vertices and indices
	if (mFollow)
	{
		num_vertices = 4;
		num_indices = 6;
	}
	else
	{
		num_vertices = 4;
		num_indices = 12;
	}

	face.setSize(num_vertices, num_indices);
	
	if (mFollow) 
	{
		sCameraUp = camera.getUpAxis();
		sCameraRight = -camera.getLeftAxis();
		sCameraPosition = camera.getOrigin();
		sNormal = -camera.getAtAxis();
		if (mUseCameraUp)
		{
			// these need to live here because the height/width may change between render calls
			mScaledUp = sCameraUp;
			mScaledRight = sCameraRight;

			mScaledUp *= mHeightDiv2;
			mScaledRight *= mWidthDiv2;

			mA = mPosition + mScaledRight + mScaledUp;
			mB = mPosition - mScaledRight + mScaledUp;
			mC = mPosition - mScaledRight - mScaledUp;
			mD = mPosition + mScaledRight - mScaledUp;
		}
		else
		{
			// The up vector is perpendicular to the camera vector...
			LLVector3 camera_vec = mPosition - sCameraPosition;
			mScaledRight = camera_vec % LLVector3(0.f, 0.f, 1.f);
			mScaledUp = -(camera_vec % mScaledRight);
			mScaledUp.normalize();
			mScaledRight.normalize();
			mScaledUp *= mHeightDiv2;
			mScaledRight *= mWidthDiv2;

			mA = mPosition + mScaledRight + mScaledUp;
			mB = mPosition - mScaledRight + mScaledUp;
			mC = mPosition - mScaledRight - mScaledUp;
			mD = mPosition + mScaledRight - mScaledUp;
		}
	}
	else
	{
		// this is equivalent to how it was done before. . . 
		// we need to establish a way to 
		// identify the orientation of a particular sprite rather than
		// just banging it in on the x,z plane if it's not following the camera.

		LLVector3 x_axis;
		LLVector3 y_axis;

		F32 dot = sNormal * LLVector3(0.f, 1.f, 0.f);
		if (dot == 1.f || dot == -1.f)
		{
			x_axis.setVec(1.f, 0.f, 0.f);
			y_axis.setVec(0.f, 1.f, 0.f);
		}
		else
		{
			x_axis = sNormal % LLVector3(0.f, -1.f, 0.f);
			x_axis.normalize();

			y_axis = sNormal % x_axis;
		}

		LLQuaternion yaw_rot(mYaw, sNormal);

		// rotate axes by specified yaw
		x_axis = x_axis * yaw_rot;
		y_axis = y_axis * yaw_rot;

		// rescale axes by width and height of sprite
		x_axis = x_axis * mWidthDiv2;
		y_axis = y_axis *  mHeightDiv2;

		mA = -x_axis + y_axis;
		mB = x_axis + y_axis;
		mC = x_axis - y_axis;
		mD = -x_axis - y_axis;

		mA += mPosition;
		mB += mPosition;
		mC += mPosition;
		mD += mPosition;
	}

	face.setFaceColor(mColor);

	LLStrider<LLVector3> verticesp;
	LLStrider<LLVector3> normalsp;
	LLStrider<LLVector2> tex_coordsp;
	LLStrider<U16> indicesp;
	U16 index_offset;

	// Setup face
	if (!face.getVertexBuffer())
	{	
		LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | 
												LLVertexBuffer::MAP_TEXCOORD0,
												GL_STREAM_DRAW_ARB);
		buff->allocateBuffer(4, 12, TRUE);
		face.setGeomIndex(0);
		face.setIndicesIndex(0);
		face.setVertexBuffer(buff);
	}
		
	index_offset = face.getGeometry(verticesp,normalsp,tex_coordsp, indicesp);

	*tex_coordsp = LLVector2(0.f, 0.f);
	*verticesp = mC;
	tex_coordsp++;
	verticesp++;
	vertex_count++;

	*tex_coordsp = LLVector2(0.f, 1.f);
	*verticesp = mB;
	tex_coordsp++;
	verticesp++;
	vertex_count++;

	*tex_coordsp = LLVector2(1.f, 1.f);
	*verticesp = mA;
	tex_coordsp++;
	verticesp++;
	vertex_count++;

	*tex_coordsp = LLVector2(1.f, 0.0f);
	*verticesp = mD;
	tex_coordsp++;
	verticesp++;
	vertex_count++;

	// Generate indices, since they're easy.
	// Just a series of quads.
	*indicesp++ = index_offset;
	*indicesp++ = 2 + index_offset;
	*indicesp++ = 1 + index_offset;

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

	if (!mFollow)
	{
		*indicesp++ = 0 + index_offset;
		*indicesp++ = 1 + index_offset;
		*indicesp++ = 2 + index_offset;
		*indicesp++ = 0 + index_offset;
		*indicesp++ = 2 + index_offset;
		*indicesp++ = 3 + index_offset;
	}

	face.getVertexBuffer()->setBuffer(0);
	face.mCenterAgent = mPosition;
}
Exemple #10
0
BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
{
	LLStrider<LLVector3> verticesp;
	LLStrider<LLVector3> normalsp;
	LLStrider<LLVector2> texCoordsp;
	LLStrider<U16> indicesp;
	S32 index_offset;
	LLFace *face;	

	LLDrawPoolGround *poolp = (LLDrawPoolGround*) gPipeline.getPool(LLDrawPool::POOL_GROUND);

	if (drawable->getNumFaces() < 1)
		drawable->addFace(poolp, NULL);
	face = drawable->getFace(0); 
		
	if (face->mVertexBuffer.isNull())
	{
		face->setSize(5, 12);
		face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
		face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
		face->setGeomIndex(0);
		face->setIndicesIndex(0);
	}
	
	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
	if (-1 == index_offset)
	{
		return TRUE;
	}

	///////////////////////////////////////
	//
	//
	//
	LLVector3 at_dir = LLViewerCamera::getInstance()->getAtAxis();
	at_dir.mV[VZ] = 0.f;
	if (at_dir.normVec() < 0.01)
	{
		// We really don't care, as we're not looking anywhere near the horizon.
	}
	LLVector3 left_dir = LLViewerCamera::getInstance()->getLeftAxis();
	left_dir.mV[VZ] = 0.f;
	left_dir.normVec();

	// Our center top point
	LLColor4 ground_color = gSky.getFogColor();
	ground_color.mV[3] = 1.f;
	face->setFaceColor(ground_color);
	
	*(verticesp++)  = LLVector3(64, 64, 0);
	*(verticesp++)  = LLVector3(-64, 64, 0);
	*(verticesp++)  = LLVector3(-64, -64, 0);
	*(verticesp++)  = LLVector3(64, -64, 0);
	*(verticesp++)  = LLVector3(0, 0, -1024);
	
	
	// Triangles for each side
	*indicesp++ = index_offset + 0;
	*indicesp++ = index_offset + 1;
	*indicesp++ = index_offset + 4;

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

	*indicesp++ = index_offset + 2;
	*indicesp++ = index_offset + 3;
	*indicesp++ = index_offset + 4;

	*indicesp++ = index_offset + 3;
	*indicesp++ = index_offset + 0;
	*indicesp++ = index_offset + 4;

	*(texCoordsp++) = LLVector2(0.f, 0.f);
	*(texCoordsp++) = LLVector2(1.f, 0.f);
	*(texCoordsp++) = LLVector2(1.f, 1.f);
	*(texCoordsp++) = LLVector2(0.f, 1.f);
	*(texCoordsp++) = LLVector2(0.5f, 0.5f);
	
	face->mVertexBuffer->setBuffer(0);
	LLPipeline::sCompiles++;
	return TRUE;
}
Exemple #11
0
BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TREE);
	const F32 SRR3 = 0.577350269f; // sqrt(1/3)
	const F32 SRR2 = 0.707106781f; // sqrt(1/2)
	U32 i, j;

	U32 slices = MAX_SLICES;

	S32 max_indices = LEAF_INDICES;
	S32 max_vertices = LEAF_VERTICES;
	S32 lod;

	LLFace *face = drawable->getFace(0);

	face->mCenterAgent = getPositionAgent();
	face->mCenterLocal = face->mCenterAgent;

	for (lod = 0; lod < 4; lod++)
	{
		slices = sLODSlices[lod];
		sLODVertexOffset[lod] = max_vertices;
		sLODVertexCount[lod] = slices*slices;
		sLODIndexOffset[lod] = max_indices;
		sLODIndexCount[lod] = (slices-1)*(slices-1)*6;
		max_indices += sLODIndexCount[lod];
		max_vertices += sLODVertexCount[lod];
	}

	LLStrider<LLVector3> vertices;
	LLStrider<LLVector3> normals;
	LLStrider<LLVector2> tex_coords;
	LLStrider<U16> indicesp;

	face->setSize(max_vertices, max_indices);

	face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
	face->mVertexBuffer->allocateBuffer(max_vertices, max_indices, TRUE);
	face->setGeomIndex(0);
	face->setIndicesIndex(0);

	face->getGeometry(vertices, normals, tex_coords, indicesp);
	

	S32 vertex_count = 0;
	S32 index_count = 0;
	
	// First leaf
	*(normals++) =		LLVector3(-SRR2, -SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f);
	vertex_count++;

	*(normals++) =		LLVector3(SRR3, -SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_TOP);
	*(vertices++) =		LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(-SRR3, -SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_TOP);
	*(vertices++) =		LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(SRR2, -SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f);
	vertex_count++;


	*(indicesp++) = 0;
	index_count++;
	*(indicesp++) = 1;
	index_count++;
	*(indicesp++) = 2;
	index_count++;

	*(indicesp++) = 0;
	index_count++;
	*(indicesp++) = 3;
	index_count++;
	*(indicesp++) = 1;
	index_count++;

	// Same leaf, inverse winding/normals
	*(normals++) =		LLVector3(-SRR2, SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f);
	vertex_count++;

	*(normals++) =		LLVector3(SRR3, SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_TOP);
	*(vertices++) =		LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(-SRR3, SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_TOP);
	*(vertices++) =		LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(SRR2, SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f);
	vertex_count++;

	*(indicesp++) = 4;
	index_count++;
	*(indicesp++) = 6;
	index_count++;
	*(indicesp++) = 5;
	index_count++;

	*(indicesp++) = 4;
	index_count++;
	*(indicesp++) = 5;
	index_count++;
	*(indicesp++) = 7;
	index_count++;


	// next leaf
	*(normals++) =		LLVector3(SRR2, -SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f);
	vertex_count++;

	*(normals++) =		LLVector3(SRR3, SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_TOP);
	*(vertices++) =		LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(SRR3, -SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_TOP);
	*(vertices++) =		LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(SRR2, SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f);
	vertex_count++;

	*(indicesp++) = 8;
	index_count++;
	*(indicesp++) = 9;
	index_count++;
	*(indicesp++) = 10;
	index_count++;

	*(indicesp++) = 8;
	index_count++;
	*(indicesp++) = 11;
	index_count++;
	*(indicesp++) = 9;
	index_count++;


	// other side of same leaf
	*(normals++) =		LLVector3(-SRR2, -SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f);
	vertex_count++;

	*(normals++) =		LLVector3(-SRR3, SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_TOP);
	*(vertices++) =		LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(-SRR3, -SRR3, SRR3);
	*(tex_coords++) =	LLVector2(LEAF_LEFT, LEAF_TOP);
	*(vertices++) =		LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f);
	vertex_count++;

	*(normals++) =		LLVector3(-SRR2, SRR2, 0.f);
	*(tex_coords++) =	LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
	*(vertices++) =		LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f);
	vertex_count++;

	*(indicesp++) = 12;
	index_count++;
	*(indicesp++) = 14;
	index_count++;
	*(indicesp++) = 13;
	index_count++;

	*(indicesp++) = 12;
	index_count++;
	*(indicesp++) = 13;
	index_count++;
	*(indicesp++) = 15;
	index_count++;

	// Generate geometry for the cylinders

	// Different LOD's

	// Generate the vertices
	// Generate the indices

	for (lod = 0; lod < 4; lod++)
	{
		slices = sLODSlices[lod];
		F32 base_radius = 0.65f;
		F32 top_radius = base_radius * sSpeciesTable[mSpecies]->mTaper;
		//llinfos << "Species " << ((U32) mSpecies) << ", taper = " << sSpeciesTable[mSpecies].mTaper << llendl;
		//llinfos << "Droop " << mDroop << ", branchlength: " << mBranchLength << llendl;
		F32 angle = 0;
		F32 angle_inc = 360.f/(slices-1);
		F32 z = 0.f;
		F32 z_inc = 1.f;
		if (slices > 3)
		{
			z_inc = 1.f/(slices - 3);
		}
		F32 radius = base_radius;

		F32 x1,y1;
		F32 noise_scale = sSpeciesTable[mSpecies]->mNoiseMag;
		LLVector3 nvec;

		const F32 cap_nudge = 0.1f;			// Height to 'peak' the caps on top/bottom of branch

		const S32 fractal_depth = 5;
		F32 nvec_scale = 1.f * sSpeciesTable[mSpecies]->mNoiseScale;
		F32 nvec_scalez = 4.f * sSpeciesTable[mSpecies]->mNoiseScale;

		F32 tex_z_repeat = sSpeciesTable[mSpecies]->mRepeatTrunkZ;

		F32 start_radius;
		F32 nangle = 0;
		F32 height = 1.f;
		F32 r0;

		for (i = 0; i < slices; i++)
		{
			if (i == 0) 
			{
				z = - cap_nudge;
				r0 = 0.0;
			}
			else if (i == (slices - 1))
			{
				z = 1.f + cap_nudge;//((i - 2) * z_inc) + cap_nudge;
				r0 = 0.0;
			}
			else  
			{
				z = (i - 1) * z_inc;
				r0 = base_radius + (top_radius - base_radius)*z;
			}

			for (j = 0; j < slices; j++)
			{
				if (slices - 1 == j)
				{
					angle = 0.f;
				}
				else
				{
					angle =  j*angle_inc;
				}
			
				nangle = angle;
				
				x1 = cos(angle * DEG_TO_RAD);
				y1 = sin(angle * DEG_TO_RAD);
				LLVector2 tc;
				// This isn't totally accurate.  Should compute based on slope as well.
				start_radius = r0 * (1.f + 1.2f*fabs(z - 0.66f*height)/height);
				nvec.setVec(	cos(nangle * DEG_TO_RAD)*start_radius*nvec_scale, 
								sin(nangle * DEG_TO_RAD)*start_radius*nvec_scale, 
								z*nvec_scalez); 
				// First and last slice at 0 radius (to bring in top/bottom of structure)
				radius = start_radius + turbulence3((F32*)&nvec.mV, (F32)fractal_depth)*noise_scale;

				if (slices - 1 == j)
				{
					// Not 0.5 for slight slop factor to avoid edges on leaves
					tc = LLVector2(0.490f, (1.f - z/2.f)*tex_z_repeat);
				}
				else
				{
					tc = LLVector2((angle/360.f)*0.5f, (1.f - z/2.f)*tex_z_repeat);
				}

				*(vertices++) =		LLVector3(x1*radius, y1*radius, z);
				*(normals++) =		LLVector3(x1, y1, 0.f);
				*(tex_coords++) = tc;
				vertex_count++;
			}
		}

		for (i = 0; i < (slices - 1); i++)
		{
			for (j = 0; j < (slices - 1); j++)
			{
				S32 x1_offset = j+1;
				if ((j+1) == slices)
				{
					x1_offset = 0;
				}
				// Generate the matching quads
				*(indicesp) = j + (i*slices) + sLODVertexOffset[lod];
				llassert(*(indicesp) < (U32)max_vertices);
				indicesp++;
				index_count++;
				*(indicesp) = x1_offset + ((i+1)*slices) + sLODVertexOffset[lod];
				llassert(*(indicesp) < (U32)max_vertices);
				indicesp++;
				index_count++;
				*(indicesp) = j + ((i+1)*slices) + sLODVertexOffset[lod];
				llassert(*(indicesp) < (U32)max_vertices);
				indicesp++;
				index_count++;

				*(indicesp) = j + (i*slices) + sLODVertexOffset[lod];
				llassert(*(indicesp) < (U32)max_vertices);
				indicesp++;
				index_count++;
				*(indicesp) = x1_offset + (i*slices) + sLODVertexOffset[lod];
				llassert(*(indicesp) < (U32)max_vertices);
				indicesp++;
				index_count++;
				*(indicesp) = x1_offset + ((i+1)*slices) + sLODVertexOffset[lod];
				llassert(*(indicesp) < (U32)max_vertices);
				indicesp++;
				index_count++;
			}
		}
		slices /= 2; 
	}

	face->mVertexBuffer->setBuffer(0);
	llassert(vertex_count == max_vertices);
	llassert(index_count == max_indices);

	return TRUE;
}
Exemple #12
0
BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER);
	LLFace *face;

	if (drawable->getNumFaces() < 1)
	{
		LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
		drawable->addFace(poolp, NULL);
	}
	face = drawable->getFace(0);

//	LLVector2 uvs[4];
//	LLVector3 vtx[4];

	LLStrider<LLVector3> verticesp, normalsp;
	LLStrider<LLVector2> texCoordsp;
	LLStrider<U16> indicesp;
	U16 index_offset;

	S32 size = 16;

	S32 num_quads = size*size;	
	face->setSize(4*num_quads, 6*num_quads);

	if (face->mVertexBuffer.isNull())
	{
		face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
		face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
		face->setIndicesIndex(0);
		face->setGeomIndex(0);
	}
	else
	{
		face->mVertexBuffer->resizeBuffer(face->getGeomCount(), face->getIndicesCount());
	}
		
	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
		
	LLVector3 position_agent;
	position_agent = getPositionAgent();
	face->mCenterAgent = position_agent;
	face->mCenterLocal = position_agent;

	S32 x, y;
	F32 step_x = getScale().mV[0] / size;
	F32 step_y = getScale().mV[1] / size;

	const LLVector3 up(0.f, step_y * 0.5f, 0.f);
	const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
	const LLVector3 normal(0.f, 0.f, 1.f);

	F32 size_inv = 1.f / size;

	for (y = 0; y < size; y++)
	{
		for (x = 0; x < size; x++)
		{
			S32 toffset = index_offset + 4*(y*size + x);
			position_agent = getPositionAgent() - getScale() * 0.5f;
			position_agent.mV[VX] += (x + 0.5f) * step_x;
			position_agent.mV[VY] += (y + 0.5f) * step_y;

			*verticesp++  = position_agent - right + up;
			*verticesp++  = position_agent - right - up;
			*verticesp++  = position_agent + right + up;
			*verticesp++  = position_agent + right - up;

			*texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2(x*size_inv, y*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv);
			
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;

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

			*indicesp++ = toffset + 1;
			*indicesp++ = toffset + 3;
			*indicesp++ = toffset + 2;
		}
	}
	
	face->mVertexBuffer->setBuffer(0);

	mDrawable->movePartition();
	LLPipeline::sCompiles++;
	return TRUE;
}