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 "controler-gmap-types.hh"
00026 #include "view.hh"
00027 #include "precompile-dart.hh"
00028 #include "dart-vertex.hh"
00029 #include "parameter-gmap-vertex.hh"
00030 #include "parameter-dart.hh"
00031 #include "parameter-selection.hh"
00032 #include <cassert>
00033 #include <climits>
00034 using namespace GMap3d;
00035
00036 CPrecompileDart::CPrecompileDart(CParameterGMapVertex * AParameterGMapV,
00037 CParameterDart * AParameterDart,
00038 CParameterSelection * AParameterSelection) :
00039 FParameterGMapV(AParameterGMapV),
00040 FParameterDart(AParameterDart),
00041 FParameterSelection(AParameterSelection)
00042 {
00043 assert(FParameterGMapV != NULL && FParameterDart != NULL);
00044
00045 FParameterGMapV->addPrecompileToUpdate(this);
00046 FParameterDart->addPrecompileToUpdate(this);
00047
00048 if (FParameterSelection != NULL)
00049 FParameterSelection->addPrecompileToUpdate(this);
00050 }
00051
00052 CPrecompileDart::CPrecompileDart(const CPrecompileDart & APrecompile) :
00053 CPrecompile(APrecompile),
00054 FParameterGMapV(APrecompile.FParameterGMapV),
00055 FParameterDart(static_cast<CParameterDart*>
00056 (APrecompile.FParameterDart->copy())),
00057 FParameterSelection(APrecompile.FParameterSelection)
00058 {
00059 assert(FParameterGMapV != NULL && FParameterDart != NULL);
00060
00061 FParameterGMapV->addPrecompileToUpdate(this);
00062 FParameterDart->addPrecompileToUpdate(this);
00063
00064 if (FParameterSelection != NULL)
00065 FParameterSelection->addPrecompileToUpdate(this);
00066 }
00067
00068 CPrecompileDart::~CPrecompileDart()
00069 {
00070 FParameterGMapV->removePrecompileToUpdate(this);
00071 FParameterDart->removePrecompileToUpdate(this);
00072
00073 if (FParameterSelection != NULL)
00074 FParameterSelection->removePrecompileToUpdate(this);
00075 }
00076
00077 CPrecompile * CPrecompileDart::copy() const
00078 { return new CPrecompileDart(*this); }
00079
00080 void CPrecompileDart::setParameter(CParameter* AParameter)
00081 {
00082 switch (AParameter->getType())
00083 {
00084 case PARAMETER_GMAP_VERTEX:
00085 setGMapVertex(static_cast<CParameterGMapVertex *>(AParameter));
00086 break;
00087 case PARAMETER_DART:
00088 setDart(static_cast<CParameterDart *>(AParameter));
00089 break;
00090 case PARAMETER_SELECTION:
00091 setSelection(static_cast<CParameterSelection *>(AParameter));
00092 break;
00093 }
00094 }
00095
00096 CParameter* CPrecompileDart::getParameter() const
00097 { return FParameterDart; }
00098
00099 void CPrecompileDart::setGMapVertex(CParameterGMapVertex* AParameterGMapV)
00100 {
00101 assert(AParameterGMapV != NULL);
00102 AParameterGMapV->addPrecompileToUpdate(this);
00103 FParameterGMapV->removePrecompileToUpdate(this);
00104 FParameterGMapV = AParameterGMapV;
00105 setToUpdate();
00106 }
00107
00108 void CPrecompileDart::setDart(CParameterDart* ADart)
00109 {
00110 assert(ADart != NULL);
00111 ADart->addPrecompileToUpdate(this);
00112 FParameterDart->removePrecompileToUpdate(this);
00113 FParameterDart = ADart;
00114 setToUpdate();
00115 }
00116
00117 void CPrecompileDart::setSelection(CParameterSelection* ASelection)
00118 {
00119 if (ASelection != NULL)
00120 ASelection->addPrecompileToUpdate(this);
00121
00122 if (FParameterSelection != NULL)
00123 FParameterSelection->removePrecompileToUpdate(this);
00124
00125 FParameterSelection = ASelection;
00126 setToUpdate();
00127 }
00128
00129 TPrecompile CPrecompileDart::getType() const
00130 { return PRECOMPILE_DART; }
00131
00132 void CPrecompileDart::drawOneDart(CDart * ADart)
00133 {
00134 CVertex * v1 = &FParameterGMapV->getMap()->getBurstVertex(ADart);
00135
00136 if (FParameterGMapV->getMap()->isFree0(ADart))
00137 {
00138
00139 glBegin(GL_POINTS);
00140 PLOT(v1);
00141 glEnd();
00142 }
00143 else
00144 {
00145
00146 CVertex v2 = FParameterGMapV->getMap()->computeBurstExtremity(ADart);
00147 glBegin(GL_LINES);
00148 LINE(v1, &v2);
00149 glEnd();
00150 }
00151 }
00152
00153 void CPrecompileDart::drawModel()
00154 {
00155 glLineWidth(FParameterDart->getLWDarts());
00156 glPointSize(FParameterDart->getSAloneDarts());
00157
00158 CVertex m;
00159 const GLfloat * clSel = NULL;
00160 const GLfloat * clUnsel = NULL;
00161 const GLfloat * clLast = NULL;
00162 int mark = -1;
00163
00164 CDart * last = NULL;
00165
00166 if (FParameterSelection != NULL)
00167 {
00168 mark = FParameterSelection->getSelectionMark();
00169 last = FParameterSelection->getLastSelectedDart();
00170
00171 clSel = FParameterDart->
00172 getCLSel(FParameterSelection->getSelectionLevel());
00173 clUnsel = FParameterDart->
00174 getCLUnsel(FParameterSelection->getSelectionLevel());
00175 clLast = FParameterDart->
00176 getCLLastSel(FParameterSelection->getSelectionLevel());
00177 }
00178 else
00179 clSel = FParameterDart->getCLUnsel(0);
00180
00181 CDynamicCoverageAll it(FParameterGMapV->getMap());
00182
00183
00184 glColor3fv(clUnsel);
00185 for (; it.cont(); ++it)
00186 if (mark == -1 || !FParameterGMapV->getMap()->isMarked(*it, mark))
00187 drawOneDart(*it);
00188
00189 if (mark != -1)
00190 {
00191
00192 glColor3fv(clSel);
00193 for (it.reinit(); it.cont(); ++it)
00194 if (FParameterGMapV->getMap()->isMarked(*it, mark) && *it != last)
00195 drawOneDart(*it);
00196 }
00197
00198
00199 if (last != NULL)
00200 {
00201 glColor3fv(clLast);
00202 drawOneDart(last);
00203 }
00204 }
00205
00206 #define DMAX (20) // Distance maximum pour la sélection d'un segment.
00207 #define RFREE (6) // Distance maximum pour la sélection d'un point.
00208
00209 float distanceToSegment(float x, float y, float x1, float y1,
00210 float x2, float y2)
00211 {
00212 #define SQR(X) (sqr((double)(X)))
00213
00214 float xa = MIN(x1, x2) - DMAX;
00215 float xb = MAX(x1, x2) + DMAX;
00216 float ya = MIN(y1, y2) - DMAX;
00217 float yb = MAX(y1, y2) + DMAX;
00218
00219 if (x < xa || x > xb || y < ya || y > yb)
00220 return INT_MAX;
00221
00222
00223 if (x1 == x2 && y1 == y2)
00224 return sqr(x -x1) + SQR(y - y1) - RFREE * RFREE;
00225
00226 double k = - double((x1 - x2) * (x - x1) + (y - y1) * (y1 - y2)) /
00227 (SQR(x1 - x2) + SQR(y1 - y2));
00228
00229
00230 if (k <= 0) return sqr(x -x1) + sqr(y - y1);
00231
00232
00233 if (k >= 1) return sqr(x -x2) + sqr(y - y2);
00234
00235
00236 return sqr(k*(x2 - x1) + x1 - x) + sqr(k*(y2 - y1) + y1 - y);
00237 }
00238
00239 void CPrecompileDart::pick(int AX, int AY, CView* AView)
00240 {
00241 assert(AView != NULL);
00242
00243 CDart* nearest = NULL;
00244 float bestDist = DMAX * DMAX;
00245
00246 for (CDynamicCoverageAll it(FParameterGMapV->getMap()); it.cont(); ++it)
00247 {
00248 CDart* current = *it;
00249
00250 CVertex& v1 = FParameterGMapV->getMap()->getBurstVertex(current);
00251
00252 float seg1[3], seg2[3];
00253
00254 AView->project(v1.getX(), v1.getY(), v1.getZ(), seg1);
00255
00256 if (FParameterGMapV->getMap()->isFree0(current))
00257 {
00258 seg2[0] = seg1[0];
00259 seg2[1] = seg1[1];
00260 }
00261 else
00262 {
00263 CVertex e = FParameterGMapV->getMap()->computeBurstExtremity(current);
00264 AView->project(e.getX(), e.getY(), e.getZ(), seg2);
00265 }
00266
00267 float currentDist = distanceToSegment(AX, AY,
00268 seg1[0], seg1[1],
00269 seg2[0], seg2[1]);
00270
00271 if (currentDist < bestDist)
00272 {
00273 nearest = current;
00274 bestDist = currentDist;
00275 }
00276 }
00277
00278 if (nearest != NULL)
00279 FParameterSelection->toggleOrbitSelection(nearest);
00280 }
00281