#include "DrawScenario.h" #include "render/DrawUtil.h" cDrawScenario::cDrawScenario(cCamera& cam) : mCam(cam) { mCamTrackMode = eCamTrackModeX; mCamTrackMode0 = mCamTrackMode; } void cDrawScenario::ParseArgs(const cArgParser& parser) { ParseCamTrackMode(parser, mCamTrackMode); mCamTrackMode0 = mCamTrackMode; } void cDrawScenario::Update(double time_elapsed) { UpdateCamera(); } void cDrawScenario::Draw() { glPushMatrix(); mCam.SetupGLView(); DrawSetup(); DrawScene(); DrawCleanup(); glPopMatrix(); } void cDrawScenario::Reset() { cScenario::Reset(); ResetCamera(); } void cDrawScenario::Keyboard(unsigned char key, int x, int y) { } void cDrawScenario::MouseClick(int button, int state, double world_x, double world_y) { } void cDrawScenario::MouseMove(double x, double y) { } void cDrawScenario::Reshape(int w, int h) { } cDrawScenario::eCamTrackMode cDrawScenario::GetTrackMode() const { return mCamTrackMode; } cDrawScenario::eCamTrackMode cDrawScenario::GetTrackMode0() const { return mCamTrackMode0; } void cDrawScenario::ParseCamTrackMode(const cArgParser& parser, eCamTrackMode& out_mode) const { std::string str = ""; parser.ParseString("cam_track_mode", str); if (str != "") { if (str == "x") { out_mode = eCamTrackModeX; } else if (str == "y") { out_mode = eCamTrackModeY; } else if (str == "still") { out_mode = eCamTrackModeStill; } else if (str == "fixed") { out_mode = eCamTrackModeFixed; } else { assert(false); // unsupported track mode } } } void cDrawScenario::UpdateCamera() { if (mCamTrackMode == eCamTrackModeX || mCamTrackMode == eCamTrackModeY || mCamTrackMode == eCamTrackModeXYZ) { UpdateCameraTracking(); } else if (mCamTrackMode == eCamTrackModeStill) { UpdateCameraStill(); } } void cDrawScenario::UpdateCameraTracking() { if (mCamTrackMode == eCamTrackModeXYZ) { tVector track_pos = GetCamTrackPos(); tVector focus_pos = mCam.GetFocus(); tVector cam_pos = mCam.GetPosition(); mCam.TranslateFocus(track_pos); } else if (mCamTrackMode == eCamTrackModeX || mCamTrackMode == eCamTrackModeY) { tVector track_pos = GetCamTrackPos(); tVector cam_focus = mCam.GetFocus(); double cam_w = mCam.GetWidth(); double cam_h = mCam.GetHeight(); const double y_pad = std::min(0.5, 0.8 * 0.5 * cam_h); const double x_pad = std::min(0.5, 0.8 * 0.5 * cam_w); if (mCamTrackMode == eCamTrackModeX) { cam_focus[0] = track_pos[0]; if (std::abs(track_pos[1] - cam_focus[1]) > ((0.5 * cam_h) - y_pad)) { const double blend = 0.5; double tar_y = track_pos[1] + ((0.5 * cam_h) - y_pad); cam_focus[1] = (1 - blend) * cam_focus[1] + blend * tar_y; } } else { cam_focus[1] = track_pos[1]; const double blend = 0.5; double tar_delta = track_pos[0] - cam_focus[0]; if (std::abs(tar_delta) > ((0.5 * cam_w) - x_pad)) { double tar_x = track_pos[0] + cMathUtil::Sign(tar_delta) * ((0.95 * cam_w) - x_pad); cam_focus[0] = (1 - blend) * cam_focus[0] + blend * tar_x; } } mCam.TranslateFocus(cam_focus); } } void cDrawScenario::UpdateCameraStill() { tVector track_pos = GetCamTrackPos(); tVector cam_focus = mCam.GetFocus(); double cam_w = mCam.GetWidth(); double cam_h = mCam.GetHeight(); double cam_still_snap_dist = GetCamStillSnapDistX(); const double pad_x = std::min(0.5, 0.4 * cam_still_snap_dist); const double pad_y = std::min(0.0, 0.2 * cam_h); double avg_h = 0; bool snap_x = std::abs(track_pos[0] - cam_focus[0]) > cam_still_snap_dist - pad_x; bool snap_y = (track_pos[1] - cam_focus[1]) > 0.5 * cam_h - pad_y || (track_pos[1] - cam_focus[1]) < -(0.5 * cam_h - pad_y); if (snap_x || snap_y) { tVector snap_pos = GetCamStillPos(); cam_focus[0] = snap_pos[0]; cam_focus[1] = snap_pos[1]; tVector pos_delta = track_pos - snap_pos; if (std::abs(pos_delta[0]) > cam_still_snap_dist - pad_x) { cam_focus[0] += pos_delta[0]; } if ((pos_delta[1]) > 0.5 * cam_h - pad_y || (pos_delta[1]) < -(0.5 * cam_h - pad_y)) { cam_focus[1] += pos_delta[1]; } if (snap_x) { cam_focus[0] += cam_still_snap_dist - pad_x; } } mCam.TranslateFocus(cam_focus); } double cDrawScenario::GetCamStillSnapDistX() const { const tVector axis = tVector(1, 0, 0, 0); double dist = 0.5 * mCam.GetWidth(); // this is all hacks tVector view_delta = mCam.GetFocus() - mCam.GetPosition(); tVector view_dir = view_delta.normalized(); double len = view_delta.norm() - mCam.GetNearZ(); view_delta = view_dir * len; view_delta[1] = 0; view_delta[3] = 0; len = view_delta.norm(); if (len > 0) { view_delta /= len; double dot = view_delta.dot(axis); double lerp = std::abs(dot); lerp = std::pow(lerp, 4); lerp = 1 - lerp; dist = lerp * dist + (1 - lerp) * 0.5 * len; } return dist; } tVector cDrawScenario::GetCamTrackPos() const { return tVector::Zero(); } tVector cDrawScenario::GetCamStillPos() const { return tVector::Zero(); } void cDrawScenario::ToggleCamTrackMode(eCamTrackMode mode) { if (mCamTrackMode == mode) { mCamTrackMode = mCamTrackMode0; } else { mCamTrackMode = mode; } } void cDrawScenario::ResetCamera() { tVector target_pos = GetDefaultCamFocus(); if (mCamTrackMode == eCamTrackModeX || mCamTrackMode == eCamTrackModeY) { target_pos = GetCamTrackPos(); } else if (mCamTrackMode == eCamTrackModeStill) { target_pos = GetCamStillPos(); } tVector cam_pos = GetDefaultCamFocus(); cam_pos[0] = target_pos[0]; cam_pos[1] = target_pos[1]; mCam.TranslateFocus(cam_pos); } tVector cDrawScenario::GetDefaultCamFocus() const { return tVector::Zero(); } void cDrawScenario::DrawSetup() { } void cDrawScenario::DrawCleanup() { } void cDrawScenario::DrawScene() { } std::string cDrawScenario::BuildTextInfoStr() const { return ""; } cDrawScenario::~cDrawScenario() { }