00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "cameramanipulator.h"
00013 #include "../../kernel.h"
00014
00015 using namespace VRUT;
00016
00017
00018 CameraManipulator::CameraManipulator(const MODULE_ID & _id, const wxString & _name, EventHandler * msgSink)
00019 : CameraModule(_id, _name, 0, msgSink), rotspeed(5e-3f), zoomspeed(2e-1f), cruisespeed(6e-2f), navspeed(1.0f)
00020 {
00021 SET_DEFAULT_PARAM(eventTimeoutParamID, wxT("0"));
00022 SET_DEFAULT_PARAM(keyEventTimeoutParamID, wxT("0"));
00023 SET_DEFAULT_PARAM(msEventTimeoutParamID, wxT("40"));
00024
00025 REGISTER_PARAM_GUI_TEXTCONTROL(fovParamID, wxT("FOV"), wxT("0.0"), wxT("Field of view."));
00026 REGISTER_PARAM_GUI_TEXTCONTROL(farPlaneParamID, wxT("farPlane"), wxT("0.0"), wxT("Far clipping plane."));
00027 REGISTER_PARAM_GUI_TEXTCONTROL(nearPlaneParamID, wxT("nearPlane"), wxT("0.0"), wxT("Near clipping plane."));
00028 REGISTER_PARAM_GUI_TEXTCONTROL(rotspeedParamID, wxT("rotspeed"), wxT("5e-3"), wxT("Speed of rotation."));
00029 REGISTER_PARAM_GUI_TEXTCONTROL(zoomspeedParamID, wxT("zoomspeed"), wxT("2e-1"), wxT("Speed of zoom."));
00030 REGISTER_PARAM_GUI_TEXTCONTROL(cruisespeedParamID, wxT("cruisespeed"), wxT("6e-2"), wxT("cruisespeed"));
00031 REGISTER_PARAM_GUI_TEXTCONTROL(navspeedParamID, wxT("navspeed"), wxT("1"), wxT("Overal navigation speed."));
00032
00033 REGISTER_LISTENER(Event::EVT_SCENE_CAM_PROJECTION_CHANGED);
00034 }
00035
00036
00037 CameraManipulator::~CameraManipulator()
00038 {
00039 }
00040
00041
00042 void CameraManipulator::processEvent(wxCommandEvent & evt)
00043 {
00044 CameraModule::processEvent(evt);
00045 bool updateCamParams = false;
00046 switch (evt.GetEventType())
00047 {
00048 case Event::EVT_SCENE_CAM_PROJECTION_CHANGED:
00049 updateCamParams = ((evt.GetId() == int(getSceneID())) && (evt.GetInt() == int(getCameraID())));
00050 break;
00051 case Event::EVT_PARAM_SET:
00052 {
00053 UPDATE_PARAM_FROM_EVENT_FLOAT(rotspeedParamID, rotspeed, evt);
00054 UPDATE_PARAM_FROM_EVENT_FLOAT(zoomspeedParamID, zoomspeed, evt);
00055 UPDATE_PARAM_FROM_EVENT_FLOAT(cruisespeedParamID, cruisespeed, evt);
00056 UPDATE_PARAM_FROM_EVENT_FLOAT(navspeedParamID, navspeed, evt);
00057 float fov = 0.0f;
00058 float nearPlane = 0.0f;
00059 float farPlane = 0.0f;
00060 UPDATE_PARAM_FROM_EVENT_FLOAT(fovParamID, fov, evt);
00061 UPDATE_PARAM_FROM_EVENT_FLOAT(nearPlaneParamID, nearPlane, evt);
00062 UPDATE_PARAM_FROM_EVENT_FLOAT(farPlaneParamID, farPlane, evt);
00063 if ( (fov || nearPlane || farPlane)
00064 && (getSceneID() != SCENE_ID_NONE)
00065 && (getCameraID() != NODE_ID_NONE) )
00066 {
00067 wxCommandEvent camEvt = Event::GET_EVT_SCENE_CAM_PROJECTION_SET(getSceneID(), getCameraID(), 0, 0, nearPlane, farPlane, fov);
00068 PostToKernel(camEvt, true);
00070 WaitForEvent(Event::EVT_SCENE_CAM_PROJECTION_CHANGED, 100, int(getSceneID()), int(getCameraID()));
00071 }
00072 }
00073 break;
00074 default:
00075 break;
00076 }
00077 if (updateCamParams)
00078 {
00079 const Scene * scene = GetSceneMgr()->GetScene(getSceneID());
00080 if (scene)
00081 {
00082 const SceneNode * camNode = scene->GetNode(getCameraID());
00083 if (camNode && camNode->IsOfType(SceneNode::CAMERA))
00084 {
00085 ReadLocker rLock(*camNode);
00086 wxCommandEvent ev1 = Event::GET_EVT_PARAM_SET_DO(fovParamID, wxString::Format(wxT("%g"), ((Camera *)camNode)->GetFOV()));
00087 PostToKernel(ev1);
00088 wxCommandEvent ev2 = Event::GET_EVT_PARAM_SET_DO(nearPlaneParamID, wxString::Format(wxT("%g"), ((Camera *)camNode)->GetNearPlane()));
00089 PostToKernel(ev2);
00090 wxCommandEvent ev3 = Event::GET_EVT_PARAM_SET_DO(farPlaneParamID, wxString::Format(wxT("%g"), ((Camera *)camNode)->GetFarPlane()));
00091 PostToKernel(ev3);
00092 }
00093 }
00094 }
00095 }
00096
00097
00098 void CameraManipulator::processKeyEvent(wxKeyEvent & evt)
00099 {
00100 #ifdef EVENT_DEBUG
00101 if (evt.GetEventType() == wxEVT_KEY_DOWN)
00102 LOG(wxT("<CamManip>Received key down event"));
00103 else
00104 LOG(wxT("<CamManip>Received key up event"));
00105 #endif
00106
00107 if (int(windowID) == evt.GetId() && evt.GetEventType() == wxEVT_KEY_UP)
00108 {
00109 switch (evt.GetKeyCode())
00110 {
00111 case WXK_SPACE:
00112 {
00113 wxCommandEvent fsEvt = Event::GET_EVT_RENDER_FULLSCREEN_TOGGLE(windowID);
00114 PostToKernel(fsEvt);
00115 }
00116 break;
00117 case WXK_ESCAPE:
00118 {
00119 wxCommandEvent fsEvt = Event::GET_EVT_RENDER_FULLSCREEN_SET(windowID, false);
00120 PostToKernel(fsEvt);
00121 }
00122 break;
00123 }
00124 }
00125 }
00126
00127
00128 void CameraManipulator::processMouseEvent(wxMouseEvent & evt)
00129 {
00130 if (int(windowID) != evt.GetId())
00131 return;
00132
00133 NODE_ID cameraID = getCameraID();
00134 Scene * scene = GetSceneMgr()->GetScene(getSceneID());
00135 if (!scene)
00136 return;
00137
00138 const SceneNode * camNode = scene->GetNode(cameraID);
00139 if (!camNode || !camNode->IsOfType(SceneNode::CAMERA))
00140 return;
00141
00142 Camera * camera = (Camera *)(const_cast<SceneNode *>(camNode));
00143 WriteLocker camLock(*camera);
00144
00145 scene->UpdateTransformation(cameraID);
00146 if (evt.LeftDClick() && !evt.Moving())
00147 {
00148 unsigned width, height;
00149 camera->GetWidthHeight(&width, &height);
00150
00151 float px = ((( 2.0f * evt.GetPosition().x) / width) - 1.0f) / camera->GetProjectionMatrix()->_m11;
00152 float py = (((-2.0f * evt.GetPosition().y) / height) + 1.0f) / camera->GetProjectionMatrix()->_m22;
00153
00154 VECTOR3 origin(0, 0, 0);
00155 VECTOR3 direction(px, py, -1.0f);
00156
00157 origin = camera->GetWorldTransMatrix()->TransformCoord(origin);
00158 direction = camera->GetWorldTransMatrix()->TransformNormal(direction).Normalize();
00159
00160 wxCommandEvent ev = Event::GET_EVT_SCENE_RAY_PICK(scene->GetID(), new Ray(origin, direction));
00161 PostToKernel(ev);
00162 }
00163
00164 wxPoint moved(evt.GetPosition().x - lastPos.x, evt.GetPosition().y - lastPos.y);
00165 if (evt.Dragging() && evt.MiddleIsDown())
00166 {
00167 float moveY = -moved.y * zoomspeed * navspeed;
00168 if (moveY)
00169 {
00170 VECTOR3 camView = camera->GetView().Normalize();
00171 float dist = camera->GetCenterDist();
00172 camera->SetCenterDist(dist - moveY);
00173 scene->Transform(cameraID, MATRIX::Translation(camera->GetView().Normalize() * moveY));
00174 if (!KERNEL)
00175 {
00176 wxCommandEvent ev = Event::GET_EVT_RENDER_UPDATE(scene->GetID());
00177 PostToKernel(ev, true);
00178 }
00179 }
00180 }
00181 else if (evt.Dragging() && evt.RightIsDown())
00182 {
00183 VECTOR3 camUp = camera->GetUp().Normalize();
00184 VECTOR3 move = moved.x * camUp.Cross(camera->GetView()).Normalize();
00185 move += moved.y * camUp;
00186 move *= cruisespeed * navspeed;
00187 scene->Transform(cameraID, MATRIX::Translation(move));
00188 if (!KERNEL)
00189 {
00190 wxCommandEvent ev = Event::GET_EVT_RENDER_UPDATE(scene->GetID());
00191 PostToKernel(ev, true);
00192 }
00193 }
00194 else if (evt.Dragging() && evt.LeftIsDown())
00195 {
00196 float angleX = moved.x * rotspeed;
00197 float angleY = -moved.y * rotspeed;
00198 VECTOR3 camUp = camera->GetUp().Normalize();
00199 VECTOR3 center = camera->GetCenterPoint();
00200
00201 if (angleX)
00202 {
00203 scene->Transform(cameraID, MATRIX::RotationAxis(camUp, angleX));
00204 scene->UpdateTransformation(cameraID);
00205 }
00206 if (angleY)
00207 {
00208 scene->Transform(cameraID, MATRIX::RotationAxis(camUp.Cross(camera->GetView()).Normalize(), angleY));
00209 scene->UpdateTransformation(cameraID);
00210 }
00211 scene->TranslateAbs(cameraID, center - camera->GetView().Normalize()*camera->GetCenterDist());
00212 if (!KERNEL)
00213 {
00214 wxCommandEvent ev = Event::GET_EVT_RENDER_UPDATE(scene->GetID());
00215 PostToKernel(ev, true);
00216 }
00217 }
00218 else
00219 evt.Skip();
00220
00221 lastPos = evt.GetPosition();
00222 }
00223
00224
00225 wxString CameraManipulator::GetDesc() const
00226 {
00227 return wxT("Process input events and manipulate associated camera");
00228 }