void CCamera::Update(bool freeze) { pos2 = pos; up.Normalize(); right = forward.cross(up); right.Normalize(); up = right.cross(forward); up.Normalize(); const float aspect = (float) gu->viewSizeX / (float) gu->viewSizeY; const float viewx = tanf(aspect * halfFov); // const float viewx = aspect * tanHalfFov; const float viewy = tanHalfFov; if (gu->viewSizeY <= 0) { lppScale = 0.0f; } else { const float span = 2.0f * tanHalfFov; lppScale = span / (float) gu->viewSizeY; } const float3 forwardy = (-forward * viewy); top = forwardy + up; top.Normalize(); bottom = forwardy - up; bottom.Normalize(); const float3 forwardx = (-forward * viewx); rightside = forwardx + right; rightside.Normalize(); leftside = forwardx - right; leftside.Normalize(); if (!freeze) { cam2->bottom = bottom; cam2->forward = forward; cam2->leftside = leftside; cam2->pos = pos; cam2->right = right; cam2->rightside = rightside; cam2->rot = rot; cam2->top = top; cam2->up = up; cam2->lppScale = lppScale; } const float gndHeight = ground->GetHeight(pos.x, pos.z); const float rangemod = 1.0f + max(0.0f, pos.y - gndHeight - 500.0f) * 0.0003f; const float zNear = (NEAR_PLANE * rangemod); gu->viewRange = MAX_VIEW_RANGE * rangemod; glMatrixMode(GL_PROJECTION); // Select the Projection Matrix glLoadIdentity(); // Reset the Projection Matrix // apply and store the transform, should be faster // than calling glGetDoublev(GL_PROJECTION_MATRIX) // right after gluPerspective() myGluPerspective(aspect, zNear, gu->viewRange); glMatrixMode(GL_MODELVIEW); // Select the Modelview Matrix glLoadIdentity(); // FIXME: should be applying the offsets to pos/up/right/forward/etc, // but without affecting the real positions (need an intermediary) float3 fShake = (forward * (1.0f + tiltOffset.z)) + (right * tiltOffset.x) + (up * tiltOffset.y); const float3 camPos = pos + posOffset; const float3 center = camPos + fShake.Normalize(); // apply and store the transform, should be faster // than calling glGetDoublev(GL_MODELVIEW_MATRIX) // right after gluLookAt() myGluLookAt(camPos, center, up); // the inverse modelview matrix (handy for shaders to have) CalculateInverse4x4((double(*)[4])modelview, (double(*)[4])modelviewInverse); // transpose the 3x3 billboard[0] = modelview[0]; billboard[1] = modelview[4]; billboard[2] = modelview[8]; billboard[4] = modelview[1]; billboard[5] = modelview[5]; billboard[6] = modelview[9]; billboard[8] = modelview[2]; billboard[9] = modelview[6]; billboard[10] = modelview[10]; glNewList(billboardList, GL_COMPILE); glMultMatrixd(billboard); glEndList(); viewport[0] = 0; viewport[1] = 0; viewport[2] = gu->viewSizeX; viewport[3] = gu->viewSizeY; }
void CCamera::Update(bool freeze, bool resetUp) { pos2 = pos; if (resetUp) { up.x = 0.0f; up.y = 1.0f; up.z = 0.0f; } right = forward.cross(up); right.UnsafeANormalize(); up = right.cross(forward); up.UnsafeANormalize(); const float aspect = globalRendering->aspectRatio; const float viewx = tan(aspect * halfFov); // const float viewx = aspect * tanHalfFov; const float viewy = tanHalfFov; if (globalRendering->viewSizeY <= 0) { lppScale = 0.0f; } else { const float span = 2.0f * tanHalfFov; lppScale = span / (float) globalRendering->viewSizeY; } const float3 forwardy = (-forward * viewy); top = forwardy + up; top.UnsafeANormalize(); bottom = forwardy - up; bottom.UnsafeANormalize(); const float3 forwardx = (-forward * viewx); rightside = forwardx + right; rightside.UnsafeANormalize(); leftside = forwardx - right; leftside.UnsafeANormalize(); if (!freeze) { cam2->bottom = bottom; cam2->forward = forward; cam2->leftside = leftside; cam2->pos = pos; cam2->right = right; cam2->rightside = rightside; cam2->rot = rot; cam2->top = top; cam2->up = up; cam2->lppScale = lppScale; } const float gndHeight = ground->GetHeight(pos.x, pos.z); const float rangemod = 1.0f + std::max(0.0f, pos.y - gndHeight - 500.0f) * 0.0003f; const float zNear = (NEAR_PLANE * rangemod); globalRendering->viewRange = MAX_VIEW_RANGE * rangemod; glMatrixMode(GL_PROJECTION); glLoadIdentity(); // apply and store the projection transform myGluPerspective(aspect, zNear, globalRendering->viewRange); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // FIXME: should be applying the offsets to pos/up/right/forward/etc, // but without affecting the real positions (need an intermediary) float3 fShake = (forward * (1.0f + tiltOffset.z)) + (right * tiltOffset.x) + (up * tiltOffset.y); const float3 camPos = pos + posOffset; const float3 center = camPos + fShake.ANormalize(); // apply and store the view transform myGluLookAt(camPos, center, up); // get the inverse view matrix (handy for shaders to have) CMatrix44f::Invert((double(*)[4]) viewMat, (double(*)[4]) viewMatInv); // transpose the 3x3 bboardMat[ 0] = viewMat[ 0]; bboardMat[ 1] = viewMat[ 4]; bboardMat[ 2] = viewMat[ 8]; bboardMat[ 4] = viewMat[ 1]; bboardMat[ 5] = viewMat[ 5]; bboardMat[ 6] = viewMat[ 9]; bboardMat[ 8] = viewMat[ 2]; bboardMat[ 9] = viewMat[ 6]; bboardMat[10] = viewMat[10]; glNewList(billboardList, GL_COMPILE); glMultMatrixd(bboardMat); glEndList(); viewport[0] = 0; viewport[1] = 0; viewport[2] = globalRendering->viewSizeX; viewport[3] = globalRendering->viewSizeY; }
void CCamera::Update(bool terrainReflectionPass) { UpdateRightAndUp(terrainReflectionPass); const float aspect = globalRendering->aspectRatio; const float viewx = math::tan(aspect * halfFov); const float viewy = tanHalfFov; if (globalRendering->viewSizeY <= 0) { lppScale = 0.0f; } else { lppScale = (2.0f * tanHalfFov) / globalRendering->viewSizeY; } const float3 forwardy = (-forward * viewy); const float3 forwardx = (-forward * viewx); // note: top- and bottom-dir should be parallel to <forward> topFrustumSideDir = (forwardy + up).UnsafeANormalize(); botFrustumSideDir = (forwardy - up).UnsafeANormalize(); rgtFrustumSideDir = (forwardx + right).UnsafeANormalize(); lftFrustumSideDir = (forwardx - right).UnsafeANormalize(); if (this == camera) cam2->CopyState(this); // apply and store the projection transform ComputeViewRange(); glMatrixMode(GL_PROJECTION); myGluPerspective(aspect, globalRendering->zNear, globalRendering->viewRange); // FIXME: should be applying the offsets to pos/up/right/forward/etc, // but without affecting the real positions (need an intermediary) float3 fShake = (forward * (1.0f + tiltOffset.z)) + (right * tiltOffset.x) + (up * tiltOffset.y); const float3 camPos = pos + posOffset; const float3 center = camPos + fShake.ANormalize(); // apply and store the view transform glMatrixMode(GL_MODELVIEW); myGluLookAt(camPos, center, up); // create extra matrices viewProjectionMatrix = projectionMatrix * viewMatrix; viewMatrixInverse = viewMatrix.InvertAffine(); projectionMatrixInverse = projectionMatrix.Invert(); viewProjectionMatrixInverse = viewProjectionMatrix.Invert(); // Billboard Matrix billboardMatrix = viewMatrix; billboardMatrix.SetPos(ZeroVector); billboardMatrix.Transpose(); // viewMatrix is affine, equals inverse billboardMatrix[15] = 1.0f; // SetPos() touches m[15] // viewport viewport[0] = 0; viewport[1] = 0; viewport[2] = globalRendering->viewSizeX; viewport[3] = globalRendering->viewSizeY; }