예제 #1
0
BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
 	if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE)))
	{
		return TRUE;
	}
	
	S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ;
	F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor;

	for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++)
	{
		if (app_angle > LLVOTree::sLODAngles[j])
		{
			trunk_LOD = j;
			break;
		}
	} 

	if (mReferenceBuffer.isNull())
	{
		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
	}
	else if (trunk_LOD != mTrunkLOD)
	{
		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE);
	}
	else
	{
		// we're not animating but we may *still* need to
		// regenerate the mesh if we moved, since position
		// and rotation are baked into the mesh.
		// *TODO: I don't know what's so special about trees
		// that they don't get REBUILD_POSITION automatically
		// at a higher level.
		const LLVector3 &this_position = getPositionAgent();
		if (this_position != mLastPosition)
		{
			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
			mLastPosition = this_position;
		}
		else
		{
			const LLQuaternion &this_rotation = getRotation();
			
			if (this_rotation != mLastRotation)
			{
				gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
				mLastRotation = this_rotation;
			}
		}
	}

	mTrunkLOD = trunk_LOD;

	return TRUE;
}
예제 #2
0
BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
	const U16 FRAMES_PER_WIND_UPDATE = 20;				//  How many frames between wind update per tree
	const F32 TREE_WIND_SENSITIVITY = 0.005f;
	const F32 TREE_TRUNK_STIFFNESS = 0.1f;

 	if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE)))
	{
		return TRUE;
	}
	
	//it's cheaper to check if wind is enabled first
	if (gLLWindEnabled && gSavedSettings.getBOOL("RenderAnimateTrees"))
	{
		F32 mass_inv; 

		//  For all tree objects, update the trunk bending with the current wind 
		//  Walk sprite list in order away from viewer 
		if (!(mFrameCount % FRAMES_PER_WIND_UPDATE)) 
		{
			//  If needed, Get latest wind for this tree
			mWind = mRegionp->mWind.getVelocity(getPositionRegion());
		}
		mFrameCount++;

		mass_inv = 1.f/(5.f + mDepth*mBranches*0.2f);
		mTrunkVel += (mWind * mass_inv * TREE_WIND_SENSITIVITY);		//  Pull in direction of wind
		mTrunkVel -= (mTrunkBend * mass_inv * TREE_TRUNK_STIFFNESS);		//  Restoring force in direction of trunk 	
		mTrunkBend += mTrunkVel;
		mTrunkVel *= 0.99f;									//  Add damping

		if (mTrunkBend.length() > 1.f)
		{
			mTrunkBend.normalize();
		}

		if (mTrunkVel.length() > 1.f)
		{
			mTrunkVel.normalize();
		}
	}

	S32 trunk_LOD = 0;
	F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor;

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

		if (app_angle > LLVOTree::sLODAngles[j])
		{
			trunk_LOD = j;
			break;
		}
	} 

	if (!gLLWindEnabled || !gSavedSettings.getBOOL("RenderAnimateTrees"))
	{
		if (mReferenceBuffer.isNull())
		{
			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
		}
		else if (trunk_LOD != mTrunkLOD)
		{
			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE);
		}
		else
		{
			// we're not animating but we may *still* need to
			// regenerate the mesh if we moved, since position
			// and rotation are baked into the mesh.
			// *TODO: I don't know what's so special about trees
			// that they don't get REBUILD_POSITION automatically
			// at a higher level.
			const LLVector3 &this_position = getPositionAgent();
			if (this_position != mLastPosition)
			{
				gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
				mLastPosition = this_position;
			}
			else
			{
				const LLQuaternion &this_rotation = getRotation();
				
				if (this_rotation != mLastRotation)
				{
					gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
					mLastRotation = this_rotation;
				}
			}
		}
	}

	mTrunkLOD = trunk_LOD;

	return TRUE;
}