Replacing french comments by english one
[occt.git] / src / V3d / V3d_Camera.cxx
CommitLineData
7fd59977 1/***********************************************************************
2
3 FONCTION :
4 ----------
5 Classe V3d_Camera :
6
7 HISTORIQUE DES MODIFICATIONS :
8 --------------------------------
9 00-09-92 : GG ; Creation.
10 18-06-96 : FMN ; Ajout MyGraphicStructure1 pour sauvegarder snopick
11 24-12-97 : FMN ; Remplacement de math par MathGra
12 31-12-97 : CAL ; Suppression de MathGra
13 21-01-98 : CAL ; Window de Xw et WNT remplacee par Aspect_Window
14 23-02-98 : FMN ; Remplacement PI par Standard_PI
15 02.15.100 : JR : Clutter
16
17************************************************************************/
18
19/*----------------------------------------------------------------------*/
20/*
21 * Includes
22 */
23
24#include <V3d_Camera.ixx>
25#include <V3d.hxx>
26#include <V3d_PerspectiveView.hxx>
27#include <Graphic3d_Vector.hxx>
28#include <Graphic3d_Vertex.hxx>
29#include <Graphic3d_Structure.hxx>
30#include <Graphic3d_Group.hxx>
31#include <Graphic3d_Array1OfVertex.hxx>
32#include <Graphic3d_AspectMarker3d.hxx>
33#include <Graphic3d_AspectLine3d.hxx>
34#include <Graphic3d_AspectText3d.hxx>
35#include <Visual3d_ViewManager.hxx>
36#include <Visual3d_ContextPick.hxx>
37#include <Visual3d_PickDescriptor.hxx>
38#include <Visual3d_HSequenceOfPickPath.hxx>
39#include <Visual3d_PickPath.hxx>
40#include <Viewer_BadValue.hxx>
41#include <gp_Dir.hxx>
42#include <gp_Ax1.hxx>
43#include <gp_Vec.hxx>
44#include <gp_Pnt.hxx>
45#include <gp_Trsf.hxx>
46#include <TColStd_Array2OfReal.hxx>
47#include <TCollection_AsciiString.hxx>
48#include <Aspect_Window.hxx>
49
50//-Declarations
51#define DEUXPI (2.*Standard_PI)
52
53//-Constructors
54
55V3d_Camera::V3d_Camera(const Handle(V3d_View)& aView) {
56 Standard_Real X,Y,Z;
57 Graphic3d_Vertex P,T;
58
81bba717 59// The eye point defines the position of the camera
7fd59977 60 aView->Eye(X,Y,Z);
61 P.SetCoord(X,Y,Z);
62 MyPosition = P;
81bba717 63 // The target point defines the target of the camera
7fd59977 64 aView->At(X,Y,Z);
65 T.SetCoord(X,Y,Z);
66 MyTarget = T;
81bba717 67// Incline Angle of the camera
7fd59977 68 MyAngle = aView->Twist();
81bba717 69// Aperture Angle of the camera
7fd59977 70 MyAperture = (aView->DynamicType()==STANDARD_TYPE(V3d_PerspectiveView)) ?
71 ((Handle(V3d_PerspectiveView)&)aView)->Angle() : 0.;
72
73}
74
75//-Methods, in order
76
77void V3d_Camera::SetPosition(const Standard_Real Xp, const Standard_Real Yp, const Standard_Real Zp) {
78
79 MyPosition.SetCoord(Xp,Yp,Zp) ;
80}
81
82void V3d_Camera::SetAngle(const Standard_Real Angle) {
83
84 Viewer_BadValue_Raise_if( Abs(Angle) > DEUXPI, "V3d_Camera::SetAngle, bad angle" );
85 MyAngle = Angle ;
86}
87
88void V3d_Camera::SetAperture(const Standard_Real Angle) {
89
90 Viewer_BadValue_Raise_if( Angle <= 0. || Angle >= Standard_PI ,"V3d_Camera::SetAperture, bad angle");
91 MyAperture = Angle ;
92}
93
94void V3d_Camera::SetTarget(const Standard_Real X, const Standard_Real Y, const Standard_Real Z) {
95
96 MyTarget.SetCoord(X,Y,Z);
97}
98
99void V3d_Camera::SetRadius(const Standard_Real Radius) {
100
101 Viewer_BadValue_Raise_if( Radius <= 0., "V3d_Camera::SetRadius, bad radius");
102
103 Standard_Real X0,Y0,Z0,Xn,Yn,Zn;
104
81bba717 105// Targer point remains unchanged, only the position of the camera is modified
106// preserving the direction.
7fd59977 107 Graphic3d_Vector D(MyTarget,MyPosition);
108 D.Normalize();
109 D.Coord(Xn,Yn,Zn);
110 MyTarget.Coord(X0,Y0,Z0);
111 Xn = X0 + Radius*Xn;
112 Yn = Y0 + Radius*Yn;
113 Zn = Z0 + Radius*Zn;
114 MyPosition.SetCoord(Xn,Yn,Zn) ;
115
116}
117
118void V3d_Camera::OnHideFace(const Handle(V3d_View)& aView) {
119
120 Standard_Real XP,YP,ZP,Rayon,X,Y,Z,VX,VY,VZ;
121
122 Rayon = this->Radius();
123 MyPosition.Coord(XP,YP,ZP);
124 SymetricPointOnSphere(aView,MyTarget,MyPosition,Rayon,X,Y,Z,VX,VY,VZ);
81bba717 125 // This point is visible
7fd59977 126 if ( (VX*(X-XP) < 0.) && (VY*(Y-YP) < 0.) && (VZ*(Z-ZP) < 0.) ) {
127 this->SetPosition(X,Y,Z);
128 }
129}
130
131void V3d_Camera::OnSeeFace(const Handle(V3d_View)& aView) {
132
133 Standard_Real XP,YP,ZP,Rayon,X,Y,Z,VX,VY,VZ;
134
135 Rayon = this->Radius();
136 MyPosition.Coord(XP,YP,ZP);
137 SymetricPointOnSphere(aView,MyTarget,MyPosition,Rayon,X,Y,Z,VX,VY,VZ);
81bba717 138 // This point is hidden
7fd59977 139 if ( (VX*(X-XP) > 0.) && (VY*(Y-YP) > 0.) && (VZ*(Z-ZP) > 0.) ) {
140 this->SetPosition(X,Y,Z);
141 }
142}
143
144Standard_Boolean V3d_Camera::SeeOrHide(const Handle(V3d_View)& aView) const {
145
146 Standard_Real XP,YP,ZP,Rayon,X,Y,Z,VX,VY,VZ;
147 Standard_Boolean Val;
148
149 Rayon = this->Radius();
150 MyPosition.Coord(XP,YP,ZP);
151 SymetricPointOnSphere(aView,MyTarget,MyPosition,Rayon,X,Y,Z,VX,VY,VZ);
81bba717 152 // Is it a visible or a hidden point?
7fd59977 153 if ( (VX*(X-XP) > 0.) || (VY*(Y-YP) > 0.) || (VZ*(Z-ZP) > 0.) )
81bba717 154// the source is on the hidden face
7fd59977 155 Val = Standard_False;
156 else
81bba717 157 // the source is on the visible face.
7fd59977 158 Val = Standard_True;
159
160 return Val;
161
162}
163
164void V3d_Camera::Position(Standard_Real& Xp, Standard_Real& Yp, Standard_Real& Zp)const {
165
166 MyPosition.Coord(Xp,Yp,Zp) ;
167}
168
169Standard_Real V3d_Camera::Angle()const {
170
171 return MyAngle ;
172}
173
174Standard_Real V3d_Camera::Aperture()const {
175
176 return MyAperture ;
177}
178
179void V3d_Camera::Target(Standard_Real& Xp, Standard_Real& Yp, Standard_Real& Zp)const {
180
181// Graphic3d_Vertex P ;
182 MyTarget.Coord(Xp,Yp,Zp) ;
183}
184
185Standard_Real V3d_Camera::Radius() const {
186
187 Standard_Real Xp,Yp,Zp,Xc,Yc,Zc,Radius;
188 MyPosition.Coord(Xp,Yp,Zp);
189 MyTarget.Coord(Xc,Yc,Zc);
190 Radius = Square(Xc - Xp) + Square(Yc - Yp) + Square(Zc - Zp);
191 Radius = Sqrt(Radius);
192 return Radius ;
193}
194
195void V3d_Camera::Symbol (const Handle(Graphic3d_Group)& gsymbol,
196// const Handle(V3d_View)& aView) const {
197 const Handle(V3d_View)& ) const {
198
199 Standard_Real X0,Y0,Z0,XP,YP,ZP,Dx,Dy,Dz,Lng;
200 Standard_Real Xc1,Yc1,Zc1,Xc2,Yc2,Zc2,Xi,Yi,Zi,Xj,Yj,Zj;
201 Standard_Real Xn,Yn,Zn,X,Y,Z,Norme;
202 Standard_Real cosinus,sinus;
203 Standard_Real Alpha = Standard_PI/4.;
204 Standard_Integer NbPoints = 4, i;
205 Graphic3d_Array1OfVertex VN1(1,NbPoints+1);
206 Graphic3d_Array1OfVertex VN2(1,NbPoints+1);
207 Graphic3d_Array1OfVertex V2(1,2);
208
81bba717 209// Direction of the camera
7fd59977 210 MyPosition.Coord(XP,YP,ZP);
211 MyTarget.Coord(X0,Y0,Z0);
212 Dx = X0 - XP; Dy = Y0 - YP; Dz = Z0 - ZP;
213 Lng = this->Radius()/10.;
214
81bba717 215// Find centers of base squares of the case of the camera :
7fd59977 216 Xc1 = XP - Dx * Lng; Yc1 = YP - Dy * Lng; Zc1 = ZP - Dz * Lng;
217 Xc2 = XP + Dx * Lng; Yc2 = YP + Dy * Lng; Zc2 = ZP + Dz * Lng;
218
81bba717 219// Construction of a mark i,j for rectangles :
7fd59977 220 Xn=0., Yn=0., Zn=0.;
221
222 if ( Abs(Dx) <= Abs(Dy) && Abs(Dx) <= Abs(Dz)) Xn=1.;
223 else if ( Abs(Dy) <= Abs(Dz) && Abs(Dy) <= Abs(Dx)) Yn=1.;
224 else Zn=1.;
225 Xi = Dy * Zn - Dz * Yn;
226 Yi = Dz * Xn - Dx * Zn;
227 Zi = Dx * Yn - Dy * Xn;
228
229 Norme = Sqrt ( Xi*Xi + Yi*Yi + Zi*Zi );
230 Xi= Xi / Norme; Yi = Yi / Norme; Zi = Zi/Norme;
231
232 Xj = Dy * Zi - Dz * Yi;
233 Yj = Dz * Xi - Dx * Zi;
234 Zj = Dx * Yi - Dy * Xi;
235
81bba717 236// Scheme of the case
7fd59977 237 for (i = 1 ; i <= NbPoints ; i++) {
238
239 cosinus = Cos ( Alpha + (i - 1) * Standard_PI/2. );
240 sinus = Sin ( Alpha + (i - 1) * Standard_PI/2. );
241
81bba717 242 // First base square
7fd59977 243 X = Xc1 + (cosinus * Xi + sinus * Xj) * Lng / 2.;
244 Y = Yc1 + (cosinus * Yi + sinus * Yj) * Lng / 2.;
245 Z = Zc1 + (cosinus * Zi + sinus * Zj) * Lng / 2.;
246 VN1(i).SetCoord(X,Y,Z);
247 if(i==1) VN1(NbPoints+1).SetCoord(X,Y,Z);
248 V2(1).SetCoord(X,Y,Z);
249
81bba717 250// Second base square
7fd59977 251 X = Xc2 + (cosinus * Xi + sinus * Xj) * Lng / 2.;
252 Y = Yc2 + (cosinus * Yi + sinus * Yj) * Lng / 2.;
253 Z = Zc2 + (cosinus * Zi + sinus * Zj) * Lng / 2.;
254 VN2(i).SetCoord(X,Y,Z);
255 if(i==1) VN2(NbPoints+1).SetCoord(X,Y,Z);
256 V2(2).SetCoord(X,Y,Z);
257
258 gsymbol->Polyline(V2);
259 }
260 gsymbol->Polyline(VN1);
261 gsymbol->Polyline(VN2);
262
81bba717 263// Scheme of the objective
7fd59977 264 for (i = 1 ; i <= NbPoints ; i++) {
265
266 cosinus = Cos ( Alpha + (i - 1) * Standard_PI/2. );
267 sinus = Sin ( Alpha + (i - 1) * Standard_PI/2. );
268
269 // Premier carre de base
270 X = Xc2 + (cosinus * Xi + sinus * Xj) * Lng / 6.;
271 Y = Yc2 + (cosinus * Yi + sinus * Yj) * Lng / 6.;
272 Z = Zc2 + (cosinus * Zi + sinus * Zj) * Lng / 6.;
273 VN1(i).SetCoord(X,Y,Z);
274 if(i==1) VN1(NbPoints+1).SetCoord(X,Y,Z);
275 V2(1).SetCoord(X,Y,Z);
276
81bba717 277// Second base square
7fd59977 278 X = Xc2 + Dx * Lng / 6. + (cosinus * Xi + sinus * Xj) * Lng / 3.;
279 Y = Yc2 + Dy * Lng / 6. + (cosinus * Yi + sinus * Yj) * Lng / 3.;
280 Z = Zc2 + Dz * Lng / 6. + (cosinus * Zi + sinus * Zj) * Lng / 3.;
281 VN2(i).SetCoord(X,Y,Z);
282 if(i==1) VN2(NbPoints+1).SetCoord(X,Y,Z);
283 V2(2).SetCoord(X,Y,Z);
284
285 gsymbol->Polyline(V2);
286 }
287 gsymbol->Polyline(VN1);
288 gsymbol->Polyline(VN2);
289
290}
291
292void V3d_Camera::Display( const Handle(V3d_View)& aView,
293 const V3d_TypeOfRepresentation TPres) {
294
295 Graphic3d_Array1OfVertex PRadius(0,1);
296 Graphic3d_Vertex PText ;
297 Standard_Real X,Y,Z,Rayon;
298 Standard_Real X0,Y0,Z0,VX,VY,VZ;
299 Standard_Real X1,Y1,Z1,XT,YT,ZT,PXT,PYT;
300 Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini;
301 Standard_Integer IXP,IYP;
302 V3d_TypeOfRepresentation Pres;
303 V3d_TypeOfUpdate UpdSov;
304
305
81bba717 306// Creation of a structure of markable elements (position of the
307// camera, and the sphere of displacement of this camera)
7fd59977 308
309 Pres = TPres;
310 Handle(V3d_Viewer) TheViewer = aView->Viewer();
311 UpdSov = TheViewer->UpdateMode();
312 TheViewer->SetUpdateMode(V3d_WAIT);
313 if (!MyGraphicStructure.IsNull()) {
314 MyGraphicStructure->Disconnect(MyGraphicStructure1);
315 MyGraphicStructure->Clear();
316 MyGraphicStructure1->Clear();
317 if (Pres == V3d_SAMELAST) Pres = MyTypeOfRepresentation;
318 }
319 else {
320 if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE;
321 Handle(Graphic3d_Structure) scamera = new Graphic3d_Structure(TheViewer->Viewer());
322 MyGraphicStructure = scamera;
323 Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->Viewer());
324 MyGraphicStructure1 = snopick;
325 }
326
327 Handle(Graphic3d_Group) gradius;
328 Handle(Graphic3d_Group) gExtArrow;
329 Handle(Graphic3d_Group) gIntArrow;
330 if (Pres == V3d_COMPLETE) {
331 gradius = new Graphic3d_Group(MyGraphicStructure);
332 gExtArrow = new Graphic3d_Group(MyGraphicStructure);
333 gIntArrow = new Graphic3d_Group(MyGraphicStructure);
334 }
335 Handle(Graphic3d_Group) gcamera = new Graphic3d_Group(MyGraphicStructure);
336 Handle(Graphic3d_Group) gsphere;
337 if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) gsphere = new Graphic3d_Group(MyGraphicStructure);
338
81bba717 339// Creation of a structure of non-markable elements (meridian and
340// parallel ).
7fd59977 341 Handle(Graphic3d_Group) gnopick = new Graphic3d_Group(MyGraphicStructure1);
342 MyGraphicStructure1->SetPick(Standard_False);
343
344 MyTarget.Coord(X0,Y0,Z0);
345
81bba717 346// Display of the position of the camera.
7fd59977 347
348 gcamera->SetPickId(1);
349 if (Pres == V3d_SIMPLE) {
81bba717 350// a viewfinder is drawn
7fd59977 351 Graphic3d_Array1OfVertex PViseur(1,2);
352 aView->Project(X0,Y0,Z0,PXT,PYT);
353 aView->Convert(PXT,PYT,IXP,IYP);
354 aView->Convert(IXP,IYP,XT,YT,ZT);
355 aView->Convert(IXP+20,IYP,X,Y,Z);
356 PViseur(1).SetCoord(X+X0-XT,Y+Y0-YT,Z+Z0-ZT);
357 aView->Convert(IXP-20,IYP,X,Y,Z);
358 PViseur(2).SetCoord(X+X0-XT,Y+Y0-YT,Z+Z0-ZT);
359 gcamera->Polyline(PViseur);
360 aView->Convert(IXP,IYP-20,X,Y,Z);
361 PViseur(1).SetCoord(X+X0-XT,Y+Y0-YT,Z+Z0-ZT);
362 aView->Convert(IXP,IYP+20,X,Y,Z);
363 PViseur(2).SetCoord(X+X0-XT,Y+Y0-YT,Z+Z0-ZT);
364 gcamera->Polyline(PViseur);
365 }
81bba717 366// a camera is drawn
7fd59977 367 else this->Symbol(gcamera,aView);
368
81bba717 369// Display of the marking sphere (limited to circle).
7fd59977 370
371 if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) {
372
373 Rayon = this->Radius();
374 aView->Proj(VX,VY,VZ);
375 gsphere->SetPickId(2);
376 V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon);
377
81bba717 378// Display of the radius of the sphere (line + text)
7fd59977 379
380 if (Pres == V3d_COMPLETE) {
381 gradius->SetPickId(3);
382 gExtArrow->SetPickId(4);
383 gIntArrow->SetPickId(5);
384 PRadius(0).SetCoord(X0,Y0,Z0);
385 MyPosition.Coord(X,Y,Z);
386 PRadius(1).SetCoord(X,Y,Z);
387 gnopick->Polyline(PRadius);
388 V3d::ArrowOfRadius(gExtArrow,X-(X-X0)/10.,
389 Y-(Y-Y0)/10.,
390 Z-(Z-Z0)/10.,X-X0,Y-Y0,Z-Z0,Standard_PI/15.,Rayon/20.);
391 V3d::ArrowOfRadius(gIntArrow,X0,Y0,Z0,X0-X,Y0-Y,Z0-Z,Standard_PI/15.,
392 Rayon/20.);
393 TCollection_AsciiString ValOfRadius(Rayon);
394 PText.SetCoord( (X0+X)/2., (Y0+Y)/2. , (Z0+Z)/2. );
395 gradius->Text(ValOfRadius.ToCString(),PText,0.01);
396 }
397
81bba717 398// Display of the meridian
7fd59977 399
400 Quantity_Color Col2(Quantity_NOC_GREEN);
401 Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d
402 (Col2,Aspect_TOL_SOLID,1.);
403 gnopick->SetPrimitivesAspect(Asp2);
404
81bba717 405 // Definition of the axis of circle
7fd59977 406 aView->Up(DXRef,DYRef,DZRef);
407 this->Position(X,Y,Z);
408 DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
409 VX = DYRef*DZini - DZRef*DYini;
410 VY = DZRef*DXini - DXRef*DZini;
411 VZ = DXRef*DYini - DYRef*DXini;
412
413 V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
414
81bba717 415// Display of the parallel
7fd59977 416
81bba717 417// Definition of the axis of circle
7fd59977 418 aView->Proj(VX,VY,VZ);
419 aView->Up(X1,Y1,Z1);
420 DXRef = VY * Z1 - VZ * Y1;
421 DYRef = VZ * X1 - VX * Z1;
422 DZRef = VX * Y1 - VY * X1;
423 this->Position(X,Y,Z);
424 DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
425 VX = DYRef*DZini - DZRef*DYini;
426 VY = DZRef*DXini - DXRef*DZini;
427 VZ = DXRef*DYini - DYRef*DXini;
428
429 V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
430
431 }
432
433 MyGraphicStructure->Connect(MyGraphicStructure1,Graphic3d_TOC_DESCENDANT);
434 MyTypeOfRepresentation = Pres;
435 MyGraphicStructure->Display();
436 TheViewer->SetUpdateMode(UpdSov);
437}
438
439void V3d_Camera::Erase() {
440
441 if (!MyGraphicStructure.IsNull()) MyGraphicStructure->Erase();
442 if (!MyGraphicStructure1.IsNull()) MyGraphicStructure1->Erase();
443}
444
445V3d_TypeOfPickCamera V3d_Camera::Pick(const Handle(V3d_View)& aView,
446 const Standard_Integer Xpix,
447 const Standard_Integer Ypix) const
448{
449
450 Standard_Integer i, Lng, Id;
451 Standard_Boolean kcont;
452 V3d_TypeOfPickCamera TPick;
453
454 Handle(Visual3d_ViewManager) VM = (aView->Viewer())->Viewer();
455 Visual3d_ContextPick CTXP;
456 Visual3d_PickDescriptor Pdes = VM->Pick(CTXP,aView->Window (),Xpix,Ypix);
457 Visual3d_PickPath OnePPath;
458 Handle(Visual3d_HSequenceOfPickPath) PPath = Pdes.PickPath();
459 Lng = PPath->Length();
460 kcont = Standard_True;
461 TPick = V3d_NOTHINGCAMERA;
462 for (i=1; i<=Lng && kcont; i++) {
463 OnePPath = PPath->Value(i);
464 Id = OnePPath.PickIdentifier();
465 if (MyGraphicStructure == OnePPath.StructIdentifier()){
466 switch (Id) {
467 case 1 : TPick = V3d_POSITIONCAMERA;
468 break;
469 case 2 : TPick = V3d_SPACECAMERA;
470 break;
471 case 3 : TPick = V3d_RADIUSTEXTCAMERA;
472 break;
473 case 4 : TPick = V3d_ExtRADIUSCAMERA;
474 break;
475 case 5 : TPick = V3d_IntRADIUSCAMERA;
476 break;
477 }
478 kcont = Standard_False;
479 }
480 }
481 return TPick;
482}
483
484void V3d_Camera::Tracking( const Handle(V3d_View)& aView,
485 const V3d_TypeOfPickCamera WhatPick,
486 const Standard_Integer Xpix,
487 const Standard_Integer Ypix) {
488
489
490 Standard_Real XPp,YPp,PXT,PYT,X,Y,Z,Rayon,Ylim;
491 Standard_Real XMinTrack,XMaxTrack,YMinTrack,YMaxTrack;
492 Standard_Real XT,YT,ZT,X0,Y0,Z0,XP,YP,ZP,VX,VY,VZ,A,B,C,Delta;
493 Standard_Real DX,DY,PXP,PYP,Xproj,Yproj;
494 Standard_Real A1,A2,B1,B2,Rap,OldRprj,NewRprj;
495 Standard_Real Xi,Yi,Zi,DeltaX,DeltaY,DeltaZ,Lambda;
496 Standard_Integer IPX,IPY;
497
498
499 aView->Convert(Xpix,Ypix,XPp,YPp);
500 MyTarget.Coord(X0,Y0,Z0);
501 aView->Project(X0,Y0,Z0,PXT,PYT);
502 aView->Convert(PXT,PYT,IPX,IPY);
81bba717 503 // Coord 3d in the plane of projection of the target.
7fd59977 504 aView->Convert(IPX,IPY,XT,YT,ZT);
505 switch (WhatPick) {
506 case V3d_POSITIONCAMERA :
81bba717 507 // Coordinates should remain inside of the sphere
7fd59977 508 Rayon = this->Radius();
509 XMinTrack = PXT - Rayon;
510 XMaxTrack = PXT + Rayon;
511 Ylim = Sqrt( Square(Rayon) - Square(XPp - PXT) );
512 YMinTrack = PYT - Ylim;
513 YMaxTrack = PYT + Ylim;
514 if (XPp >= XMinTrack && XPp <= XMaxTrack) {
515 if (YPp >= YMinTrack && YPp <= YMaxTrack) {
516 aView->ProjReferenceAxe(Xpix,Ypix,XP,YP,ZP,VX,VY,VZ);
517 DeltaX = X0 - XP;
518 DeltaY = Y0 - YP;
519 DeltaZ = Z0 - ZP;
520
81bba717 521// The point of intersection of straight lines defined by :
522// - Straight line passing by the point of projection and the eye
523// if this is a perspective, parallel to the normal of the
524// view if there is an axonometric view.
525// position in the view is parallel to the normal of the view
526// - The distance position of the target camera cible is equal
527// to the radius.
7fd59977 528
529 A = VX*VX + VY*VY + VZ*VZ ;
530 B = -2. * (VX*DeltaX + VY*DeltaY + VZ*DeltaZ);
531 C = DeltaX*DeltaX + DeltaY*DeltaY + DeltaZ*DeltaZ
532 - Rayon*Rayon ;
533 Delta = B*B - 4.*A*C;
534 if ( Delta >= 0 ) {
535 Lambda = (-B + Sqrt(Delta))/(2.*A);
536 X = XP + Lambda*VX;
537 Y = YP + Lambda*VY;
538 Z = ZP + Lambda*VZ;
539 MyPosition.SetCoord(X,Y,Z);
540 this->Display(aView,MyTypeOfRepresentation);
541 aView->Update();
542 }
543 }
544
545 break;
546 }
547 case V3d_SPACECAMERA :
548 aView->Convert(PXT,PYT,IPX,IPY);
81bba717 549// In case Xpix,Ypix corresponding to a distance , relative
550// to the translation that is planned to be done on the sphere.
7fd59977 551 aView->Convert(IPX+Xpix,IPY+Ypix,X,Y,Z);
552 X = X+X0-XT;
553 Y = Y+Y0-YT;
554 Z = Z+Z0-ZT;
555 MyTarget.SetCoord(X,Y,Z);
556 MyPosition.Coord(Xi,Yi,Zi);
557 Xi = Xi + (X - X0);
558 Yi = Yi + (Y - Y0);
559 Zi = Zi + (Z - Z0);
560 MyPosition.SetCoord(Xi,Yi,Zi);
561 this->Display(aView,MyTypeOfRepresentation);
562 aView->Update();
563 break;
564
565 case V3d_ExtRADIUSCAMERA :
81bba717 566// It is attempted to preserve the target positioning direction of the
567// camera ==> the point is projected on the target camera direction.
7fd59977 568 this->Position(Xi,Yi,Zi);
569 aView->Project(Xi,Yi,Zi,PXP,PYP);
570 DX = PXP - PXT;
571 DY = PYP - PYT;
572 A1 = DY/DX ; B1 = PYT - A1*PXT;
573 A2 = -DX/DY; B2 = YPp - A2*XPp;
574 Xproj = (B2 - B1) / (A1 - A2);
575 Yproj = A1*Xproj + B1;
576 if ( (DX*(Xproj-PXT) > 0.) && (DY*(Yproj-PYT) > 0.) ) {
577 OldRprj = Sqrt ( Square (PXP-PXT) + Square (PYP-PYT) );
578 NewRprj = Sqrt ( Square (Xproj-PXT) + Square (Yproj-PYT) );
579 Rap = NewRprj/OldRprj;
580 Rayon = this->Radius();
581 Rayon = Rayon * Rap;
582 this->SetRadius(Rayon);
583 this->Display(aView,MyTypeOfRepresentation);
584 aView->Update();
585 }
586 break;
587 case V3d_IntRADIUSCAMERA :
81bba717 588// It is attempted to preserve the target positioning direction of the
589// camera ==> the point is projected on the target camera direction.
7fd59977 590 this->Position(Xi,Yi,Zi);
591 aView->Project(Xi,Yi,Zi,PXP,PYP);
592 DX = PXP - PXT;
593 DY = PYP - PYT;
594 A1 = DY/DX ; B1 = PYT - A1*PXT;
595 A2 = -DX/DY; B2 = YPp - A2*XPp;
596 Xproj = (B2 - B1) / (A1 - A2);
597 Yproj = A1*Xproj + B1;
598 if ( (DX*(Xproj-PXP) < 0.) && (DY*(Yproj-PYP) < 0.) ) {
599 OldRprj = Sqrt ( Square (PXP-PXT) + Square (PYP-PYT) );
600 NewRprj = Sqrt ( Square (Xproj-PXP) + Square (Yproj-PYP) );
601 Rap = NewRprj/OldRprj;
602 Rayon = this->Radius();
603 Rayon = Rayon * Rap;
81bba717 604// the camera should remain at a fixed position, only the target is modified.
7fd59977 605 Graphic3d_Vector Dir(MyPosition,MyTarget);
606 Dir.Normalize();
607 Dir.Coord(X,Y,Z);
608 X = Xi + Rayon*X;
609 Y = Yi + Rayon*Y;
610 Z = Zi + Rayon*Z;
611 MyTarget.SetCoord(X,Y,Z);
612 this->Display(aView,MyTypeOfRepresentation);
613 aView->Update();
614 }
615 break;
616 case V3d_RADIUSTEXTCAMERA :
617 break;
618 case V3d_NOTHINGCAMERA :
619 break;
620 }
621}
622
623void V3d_Camera::AerialPilot( const Handle(V3d_View)& aView,
624 const Standard_Integer Xpix,
625 const Standard_Integer Ypix) {
626
627 Standard_Real Xp,Yp,Zp,Xc,Yc,Zc,Xv,Yv,Zv,Xf,Yf,Zf;
628 Standard_Real VX,VY,VZ,DXH,DYH,DZH,A,B,C,PXT,PYT,X1,Y1,Z1,Dist;
629 Standard_Real Height,Width,Beta,CosBeta,SinBeta,Coef;
630 Standard_Integer IPX,IPY,IHeight,IWidth;
631 TColStd_Array2OfReal MatRot(0,2,0,2);
632
633
634 MyPosition.Coord(Xp,Yp,Zp);
635 MyTarget.Coord(Xc,Yc,Zc);
636 aView->At(Xv,Yv,Zv);
637 aView->Project(Xv,Yv,Zv,PXT,PYT);
638 aView->Convert(PXT,PYT,IPX,IPY);
81bba717 639// Find the pitching ==> Xpix = IPX and Ypix inverted
640// The target point turns around an axis passing through the eye and the
641// direction of vector belonging to the view plane
642// and perpendicular to the vector above the view.
7fd59977 643 if ( Ypix != IPY ) {
644 aView->Size(Width,Height);
645 IHeight = aView->Convert(Height);
646 Beta = ((IPY - Ypix)*Standard_PI)/(IHeight*2.);
647 aView->Proj(VX,VY,VZ);
648 aView->Up(DXH,DYH,DZH);
649 A = VY*DZH - VZ*DYH;
650 B = VZ*DXH - VX*DZH;
651 C = VX*DYH - VY*DXH;
652 Dist = Sqrt( A*A + B*B + C*C);
653 A = A/Dist; B = B/Dist; C = C/Dist;
654 CosBeta = Cos(Beta);
655 SinBeta = Sin(Beta);
656 Coef = 1. - CosBeta;
657 MatRot(0,0) = A * A + (1. - A * A) * CosBeta;
658 MatRot(0,1) = -C * SinBeta + Coef * A * B;
659 MatRot(0,2) = B * SinBeta + Coef * A * C;
660 MatRot(1,0) = C * SinBeta + Coef * A * B;
661 MatRot(1,1) = B * B + (1. - B * B) * CosBeta;
662 MatRot(1,2) = -A * SinBeta + Coef * B * C;
663 MatRot(2,0) = -B * SinBeta + Coef * A * C;
664 MatRot(2,1) = A * SinBeta + Coef * B * C;
665 MatRot(2,2) = C * C + (1. - C * C) * CosBeta;
666 Xf = Xp * MatRot(0,0) + Yp * MatRot(0,1) + Zp * MatRot(0,2);
667 Yf = Xp * MatRot(1,0) + Yp * MatRot(1,1) + Zp * MatRot(1,2);
668 Zf = Xp * MatRot(2,0) + Yp * MatRot(2,1) + Zp * MatRot(2,2);
81bba717 669// Rotation of the target point (target of the camera)
7fd59977 670 X1 = Xc * MatRot(0,0) + Yc * MatRot(0,1) + Zc * MatRot(0,2);
671 Y1 = Xc * MatRot(1,0) + Yc * MatRot(1,1) + Zc * MatRot(1,2);
672 Z1 = Xc * MatRot(2,0) + Yc * MatRot(2,1) + Zc * MatRot(2,2);
673 Xc = X1 + Xp - Xf ; Yc = Y1 + Yp - Yf ; Zc = Z1 + Zp - Zf;
674 MyTarget.SetCoord(Xc,Yc,Zc);
675 }
81bba717 676// Find the rolling determined by Xpix
7fd59977 677 if ( Xpix != IPX ) {
678 IWidth = aView->Convert(Width);
679 Beta = ((IPX - Xpix)*Standard_PI)/(IWidth*2.);
680 MyAngle = MyAngle + Beta;
681 }
682}
683
684
685void V3d_Camera::EarthPilot( const Handle(V3d_View)& aView,
686 const Standard_Integer Xpix,
687 const Standard_Integer Ypix) {
81bba717 688// Piloting in land mode, resembles to the car driving
689// In this case, only the target point is modified.
7fd59977 690
691 Standard_Real Xp,Yp,Zp,Xc,Yc,Zc,Xv,Yv,Zv,Xf,Yf,Zf;
692 Standard_Real VX,VY,VZ,DXH,DYH,DZH,A,B,C,PXT,PYT,X1,Y1,Z1,Dist;
693 Standard_Real Height,Width,Beta,CosBeta,SinBeta,Coef;
694 Standard_Integer IPX,IPY,IHeight,IWidth;
695 TColStd_Array2OfReal MatRot(0,2,0,2);
696
697 MyPosition.Coord(Xp,Yp,Zp);
698 MyTarget.Coord(Xc,Yc,Zc);
699 aView->At(Xv,Yv,Zv);
700 aView->Project(Xv,Yv,Zv,PXT,PYT);
701 aView->Convert(PXT,PYT,IPX,IPY);
81bba717 702// Find the pitching ==> Xpix = IPX and Ypix inverted
703// The target point turns around an axis passing through the eye and the
704// direction of vector belonging to the view plane
705// and perpendicular to the vector above the view.
7fd59977 706 if ( Ypix != IPY ) {
707 aView->Size(Width,Height);
708 IHeight = aView->Convert(Height);
709 Beta = ((IPY - Ypix)*Standard_PI)/(IHeight*2.);
710 aView->Proj(VX,VY,VZ);
711 aView->Up(DXH,DYH,DZH);
712 A = VY*DZH - VZ*DYH;
713 B = VZ*DXH - VX*DZH;
714 C = VX*DYH - VY*DXH;
715 Dist = Sqrt( A*A + B*B + C*C);
716 A = A/Dist; B = B/Dist; C = C/Dist;
717 CosBeta = Cos(Beta);
718 SinBeta = Sin(Beta);
719 Coef = 1. - CosBeta;
720 MatRot(0,0) = A * A + (1. - A * A) * CosBeta;
721 MatRot(0,1) = -C * SinBeta + Coef * A * B;
722 MatRot(0,2) = B * SinBeta + Coef * A * C;
723 MatRot(1,0) = C * SinBeta + Coef * A * B;
724 MatRot(1,1) = B * B + (1. - B * B) * CosBeta;
725 MatRot(1,2) = -A * SinBeta + Coef * B * C;
726 MatRot(2,0) = -B * SinBeta + Coef * A * C;
727 MatRot(2,1) = A * SinBeta + Coef * B * C;
728 MatRot(2,2) = C * C + (1. - C * C) * CosBeta;
729 Xf = Xp * MatRot(0,0) + Yp * MatRot(0,1) + Zp * MatRot(0,2);
730 Yf = Xp * MatRot(1,0) + Yp * MatRot(1,1) + Zp * MatRot(1,2);
731 Zf = Xp * MatRot(2,0) + Yp * MatRot(2,1) + Zp * MatRot(2,2);
81bba717 732// Rotation of the target point (target of the camera)
7fd59977 733 X1 = Xc * MatRot(0,0) + Yc * MatRot(0,1) + Zc * MatRot(0,2);
734 Y1 = Xc * MatRot(1,0) + Yc * MatRot(1,1) + Zc * MatRot(1,2);
735 Z1 = Xc * MatRot(2,0) + Yc * MatRot(2,1) + Zc * MatRot(2,2);
736 Xc = X1 + Xp - Xf ; Yc = Y1 + Yp - Yf ; Zc = Z1 + Zp - Zf;
737 }
81bba717 738// Find turning ==> Ypix = IPY . The target point rotates around
739// an axis // a vector above passing through the eye
7fd59977 740 if ( Xpix != IPX ) {
741 IWidth = aView->Convert(Width);
742 Beta = ((IPX - Xpix)*Standard_PI)/(IWidth*2.);
743 aView->Up(A,B,C);
744 Dist = Sqrt( A*A + B*B + C*C);
745 A = A/Dist; B = B/Dist; C = C/Dist;
746 CosBeta = Cos(Beta);
747 SinBeta = Sin(Beta);
748 Coef = 1. - CosBeta;
749 MatRot(0,0) = A * A + (1. - A * A) * CosBeta;
750 MatRot(0,1) = -C * SinBeta + Coef * A * B;
751 MatRot(0,2) = B * SinBeta + Coef * A * C;
752 MatRot(1,0) = C * SinBeta + Coef * A * B;
753 MatRot(1,1) = B * B + (1. - B * B) * CosBeta;
754 MatRot(1,2) = -A * SinBeta + Coef * B * C;
755 MatRot(2,0) = -B * SinBeta + Coef * A * C;
756 MatRot(2,1) = A * SinBeta + Coef * B * C;
757 MatRot(2,2) = C * C + (1. - C * C) * CosBeta;
758 Xf = Xp * MatRot(0,0) + Yp * MatRot(0,1) + Zp * MatRot(0,2);
759 Yf = Xp * MatRot(1,0) + Yp * MatRot(1,1) + Zp * MatRot(1,2);
760 Zf = Xp * MatRot(2,0) + Yp * MatRot(2,1) + Zp * MatRot(2,2);
81bba717 761 // Rotation of the target point (target of the camera)
7fd59977 762 X1 = Xc * MatRot(0,0) + Yc * MatRot(0,1) + Zc * MatRot(0,2);
763 Y1 = Xc * MatRot(1,0) + Yc * MatRot(1,1) + Zc * MatRot(1,2);
764 Z1 = Xc * MatRot(2,0) + Yc * MatRot(2,1) + Zc * MatRot(2,2);
765 Xc = X1 + Xp - Xf ; Yc = Y1 + Yp - Yf ; Zc = Z1 + Zp - Zf;
766 }
767 MyTarget.SetCoord(Xc,Yc,Zc);
768}
769
770void V3d_Camera::Move (const Standard_Real Dist) {
81bba717 771// Displacement of the camera by preserving the direction camera - target.
7fd59977 772
773 Standard_Real XP,YP,ZP,X0,Y0,Z0,DX,DY,DZ,Norme;
774
775 MyPosition.Coord(XP,YP,ZP);
776 MyTarget.Coord(X0,Y0,Z0);
777 DX = X0 - XP; DY = Y0 - YP; DZ = Z0 - ZP;
778 Norme = Sqrt(DX*DX + DY*DY + DZ*DZ);
779 DX = Dist*DX/Norme; DY = Dist*DY/Norme; DZ = Dist*DZ/Norme;
780 XP = XP + DX; YP = YP + DY; ZP = ZP + DZ;
781 X0 = X0 + DX; Y0 = Y0 + DY; Z0 = Z0 + DZ;
782 MyPosition.SetCoord(XP,YP,ZP);
783 MyTarget.SetCoord(X0,Y0,Z0);
784}
785
786void V3d_Camera::GoUp (const Standard_Real Haut) {
787
81bba717 788// Displacement of the camera by axis z, preserving the direction camera -
789// target of the camera
7fd59977 790
791 MyPosition.SetZCoord(MyPosition.Z()+Haut);
792 MyTarget.SetZCoord(MyTarget.Z()+Haut);
793}
794
795void V3d_Camera::SymetricPointOnSphere (const Handle(V3d_View)& aView, const Graphic3d_Vertex &Center, const Graphic3d_Vertex &aPoint, const Standard_Real Rayon, Standard_Real& X, Standard_Real& Y, Standard_Real& Z, Standard_Real& VX, Standard_Real& VY, Standard_Real& VZ ) {
796
797 Standard_Real X0,Y0,Z0,XP,YP,ZP;
798 Standard_Real PXP,PYP,DeltaX,DeltaY,DeltaZ;
799 Standard_Real A,B,C,Delta,Lambda;
800 Standard_Integer IPX,IPY;
801
802 Center.Coord(X0,Y0,Z0);
803 aPoint.Coord(XP,YP,ZP);
804 aView->Project(XP,YP,ZP,PXP,PYP);
805 aView->Convert(PXP,PYP,IPX,IPY);
806 aView->ProjReferenceAxe(IPX,IPY,X,Y,Z,VX,VY,VZ);
807 DeltaX = X0 - XP;
808 DeltaY = Y0 - YP;
809 DeltaZ = Z0 - ZP;
810
81bba717 811// The point of intersection of straight lines defined by :
812// - Straight line passing by the point of projection and the eye
813// if this is a perspective, parallel to the normal of the
814// view if there is an axonometric view.
815// position in the view is parallel to the normal of the view
816// - The distance position of the target camera cible is equal
817// to the radius.
7fd59977 818
819 A = VX*VX + VY*VY + VZ*VZ ;
820 B = -2. * (VX*DeltaX + VY*DeltaY + VZ*DeltaZ);
821 C = DeltaX*DeltaX + DeltaY*DeltaY + DeltaZ*DeltaZ
822 - Rayon*Rayon ;
823 Delta = B*B - 4.*A*C;
824 if ( Delta >= 0 ) {
825 Lambda = (-B + Sqrt(Delta))/(2.*A);
826 if ( Lambda >= -0.0001 && Lambda <= 0.0001 )
827 Lambda = (-B - Sqrt(Delta))/(2.*A);
828 X = XP + Lambda*VX;
829 Y = YP + Lambda*VY;
830 Z = ZP + Lambda*VZ;
831 }
832 else {
833 X = XP; Y = YP; Z = ZP;
834 }
835}