diff options
Diffstat (limited to 'indra/newview/llviewercamera.cpp')
-rw-r--r-- | indra/newview/llviewercamera.cpp | 208 |
1 files changed, 117 insertions, 91 deletions
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 437f1239bf..3300d6f633 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -94,21 +94,25 @@ LLViewerCamera::LLViewerCamera() : LLCamera() mZoomSubregion = 1; mAverageSpeed = 0.f; mAverageAngularSpeed = 0.f; - gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); + + mCameraAngleChangedSignal = gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); +} + +LLViewerCamera::~LLViewerCamera() +{ + mCameraAngleChangedSignal.disconnect(); } -void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) +bool LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) { // do not update if avatar didn't move if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate()) { - return; + return true; } - LLVector3 last_position; - LLVector3 last_axis; - last_position = getOrigin(); - last_axis = getAtAxis(); + LLVector3 last_position = getOrigin(); + LLVector3 last_axis = getAtAxis(); mLastPointOfInterest = point_of_interest; @@ -118,30 +122,49 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVecto regp = gAgent.getRegion(); } - F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f; + F32 water_height = regp ? regp->getWaterHeight() : 0.f; LLVector3 origin = center; + // Move origin[VZ] far enough (up or down) from the water surface + static const F32 MIN_DIST_TO_WATER = 0.2f; + F32& zpos = origin.mV[VZ]; + if (zpos < water_height + MIN_DIST_TO_WATER) { - if (origin.mV[2] > water_height) + if (zpos >= water_height) { - origin.mV[2] = llmax(origin.mV[2], water_height + 0.20f); + zpos = water_height + MIN_DIST_TO_WATER; } - else + else if (zpos > water_height - MIN_DIST_TO_WATER) { - origin.mV[2] = llmin(origin.mV[2], water_height - 0.20f); + zpos = water_height - MIN_DIST_TO_WATER; } } - setOriginAndLookAt(origin, up_direction, point_of_interest); + LLVector3 at(point_of_interest - origin); + at.normalize(); + if (at.isNull() || !at.isFinite()) + return false; + + LLVector3 left(up_direction % at); + left.normalize(); + if (left.isNull() || !left.isFinite()) + return false; + + LLVector3 up = at % left; + up.normalize(); + if (up.isNull() || !up.isFinite()) + return false; - mVelocityDir = origin - last_position ; - F32 dpos = mVelocityDir.normVec() ; + setOrigin(origin); + setAxes(at, left, up); + + mVelocityDir = origin - last_position; + F32 dpos = mVelocityDir.normVec(); LLQuaternion rotation; rotation.shortestArc(last_axis, getAtAxis()); - F32 x, y, z; - F32 drot; + F32 drot, x, y, z; rotation.getAngleAxis(&drot, &x, &y, &z); add(sVelocityStat, dpos); @@ -152,16 +175,17 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVecto mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); // update pixel meter ratio using default fov, not modified one - mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5)); + mPixelMeterRatio = getViewHeightInPixels() / (2.f * tanf(mCameraFOVDefault * 0.5)); // update screen pixel area - mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); + mScreenPixelArea = (S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); + + return true; } const LLMatrix4 &LLViewerCamera::getProjection() const { calcProjection(getFar()); return mProjectionMatrix; - } const LLMatrix4 &LLViewerCamera::getModelview() const @@ -174,19 +198,18 @@ const LLMatrix4 &LLViewerCamera::getModelview() const void LLViewerCamera::calcProjection(const F32 far_distance) const { - F32 fov_y, z_far, z_near, aspect, f; - fov_y = getView(); - z_far = far_distance; - z_near = getNear(); - aspect = getAspect(); + F32 fov_y = getView(); + F32 z_far = far_distance; + F32 z_near = getNear(); + F32 aspect = getAspect(); - f = 1/tan(fov_y*0.5f); + F32 f = 1 / tan(fov_y * 0.5f); mProjectionMatrix.setZero(); - mProjectionMatrix.mMatrix[0][0] = f/aspect; + mProjectionMatrix.mMatrix[0][0] = f / aspect; mProjectionMatrix.mMatrix[1][1] = f; - mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far); - mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far); + mProjectionMatrix.mMatrix[2][2] = (z_far + z_near) / (z_near - z_far); + mProjectionMatrix.mMatrix[3][2] = (2 * z_far * z_near) / (z_near - z_far); mProjectionMatrix.mMatrix[2][3] = -1; } @@ -208,71 +231,71 @@ void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zfli proj[i] = (F64) gGLProjection[i]; } - GLdouble objX,objY,objZ; + GLdouble objX, objY, objZ; LLVector3 frust[8]; if (no_hacks) { - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); - - gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0], viewport[1], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[0].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[1].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1] + viewport[3], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[2].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0], viewport[1] + viewport[3], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[3].setVec((F32)objX, (F32)objY, (F32)objZ); + + gluUnProject(viewport[0], viewport[1], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[4].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[5].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1] + viewport[3], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[6].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0], viewport[1] + viewport[3], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[7].setVec((F32)objX, (F32)objY, (F32)objZ); } else if (zflip) { - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); - - gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); - frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); - frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0], viewport[1] + viewport[3], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[0].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1] + viewport[3], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[1].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[2].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0], viewport[1], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[3].setVec((F32)objX, (F32)objY, (F32)objZ); + + gluUnProject(viewport[0], viewport[1] + viewport[3], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[4].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1] + viewport[3], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[5].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[6].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0], viewport[1], 1, model, proj, viewport, &objX, &objY, &objZ); + frust[7].setVec((F32)objX, (F32)objY, (F32)objZ); for (U32 i = 0; i < 4; i++) { - frust[i+4] = frust[i+4]-frust[i]; - frust[i+4].normVec(); - frust[i+4] = frust[i] + frust[i+4]*camera.getFar(); + frust[i + 4] = frust[i + 4] - frust[i]; + frust[i + 4].normVec(); + frust[i + 4] = frust[i] + frust[i + 4] * camera.getFar(); } } else { - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0], viewport[1], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[0].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[1].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0] + viewport[2], viewport[1] + viewport[3], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[2].setVec((F32)objX, (F32)objY, (F32)objZ); + gluUnProject(viewport[0], viewport[1] + viewport[3], 0, model, proj, viewport, &objX, &objY, &objZ); + frust[3].setVec((F32)objX, (F32)objY, (F32)objZ); if (ortho) { - LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f; + LLVector3 far_shift = camera.getAtAxis() * camera.getFar() * 2.f; for (U32 i = 0; i < 4; i++) { frust[i+4] = frust[i] + far_shift; @@ -284,7 +307,7 @@ void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zfli { LLVector3 vec = frust[i] - camera.getOrigin(); vec.normVec(); - frust[i+4] = camera.getOrigin() + vec*camera.getFar(); + frust[i + 4] = camera.getOrigin() + vec * camera.getFar(); } } } @@ -322,11 +345,13 @@ void LLViewerCamera::setPerspective(BOOL 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(); + GLint viewport[] = + { + gViewerWindow->getWorldViewRectRaw().mLeft, + gViewerWindow->getWorldViewRectRaw().mBottom, + gViewerWindow->getWorldViewRectRaw().getWidth(), + gViewerWindow->getWorldViewRectRaw().getHeight() + }; proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport); @@ -383,7 +408,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection, glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION); - GLfloat ogl_matrix[16]; + GLfloat ogl_matrix[16]; getOpenGLTransform(ogl_matrix); @@ -396,11 +421,13 @@ void LLViewerCamera::setPerspective(BOOL for_selection, // 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); - + 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 @@ -896,9 +923,8 @@ BOOL LLViewerCamera::isDefaultFOVChanged() } // static -void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value) +void LLViewerCamera::updateCameraAngle(const LLSD& value) { - LLViewerCamera* self=(LLViewerCamera*)user_data; - self->setDefaultFOV(value.asReal()); + setDefaultFOV(value.asReal()); } |