Esempio n. 1
0
void LLCamera::setNear(F32 near_plane) 
{
	mNearPlane = near_plane;
	if (mNearPlane < MIN_NEAR_PLANE)		{ mNearPlane = MIN_NEAR_PLANE; }
	else if (mNearPlane > MAX_NEAR_PLANE)	{ mNearPlane = MAX_NEAR_PLANE; }
	calculateFrustumPlanes();
}
Esempio n. 2
0
void LLCamera::setView(F32 field_of_view) 
{
	mView = field_of_view;
	if (mView < MIN_FIELD_OF_VIEW) 			{ mView = MIN_FIELD_OF_VIEW; }
	else if (mView > MAX_FIELD_OF_VIEW)		{ mView = MAX_FIELD_OF_VIEW; }
	calculateFrustumPlanes();
}
Esempio n. 3
0
LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) :
	LLCoordFrame(),
	mView(z_field_of_view),
	mAspect(aspect_ratio),
	mViewHeightInPixels(view_height_in_pixels),
	mNearPlane(near_plane),
	mFarPlane(far_plane),
	mFixedDistance(-1.f),
	mPlaneCount(6)
{
	if (mView < MIN_FIELD_OF_VIEW) 			{ mView = MIN_FIELD_OF_VIEW; }
	else if (mView > MAX_FIELD_OF_VIEW)		{ mView = MAX_FIELD_OF_VIEW; }

	if (mAspect < MIN_ASPECT_RATIO)			{ mAspect = MIN_ASPECT_RATIO; }
	else if (mAspect > MAX_ASPECT_RATIO)	{ mAspect = MAX_ASPECT_RATIO; }

	if (mNearPlane < MIN_NEAR_PLANE)		{ mNearPlane = MIN_NEAR_PLANE; }
	else if (mNearPlane > MAX_NEAR_PLANE)	{ mNearPlane = MAX_NEAR_PLANE; }

	if (mFarPlane < 0) 						{ mFarPlane = DEFAULT_FAR_PLANE; }
	else if (mFarPlane < MIN_FAR_PLANE)		{ mFarPlane = MIN_FAR_PLANE; }
	else if (mFarPlane > MAX_FAR_PLANE)		{ mFarPlane = MAX_FAR_PLANE; }

	calculateFrustumPlanes();
} 
Esempio n. 4
0
void LLCamera::setFar(F32 far_plane) 
{
	mFarPlane = far_plane;
	if (mFarPlane < MIN_FAR_PLANE)			{ mFarPlane = MIN_FAR_PLANE; }
	else if (mFarPlane > MAX_FAR_PLANE)		{ mFarPlane = MAX_FAR_PLANE; }
	calculateFrustumPlanes();
}
Esempio n. 5
0
void LLCamera::setViewHeightInPixels(S32 height)
{
	mViewHeightInPixels = height;

	// Don't really need to do this, but update the pixel meter ratio with it.
	calculateFrustumPlanes();
}
Esempio n. 6
0
void LLCamera::setAspect(F32 aspect_ratio) 
{
	mAspect = aspect_ratio;
	if (mAspect < MIN_ASPECT_RATIO)			{ mAspect = MIN_ASPECT_RATIO; }
	else if (mAspect > MAX_ASPECT_RATIO)	{ mAspect = MAX_ASPECT_RATIO; }
	calculateFrustumPlanes();
}
Esempio n. 7
0
bool Camera::update() {
    if ((!dirty) && equal(posSpeed, 0.0f) && equal(rotSpeed, 0.0f))
        return false;

    while (rot.x > rotationAngleClamp)
        rot.x -= rotationAngleClamp;
    while (rot.x < -rotationAngleClamp)
        rot.x += rotationAngleClamp;
    while (rot.y > rotationAngleClamp)
        rot.y -= rotationAngleClamp;
    while (rot.y < -rotationAngleClamp)
        rot.y += rotationAngleClamp;

    float dT = RunTime::getLastFrameTime();
    glm::vec2 newRot = rot + rotSpeed * dT;

    if ((newRot.y > -rotationAngleVertMax) && (newRot.y < rotationAngleVertMax))
        rot = newRot;
    else
        rotSpeed = glm::vec2(0.0f, 0.0f);

    static glm::quat quatZ = glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f));
    glm::quat quatY = glm::angleAxis(rot.x, glm::vec3(0.0f, 1.0f, 0.0f));
    glm::quat quatX = glm::angleAxis(rot.y, glm::vec3(1.0f, 0.0f, 0.0f));
    glm::quat quaternion = quatZ * quatY * quatX;

    float factor = movingFaster ? runFactor : 1.0f;
    glm::vec3 clampedSpeed = posSpeed * factor;
    if (glm::length(clampedSpeed) > (maxSpeed * factor)) {
        clampedSpeed = glm::normalize(clampedSpeed) * maxSpeed * factor;
    }

    glm::vec3 newPos = pos + (quaternion * clampedSpeed * dT);
    if (keepInRoom) {
        if ((room < 0) || (room >= World::sizeRoom())) {
            keepInRoom = false;
            pos = newPos;
        } else if (World::getRoom(room).getBoundingBox().inBox(newPos)) {
            pos = newPos;
        }
    } else {
        pos = newPos;
    }

    glm::mat4 translate = glm::translate(glm::mat4(1.0f), pos);
    glm::mat4 rotate = glm::toMat4(quaternion);
    view = glm::inverse(translate * rotate);

    if (updateViewFrustum)
        calculateFrustumPlanes();

    glm::vec3 at(0.0f, 0.0f, -1.0f);
    glm::vec3 up(0.0f, -1.0f, 0.0f);
    Sound::listenAt(pos, quaternion * at, quaternion * up);

    dirty = false;
    return updateViewFrustum;
}
Esempio n. 8
0
LLCamera::LLCamera() :
	LLCoordFrame(),
	mView(DEFAULT_FIELD_OF_VIEW),
	mAspect(DEFAULT_ASPECT_RATIO),
	mViewHeightInPixels( -1 ),			// invalid height
	mNearPlane(DEFAULT_NEAR_PLANE),
	mFarPlane(DEFAULT_FAR_PLANE),
	mFixedDistance(-1.f)
{
	calculateFrustumPlanes();
} 
Esempio n. 9
0
// x and y are in WINDOW space, so x = Y-Axis (left/right), y= Z-Axis(Up/Down)
void LLCamera::calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2)
{
	F32 bottom, top, left, right;
	F32 view_height = (F32)tanf(0.5f * mView) * mFarPlane;
	F32 view_width = view_height * mAspect;
	
	left = 	 x1 * -2.f * view_width;
	right =  x2 * -2.f * view_width;
	bottom = y1 * 2.f * view_height; 
	top = 	 y2 * 2.f * view_height;

	calculateFrustumPlanes(left, right, top, bottom);
}
Esempio n. 10
0
void LLCamera::calculateFrustumPlanes() 
{
	// The planes only change when any of the frustum descriptions change.
	// They are not affected by changes of the position of the Frustum
	// because they are known in the view frame and the position merely
	// provides information on how to get from the absolute frame to the 
	// view frame.

	F32 left,right,top,bottom;
	top = mFarPlane * (F32)tanf(0.5f * mView);
	bottom = -top;
	left = top * mAspect;
	right = -left;

	calculateFrustumPlanes(left, right, top, bottom);
}
Esempio n. 11
0
void LLCamera::setFar(F32 far_plane) 
{
	mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
	calculateFrustumPlanes();
}
Esempio n. 12
0
void LLCamera::setNear(F32 near_plane) 
{
	mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
	calculateFrustumPlanes();
}
Esempio n. 13
0
void LLCamera::setAspect(F32 aspect_ratio) 
{
	mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
	calculateFrustumPlanes();
}
Esempio n. 14
0
void LLCamera::setView(F32 vertical_fov_rads) 
{
	mView = llclamp(vertical_fov_rads, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW);
	calculateFrustumPlanes();
}
Esempio n. 15
0
void ofApp::draw(){
	ofBackground(ofFloatColor(0.23));
	ofSetColor(ofColor::white);
	ofNoFill();
	ofEnableDepthTest();

	mCam[activeCam].begin();
	{

		ofSetColor(ofColor::white);

		vector<ofVec4f> frustumPlanes = calculateFrustumPlanes(mCam[0].getProjectionMatrix());

		// we could erase the 3rd element, that is the far plane,
		// therefore we are testing against an infinitely far frustum,
		// that is, an open frustum in view direction.

		// frustumPlanes.erase(frustumPlanes.begin() + 2); 

		ofMatrix4x4 mvm = mCam[0].getModelViewMatrix();

		for (auto & s : spheres){
			// --- note that we have to transform the sphere centres to the eye space of our frustum culling camera manually, 
			ofVec3f sInEyeSpace = s.getGlobalPosition() * mvm;
			s.inFrustum = getInFrustum(frustumPlanes, sInEyeSpace, s.radius);
		}

		// -----------

		// let's count the number of spheres within the frustum of camera 0:

		mCountInFrustum = 0;

		for(auto & s : spheres){
			s.draw();
			if (s.inFrustum) ++ mCountInFrustum;
		}

		if (activeCam == 1) {
			// let's draw the frustum of camera 0

			// but first, draw a stand-in for the actual camera.
			// this will draw a cube and an axis representation where the other camera sits.
			mCam[0].draw();

			// get the camera's near and far plane distance values.
			float nearC = mCam[0].getNearClip();
			float farC  = mCam[0].getFarClip();

			// Now comes the tricky bit: we want to draw the frustum where camera 0 sits.
			// Therefore, we move to camera 0 eye space, And draw the frustum fron there.

			ofPushMatrix(); // we are currently in world space.
			ofMultMatrix(mCam[0].getModelViewMatrix().getInverse());
			// we are now in camera2 view space!
			// where the origin is at camera2's global position.

			// draw the frustum in yellow, wireframe
			ofSetColor(ofColor::yellow);

			// we want to draw the frustum of camera 0. to do this, we grab the matrix that transforms
			// from view space into clip space (i.e. the projection matrix)
			// then we take our unit clip cube (i.e. the cube that delimits clip space)
			// (this cube is defined to be +-1 into  each x, y , z)
			// and transform it back into view space. We transform it back into
			// viewspace by applying the inverse transform viewspace -> clipspace
			// which is the inverse of applying the projection matrix, which is applying
			// the inverse projection matrix.

			// so first, grab camera 0's inverse projection matrix:
			ofMatrix4x4 projectionMatrixInverse = mCam[0].getProjectionMatrix().getInverse();

			// the edges of our unit cube in clip space:

			ofVec3f clipCube[8] = {
				ofVec3f(-1,-1,-1), ofVec3f(-1, 1,-1), ofVec3f( 1,-1,-1), ofVec3f( 1, 1,-1),
				ofVec3f(-1,-1, 1), ofVec3f(-1, 1, 1), ofVec3f( 1,-1, 1), ofVec3f( 1, 1, 1),
			};
			// since the clip cube is expressed in clip (=projection) space, we want this 
			// transformed back into our current space, view space, i.e. apply the inverse 
			// projection matrix to it.

			for (int i =0; i<8; i++){
				clipCube[i] = clipCube[i] * projectionMatrixInverse;
			} 

			// now draw our clip cube side edge rays - note that since the coordinates are
			// now in world space, we can draw them without applying any additional trans-
			// formations.
			for (int i=0;i<4;i++){
				ofLine(clipCube[i],clipCube[i+4]);
			}

			//// draw the clip cube cap
			ofRect(clipCube[0],clipCube[3].x-clipCube[0].x,clipCube[3].y-clipCube[0].y);
			ofRect(clipCube[4],clipCube[7].x-clipCube[4].x,clipCube[7].y-clipCube[4].y);

			ofPopMatrix(); // and back to world space!
		}
	}

	mCam[activeCam].end();

	ofDrawBitmapStringHighlight(
		"Active Cam: "+ ofToString(activeCam,4,' ') + "\n" +
		"Visible spheres: "+ ofToString(mCountInFrustum,4,' ') + "\n" +
		"Press 'c' to switch cameras.", 200, 20);

}