00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "g-map-vertex.hh"
00026 #include "controler.hh"
00027 #include "view-precompile.hh"
00028 #include <cassert>
00029
00030 using namespace GMap3d;
00031
00032
00033
00034
00035
00036
00037
00038 static float fpmod(float div,float mod)
00039 {
00040 float res = fmod(div,mod);
00041 return (res < 0 ? res + mod : res);
00042 }
00043
00044
00045
00046
00047
00048
00049 static CVertex multMatrixVector(const float mat[3][3], float x, float y, float z)
00050 {
00051 return CVertex(
00052 mat[0][0] * x + mat[0][1] * y + mat[0][2] * z,
00053 mat[1][0] * x + mat[1][1] * y + mat[1][2] * z,
00054 mat[2][0] * x + mat[2][1] * y + mat[2][2] * z);
00055 }
00056
00057
00058
00059
00060
00061 static void createRotationMatrix(float mat[3][3], float angle, const CVertex & axe)
00062 {
00063 float cos_a = cosf(angle);
00064 float sin_a = sinf(angle);
00065 float inv_cos = 1. - cos_a;
00066
00067
00068 mat[0][0] = cos_a + (inv_cos * axe.getX() * axe.getX());
00069 mat[0][1] = (inv_cos * axe.getX() * axe.getY()) - (sin_a * axe.getZ());
00070 mat[0][2] = (inv_cos * axe.getX() * axe.getZ()) + (sin_a * axe.getY());
00071
00072 mat[1][0] = (inv_cos * axe.getX() * axe.getY()) + (sin_a * axe.getZ());
00073 mat[1][1] = cos_a + (inv_cos * axe.getY() * axe.getY());
00074 mat[1][2] = (inv_cos * axe.getY() * axe.getZ()) - (sin_a * axe.getX());;
00075
00076 mat[2][0] = (inv_cos * axe.getX() * axe.getZ()) - (sin_a * axe.getY());
00077 mat[2][1] = (inv_cos * axe.getY() * axe.getZ()) + (sin_a * axe.getX());
00078 mat[2][2] = cos_a + (inv_cos * axe.getZ() * axe.getZ());
00079 }
00080
00081
00082
00083
00084
00085 void CControler::calculEyePosition(TViewId AView, CParameterEyePosition * eye_pos, CParameterAimedPosition * pt_view)
00086 {
00087 float alpha_rad = rad(fpmod(eye_pos -> getRotationAlpha() - 90.0, 360));
00088 float beta_rad = rad(fpmod(eye_pos -> getRotationBeta() + 90.0, 360));
00089 float distance = eye_pos -> getDistance();
00090
00091 eye_coord.setX(pt_view -> getLookAt(0) + distance * cosf(alpha_rad) * sinf(beta_rad));
00092 eye_coord.setY(pt_view -> getLookAt(1) + distance * sinf(alpha_rad) * sinf(beta_rad));
00093 eye_coord.setZ(pt_view -> getLookAt(2) + distance * cosf(beta_rad));
00094 }
00095
00096
00097
00098
00099
00100 CVertex CControler::calculEyePosition(TViewId AView)
00101 {
00102 CParameterEyePosition * eye_pos = getParameterEyePosition(AView);
00103 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00104 calculEyePosition(AView,eye_pos,pt_view);
00105 return CVertex(eye_coord);
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 const CVertex & CControler::getEyePosition() const
00117 {
00118 return eye_coord;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128 void CControler::horizontalRotationEye(TViewId AView,bool positive,float alpha)
00129 {
00130 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00131 CParameterEyePosition * eye_pos = getParameterEyePosition(AView);
00132 calculEyePosition(AView,eye_pos,pt_view);
00133
00134 if (alpha == 0) alpha = eye_pos -> getAngleRotation();
00135 if (!positive) alpha = -alpha;
00136
00137
00138 CVertex cam_y(pt_view -> getLookAt(0) - eye_coord.getX(),
00139 pt_view -> getLookAt(1) - eye_coord.getY(),
00140 pt_view -> getLookAt(2) - eye_coord.getZ());
00141
00142
00143 float rotation_mat[3][3];
00144 createRotationMatrix(rotation_mat, rad(alpha), OZ);
00145 CVertex coord_pt_view = multMatrixVector(rotation_mat, cam_y.getX(),cam_y.getY(),cam_y.getZ() );
00146
00147
00148 coord_pt_view += eye_coord;
00149 pt_view -> setLookAt(0,coord_pt_view.getX());
00150 pt_view -> setLookAt(1,coord_pt_view.getY());
00151 pt_view -> setLookAt(2,coord_pt_view.getZ());
00152
00153
00154 eye_pos -> setRotationAlpha(fpmod(eye_pos -> getRotationAlpha() + alpha,360));
00155 }
00156
00157
00158
00159
00160
00161
00162 void CControler::verticalRotationEye(TViewId AView,bool positive,float beta)
00163 {
00164 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00165 CParameterEyePosition * eye_pos = getParameterEyePosition(AView);
00166 calculEyePosition(AView,eye_pos,pt_view);
00167
00168 if (beta == 0) beta = eye_pos -> getAngleRotation();
00169 if (!positive) beta = -beta;
00170
00171
00172 CVertex cam_y(pt_view -> getLookAt(0) - eye_coord.getX(),
00173 pt_view -> getLookAt(1) - eye_coord.getY(),
00174 pt_view -> getLookAt(2) - eye_coord.getZ());
00175
00176
00177 CVertex axe_de_rotation = OZ * cam_y;
00178 axe_de_rotation.normalize();
00179
00180 float rotation_mat[3][3];
00181 createRotationMatrix(rotation_mat, rad(-beta), axe_de_rotation);
00182 CVertex coord_pt_view = multMatrixVector(rotation_mat, cam_y.getX(),cam_y.getY(),cam_y.getZ() );
00183
00184
00185 coord_pt_view += eye_coord;
00186 pt_view -> setLookAt(0,coord_pt_view.getX());
00187 pt_view -> setLookAt(1,coord_pt_view.getY());
00188 pt_view -> setLookAt(2,coord_pt_view.getZ());
00189
00190
00191 eye_pos -> setRotationBeta(fpmod(eye_pos -> getRotationBeta() + beta,360));
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201 void CControler::moveEye(TViewId AView,bool positive,float coeff)
00202 {
00203 CParameterEyePosition * eye_pos = getParameterEyePosition(AView);
00204 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00205 calculEyePosition(AView,eye_pos,pt_view);
00206
00207 if (coeff == 0) coeff = eye_pos -> getPasAvancement();
00208 if (!positive) coeff = -coeff;
00209
00210 CVertex direction(pt_view -> getLookAt(0) - eye_coord.getX(),
00211 pt_view -> getLookAt(1) - eye_coord.getY(),
00212 pt_view -> getLookAt(2) - eye_coord.getZ());
00213
00214 direction.normalize();
00215 direction *= coeff;
00216 eye_coord += direction;
00217
00218 pt_view -> setLookAt(0,pt_view -> getLookAt(0) + direction.getX());
00219 pt_view -> setLookAt(1,pt_view -> getLookAt(1) + direction.getY());
00220 pt_view -> setLookAt(2,pt_view -> getLookAt(2) + direction.getZ());
00221 }
00222
00223
00224
00225
00226
00227 void CControler::moveEyeLateral(TViewId AView,bool positive,float coeff)
00228 {
00229 CParameterEyePosition * eye_pos = getParameterEyePosition(AView);
00230 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00231 calculEyePosition(AView,eye_pos,pt_view);
00232
00233 if (coeff == 0) coeff = eye_pos -> getPasAvancement();
00234 if (!positive) coeff = -coeff;
00235
00236 CVertex avant(pt_view -> getLookAt(0) - eye_coord.getX(),
00237 pt_view -> getLookAt(1) - eye_coord.getY(),
00238 pt_view -> getLookAt(2) - eye_coord.getZ());
00239
00240 CVertex direction=avant*OZ;
00241 direction.normalize();
00242 direction *= coeff;
00243 eye_coord += direction;
00244
00245 pt_view -> setLookAt(0,pt_view -> getLookAt(0) + direction.getX());
00246 pt_view -> setLookAt(1,pt_view -> getLookAt(1) + direction.getY());
00247 pt_view -> setLookAt(2,pt_view -> getLookAt(2) + direction.getZ());
00248 }
00249
00250
00251
00252
00253
00254
00255 void CControler::moveEyeX(TViewId AView,bool positive,float coeff)
00256 {
00257 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00258 if (coeff == 0) coeff = getParameterEyePosition(AView) -> getPasAvancement();
00259 if (!positive) coeff = -coeff;
00260 pt_view -> setLookAt(0,pt_view -> getLookAt(0) + coeff);
00261 }
00262
00263
00264 void CControler::moveEyeY(TViewId AView,bool positive,float coeff)
00265 {
00266 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00267 if (coeff == 0) coeff = getParameterEyePosition(AView) -> getPasAvancement();
00268 if (!positive) coeff = -coeff;
00269 pt_view -> setLookAt(1,pt_view -> getLookAt(1) + coeff);
00270 }
00271
00272
00273
00274 void CControler::moveEyeZ(TViewId AView,bool positive,float coeff)
00275 {
00276 CParameterAimedPosition * pt_view = getParameterAimedPosition(AView);
00277 if (coeff == 0) coeff = getParameterEyePosition(AView) -> getPasAvancement();
00278 if (!positive) coeff = -coeff;
00279 pt_view -> setLookAt(2,pt_view -> getLookAt(2) + coeff);
00280 }
00281