示例#1
0
void LLVOCacheEntry::calcSceneContribution(const LLVector4a& camera_origin, bool needs_update, U32 last_update, F32 max_dist)
{
	if(!needs_update && getVisible() >= last_update)
	{
		return; //no need to update
	}

	LLVector4a lookAt;
	lookAt.setSub(getPositionGroup(), camera_origin);
	F32 distance = lookAt.getLength3().getF32();
	distance -= sNearRadius;

	if(distance <= 0.f)
	{
		//nearby objects, set a large number
		const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object.
		mSceneContrib = LARGE_SCENE_CONTRIBUTION;
	}
	else
	{
		F32 rad = getBinRadius();
		max_dist += rad;

		if(distance + sNearRadius < max_dist)
		{
			mSceneContrib = (rad * rad) / distance;		
		}
		else
		{
			mSceneContrib = 0.f; //out of draw distance, not to load
		}
	}

	setVisible();
}
示例#2
0
BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
{
	//VECTORIZE THIS
	//get area of circle around face
	LLVector4a center;
	center.load3(getPositionAgent().mV);
	LLVector4a size;
	size.setSub(mExtents[1], mExtents[0]);
	size.mul(0.5f);

	LLViewerCamera* camera = LLViewerCamera::getInstance();

	F32 size_squared = size.dot3(size).getF32();
	LLVector4a lookAt;
	LLVector4a t;
	t.load3(camera->getOrigin().mV);
	lookAt.setSub(center, t);
	F32 dist = lookAt.getLength3().getF32();
	dist = llmax(dist-size.getLength3().getF32(), 0.f);
	lookAt.normalize3fast() ;	

	//get area of circle around node
	F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
	radius = app_angle*LLDrawable::sCurPixelAngle;
	mPixelArea = radius*radius * 3.14159f;
	LLVector4a x_axis;
	x_axis.load3(camera->getXAxis().mV);
	cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32();

	if(dist < mBoundingSphereRadius) //camera is very close
	{
		cos_angle_to_view_dir = 1.0f;
		mImportanceToCamera = 1.0f;
	}
	else
	{
		mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist);
	}

	return true;
}
示例#3
0
void LLVOCacheEntry::setBoundingInfo(const LLVector3& pos, const LLVector3& scale)
{
	LLVector4a center, newMin, newMax;
	center.load3(pos.mV);
	LLVector4a size;
	size.load3(scale.mV);
	newMin.setSub(center, size);
	newMax.setAdd(center, size);
	
	setPositionGroup(center);
	setSpatialExtents(newMin, newMax);

	if(getNumOfChildren() > 0) //has children
	{
		updateParentBoundingInfo();
	}
	else
	{
		setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f));
	}
}
bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 pixel_threshold, F32 near_radius)
{	
	LLVector3 local_orig = mCamera->getOrigin() - shift;
	LLVector4a origin;
	origin.load3(local_orig.mV);

	LLVector4a lookAt;
	lookAt.setSub(center, origin);
	F32 distance = lookAt.getLength3().getF32();
	if(distance <= near_radius)
	{
		return true; //always load close-by objects
	}

	// treat object as if it were near_radius meters closer than it actually was.
	// this allows us to get some temporal coherence on visibility...objects that can be reached quickly will tend to be visible
	distance -= near_radius;

	F32 squared_rad = size.dot3(size).getF32();
	return squared_rad / distance > pixel_threshold;
}
示例#5
0
//make the parent bounding box to include this child
void LLVOCacheEntry::updateParentBoundingInfo(const LLVOCacheEntry* child)
{
	const LLVector4a* child_exts = child->getSpatialExtents();
	LLVector4a newMin, newMax;
	newMin = child_exts[0];
	newMax = child_exts[1];
	
	//move to regional space.
	{
		const LLVector4a& parent_pos = getPositionGroup();
		newMin.add(parent_pos);
		newMax.add(parent_pos);
	}

	//update parent's bbox(min, max)
	const LLVector4a* parent_exts = getSpatialExtents();
	update_min_max(newMin, newMax, parent_exts[0]);
	update_min_max(newMin, newMax, parent_exts[1]);
	for(S32 i = 0; i < 4; i++)
	{
		llclamp(newMin[i], 0.f, 256.f);
		llclamp(newMax[i], 0.f, 256.f);
	}
	setSpatialExtents(newMin, newMax);

	//update parent's bbox center
	LLVector4a center;
	center.setAdd(newMin, newMax);
	center.mul(0.5f);
	setPositionGroup(center);	

	//update parent's bbox size vector
	LLVector4a size;
	size.setSub(newMax, newMin);
	size.mul(0.5f);
	setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f));
}
void LLSpatialBridge::updateSpatialExtents()
{
	LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0);
	
	{
		LLFastTimer ftm(FTM_CULL_REBOUND);
		root->rebound();
	}
	
	LLVector4a offset;
	LLVector4a size = root->mBounds[1];
		
	//VECTORIZE THIS
	LLMatrix4a mat;
	mat.loadu(mDrawable->getXform()->getWorldMatrix());

	LLVector4a t;
	t.splat(0.f);

	LLVector4a center;
	mat.affineTransform(t, center);
	
	mat.rotate(root->mBounds[0], offset);
	center.add(offset);
	
	LLVector4a v[4];

	//get 4 corners of bounding box
	mat.rotate(size,v[0]);

	LLVector4a scale;
	
	scale.set(-1.f, -1.f, 1.f);
	scale.mul(size);
	mat.rotate(scale, v[1]);
	
	scale.set(1.f, -1.f, -1.f);
	scale.mul(size);
	mat.rotate(scale, v[2]);
	
	scale.set(-1.f, 1.f, -1.f);
	scale.mul(size);
	mat.rotate(scale, v[3]);

	
	LLVector4a& newMin = mExtents[0];
	LLVector4a& newMax = mExtents[1];
	
	newMin = newMax = center;
	
	for (U32 i = 0; i < 4; i++)
	{
		LLVector4a delta;
		delta.setAbs(v[i]);
		LLVector4a min;
		min.setSub(center, delta);
		LLVector4a max;
		max.setAdd(center, delta);

		newMin.setMin(newMin, min);
		newMax.setMax(newMax, max);
	}
	
	LLVector4a diagonal;
	diagonal.setSub(newMax, newMin);
	mRadius = diagonal.getLength3().getF32() * 0.5f;
	
	mPositionGroup.setAdd(newMin,newMax);
	mPositionGroup.mul(0.5f);
	updateBinRadius();
}
示例#7
0
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
								const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
{
	LLMemType mt1(LLMemType::MTYPE_DRAWABLE);

	//get bounding box
	if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION
#if MESH_ENABLED
		| LLDrawable::REBUILD_RIGGED
#endif //MESH_ENABLED
		))
	{
		//VECTORIZE THIS
		LLMatrix4a mat_vert;
		mat_vert.loadu(mat_vert_in);

		LLMatrix4a mat_normal;
		mat_normal.loadu(mat_normal_in);

		//if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
		//{ //vertex buffer no longer valid
		//	mVertexBuffer = NULL;
		//	mLastVertexBuffer = NULL;
		//}

		//VECTORIZE THIS
		LLVector4a min,max;
	
		if (f >= volume.getNumVolumeFaces())
		{
			llwarns << "Generating bounding box for invalid face index!" << llendl;
			f = 0;
		}

		const LLVolumeFace &face = volume.getVolumeFace(f);
		min = face.mExtents[0];
		max = face.mExtents[1];
		
		llassert(less_than_max_mag(min));
		llassert(less_than_max_mag(max));

		//min, max are in volume space, convert to drawable render space
		LLVector4a center;
		LLVector4a t;
		t.setAdd(min, max);
		t.mul(0.5f);
		mat_vert.affineTransform(t, center);
		LLVector4a size;
		size.setSub(max, min);
		size.mul(0.5f);

		llassert(less_than_max_mag(min));
		llassert(less_than_max_mag(max));

		if (!global_volume)
		{
			//VECTORIZE THIS
			LLVector4a scale;
			scale.load3(mDrawablep->getVObj()->getScale().mV);
			size.mul(scale);
		}

		mat_normal.mMatrix[0].normalize3fast();
		mat_normal.mMatrix[1].normalize3fast();
		mat_normal.mMatrix[2].normalize3fast();
		
		LLVector4a v[4];

		//get 4 corners of bounding box
		mat_normal.rotate(size,v[0]);

		//VECTORIZE THIS
		LLVector4a scale;
		
		scale.set(-1.f, -1.f, 1.f);
		scale.mul(size);
		mat_normal.rotate(scale, v[1]);
		
		scale.set(1.f, -1.f, -1.f);
		scale.mul(size);
		mat_normal.rotate(scale, v[2]);
		
		scale.set(-1.f, 1.f, -1.f);
		scale.mul(size);
		mat_normal.rotate(scale, v[3]);

		LLVector4a& newMin = mExtents[0];
		LLVector4a& newMax = mExtents[1];
		
		newMin = newMax = center;
		
		llassert(less_than_max_mag(center));
		
		for (U32 i = 0; i < 4; i++)
		{
			LLVector4a delta;
			delta.setAbs(v[i]);
			LLVector4a min;
			min.setSub(center, delta);
			LLVector4a max;
			max.setAdd(center, delta);

			newMin.setMin(newMin,min);
			newMax.setMax(newMax,max);

			llassert(less_than_max_mag(newMin));
			llassert(less_than_max_mag(newMax));
		}

		if (!mDrawablep->isActive())
		{
			LLVector4a offset;
			offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
			newMin.add(offset);
			newMax.add(offset);
			
			llassert(less_than_max_mag(newMin));
			llassert(less_than_max_mag(newMax));
		}

		t.setAdd(newMin, newMax);
		t.mul(0.5f);

		llassert(less_than_max_mag(t));
		
		//VECTORIZE THIS
		mCenterLocal.set(t.getF32ptr());
		
		llassert(less_than_max_mag(newMin));
		llassert(less_than_max_mag(newMax));

		t.setSub(newMax,newMin);
		mBoundingSphereRadius = t.getLength3().getF32()*0.5f;

		updateCenterAgent();
	}

	return TRUE;
}