CameraAngle changes now picked up on even after camera initilization. Also updated viewport/windowdimension functions and such to new variants.

This commit is contained in:
Shyotl
2011-08-19 02:12:21 -05:00
parent ce4729d8e9
commit 13e0359c6e
2 changed files with 76 additions and 46 deletions

View File

@@ -114,15 +114,15 @@ LLViewerCamera::LLViewerCamera() : LLCamera()
mZoomSubregion = 1; mZoomSubregion = 1;
mAverageSpeed = 0.f; mAverageSpeed = 0.f;
mAverageAngularSpeed = 0.f; mAverageAngularSpeed = 0.f;
gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2));
} }
void LLViewerCamera::updateCameraLocation(const LLVector3 &center, void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
const LLVector3 &up_direction, const LLVector3 &up_direction,
const LLVector3 &point_of_interest) const LLVector3 &point_of_interest)
{ {
// do not update if we are in build mode AND avatar didn't move // do not update if avatar didn't move
if (LLToolMgr::getInstance()->inBuildMode() if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate())
&& !LLViewerJoystick::getInstance()->getCameraNeedsUpdate())
{ {
return; return;
} }
@@ -332,7 +332,12 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
{ {
// make a tiny little viewport // make a tiny little viewport
// anything drawn into this viewport will be "selected" // anything drawn into this viewport will be "selected"
GLint* viewport = (GLint*) gGLViewport;
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); proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport);
@@ -399,10 +404,13 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
if (for_selection && (width > 1 || height > 1)) if (for_selection && (width > 1 || height > 1))
{ {
calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidth() - 0.5f, // NB: as of this writing, i believe the code below is broken (doesn't take into account the world view, assumes entire window)
(F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeight() - 0.5f, // however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not
(F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidth() - 0.5f, // comfortable hacking on it.
(F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeight() - 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);
} }
@@ -467,8 +475,15 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
} }
} }
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
S32 viewport[4];
viewport[0] = world_view_rect.mLeft;
viewport[1] = world_view_rect.mBottom;
viewport[2] = world_view_rect.getWidth();
viewport[3] = world_view_rect.getHeight();
if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ], if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ],
gGLModelView, gGLProjection, (GLint*)gGLViewport, gGLModelView, gGLProjection, (GLint*)viewport,
&x, &y, &z)) &x, &y, &z))
{ {
// convert screen coordinates to virtual UI coordinates // convert screen coordinates to virtual UI coordinates
@@ -476,7 +491,7 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
y /= gViewerWindow->getDisplayScale().mV[VY]; y /= gViewerWindow->getDisplayScale().mV[VY];
// should now have the x,y coords of grab_point in screen space // should now have the x,y coords of grab_point in screen space
const LLRect& window_rect = gViewerWindow->getWindowRect(); LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
// ...sanity check // ...sanity check
S32 int_x = lltrunc(x); S32 int_x = lltrunc(x);
@@ -486,14 +501,14 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
if (clamp) if (clamp)
{ {
if (int_x < window_rect.mLeft) if (int_x < world_rect.mLeft)
{ {
out_point.mX = window_rect.mLeft; out_point.mX = world_rect.mLeft;
valid = FALSE; valid = FALSE;
} }
else if (int_x > window_rect.mRight) else if (int_x > world_rect.mRight)
{ {
out_point.mX = window_rect.mRight; out_point.mX = world_rect.mRight;
valid = FALSE; valid = FALSE;
} }
else else
@@ -501,14 +516,14 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
out_point.mX = int_x; out_point.mX = int_x;
} }
if (int_y < window_rect.mBottom) if (int_y < world_rect.mBottom)
{ {
out_point.mY = window_rect.mBottom; out_point.mY = world_rect.mBottom;
valid = FALSE; valid = FALSE;
} }
else if (int_y > window_rect.mTop) else if (int_y > world_rect.mTop)
{ {
out_point.mY = window_rect.mTop; out_point.mY = world_rect.mTop;
valid = FALSE; valid = FALSE;
} }
else else
@@ -522,19 +537,19 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
out_point.mX = int_x; out_point.mX = int_x;
out_point.mY = int_y; out_point.mY = int_y;
if (int_x < window_rect.mLeft) if (int_x < world_rect.mLeft)
{ {
valid = FALSE; valid = FALSE;
} }
else if (int_x > window_rect.mRight) else if (int_x > world_rect.mRight)
{ {
valid = FALSE; valid = FALSE;
} }
if (int_y < window_rect.mBottom) if (int_y < world_rect.mBottom)
{ {
valid = FALSE; valid = FALSE;
} }
else if (int_y > window_rect.mTop) else if (int_y > world_rect.mTop)
{ {
valid = FALSE; valid = FALSE;
} }
@@ -563,24 +578,30 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
in_front = FALSE; in_front = FALSE;
} }
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
S32 viewport[4];
viewport[0] = world_view_rect.mLeft;
viewport[1] = world_view_rect.mBottom;
viewport[2] = world_view_rect.getWidth();
viewport[3] = world_view_rect.getHeight();
GLdouble x, y, z; // object's window coords, GL-style GLdouble x, y, z; // object's window coords, GL-style
if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY],
pos_agent.mV[VZ], gGLModelView, pos_agent.mV[VZ], gGLModelView,
gGLProjection, (GLint*)gGLViewport, gGLProjection, (GLint*)viewport,
&x, &y, &z)) &x, &y, &z))
{ {
x /= gViewerWindow->getDisplayScale().mV[VX]; x /= gViewerWindow->getDisplayScale().mV[VX];
y /= gViewerWindow->getDisplayScale().mV[VY]; y /= gViewerWindow->getDisplayScale().mV[VY];
// should now have the x,y coords of grab_point in screen space // should now have the x,y coords of grab_point in screen space
const LLRect& window_rect = gViewerWindow->getVirtualWindowRect(); const LLRect& world_rect = gViewerWindow->getWorldViewRectScaled();
// ...sanity check // ...sanity check
S32 int_x = lltrunc(x); S32 int_x = lltrunc(x);
S32 int_y = lltrunc(y); S32 int_y = lltrunc(y);
// find the center // find the center
GLdouble center_x = (GLdouble)(0.5f * (window_rect.mLeft + window_rect.mRight)); GLdouble center_x = (GLdouble)world_rect.getCenterX();
GLdouble center_y = (GLdouble)(0.5f * (window_rect.mBottom + window_rect.mTop)); GLdouble center_y = (GLdouble)world_rect.getCenterY();
if (x == center_x && y == center_y) if (x == center_x && y == center_y)
{ {
@@ -601,41 +622,41 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
// the slope of the line is undefined // the slope of the line is undefined
if (line_y > 0.f) if (line_y > 0.f)
{ {
int_y = window_rect.mTop; int_y = world_rect.mTop;
} }
else else
{ {
int_y = window_rect.mBottom; int_y = world_rect.mBottom;
} }
} }
else if (0 == window_rect.getWidth()) else if (0 == world_rect.getWidth())
{ {
// the diagonal slope of the view is undefined // the diagonal slope of the view is undefined
if (y < window_rect.mBottom) if (y < world_rect.mBottom)
{ {
int_y = window_rect.mBottom; int_y = world_rect.mBottom;
} }
else if ( y > window_rect.mTop) else if ( y > world_rect.mTop)
{ {
int_y = window_rect.mTop; int_y = world_rect.mTop;
} }
} }
else else
{ {
F32 line_slope = (F32)(line_y / line_x); F32 line_slope = (F32)(line_y / line_x);
F32 rect_slope = ((F32)window_rect.getHeight()) / ((F32)window_rect.getWidth()); F32 rect_slope = ((F32)world_rect.getHeight()) / ((F32)world_rect.getWidth());
if (fabs(line_slope) > rect_slope) if (fabs(line_slope) > rect_slope)
{ {
if (line_y < 0.f) if (line_y < 0.f)
{ {
// bottom // bottom
int_y = window_rect.mBottom; int_y = world_rect.mBottom;
} }
else else
{ {
// top // top
int_y = window_rect.mTop; int_y = world_rect.mTop;
} }
int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x); int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x);
} }
@@ -644,12 +665,12 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
if (line_x < 0.f) if (line_x < 0.f)
{ {
// left // left
int_x = window_rect.mLeft; int_x = world_rect.mLeft;
} }
else else
{ {
// right // right
int_x = window_rect.mRight; int_x = world_rect.mRight;
} }
int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y); int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y);
} }
@@ -658,29 +679,30 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
// exactly parallel ==> push to the corners // exactly parallel ==> push to the corners
if (line_x > 0.f) if (line_x > 0.f)
{ {
int_x = window_rect.mRight; int_x = world_rect.mRight;
} }
else else
{ {
int_x = window_rect.mLeft; int_x = world_rect.mLeft;
} }
if (line_y > 0.0f) if (line_y > 0.0f)
{ {
int_y = window_rect.mTop; int_y = world_rect.mTop;
} }
else else
{ {
int_y = window_rect.mBottom; int_y = world_rect.mBottom;
} }
} }
} }
if (!in_front) if (!in_front)
{ {
int_x = window_rect.mLeft + window_rect.mRight - int_x; int_x = world_rect.mLeft + world_rect.mRight - int_x;
int_y = window_rect.mBottom + window_rect.mTop - int_y; int_y = world_rect.mBottom + world_rect.mTop - int_y;
} }
out_point.mX = int_x;
out_point.mY = int_y; out_point.mX = int_x + world_rect.mLeft;
out_point.mY = int_y + world_rect.mBottom;
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@@ -832,3 +854,10 @@ void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)
mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
} }
// static
void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value)
{
LLViewerCamera* self=(LLViewerCamera*)user_data;
self->setDefaultFOV(value.asReal());
}

View File

@@ -79,6 +79,7 @@ public:
const LLVector3 &point_of_interest); const LLVector3 &point_of_interest);
static void updateFrustumPlanes(LLCamera& camera, BOOL ortho = FALSE, BOOL zflip = FALSE, BOOL no_hacks = FALSE); static void updateFrustumPlanes(LLCamera& camera, BOOL ortho = FALSE, BOOL zflip = FALSE, BOOL no_hacks = FALSE);
static void updateCameraAngle(void* user_data, const LLSD& value);
void setPerspective(BOOL for_selection, S32 x, S32 y_from_bot, S32 width, S32 height, BOOL limit_select_distance, F32 z_near = 0, F32 z_far = 0); void setPerspective(BOOL for_selection, S32 x, S32 y_from_bot, S32 width, S32 height, BOOL limit_select_distance, F32 z_near = 0, F32 z_far = 0);
const LLMatrix4 &getProjection() const; const LLMatrix4 &getProjection() const;