Esempio n. 1
0
	//-----------------------------------------------------------------------
	bool Frustum::isVisible(const Vector3& vert, FrustumPlane* culledBy) const
	{
		// 对视锥体进行必要的更新
		updateFrustumPlanes();

		// 遍历视锥体的每个平面,对每个平面, 见如果所有的点都在反面
		// 如果这样,对象不可见
		for (int plane = 0; plane < 6; ++plane)
		{
			// 如果视锥体无限,跳过远裁平面
			if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
				continue;

			if (mFrustumPlanes[plane].getSide(vert) == Plane::NEGATIVE_SIDE)
			{
				// 所有的角都在反面,那么在视域之外
				if (culledBy)
					*culledBy = (FrustumPlane)plane;
				return false;
			}

		}

		return true;
	}
Esempio n. 2
0
	//-----------------------------------------------------------------------
	bool Frustum::isVisible(const Sphere& sphere, FrustumPlane* culledBy) const
	{

		updateFrustumPlanes();

		// 遍历视锥体的每个平面,对每个平面, 见如果所有的点都在反面
		// 如果这样,对象不可见
		for (int plane = 0; plane < 6; ++plane)
		{
			// 如果视锥体空间无限,跳过
			if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
				continue;

			// 如果球体中心到平面的距离为负,并且大于球体半径,那么球在视锥体之外
			if (mFrustumPlanes[plane].getDistance(sphere.getCenter()) < -sphere.getRadius())
			{
				// 所有的角在反面,那么不在视野
				if (culledBy)
					*culledBy = (FrustumPlane)plane;
				return false;
			}

		}

		return true;
	}
Esempio n. 3
0
    //-----------------------------------------------------------------------
    bool Frustum::isVisible(const Sphere& sphere, FrustumPlane* culledBy) const
    {
        // Make any pending updates to the calculated frustum planes
        updateFrustumPlanes();

        // For each plane, see if sphere is on negative side
        // If so, object is not visible
        for (int plane = 0; plane < 6; ++plane)
        {
            // Skip far plane if infinite view frustum
            if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
                continue;

            // If the distance from sphere center to plane is negative, and 'more negative' 
            // than the radius of the sphere, sphere is outside frustum
            if (mFrustumPlanes[plane].getDistance(sphere.getCenter()) < -sphere.getRadius())
            {
                // ALL corners on negative side therefore out of view
                if (culledBy)
                    *culledBy = (FrustumPlane)plane;
                return false;
            }

        }

        return true;
    }
Esempio n. 4
0
	//-----------------------------------------------------------------------
	const Plane* Frustum::getFrustumPlanes(void) const
	{
		// 使任何未发生的更新这个视锥体平面发生更新
		updateFrustumPlanes();

		return mFrustumPlanes;
	}
    // this version checks against extra culling planes
    bool PCZCamera::isVisible( const AxisAlignedBox &bound, FrustumPlane *culledBy) const 
    {
        // Null boxes always invisible
        if ( bound.isNull() )
            return false;

        // Make any pending updates to the calculated frustum planes
        updateFrustumPlanes();

		// check extra culling planes
        bool extraResults;
        extraResults = mExtraCullingFrustum.isVisible(bound);
        if (!extraResults)
        {
            return false;
        }

		// check "regular" camera frustum
		bool regcamresults = Camera::isVisible(bound, culledBy);

		if (!regcamresults)
		{
			// culled by regular culling planes
			return regcamresults;
		}


		return true;
   }
Esempio n. 6
0
    //-----------------------------------------------------------------------
    bool Frustum::isVisible(const Vector3& vert, FrustumPlane* culledBy) const
    {
        // Make any pending updates to the calculated frustum planes
        updateFrustumPlanes();

        // For each plane, see if all points are on the negative side
        // If so, object is not visible
        for (int plane = 0; plane < 6; ++plane)
        {
            // Skip far plane if infinite view frustum
            if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
                continue;

            if (mFrustumPlanes[plane].getSide(vert) == Plane::NEGATIVE_SIDE)
            {
                // ALL corners on negative side therefore out of view
                if (culledBy)
                    *culledBy = (FrustumPlane)plane;
                return false;
            }

        }

        return true;
    }
Esempio n. 7
0
    //-----------------------------------------------------------------------
    const Plane* Frustum::getFrustumPlanes(void) const
    {
        // Make any pending updates to the calculated frustum planes
        updateFrustumPlanes();

        return mFrustumPlanes;
    }
Esempio n. 8
0
	//-----------------------------------------------------------------------
	const Plane& Frustum::getFrustumPlane(unsigned short plane) const
	{
		// 使任何未发生的更新这个视锥体平面发生更新
		updateFrustumPlanes();

		return mFrustumPlanes[plane];

	}
Esempio n. 9
0
    //-----------------------------------------------------------------------
    const Plane& Frustum::getFrustumPlane(unsigned short plane) const
    {
        // Make any pending updates to the calculated frustum planes
        updateFrustumPlanes();

        return mFrustumPlanes[plane];

    }
Esempio n. 10
0
	PlaneBoundedVolume Frustum::getPlaneBoundedVolume()
	{
		updateFrustumPlanes();

		PlaneBoundedVolume volume;
		volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_NEAR]);
		volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_FAR]);
		volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_BOTTOM]);
		volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_TOP]);
		volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_LEFT]);
		volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_RIGHT]);
		return volume;
	}
Esempio n. 11
0
	//-----------------------------------------------------------------------
	bool Frustum::isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy) const
	{
		// AABB盒子是个空盒子,不可见
		if (bound.isNull()) return false;

		// AABB盒子无限大
		if (bound.isInfinite()) return true;

		// 进行必要的更新
		updateFrustumPlanes();

		// 获取AABB盒子的中心
		Vector3 centre = bound.getCenter();
		// 获取盒子半大小向量
		Vector3 halfSize = bound.getHalfSize();

		// 遍历视锥体的每个平面,对每个平面, 见如果所有的点都在反面
		// 如果这样,对象不可见
		for (int plane = 0; plane < 6; ++plane)
		{
			// 如果视锥体无限,跳过远裁平面
			if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
				continue;

			Plane::Side side = mFrustumPlanes[plane].getSide(centre, halfSize);
			if (side == Plane::NEGATIVE_SIDE)
			{
				// 所有的角都在反面,那么在视域之外
				if (culledBy)
					*culledBy = (FrustumPlane)plane;
				return false;
			}

		}

		return true;
	}
Esempio n. 12
0
    //-----------------------------------------------------------------------
    bool Frustum::isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy) const
    {
        // Null boxes always invisible
        if (bound.isNull()) return false;

        // Infinite boxes always visible
        if (bound.isInfinite()) return true;

        // Make any pending updates to the calculated frustum planes
        updateFrustumPlanes();

        // Get centre of the box
        Vector3 centre = bound.getCenter();
        // Get the half-size of the box
        Vector3 halfSize = bound.getHalfSize();

        // For each plane, see if all points are on the negative side
        // If so, object is not visible
        for (int plane = 0; plane < 6; ++plane)
        {
            // Skip far plane if infinite view frustum
            if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
                continue;

            Plane::Side side = mFrustumPlanes[plane].getSide(centre, halfSize);
            if (side == Plane::NEGATIVE_SIDE)
            {
                // ALL corners on negative side therefore out of view
                if (culledBy)
                    *culledBy = (FrustumPlane)plane;
                return false;
            }

        }

        return true;
    }
Esempio n. 13
0
	//---------------------------------------------------------------------()
	void Camera::getCameraToViewportBoxVolume(Real screenLeft, 
		Real screenTop, Real screenRight, Real screenBottom, 
		PlaneBoundedVolume* outVolume, bool includeFarPlane)
	{
		outVolume->planes.clear();

		if (mProjType == PT_PERSPECTIVE)
		{

			// Use the corner rays to generate planes
			Ray ul = getCameraToViewportRay(screenLeft, screenTop);
			Ray ur = getCameraToViewportRay(screenRight, screenTop);
			Ray bl = getCameraToViewportRay(screenLeft, screenBottom);
			Ray br = getCameraToViewportRay(screenRight, screenBottom);


			Vector3 normal;
			// top plane
			normal = ul.getDirection().crossProduct(ur.getDirection());
			normal.normalise();
			outVolume->planes.push_back(
				Plane(normal, getDerivedPosition()));

			// right plane
			normal = ur.getDirection().crossProduct(br.getDirection());
			normal.normalise();
			outVolume->planes.push_back(
				Plane(normal, getDerivedPosition()));

			// bottom plane
			normal = br.getDirection().crossProduct(bl.getDirection());
			normal.normalise();
			outVolume->planes.push_back(
				Plane(normal, getDerivedPosition()));

			// left plane
			normal = bl.getDirection().crossProduct(ul.getDirection());
			normal.normalise();
			outVolume->planes.push_back(
				Plane(normal, getDerivedPosition()));

		}
		else
		{
			// ortho planes are parallel to frustum planes

			Ray ul = getCameraToViewportRay(screenLeft, screenTop);
			Ray br = getCameraToViewportRay(screenRight, screenBottom);

			updateFrustumPlanes();
			outVolume->planes.push_back(
				Plane(mFrustumPlanes[FRUSTUM_PLANE_TOP].normal, ul.getOrigin()));
			outVolume->planes.push_back(
				Plane(mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal, br.getOrigin()));
			outVolume->planes.push_back(
				Plane(mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal, br.getOrigin()));
			outVolume->planes.push_back(
				Plane(mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal, ul.getOrigin()));
			

		}

		// near & far plane applicable to both projection types
		outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_NEAR));
		if (includeFarPlane)
			outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_FAR));
	}
Esempio n. 14
0
void LLViewerCamera::setPerspective(BOOL for_selection,
									S32 x, S32 y_from_bot, S32 width, S32 height,
									BOOL limit_select_distance,
									F32 z_near, F32 z_far)
{
	F32 fov_y, aspect;
	fov_y = RAD_TO_DEG * getView();
	BOOL z_default_near, z_default_far = FALSE;
	if (z_far <= 0)
	{
		z_default_far = TRUE;
		z_far = getFar();
	}
	if (z_near <= 0)
	{
		z_default_near = TRUE;
		z_near = getNear();
	}
	aspect = getAspect();

	// Load camera view matrix
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();

	glh::matrix4f proj_mat;

	if (for_selection)
	{
		// make a tiny little viewport
		// anything drawn into this viewport will be "selected"

		GLint viewport[4];
		viewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
		viewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
		viewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
		viewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
		
		proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport);

		if (limit_select_distance)
		{
			// ...select distance from control
			z_far = gSavedSettings.getF32("MaxSelectDistance");
		}
		else
		{
			z_far = gAgent.mDrawDistance;
		}
	}
	else
	{
		// Only override the far clip if it's not passed in explicitly.
		if (z_default_far)
		{
			z_far = MAX_FAR_CLIP;
		}
		glViewport(x, y_from_bot, width, height);
		gGLViewport[0] = x;
		gGLViewport[1] = y_from_bot;
		gGLViewport[2] = width;
		gGLViewport[3] = height;
	}
	
	if (mZoomFactor > 1.f)
	{
		float offset = mZoomFactor - 1.f;
		int pos_y = mZoomSubregion / llceil(mZoomFactor);
		int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor));
		glh::matrix4f translate;
		translate.set_translate(glh::vec3f(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f));
		glh::matrix4f scale;
		scale.set_scale(glh::vec3f(mZoomFactor, mZoomFactor, 1.f));

		proj_mat = scale*proj_mat;
		proj_mat = translate*proj_mat;
	}

	calcProjection(z_far); // Update the projection matrix cache

	proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far);

	glLoadMatrixf(proj_mat.m);

	for (U32 i = 0; i < 16; i++)
	{
		gGLProjection[i] = proj_mat.m[i];
	}

	glMatrixMode( GL_MODELVIEW );

	glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION);

	GLfloat			ogl_matrix[16];

	getOpenGLTransform(ogl_matrix);

	modelview *= glh::matrix4f(ogl_matrix);
	
	glLoadMatrixf(modelview.m);
	
	if (for_selection && (width > 1 || height > 1))
	{
		// NB: as of this writing, i believe the code below is broken (doesn't take into account the world view, assumes entire window)
		// however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not
		// comfortable hacking on it.
		calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
								(F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f,
								(F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
								(F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f);

	}

	// if not picking and not doing a snapshot, cache various GL matrices
	if (!for_selection && mZoomFactor == 1.f)
	{
		// Save GL matrices for access elsewhere in code, especially project_world_to_screen
		//glGetDoublev(GL_MODELVIEW_MATRIX, gGLModelView);
		for (U32 i = 0; i < 16; i++)
		{
			gGLModelView[i] = modelview.m[i];
		}
	}

	updateFrustumPlanes(*this);

	/*if (gSavedSettings.getBOOL("CameraOffset"))
	{
		glMatrixMode(GL_PROJECTION);
		glTranslatef(0,0,-50);
		glRotatef(20.0,1,0,0);
		glMatrixMode(GL_MODELVIEW);
	}*/
}
Esempio n. 15
0
void LLViewerCamera::setPerspective(BOOL for_selection,
									S32 x, S32 y_from_bot, S32 width, S32 height,
									BOOL limit_select_distance,
									F32 z_near, F32 z_far)
{
	F32 fov_y, aspect;
	fov_y = RAD_TO_DEG * getView();
	BOOL z_default_far = FALSE;
	if (z_far <= 0)
	{
		z_default_far = TRUE;
		z_far = getFar();
	}
	if (z_near <= 0)
	{
		z_near = getNear();
	}
	aspect = getAspect();

	// Load camera view matrix
	gGL.matrixMode( LLRender::MM_PROJECTION );
	gGL.loadIdentity();

	LLMatrix4a proj_mat;
	proj_mat.setIdentity();

	if (for_selection)
	{
		// make a tiny little viewport
		// anything drawn into this viewport will be "selected"

		const LLRect& rect = gViewerWindow->getWorldViewRectRaw();
		
		const F32 scale_x = rect.getWidth() / F32(width);
		const F32 scale_y = rect.getHeight() / F32(height);
		const F32 trans_x = scale_x + (2.f * (rect.mLeft - x)) / F32(width) - 1.f;
		const F32 trans_y = scale_y + (2.f * (rect.mBottom - y_from_bot)) / F32(height) - 1.f;

		//Generate a pick matrix
		proj_mat.applyScale_affine(scale_x, scale_y, 1.f);
		proj_mat.setTranslate_affine(LLVector3(trans_x, trans_y, 0.f));

		if (limit_select_distance)
		{
			// ...select distance from control
//			z_far = gSavedSettings.getF32("MaxSelectDistance");
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e
			z_far = (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) ? gSavedSettings.getF32("MaxSelectDistance") : 1.5;
// [/RLVa:KB]
		}
		else
		{
			z_far = gAgentCamera.mDrawDistance;
		}
	}
	else
	{
		// Only override the far clip if it's not passed in explicitly.
		if (z_default_far)
		{
			z_far = MAX_FAR_CLIP;
		}
		glViewport(x, y_from_bot, width, height);
		gGLViewport[0] = x;
		gGLViewport[1] = y_from_bot;
		gGLViewport[2] = width;
		gGLViewport[3] = height;
	}
	
	if (mZoomFactor > 1.f)
	{
		float offset = mZoomFactor - 1.f;
		int pos_y = mZoomSubregion / llceil(mZoomFactor);
		int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor));

		proj_mat.applyTranslation_affine(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f);
		proj_mat.applyScale_affine(mZoomFactor,mZoomFactor,1.f);
	}

	calcProjection(z_far); // Update the projection matrix cache

	proj_mat.mul(gGL.genPersp(fov_y,aspect,z_near,z_far));
	
	gGL.loadMatrix(proj_mat);
	
	gGLProjection = proj_mat;

	gGL.matrixMode(LLRender::MM_MODELVIEW );

	LLMatrix4a ogl_matrix;
	getOpenGLTransform(ogl_matrix.getF32ptr());

	LLMatrix4a modelview;
	modelview.setMul(OGL_TO_CFR_ROTATION, ogl_matrix);
	
	gGL.loadMatrix(modelview);
	
	if (for_selection && (width > 1 || height > 1))
	{
		// NB: as of this writing, i believe the code below is broken (doesn't take into account the world view, assumes entire window)
		// however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not
		// comfortable hacking on it.
		calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
								(F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f,
								(F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
								(F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f);

	}

	// if not picking and not doing a snapshot, cache various GL matrices
	if (!for_selection && mZoomFactor == 1.f)
	{
		// Save GL matrices for access elsewhere in code, especially project_world_to_screen
		//glGetDoublev(GL_MODELVIEW_MATRIX, gGLModelView);
		glh_set_current_modelview(modelview);
	}

	updateFrustumPlanes(*this);

	/*if (gSavedSettings.getBOOL("CameraOffset"))
	{
		gGL.matrixMode(LLRender::MM_PROJECTION);
		gGL.translatef(0,0,-50);
		gGL.rotatef(20.0,1,0,0);
		gGL.matrixMode(LLRender::MM_MODELVIEW);
	}*/
}
Esempio n. 16
0
void kore::Camera::paramsChanged() {
    _matViewProj = _matProjection * _matView;
    updateFrustumPlanes();
}