1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkCamera.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkCamera.h"
16
17 #include "vtkCallbackCommand.h"
18 #include "vtkInformation.h"
19 #include "vtkMath.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPerspectiveTransform.h"
22 #include "vtkRenderer.h"
23 #include "vtkTimeStamp.h"
24 #include "vtkTransform.h"
25
26 #include <cassert>
27 #include <cmath>
28
29 //------------------------------------------------------------------------------
30 // Needed when we don't use the vtkStandardNewMacro.
31 vtkObjectFactoryNewMacro(vtkCamera);
32
33 vtkCxxSetObjectMacro(vtkCamera, Information, vtkInformation);
34 vtkCxxSetObjectMacro(vtkCamera, EyeTransformMatrix, vtkMatrix4x4);
35 vtkCxxSetObjectMacro(vtkCamera, ModelTransformMatrix, vtkMatrix4x4);
36 vtkCxxSetObjectMacro(vtkCamera, ExplicitProjectionTransformMatrix, vtkMatrix4x4);
37
38 //------------------------------------------------------------------------------
39 class vtkCameraCallbackCommand : public vtkCommand
40 {
41 public:
New()42 static vtkCameraCallbackCommand* New() { return new vtkCameraCallbackCommand; }
43 vtkCamera* Self;
Execute(vtkObject *,unsigned long,void *)44 void Execute(vtkObject*, unsigned long, void*) override
45 {
46 if (this->Self)
47 {
48 this->Self->Modified();
49 this->Self->ComputeViewTransform();
50 this->Self->ComputeDistance();
51 this->Self->ComputeCameraLightTransform();
52 }
53 }
54
55 protected:
vtkCameraCallbackCommand()56 vtkCameraCallbackCommand() { this->Self = nullptr; }
57 ~vtkCameraCallbackCommand() override = default;
58 };
59
60 //------------------------------------------------------------------------------
61 // Construct camera instance with its focal point at the origin,
62 // and position=(0,0,1). The view up is along the y-axis,
63 // view angle is 30 degrees, and the clipping range is (.1,1000).
vtkCamera()64 vtkCamera::vtkCamera()
65 {
66 this->FocalPoint[0] = 0.0;
67 this->FocalPoint[1] = 0.0;
68 this->FocalPoint[2] = 0.0;
69
70 this->Position[0] = 0.0;
71 this->Position[1] = 0.0;
72 this->Position[2] = 1.0;
73
74 this->ViewUp[0] = 0.0;
75 this->ViewUp[1] = 1.0;
76 this->ViewUp[2] = 0.0;
77
78 this->DirectionOfProjection[0] = 0.0;
79 this->DirectionOfProjection[1] = 0.0;
80 this->DirectionOfProjection[2] = 0.0;
81
82 this->ViewAngle = 30.0;
83 this->UseHorizontalViewAngle = 0;
84
85 this->UseOffAxisProjection = 0;
86
87 this->ScreenBottomLeft[0] = -0.5;
88 this->ScreenBottomLeft[1] = -0.5;
89 this->ScreenBottomLeft[2] = -0.5;
90
91 this->ScreenBottomRight[0] = 0.5;
92 this->ScreenBottomRight[1] = -0.5;
93 this->ScreenBottomRight[2] = -0.5;
94
95 this->ScreenTopRight[0] = 0.5;
96 this->ScreenTopRight[1] = 0.5;
97 this->ScreenTopRight[2] = -0.5;
98
99 this->EyeSeparation = 0.06;
100
101 this->WorldToScreenMatrix = vtkMatrix4x4::New();
102 this->WorldToScreenMatrix->Identity();
103
104 this->EyeTransformMatrix = vtkMatrix4x4::New();
105 this->EyeTransformMatrix->Identity();
106
107 this->ModelTransformMatrix = vtkMatrix4x4::New();
108 this->ModelTransformMatrix->Identity();
109
110 this->ClippingRange[0] = 0.01;
111 this->ClippingRange[1] = 1000.01;
112 this->Thickness = 1000.0;
113
114 this->ParallelProjection = 0;
115 this->ParallelScale = 1.0;
116
117 this->EyeAngle = 2.0;
118 this->Stereo = 0;
119 this->LeftEye = 1;
120
121 this->WindowCenter[0] = 0.0;
122 this->WindowCenter[1] = 0.0;
123
124 this->ViewShear[0] = 0.0;
125 this->ViewShear[1] = 0.0;
126 this->ViewShear[2] = 1.0;
127
128 this->FocalDisk = 1.0;
129 this->FocalDistance = 0.0;
130
131 this->Transform = vtkPerspectiveTransform::New();
132 this->ViewTransform = vtkTransform::New();
133 this->ProjectionTransform = vtkPerspectiveTransform::New();
134 this->CameraLightTransform = vtkTransform::New();
135 this->ModelViewTransform = vtkTransform::New();
136 this->ExplicitProjectionTransformMatrix = nullptr;
137 this->UseExplicitProjectionTransformMatrix = false;
138 this->UserTransform = nullptr;
139 this->UserViewTransform = nullptr;
140 this->UserViewTransformCallbackCommand = nullptr;
141
142 // initialize the ViewTransform
143 this->ComputeViewTransform();
144 this->ComputeDistance();
145 this->ComputeCameraLightTransform();
146
147 this->FreezeFocalPoint = false;
148 this->UseScissor = false;
149
150 this->Information = vtkInformation::New();
151 this->Information->Register(this);
152 this->Information->Delete();
153
154 this->ExplicitAspectRatio = 1.0;
155 this->UseExplicitAspectRatio = false;
156
157 this->FocalPointScale = 1.0;
158 this->FocalPointShift[0] = 0.0;
159 this->FocalPointShift[1] = 0.0;
160 this->FocalPointShift[2] = 0.0;
161 this->NearPlaneScale = 1.0;
162 this->NearPlaneShift[0] = 0.0;
163 this->NearPlaneShift[1] = 0.0;
164 this->NearPlaneShift[2] = 0.0;
165 this->ShiftScaleThreshold = 2.0;
166 }
167
168 //------------------------------------------------------------------------------
~vtkCamera()169 vtkCamera::~vtkCamera()
170 {
171 this->WorldToScreenMatrix->Delete();
172 this->WorldToScreenMatrix = nullptr;
173
174 this->EyeTransformMatrix->Delete();
175 this->EyeTransformMatrix = nullptr;
176
177 this->ModelTransformMatrix->Delete();
178 this->ModelTransformMatrix = nullptr;
179
180 this->Transform->Delete();
181 this->ViewTransform->Delete();
182 this->ProjectionTransform->Delete();
183 this->CameraLightTransform->Delete();
184 this->ModelViewTransform->Delete();
185 if (this->ExplicitProjectionTransformMatrix)
186 {
187 this->ExplicitProjectionTransformMatrix->UnRegister(this);
188 this->ExplicitProjectionTransformMatrix = nullptr;
189 }
190 if (this->UserTransform)
191 {
192 this->UserTransform->UnRegister(this);
193 this->UserTransform = nullptr;
194 }
195 if (this->UserViewTransform)
196 {
197 this->UserViewTransform->RemoveObserver(this->UserViewTransformCallbackCommand);
198 this->UserViewTransform->UnRegister(this);
199 this->UserViewTransform = nullptr;
200 }
201 if (this->UserViewTransformCallbackCommand)
202 {
203 this->UserViewTransformCallbackCommand->Delete();
204 }
205
206 this->SetInformation(nullptr);
207 }
208
209 //------------------------------------------------------------------------------
SetScissorRect(vtkRecti scissorRect)210 void vtkCamera::SetScissorRect(vtkRecti scissorRect)
211 {
212 this->ScissorRect = scissorRect;
213 }
214
215 //------------------------------------------------------------------------------
GetScissorRect(vtkRecti & scissorRect)216 void vtkCamera::GetScissorRect(vtkRecti& scissorRect)
217 {
218 scissorRect = this->ScissorRect;
219 }
220
221 //------------------------------------------------------------------------------
222 // The first set of methods deal exclusively with the ViewTransform, which
223 // is the only transform which is set up entirely in the camera. The
224 // perspective transform must be set up by the Renderer because the
225 // Camera doesn't know the Renderer's aspect ratio.
226 //------------------------------------------------------------------------------
SetPosition(double x,double y,double z)227 void vtkCamera::SetPosition(double x, double y, double z)
228 {
229 if (x == this->Position[0] && y == this->Position[1] && z == this->Position[2])
230 {
231 return;
232 }
233
234 this->Position[0] = x;
235 this->Position[1] = y;
236 this->Position[2] = z;
237
238 vtkDebugMacro(<< " Position set to ( " << this->Position[0] << ", " << this->Position[1] << ", "
239 << this->Position[2] << ")");
240
241 this->ComputeViewTransform();
242 // recompute the focal distance
243 this->ComputeDistance();
244 this->ComputeCameraLightTransform();
245
246 this->Modified();
247 }
248
249 //------------------------------------------------------------------------------
SetUserTransform(vtkHomogeneousTransform * transform)250 void vtkCamera::SetUserTransform(vtkHomogeneousTransform* transform)
251 {
252 if (transform == this->UserTransform)
253 {
254 return;
255 }
256 if (this->UserTransform)
257 {
258 this->UserTransform->Delete();
259 this->UserTransform = nullptr;
260 }
261 if (transform)
262 {
263 this->UserTransform = transform;
264 this->UserTransform->Register(this);
265 }
266 this->Modified();
267 }
268
269 //------------------------------------------------------------------------------
SetUserViewTransform(vtkHomogeneousTransform * transform)270 void vtkCamera::SetUserViewTransform(vtkHomogeneousTransform* transform)
271 {
272 if (transform == this->UserViewTransform)
273 {
274 return;
275 }
276 if (this->UserViewTransform)
277 {
278 this->UserViewTransform->RemoveObserver(this->UserViewTransformCallbackCommand);
279 this->UserViewTransform->Delete();
280 this->UserViewTransform = nullptr;
281 }
282 if (transform)
283 {
284 this->UserViewTransform = transform;
285 this->UserViewTransform->Register(this);
286 if (!this->UserViewTransformCallbackCommand)
287 {
288 this->UserViewTransformCallbackCommand = vtkCameraCallbackCommand::New();
289 this->UserViewTransformCallbackCommand->Self = this;
290 }
291 this->UserViewTransform->AddObserver(
292 vtkCommand::ModifiedEvent, this->UserViewTransformCallbackCommand);
293 }
294 this->Modified();
295 this->ComputeViewTransform();
296 this->ComputeDistance();
297 this->ComputeCameraLightTransform();
298 }
299
300 //------------------------------------------------------------------------------
SetFocalPoint(double x,double y,double z)301 void vtkCamera::SetFocalPoint(double x, double y, double z)
302 {
303 if (x == this->FocalPoint[0] && y == this->FocalPoint[1] && z == this->FocalPoint[2])
304 {
305 return;
306 }
307
308 this->FocalPoint[0] = x;
309 this->FocalPoint[1] = y;
310 this->FocalPoint[2] = z;
311
312 vtkDebugMacro(<< " FocalPoint set to ( " << this->FocalPoint[0] << ", " << this->FocalPoint[1]
313 << ", " << this->FocalPoint[2] << ")");
314
315 this->ComputeViewTransform();
316 // recompute the focal distance
317 this->ComputeDistance();
318 this->ComputeCameraLightTransform();
319
320 this->Modified();
321 }
322
323 //------------------------------------------------------------------------------
SetViewUp(double x,double y,double z)324 void vtkCamera::SetViewUp(double x, double y, double z)
325 {
326 // normalize ViewUp, but do _not_ orthogonalize it by default
327 double norm = sqrt(x * x + y * y + z * z);
328
329 if (norm != 0)
330 {
331 x /= norm;
332 y /= norm;
333 z /= norm;
334 }
335 else
336 {
337 x = 0;
338 y = 1;
339 z = 0;
340 }
341
342 if (x == this->ViewUp[0] && y == this->ViewUp[1] && z == this->ViewUp[2])
343 {
344 return;
345 }
346
347 this->ViewUp[0] = x;
348 this->ViewUp[1] = y;
349 this->ViewUp[2] = z;
350
351 vtkDebugMacro(<< " ViewUp set to ( " << this->ViewUp[0] << ", " << this->ViewUp[1] << ", "
352 << this->ViewUp[2] << ")");
353
354 this->ComputeViewTransform();
355 this->ComputeCameraLightTransform();
356 this->Modified();
357 }
358
359 //------------------------------------------------------------------------------
360 // The ViewTransform depends on only three ivars: the Position, the
361 // FocalPoint, and the ViewUp vector. All the other methods are there
362 // simply for the sake of the users' convenience.
ComputeViewTransform()363 void vtkCamera::ComputeViewTransform()
364 {
365 // main view through the camera
366 this->Transform->Identity();
367 if (this->UserViewTransform)
368 {
369 this->Transform->Concatenate(this->UserViewTransform);
370 }
371 this->Transform->SetupCamera(this->Position, this->FocalPoint, this->ViewUp);
372 this->ViewTransform->Identity();
373 this->ViewTransform->Concatenate(this->Transform->GetMatrix());
374 }
375
376 //------------------------------------------------------------------------------
ComputeCameraLightTransform()377 void vtkCamera::ComputeCameraLightTransform()
378 {
379 vtkTransform* t;
380 double d;
381
382 // assumes a valid view transform and valid camera distance
383
384 t = this->CameraLightTransform;
385 t->Identity();
386 t->SetMatrix(this->ViewTransform->GetMatrix());
387 t->Inverse();
388
389 d = this->Distance;
390 t->Scale(d, d, d);
391 t->Translate(0.0, 0.0, -1.0);
392 }
393
394 //------------------------------------------------------------------------------
ComputeWorldToScreenMatrix()395 void vtkCamera::ComputeWorldToScreenMatrix()
396 {
397 // Avoid recalculating screen orientation if we don't need to.
398 if (this->WorldToScreenMatrixMTime.GetMTime() < this->GetMTime())
399 {
400 double xAxis[3];
401 double yAxis[3];
402 double zAxis[3];
403
404 for (int i = 0; i < 3; ++i)
405 {
406 xAxis[i] = this->ScreenBottomRight[i] - this->ScreenBottomLeft[i];
407 yAxis[i] = this->ScreenTopRight[i] - this->ScreenBottomRight[i];
408 }
409
410 vtkMath::Normalize(xAxis);
411 vtkMath::Normalize(yAxis);
412 vtkMath::Cross(xAxis, yAxis, zAxis);
413 vtkMath::Normalize(zAxis);
414
415 // Setting individual elements of the matrix.
416
417 // Make it column major and then invert it to make sure the translation is correct
418 // This is using column major (vectors are copied into the column)
419 // \Note: while the initial element assignments are made in column-major
420 // ordering, the matrix will be inverted, resulting in a row-major
421 // matrix that provides the transformation from World to Screen space.
422 this->WorldToScreenMatrix->SetElement(0, 0, xAxis[0]);
423 this->WorldToScreenMatrix->SetElement(1, 0, xAxis[1]);
424 this->WorldToScreenMatrix->SetElement(2, 0, xAxis[2]);
425
426 this->WorldToScreenMatrix->SetElement(0, 1, yAxis[0]);
427 this->WorldToScreenMatrix->SetElement(1, 1, yAxis[1]);
428 this->WorldToScreenMatrix->SetElement(2, 1, yAxis[2]);
429
430 this->WorldToScreenMatrix->SetElement(0, 2, zAxis[0]);
431 this->WorldToScreenMatrix->SetElement(1, 2, zAxis[1]);
432 this->WorldToScreenMatrix->SetElement(2, 2, zAxis[2]);
433
434 this->WorldToScreenMatrix->SetElement(0, 3, this->ScreenBottomLeft[0]);
435 this->WorldToScreenMatrix->SetElement(1, 3, this->ScreenBottomLeft[1]);
436 this->WorldToScreenMatrix->SetElement(2, 3, this->ScreenBottomLeft[2]);
437
438 this->WorldToScreenMatrix->SetElement(3, 3, 1.0);
439
440 // The reason for doing this as an Invert as the goal here is to put
441 // the translation through the rotation that we've just assigned ie.
442 // the translation has to be put into screen space too.
443 this->WorldToScreenMatrix->Invert();
444
445 this->WorldToScreenMatrixMTime.Modified();
446 }
447 }
448
449 //------------------------------------------------------------------------------
ComputeOffAxisProjectionFrustum()450 void vtkCamera::ComputeOffAxisProjectionFrustum()
451 {
452 this->ComputeWorldToScreenMatrix();
453
454 // \NOTE: Variable names reflect naming convention used in
455 // "High Resolution Virtual Reality", in Proc.
456 // SIGGRAPH '92, Computer Graphics, pages 195-202, 1992.
457
458 // OffAxis calculations.
459
460 // vtkMatrix::MultiplyPoint expect homogeneous coordinate.
461 double E[4] = { 0.0, 0.0, 0.0, 1.0 };
462
463 double L[4] = { this->ScreenBottomLeft[0], this->ScreenBottomLeft[1], this->ScreenBottomLeft[2],
464 1.0 };
465 double H[4] = { this->ScreenTopRight[0], this->ScreenTopRight[1], this->ScreenTopRight[2], 1.0 };
466
467 double eyeSeparationCorrectionFactor = 10.0;
468 double shiftDistance = this->EyeSeparation / (2.0 * eyeSeparationCorrectionFactor);
469 if (this->Distance < 1.0)
470 {
471 shiftDistance *= this->Distance;
472 }
473 if (this->LeftEye)
474 {
475 E[0] -= shiftDistance;
476 }
477 else
478 {
479 E[0] += shiftDistance;
480 }
481
482 // First transform the eye to new position.
483 this->EyeTransformMatrix->MultiplyPoint(E, E);
484
485 // Now transform the eye and screen corner points into the screen
486 // coordinate system.
487 this->WorldToScreenMatrix->MultiplyPoint(E, E);
488 this->WorldToScreenMatrix->MultiplyPoint(H, H);
489 this->WorldToScreenMatrix->MultiplyPoint(L, L);
490
491 double matrix[4][4];
492 double width = H[0] - L[0];
493 double height = H[1] - L[1];
494
495 // Back and front are not traditional near and far.
496 // Front (aka near)
497 double F = E[2] - (this->Distance + this->Thickness); // E[2] - 10000.0;//this->ClippingRange[1];
498 // Back (aka far)
499 double nearDistanceCorrectionFactor = 1000.0;
500 double B =
501 E[2] - (this->Distance / nearDistanceCorrectionFactor); // E[2] - .1;//this->ClippingRange[0];
502
503 double depth = B - F;
504 matrix[0][0] = (2 * E[2]) / width;
505 matrix[1][0] = 0;
506 matrix[2][0] = 0;
507 matrix[3][0] = 0;
508
509 matrix[0][1] = 0;
510 matrix[1][1] = (2 * E[2]) / height;
511 matrix[2][1] = 0;
512 matrix[3][1] = 0;
513
514 matrix[0][2] = (H[0] + L[0] - 2 * E[0]) / width;
515 matrix[1][2] = (H[1] + L[1] - 2 * E[1]) / height;
516 matrix[2][2] = (B + F - 2 * E[2]) / depth;
517 matrix[3][2] = -1;
518
519 matrix[0][3] = (-E[2] * (H[0] + L[0])) / width;
520 matrix[1][3] = (-E[2] * (H[1] + L[1])) / height;
521 matrix[2][3] = B - E[2] - (B * (B + F - 2 * E[2]) / depth);
522 matrix[3][3] = E[2];
523
524 for (int i = 0; i < 4; i++)
525 {
526 for (int j = 0; j < 4; j++)
527 {
528 this->ProjectionTransform->GetMatrix()->SetElement(i, j, matrix[i][j]);
529 }
530 }
531
532 // Now move the world into display space.
533 vtkMatrix4x4::Multiply4x4(this->ProjectionTransform->GetMatrix(), this->WorldToScreenMatrix,
534 this->ProjectionTransform->GetMatrix());
535 }
536
537 //------------------------------------------------------------------------------
ComputeModelViewMatrix()538 void vtkCamera::ComputeModelViewMatrix()
539 {
540 if (this->ModelViewTransform->GetMTime() < this->ModelTransformMatrix->GetMTime() ||
541 this->ModelViewTransform->GetMTime() < this->ViewTransform->GetMTime())
542 {
543 vtkMatrix4x4::Multiply4x4(this->ViewTransform->GetMatrix(), this->ModelTransformMatrix,
544 this->ModelViewTransform->GetMatrix());
545 }
546 }
547
548 //------------------------------------------------------------------------------
OrthogonalizeViewUp()549 void vtkCamera::OrthogonalizeViewUp()
550 {
551 // the orthogonalized ViewUp is just the second row of the view matrix
552 vtkMatrix4x4* matrix = this->ViewTransform->GetMatrix();
553 this->ViewUp[0] = matrix->GetElement(1, 0);
554 this->ViewUp[1] = matrix->GetElement(1, 1);
555 this->ViewUp[2] = matrix->GetElement(1, 2);
556
557 this->Modified();
558 }
559
560 //------------------------------------------------------------------------------
561 // Set the distance of the focal point from the camera. The focal point is
562 // modified accordingly. This should be positive.
SetDistance(double d)563 void vtkCamera::SetDistance(double d)
564 {
565 if (this->Distance == d)
566 {
567 return;
568 }
569
570 this->Distance = d;
571
572 // Distance should be greater than .0002
573 if (this->Distance < 0.0002)
574 {
575 this->Distance = 0.0002;
576 vtkDebugMacro(<< " Distance is set to minimum.");
577 }
578
579 // we want to keep the camera pointing in the same direction
580 double* vec = this->DirectionOfProjection;
581
582 // recalculate FocalPoint
583 this->FocalPoint[0] = this->Position[0] + vec[0] * this->Distance;
584 this->FocalPoint[1] = this->Position[1] + vec[1] * this->Distance;
585 this->FocalPoint[2] = this->Position[2] + vec[2] * this->Distance;
586
587 vtkDebugMacro(<< " Distance set to ( " << this->Distance << ")");
588
589 this->ComputeViewTransform();
590 this->ComputeCameraLightTransform();
591 this->Modified();
592 }
593
594 //------------------------------------------------------------------------------
595 // This method must be called when the focal point or camera position changes
ComputeDistance()596 void vtkCamera::ComputeDistance()
597 {
598 double dx = this->FocalPoint[0] - this->Position[0];
599 double dy = this->FocalPoint[1] - this->Position[1];
600 double dz = this->FocalPoint[2] - this->Position[2];
601
602 this->Distance = sqrt(dx * dx + dy * dy + dz * dz);
603
604 if (this->Distance < 1e-20)
605 {
606 this->Distance = 1e-20;
607 vtkDebugMacro(<< " Distance is set to minimum.");
608
609 double* vec = this->DirectionOfProjection;
610
611 // recalculate FocalPoint
612 this->FocalPoint[0] = this->Position[0] + vec[0] * this->Distance;
613 this->FocalPoint[1] = this->Position[1] + vec[1] * this->Distance;
614 this->FocalPoint[2] = this->Position[2] + vec[2] * this->Distance;
615 }
616
617 this->DirectionOfProjection[0] = dx / this->Distance;
618 this->DirectionOfProjection[1] = dy / this->Distance;
619 this->DirectionOfProjection[2] = dz / this->Distance;
620
621 this->ComputeViewPlaneNormal();
622 }
623
624 //------------------------------------------------------------------------------
625 // Move the position of the camera along the view plane normal. Moving
626 // towards the focal point (e.g., > 1) is a dolly-in, moving away
627 // from the focal point (e.g., < 1) is a dolly-out.
Dolly(double amount)628 void vtkCamera::Dolly(double amount)
629 {
630 if (amount <= 0.0)
631 {
632 return;
633 }
634
635 // dolly moves the camera towards the focus
636 double d = this->Distance / amount;
637
638 this->SetPosition(this->FocalPoint[0] - d * this->DirectionOfProjection[0],
639 this->FocalPoint[1] - d * this->DirectionOfProjection[1],
640 this->FocalPoint[2] - d * this->DirectionOfProjection[2]);
641 }
642
643 //------------------------------------------------------------------------------
644 // Set the roll angle of the camera about the direction of projection
SetRoll(double roll)645 void vtkCamera::SetRoll(double roll)
646 {
647 // roll is a rotation of camera view up about the direction of projection
648 vtkDebugMacro(<< " Setting Roll to " << roll << "");
649
650 // subtract the current roll
651 roll -= this->GetRoll();
652
653 if (fabs(roll) < 0.00001)
654 {
655 return;
656 }
657
658 this->Roll(roll);
659 }
660
661 //------------------------------------------------------------------------------
662 // Returns the roll of the camera.
GetRoll()663 double vtkCamera::GetRoll()
664 {
665 double orientation[3];
666 this->ViewTransform->GetOrientation(orientation);
667 return orientation[2];
668 }
669
670 //------------------------------------------------------------------------------
671 // Rotate the camera around the view plane normal.
Roll(double angle)672 void vtkCamera::Roll(double angle)
673 {
674 double newViewUp[3];
675 this->Transform->Identity();
676
677 // rotate ViewUp about the Direction of Projection
678 this->Transform->RotateWXYZ(angle, this->DirectionOfProjection);
679
680 // okay, okay, TransformPoint shouldn't be used on vectors -- but
681 // the transform is rotation with no translation so this works fine.
682 this->Transform->TransformPoint(this->ViewUp, newViewUp);
683 this->SetViewUp(newViewUp);
684 }
685
686 //------------------------------------------------------------------------------
687 // Rotate the focal point about the view up vector centered at the camera's
688 // position.
Yaw(double angle)689 void vtkCamera::Yaw(double angle)
690 {
691 double newFocalPoint[3];
692 double* pos = this->Position;
693 this->Transform->Identity();
694
695 // translate the camera to the origin,
696 // rotate about axis,
697 // translate back again
698 this->Transform->Translate(+pos[0], +pos[1], +pos[2]);
699 this->Transform->RotateWXYZ(angle, this->ViewUp);
700 this->Transform->Translate(-pos[0], -pos[1], -pos[2]);
701
702 // now transform focal point
703 this->Transform->TransformPoint(this->FocalPoint, newFocalPoint);
704 this->SetFocalPoint(newFocalPoint);
705 }
706
707 //------------------------------------------------------------------------------
708 // Rotate the focal point about the cross product of the view up vector
709 // and the negative of the , centered at the camera's position.
Pitch(double angle)710 void vtkCamera::Pitch(double angle)
711 {
712 double axis[3], newFocalPoint[3], savedViewUp[3];
713 double* pos = this->Position;
714 this->Transform->Identity();
715
716 // the axis is the first row of the view transform matrix
717 axis[0] = this->ViewTransform->GetMatrix()->GetElement(0, 0);
718 axis[1] = this->ViewTransform->GetMatrix()->GetElement(0, 1);
719 axis[2] = this->ViewTransform->GetMatrix()->GetElement(0, 2);
720
721 // temporarily set the view up with the transformation applied
722 // to avoid bad cross product computations during SetFocalPoint call
723 this->GetViewUp(savedViewUp);
724 this->Transform->RotateWXYZ(angle, axis);
725 this->Transform->TransformPoint(this->ViewUp, this->ViewUp);
726 this->Transform->Identity();
727
728 // translate the camera to the origin,
729 // rotate about axis,
730 // translate back again
731 this->Transform->Translate(+pos[0], +pos[1], +pos[2]);
732 this->Transform->RotateWXYZ(angle, axis);
733 this->Transform->Translate(-pos[0], -pos[1], -pos[2]);
734
735 // now transform focal point
736 this->Transform->TransformPoint(this->FocalPoint, newFocalPoint);
737 this->SetFocalPoint(newFocalPoint);
738
739 // restore the previous ViewUp vector
740 this->ViewUp[0] = savedViewUp[0];
741 this->ViewUp[1] = savedViewUp[1];
742 this->ViewUp[2] = savedViewUp[2];
743 // this is needed since the last time Modified was called (in SetFocalPoint),
744 // the ViewUp was not same as savedViewUp. Since we're changing its value
745 // here, we need to fire Modified event. We don't call `SetViewUp` since we
746 // don't want the computation of the view transform to happen again.
747 this->Modified();
748 }
749
750 //------------------------------------------------------------------------------
751 // Rotate the camera about the view up vector centered at the focal point.
Azimuth(double angle)752 void vtkCamera::Azimuth(double angle)
753 {
754 double newPosition[3];
755 double* fp = this->FocalPoint;
756 this->Transform->Identity();
757
758 // translate the focal point to the origin,
759 // rotate about view up,
760 // translate back again
761 this->Transform->Translate(+fp[0], +fp[1], +fp[2]);
762 this->Transform->RotateWXYZ(angle, this->ViewUp);
763 this->Transform->Translate(-fp[0], -fp[1], -fp[2]);
764
765 // apply the transform to the position
766 this->Transform->TransformPoint(this->Position, newPosition);
767 this->SetPosition(newPosition);
768 }
769
770 //------------------------------------------------------------------------------
771 // Rotate the camera about the cross product of the negative of the
772 // direction of projection and the view up vector centered on the focal point.
Elevation(double angle)773 void vtkCamera::Elevation(double angle)
774 {
775 double axis[3], newPosition[3], savedViewUp[3];
776 double* fp = this->FocalPoint;
777 this->Transform->Identity();
778
779 // snatch the axis from the view transform matrix
780 axis[0] = -this->ViewTransform->GetMatrix()->GetElement(0, 0);
781 axis[1] = -this->ViewTransform->GetMatrix()->GetElement(0, 1);
782 axis[2] = -this->ViewTransform->GetMatrix()->GetElement(0, 2);
783
784 // temporarily set the view up with the transformation applied
785 // to avoid bad cross product computations during SetPosition call
786 this->GetViewUp(savedViewUp);
787 this->Transform->RotateWXYZ(angle, axis);
788 this->Transform->TransformPoint(this->ViewUp, this->ViewUp);
789 this->Transform->Identity();
790
791 // translate the focal point to the origin,
792 // rotate about axis,
793 // translate back again
794 this->Transform->Translate(+fp[0], +fp[1], +fp[2]);
795 this->Transform->RotateWXYZ(angle, axis);
796 this->Transform->Translate(-fp[0], -fp[1], -fp[2]);
797
798 // now transform position
799 this->Transform->TransformPoint(this->Position, newPosition);
800 this->SetPosition(newPosition);
801
802 // restore the previous ViewUp vector
803 this->ViewUp[0] = savedViewUp[0];
804 this->ViewUp[1] = savedViewUp[1];
805 this->ViewUp[2] = savedViewUp[2];
806 // this is needed since the last time Modified was called (in SetPosition),
807 // the ViewUp was not same as savedViewUp. Since we're changing its value
808 // here, we need to fire Modified event. We don't call `SetViewUp` since we
809 // don't want the computation of the view transform to happen again.
810 this->Modified();
811 }
812
813 //------------------------------------------------------------------------------
814 // Apply Transform to camera
ApplyTransform(vtkTransform * t)815 void vtkCamera::ApplyTransform(vtkTransform* t)
816 {
817 double posOld[4], posNew[4], fpOld[4], fpNew[4], vuOld[4], vuNew[4];
818
819 this->GetPosition(posOld);
820 this->GetFocalPoint(fpOld);
821 this->GetViewUp(vuOld);
822
823 posOld[3] = 1.0;
824 fpOld[3] = 1.0;
825 vuOld[3] = 1.0;
826
827 vuOld[0] += posOld[0];
828 vuOld[1] += posOld[1];
829 vuOld[2] += posOld[2];
830
831 t->MultiplyPoint(posOld, posNew);
832 t->MultiplyPoint(fpOld, fpNew);
833 t->MultiplyPoint(vuOld, vuNew);
834
835 vuNew[0] -= posNew[0];
836 vuNew[1] -= posNew[1];
837 vuNew[2] -= posNew[2];
838
839 this->SetPosition(posNew);
840 this->SetFocalPoint(fpNew);
841 this->SetViewUp(vuNew);
842 }
843
844 //------------------------------------------------------------------------------
845 //------------------------------------------------------------------------------
846 // The following methods set up the information that the Renderer needs
847 // to set up the perspective transform. The transformation matrix is
848 // created using the GetPerspectiveTransformMatrix method.
849 //------------------------------------------------------------------------------
850 //------------------------------------------------------------------------------
851
852 //------------------------------------------------------------------------------
SetParallelProjection(vtkTypeBool flag)853 void vtkCamera::SetParallelProjection(vtkTypeBool flag)
854 {
855 if (this->ParallelProjection != flag)
856 {
857 this->ParallelProjection = flag;
858 this->Modified();
859 this->ViewingRaysModified();
860 }
861 }
862
863 //------------------------------------------------------------------------------
SetViewAngle(double angle)864 void vtkCamera::SetViewAngle(double angle)
865 {
866 double min = 0.00000001;
867 double max = 179.0;
868
869 if (this->ViewAngle != angle)
870 {
871 this->ViewAngle = (angle < min ? min : (angle > max ? max : angle));
872 this->Modified();
873 this->ViewingRaysModified();
874 }
875 }
876
877 //------------------------------------------------------------------------------
SetUseHorizontalViewAngle(vtkTypeBool flag)878 void vtkCamera::SetUseHorizontalViewAngle(vtkTypeBool flag)
879 {
880 if (flag == this->UseHorizontalViewAngle)
881 {
882 return;
883 }
884 this->UseHorizontalViewAngle = flag;
885 this->Modified();
886 this->ViewingRaysModified();
887 }
888
889 //------------------------------------------------------------------------------
SetParallelScale(double scale)890 void vtkCamera::SetParallelScale(double scale)
891 {
892 if (this->ParallelScale != scale)
893 {
894 this->ParallelScale = scale;
895 this->Modified();
896 this->ViewingRaysModified();
897 }
898 }
899
900 //------------------------------------------------------------------------------
901 // Change the ViewAngle (for perspective) or the ParallelScale (for parallel)
902 // so that more or less of a scene occupies the viewport. A value > 1 is a
903 // zoom-in. A value < 1 is a zoom-out.
Zoom(double amount)904 void vtkCamera::Zoom(double amount)
905 {
906 if (amount <= 0.0)
907 {
908 return;
909 }
910
911 if (this->ParallelProjection)
912 {
913 this->SetParallelScale(this->ParallelScale / amount);
914 }
915 else
916 {
917 this->SetViewAngle(this->ViewAngle / amount);
918 }
919 }
920
921 //------------------------------------------------------------------------------
SetClippingRange(double nearz,double farz)922 void vtkCamera::SetClippingRange(double nearz, double farz)
923 {
924 double thickness;
925
926 // check the order
927 if (nearz > farz)
928 {
929 vtkDebugMacro(<< " Front and back clipping range reversed");
930 double temp = nearz;
931 nearz = farz;
932 farz = temp;
933 }
934
935 thickness = farz - nearz;
936
937 // thickness should be greater than 1e-20
938 if (thickness < 1e-20)
939 {
940 thickness = 1e-20;
941 vtkDebugMacro(<< " ClippingRange thickness is set to minimum.");
942
943 // set back plane
944 farz = nearz + thickness;
945 }
946
947 if (nearz == this->ClippingRange[0] && farz == this->ClippingRange[1] &&
948 this->Thickness == thickness)
949 {
950 return;
951 }
952
953 this->ClippingRange[0] = nearz;
954 this->ClippingRange[1] = farz;
955 this->Thickness = thickness;
956
957 vtkDebugMacro(<< " ClippingRange set to ( " << this->ClippingRange[0] << ", "
958 << this->ClippingRange[1] << ")");
959
960 this->Modified();
961 }
962
963 //------------------------------------------------------------------------------
964 // Set the distance between clipping planes.
965 // This method adjusts the back clipping plane to the specified thickness
966 // behind the front clipping plane
SetThickness(double s)967 void vtkCamera::SetThickness(double s)
968 {
969 if (this->Thickness == s)
970 {
971 return;
972 }
973
974 this->Thickness = s;
975
976 // thickness should be greater than 1e-20
977 if (this->Thickness < 1e-20)
978 {
979 this->Thickness = 1e-20;
980 vtkDebugMacro(<< " ClippingRange thickness is set to minimum.");
981 }
982
983 // set back plane
984 this->ClippingRange[1] = this->ClippingRange[0] + this->Thickness;
985
986 vtkDebugMacro(<< " ClippingRange set to ( " << this->ClippingRange[0] << ", "
987 << this->ClippingRange[1] << ")");
988
989 this->Modified();
990 }
991
992 //------------------------------------------------------------------------------
SetWindowCenter(double x,double y)993 void vtkCamera::SetWindowCenter(double x, double y)
994 {
995 if (this->WindowCenter[0] != x || this->WindowCenter[1] != y)
996 {
997 this->Modified();
998 this->ViewingRaysModified();
999 this->WindowCenter[0] = x;
1000 this->WindowCenter[1] = y;
1001 }
1002 }
1003
1004 //------------------------------------------------------------------------------
SetObliqueAngles(double alpha,double beta)1005 void vtkCamera::SetObliqueAngles(double alpha, double beta)
1006 {
1007 alpha = vtkMath::RadiansFromDegrees(alpha);
1008 beta = vtkMath::RadiansFromDegrees(beta);
1009
1010 double cotbeta = cos(beta) / sin(beta);
1011 double dxdz = cos(alpha) * cotbeta;
1012 double dydz = sin(alpha) * cotbeta;
1013
1014 this->SetViewShear(dxdz, dydz, 1.0);
1015 }
1016
1017 //------------------------------------------------------------------------------
1018 // Set the shear transform of the viewing frustum. Parameters are
1019 // dx/dz, dy/dz, and center. center is a factor that describes where
1020 // to shear around. The distance dshear from the camera where
1021 // no shear occurs is given by (dshear = center * FocalDistance).
1022 //
SetViewShear(double dxdz,double dydz,double center)1023 void vtkCamera::SetViewShear(double dxdz, double dydz, double center)
1024 {
1025 if (dxdz != this->ViewShear[0] || dydz != this->ViewShear[1] || center != this->ViewShear[2])
1026 {
1027 this->Modified();
1028 this->ViewingRaysModified();
1029
1030 this->ViewShear[0] = dxdz;
1031 this->ViewShear[1] = dydz;
1032 this->ViewShear[2] = center;
1033
1034 this->ComputeViewPlaneNormal();
1035 }
1036 }
1037 //------------------------------------------------------------------------------
1038
SetViewShear(double d[3])1039 void vtkCamera::SetViewShear(double d[3])
1040 {
1041 this->SetViewShear(d[0], d[1], d[2]);
1042 }
1043
1044 //------------------------------------------------------------------------------
1045 // Compute the projection transform matrix. This is used in converting
1046 // between view and world coordinates.
ComputeProjectionTransform(double aspect,double nearz,double farz)1047 void vtkCamera::ComputeProjectionTransform(double aspect, double nearz, double farz)
1048 {
1049 this->ProjectionTransform->Identity();
1050
1051 // apply user defined transform last if there is one
1052 if (this->UserTransform)
1053 {
1054 this->ProjectionTransform->Concatenate(this->UserTransform->GetMatrix());
1055 }
1056
1057 if (this->UseExplicitProjectionTransformMatrix)
1058 {
1059 assert(this->ExplicitProjectionTransformMatrix != nullptr);
1060 this->ProjectionTransform->Concatenate(this->ExplicitProjectionTransformMatrix);
1061 return;
1062 }
1063
1064 if (this->UseExplicitAspectRatio)
1065 {
1066 aspect = this->ExplicitAspectRatio;
1067 }
1068
1069 // adjust Z-buffer range
1070 this->ProjectionTransform->AdjustZBuffer(-1, +1, nearz, farz);
1071
1072 if (this->ParallelProjection)
1073 {
1074 // set up a rectangular parallelipiped
1075
1076 double width = this->ParallelScale * aspect;
1077 double height = this->ParallelScale;
1078
1079 double xmin = (this->WindowCenter[0] - 1.0) * width;
1080 double xmax = (this->WindowCenter[0] + 1.0) * width;
1081 double ymin = (this->WindowCenter[1] - 1.0) * height;
1082 double ymax = (this->WindowCenter[1] + 1.0) * height;
1083
1084 this->ProjectionTransform->Ortho(
1085 xmin, xmax, ymin, ymax, this->ClippingRange[0], this->ClippingRange[1]);
1086 }
1087 else if (this->UseOffAxisProjection)
1088 {
1089 this->ComputeOffAxisProjectionFrustum();
1090 }
1091 else
1092 {
1093 // set up a perspective frustum
1094
1095 double tmp = tan(vtkMath::RadiansFromDegrees(this->ViewAngle) / 2.);
1096 double width;
1097 double height;
1098 if (this->UseHorizontalViewAngle)
1099 {
1100 width = this->ClippingRange[0] * tmp;
1101 height = this->ClippingRange[0] * tmp / aspect;
1102 }
1103 else
1104 {
1105 width = this->ClippingRange[0] * tmp * aspect;
1106 height = this->ClippingRange[0] * tmp;
1107 }
1108
1109 double xmin = (this->WindowCenter[0] - 1.0) * width;
1110 double xmax = (this->WindowCenter[0] + 1.0) * width;
1111 double ymin = (this->WindowCenter[1] - 1.0) * height;
1112 double ymax = (this->WindowCenter[1] + 1.0) * height;
1113
1114 this->ProjectionTransform->Frustum(
1115 xmin, xmax, ymin, ymax, this->ClippingRange[0], this->ClippingRange[1]);
1116 }
1117
1118 if (this->Stereo && !this->UseOffAxisProjection)
1119 {
1120 // set up a shear for stereo views
1121 if (this->LeftEye)
1122 {
1123 this->ProjectionTransform->Stereo(-this->EyeAngle / 2, this->Distance);
1124 }
1125 else
1126 {
1127 this->ProjectionTransform->Stereo(+this->EyeAngle / 2, this->Distance);
1128 }
1129 }
1130
1131 if (this->ViewShear[0] != 0.0 || this->ViewShear[1] != 0.0)
1132 {
1133 this->ProjectionTransform->Shear(
1134 this->ViewShear[0], this->ViewShear[1], this->ViewShear[2] * this->Distance);
1135 }
1136 }
1137
1138 //------------------------------------------------------------------------------
1139 // Return the projection transform matrix. See ComputeProjectionTransform.
GetProjectionTransformMatrix(vtkRenderer * ren)1140 vtkMatrix4x4* vtkCamera::GetProjectionTransformMatrix(vtkRenderer* ren)
1141 {
1142 double aspect[2];
1143 int lowerLeft[2];
1144 int usize, vsize;
1145 vtkMatrix4x4* matrix = vtkMatrix4x4::New();
1146
1147 ren->GetTiledSizeAndOrigin(&usize, &vsize, lowerLeft, lowerLeft + 1);
1148
1149 // some renderer subclasses may have more complicated computations for the
1150 // aspect ratio. So take that into account by computing the difference
1151 // between our simple aspect ratio and what the actual renderer is reporting.
1152 ren->ComputeAspect();
1153 ren->GetAspect(aspect);
1154 double aspect2[2];
1155 ren->vtkViewport::ComputeAspect();
1156 ren->vtkViewport::GetAspect(aspect2);
1157 double aspectModification = aspect[0] * aspect2[1] / (aspect[1] * aspect2[0]);
1158
1159 if (usize && vsize)
1160 {
1161 matrix->DeepCopy(this->GetProjectionTransformMatrix(aspectModification * usize / vsize, -1, 1));
1162 matrix->Transpose();
1163 }
1164
1165 return matrix;
1166 }
1167
1168 //------------------------------------------------------------------------------
1169 // Return the projection transform matrix. See ComputeProjectionTransform.
GetProjectionTransformMatrix(double aspect,double nearz,double farz)1170 vtkMatrix4x4* vtkCamera::GetProjectionTransformMatrix(double aspect, double nearz, double farz)
1171 {
1172 this->ComputeProjectionTransform(aspect, nearz, farz);
1173
1174 // return the transform
1175 return this->ProjectionTransform->GetMatrix();
1176 }
1177
1178 //------------------------------------------------------------------------------
1179 // Return the projection transform object. See ComputeProjectionTransform.
GetProjectionTransformObject(double aspect,double nearz,double farz)1180 vtkPerspectiveTransform* vtkCamera::GetProjectionTransformObject(
1181 double aspect, double nearz, double farz)
1182 {
1183 this->ComputeProjectionTransform(aspect, nearz, farz);
1184
1185 // return the transform
1186 return this->ProjectionTransform;
1187 }
1188
1189 //------------------------------------------------------------------------------
1190 // Return the projection transform matrix. See ComputeProjectionTransform.
GetCompositeProjectionTransformMatrix(double aspect,double nearz,double farz)1191 vtkMatrix4x4* vtkCamera::GetCompositeProjectionTransformMatrix(
1192 double aspect, double nearz, double farz)
1193 {
1194 // turn off stereo, the CompositeProjectionTransformMatrix is used for
1195 // picking, not for rendering.
1196 int stereo = this->Stereo;
1197 this->Stereo = 0;
1198
1199 this->Transform->Identity();
1200 this->Transform->Concatenate(this->GetProjectionTransformMatrix(aspect, nearz, farz));
1201 this->Transform->Concatenate(this->GetViewTransformMatrix());
1202
1203 this->Stereo = stereo;
1204
1205 // return the transform
1206 return this->Transform->GetMatrix();
1207 }
1208
1209 //------------------------------------------------------------------------------
1210 // Return the attached light transform matrix.
GetCameraLightTransformMatrix()1211 vtkMatrix4x4* vtkCamera::GetCameraLightTransformMatrix()
1212 {
1213 // return the transform
1214 return this->CameraLightTransform->GetMatrix();
1215 }
1216
1217 //------------------------------------------------------------------------------
ComputeViewPlaneNormal()1218 void vtkCamera::ComputeViewPlaneNormal()
1219 {
1220 if (this->ViewShear[0] != 0.0 || this->ViewShear[1] != 0.0)
1221 {
1222 // set the VPN in camera coordinates
1223 this->ViewPlaneNormal[0] = this->ViewShear[0];
1224 this->ViewPlaneNormal[1] = this->ViewShear[1];
1225 this->ViewPlaneNormal[2] = 1.0;
1226 // transform the VPN to world coordinates using inverse of view transform
1227 this->ViewTransform->GetLinearInverse()->TransformNormal(
1228 this->ViewPlaneNormal, this->ViewPlaneNormal);
1229 }
1230 else
1231 {
1232 // VPN is -DOP
1233 this->ViewPlaneNormal[0] = -this->DirectionOfProjection[0];
1234 this->ViewPlaneNormal[1] = -this->DirectionOfProjection[1];
1235 this->ViewPlaneNormal[2] = -this->DirectionOfProjection[2];
1236 }
1237 }
1238
1239 //------------------------------------------------------------------------------
1240 // Return the 6 planes (Ax + By + Cz + D = 0) that bound
1241 // the view frustum.
GetFrustumPlanes(double aspect,double planes[24])1242 void vtkCamera::GetFrustumPlanes(double aspect, double planes[24])
1243 {
1244 int i;
1245 double f, normals[6][4], matrix[4][4];
1246
1247 // set up the normals
1248 for (i = 0; i < 6; i++)
1249 {
1250 normals[i][0] = 0.0;
1251 normals[i][1] = 0.0;
1252 normals[i][2] = 0.0;
1253 normals[i][3] = 1.0;
1254 // if i is even set to 1, if odd set to -1
1255 normals[i][i / 2] = 1 - (i % 2) * 2;
1256 }
1257
1258 if (this->UseExplicitAspectRatio)
1259 {
1260 aspect = this->ExplicitAspectRatio;
1261 }
1262
1263 // get the composite perspective matrix
1264 vtkMatrix4x4::DeepCopy(*matrix, this->GetCompositeProjectionTransformMatrix(aspect, -1, +1));
1265
1266 // transpose the matrix for use with normals
1267 vtkMatrix4x4::Transpose(*matrix, *matrix);
1268
1269 // transform the normals to world coordinates
1270 for (i = 0; i < 6; i++)
1271 {
1272 vtkMatrix4x4::MultiplyPoint(*matrix, normals[i], normals[i]);
1273
1274 f = 1.0 /
1275 sqrt(normals[i][0] * normals[i][0] + normals[i][1] * normals[i][1] +
1276 normals[i][2] * normals[i][2]);
1277
1278 planes[4 * i + 0] = normals[i][0] * f;
1279 planes[4 * i + 1] = normals[i][1] * f;
1280 planes[4 * i + 2] = normals[i][2] * f;
1281 planes[4 * i + 3] = normals[i][3] * f;
1282 }
1283 }
1284
UpdateIdealShiftScale(double aspect)1285 void vtkCamera::UpdateIdealShiftScale(double aspect)
1286 {
1287 double matrix[4][4];
1288 double imatrix[4][4];
1289
1290 if (this->UseExplicitAspectRatio)
1291 {
1292 aspect = this->ExplicitAspectRatio;
1293 }
1294
1295 // get the composite perspective matrix
1296 vtkMatrix4x4::DeepCopy(*matrix, this->GetCompositeProjectionTransformMatrix(aspect, -1, +1));
1297 vtkMatrix4x4::Invert(*matrix, *imatrix);
1298
1299 double tmp[4];
1300 tmp[0] = 0;
1301 tmp[1] = 0;
1302 tmp[2] = -1;
1303 tmp[3] = 1;
1304 vtkMatrix4x4::MultiplyPoint(*imatrix, tmp, tmp);
1305
1306 double shift[3];
1307 shift[0] = tmp[0] / tmp[3];
1308 shift[1] = tmp[1] / tmp[3];
1309 shift[2] = tmp[2] / tmp[3];
1310
1311 tmp[0] = 1;
1312 tmp[1] = 1;
1313 tmp[2] = -1;
1314 tmp[3] = 1;
1315 vtkMatrix4x4::MultiplyPoint(*imatrix, tmp, tmp);
1316
1317 tmp[0] /= tmp[3];
1318 tmp[1] /= tmp[3];
1319 tmp[2] /= tmp[3];
1320
1321 double scale = sqrt(vtkMath::Distance2BetweenPoints(tmp, shift));
1322
1323 // now snap
1324 if (fabs(log10(scale / this->NearPlaneScale)) > this->ShiftScaleThreshold)
1325 {
1326 this->NearPlaneScale = scale;
1327 }
1328
1329 // our metric for shifting depends on scale
1330 double dist2 = vtkMath::Distance2BetweenPoints(this->NearPlaneShift, shift);
1331 if (dist2 && log10(sqrt(dist2) / this->NearPlaneScale) > this->ShiftScaleThreshold)
1332 {
1333 this->NearPlaneShift[0] = shift[0];
1334 this->NearPlaneShift[1] = shift[1];
1335 this->NearPlaneShift[2] = shift[2];
1336 }
1337
1338 // now the focal point calcs
1339 tmp[0] = this->FocalPoint[0];
1340 tmp[1] = this->FocalPoint[1];
1341 tmp[2] = this->FocalPoint[2];
1342 tmp[3] = 1.0;
1343 vtkMatrix4x4::MultiplyPoint(*matrix, tmp, tmp);
1344
1345 tmp[0] = 0.0;
1346 tmp[1] = 0.0;
1347 tmp[2] /= tmp[3];
1348 double fpdepth = tmp[2];
1349 tmp[3] = 1.0;
1350 vtkMatrix4x4::MultiplyPoint(*imatrix, tmp, tmp);
1351
1352 shift[0] = tmp[0] / tmp[3];
1353 shift[1] = tmp[1] / tmp[3];
1354 shift[2] = tmp[2] / tmp[3];
1355
1356 tmp[0] = 1;
1357 tmp[1] = 1;
1358 tmp[2] = fpdepth;
1359 tmp[3] = 1;
1360 vtkMatrix4x4::MultiplyPoint(*imatrix, tmp, tmp);
1361
1362 tmp[0] /= tmp[3];
1363 tmp[1] /= tmp[3];
1364 tmp[2] /= tmp[3];
1365
1366 scale = sqrt(vtkMath::Distance2BetweenPoints(tmp, shift));
1367
1368 // now snap
1369 if (fabs(log10(scale / this->FocalPointScale)) > this->ShiftScaleThreshold)
1370 {
1371 this->FocalPointScale = scale;
1372 }
1373
1374 // our metric for shifting depends on scale
1375 dist2 = vtkMath::Distance2BetweenPoints(this->FocalPointShift, shift);
1376 if (dist2 && log10(sqrt(dist2) / this->FocalPointScale) > this->ShiftScaleThreshold)
1377 {
1378 this->FocalPointShift[0] = shift[0];
1379 this->FocalPointShift[1] = shift[1];
1380 this->FocalPointShift[2] = shift[2];
1381 }
1382 }
1383
1384 //------------------------------------------------------------------------------
GetViewingRaysMTime()1385 vtkMTimeType vtkCamera::GetViewingRaysMTime()
1386 {
1387 return this->ViewingRaysMTime.GetMTime();
1388 }
1389
1390 //------------------------------------------------------------------------------
ViewingRaysModified()1391 void vtkCamera::ViewingRaysModified()
1392 {
1393 this->ViewingRaysMTime.Modified();
1394 }
1395
1396 //------------------------------------------------------------------------------
1397 // Description:
1398 // Copy the properties of `source' into `this'.
1399 // Copy pointers of matrices.
1400 // \pre source_exists!=0
1401 // \pre not_this: source!=this
ShallowCopy(vtkCamera * source)1402 void vtkCamera::ShallowCopy(vtkCamera* source)
1403 {
1404 assert("pre: source_exists" && source != nullptr);
1405 assert("pre: not_this" && source != this);
1406
1407 this->PartialCopy(source);
1408
1409 // Shallow copy of matrices:
1410 if (this->UserTransform != nullptr)
1411 {
1412 this->UserTransform->Delete();
1413 }
1414 this->UserTransform = source->UserTransform;
1415 if (this->UserTransform != nullptr)
1416 {
1417 this->UserTransform->Register(this);
1418 }
1419 if (this->UserViewTransform != nullptr)
1420 {
1421 this->UserViewTransform->Delete();
1422 }
1423 this->UserViewTransform = source->UserViewTransform;
1424 if (this->UserViewTransform != nullptr)
1425 {
1426 this->UserViewTransform->Register(this);
1427 }
1428
1429 if (this->ViewTransform != nullptr)
1430 {
1431 this->ViewTransform->Delete();
1432 }
1433 this->ViewTransform = source->ViewTransform;
1434 if (this->ViewTransform != nullptr)
1435 {
1436 this->ViewTransform->Register(this);
1437 }
1438
1439 if (this->ProjectionTransform != nullptr)
1440 {
1441 this->ProjectionTransform->Delete();
1442 }
1443 this->ProjectionTransform = source->ProjectionTransform;
1444 if (this->ProjectionTransform != nullptr)
1445 {
1446 this->ProjectionTransform->Register(this);
1447 }
1448
1449 if (this->Transform != nullptr)
1450 {
1451 this->Transform->Delete();
1452 }
1453 this->Transform = source->Transform;
1454 if (this->Transform != nullptr)
1455 {
1456 this->Transform->Register(this);
1457 }
1458
1459 if (this->CameraLightTransform != nullptr)
1460 {
1461 this->CameraLightTransform->Delete();
1462 }
1463 this->CameraLightTransform = source->CameraLightTransform;
1464 if (this->CameraLightTransform != nullptr)
1465 {
1466 this->CameraLightTransform->Register(this);
1467 }
1468
1469 if (this->EyeTransformMatrix != nullptr)
1470 {
1471 this->EyeTransformMatrix->Delete();
1472 }
1473 this->EyeTransformMatrix = source->EyeTransformMatrix;
1474 if (this->EyeTransformMatrix != nullptr)
1475 {
1476 this->EyeTransformMatrix->Register(this);
1477 }
1478
1479 if (this->WorldToScreenMatrix != nullptr)
1480 {
1481 this->WorldToScreenMatrix->Delete();
1482 }
1483 this->WorldToScreenMatrix = source->WorldToScreenMatrix;
1484 if (this->WorldToScreenMatrix != nullptr)
1485 {
1486 this->WorldToScreenMatrix->Register(this);
1487 }
1488
1489 if (this->ModelTransformMatrix != nullptr)
1490 {
1491 this->ModelTransformMatrix->Delete();
1492 }
1493 this->ModelTransformMatrix = source->ModelTransformMatrix;
1494 if (this->ModelTransformMatrix != nullptr)
1495 {
1496 this->ModelTransformMatrix->Register(this);
1497 }
1498
1499 if (this->ModelViewTransform != nullptr)
1500 {
1501 this->ModelViewTransform->Delete();
1502 }
1503 this->ModelViewTransform = source->ModelViewTransform;
1504 if (this->ModelViewTransform != nullptr)
1505 {
1506 this->ModelViewTransform->Register(this);
1507 }
1508 }
1509
1510 //------------------------------------------------------------------------------
1511 // Description:
1512 // Copy the properties of `source' into `this'.
1513 // Copy the contents of the matrices.
1514 // \pre source_exists!=0
1515 // \pre not_this: source!=this
DeepCopy(vtkCamera * source)1516 void vtkCamera::DeepCopy(vtkCamera* source)
1517 {
1518 assert("pre: source_exists" && source != nullptr);
1519 assert("pre: not_this" && source != this);
1520
1521 this->PartialCopy(source);
1522
1523 // Deep copy the matrices:
1524 if (source->UserTransform == nullptr)
1525 {
1526 if (this->UserTransform != nullptr)
1527 {
1528 this->UserTransform->UnRegister(this);
1529 this->UserTransform = nullptr;
1530 }
1531 }
1532 else
1533 {
1534 if (this->UserTransform == nullptr)
1535 {
1536 this->UserTransform =
1537 static_cast<vtkHomogeneousTransform*>(source->UserTransform->MakeTransform());
1538 }
1539 this->UserTransform->DeepCopy(source->UserTransform);
1540 }
1541
1542 if (source->UserViewTransform == nullptr)
1543 {
1544 if (this->UserViewTransform != nullptr)
1545 {
1546 this->UserViewTransform->UnRegister(this);
1547 this->UserViewTransform = nullptr;
1548 }
1549 }
1550 else
1551 {
1552 if (this->UserViewTransform == nullptr)
1553 {
1554 this->UserViewTransform =
1555 static_cast<vtkHomogeneousTransform*>(source->UserViewTransform->MakeTransform());
1556 }
1557 this->UserViewTransform->DeepCopy(source->UserViewTransform);
1558 }
1559
1560 if (source->ViewTransform == nullptr)
1561 {
1562 if (this->ViewTransform != nullptr)
1563 {
1564 this->ViewTransform->UnRegister(this);
1565 this->ViewTransform = nullptr;
1566 }
1567 }
1568 else
1569 {
1570 if (this->ViewTransform == nullptr)
1571 {
1572 this->ViewTransform = static_cast<vtkTransform*>(source->ViewTransform->MakeTransform());
1573 }
1574 this->ViewTransform->DeepCopy(source->ViewTransform);
1575 }
1576
1577 if (source->ProjectionTransform == nullptr)
1578 {
1579 if (this->ProjectionTransform != nullptr)
1580 {
1581 this->ProjectionTransform->UnRegister(this);
1582 this->ProjectionTransform = nullptr;
1583 }
1584 }
1585 else
1586 {
1587 if (this->ProjectionTransform == nullptr)
1588 {
1589 this->ProjectionTransform =
1590 static_cast<vtkPerspectiveTransform*>(source->ProjectionTransform->MakeTransform());
1591 }
1592 this->ProjectionTransform->DeepCopy(source->ProjectionTransform);
1593 }
1594
1595 if (source->Transform == nullptr)
1596 {
1597 if (this->Transform != nullptr)
1598 {
1599 this->Transform->UnRegister(this);
1600 this->Transform = nullptr;
1601 }
1602 }
1603 else
1604 {
1605 if (this->Transform == nullptr)
1606 {
1607 this->Transform = static_cast<vtkPerspectiveTransform*>(source->Transform->MakeTransform());
1608 }
1609 this->Transform->DeepCopy(source->Transform);
1610 }
1611
1612 if (source->CameraLightTransform == nullptr)
1613 {
1614 if (this->CameraLightTransform != nullptr)
1615 {
1616 this->CameraLightTransform->UnRegister(this);
1617 this->CameraLightTransform = nullptr;
1618 }
1619 }
1620 else
1621 {
1622 if (this->CameraLightTransform == nullptr)
1623 {
1624 this->CameraLightTransform =
1625 static_cast<vtkTransform*>(source->CameraLightTransform->MakeTransform());
1626 }
1627 this->CameraLightTransform->DeepCopy(source->CameraLightTransform);
1628 }
1629
1630 if (source->ModelViewTransform == nullptr)
1631 {
1632 if (this->ModelViewTransform != nullptr)
1633 {
1634 this->ModelViewTransform->UnRegister(this);
1635 this->ModelViewTransform = nullptr;
1636 }
1637 }
1638 else
1639 {
1640 if (this->ModelViewTransform == nullptr)
1641 {
1642 this->ModelViewTransform =
1643 static_cast<vtkTransform*>(source->ModelViewTransform->MakeTransform());
1644 }
1645 this->ModelViewTransform->DeepCopy(source->ModelViewTransform);
1646 }
1647
1648 if (source->ModelTransformMatrix == nullptr)
1649 {
1650 if (this->ModelTransformMatrix != nullptr)
1651 {
1652 this->ModelTransformMatrix->UnRegister(this);
1653 this->ModelTransformMatrix = nullptr;
1654 }
1655 }
1656 else
1657 {
1658 if (this->ModelTransformMatrix == nullptr)
1659 {
1660 this->ModelTransformMatrix =
1661 static_cast<vtkMatrix4x4*>(source->ModelTransformMatrix->NewInstance());
1662 }
1663 this->ModelTransformMatrix->DeepCopy(source->ModelTransformMatrix);
1664 }
1665
1666 if (source->EyeTransformMatrix == nullptr)
1667 {
1668 if (this->EyeTransformMatrix != nullptr)
1669 {
1670 this->EyeTransformMatrix->UnRegister(this);
1671 this->EyeTransformMatrix = nullptr;
1672 }
1673 }
1674 else
1675 {
1676 if (this->EyeTransformMatrix == nullptr)
1677 {
1678 this->EyeTransformMatrix =
1679 static_cast<vtkMatrix4x4*>(source->EyeTransformMatrix->NewInstance());
1680 }
1681 this->EyeTransformMatrix->DeepCopy(source->EyeTransformMatrix);
1682 }
1683
1684 if (source->WorldToScreenMatrix == nullptr)
1685 {
1686 if (this->WorldToScreenMatrix != nullptr)
1687 {
1688 this->WorldToScreenMatrix->UnRegister(this);
1689 this->WorldToScreenMatrix = nullptr;
1690 }
1691 }
1692 else
1693 {
1694 if (this->WorldToScreenMatrix == nullptr)
1695 {
1696 this->WorldToScreenMatrix =
1697 static_cast<vtkMatrix4x4*>(source->WorldToScreenMatrix->NewInstance());
1698 }
1699 this->WorldToScreenMatrix->DeepCopy(source->WorldToScreenMatrix);
1700 }
1701 }
1702
1703 //------------------------------------------------------------------------------
1704 // Description:
1705 // Copy the ivars. Do nothing for the matrices.
1706 // Called by ShallowCopy() and DeepCopy()
1707 // \pre source_exists!=0
1708 // \pre not_this: source!=this
PartialCopy(vtkCamera * source)1709 void vtkCamera::PartialCopy(vtkCamera* source)
1710 {
1711 assert("pre: source_exists" && source != nullptr);
1712 assert("pre: not_this" && source != this);
1713
1714 int i;
1715
1716 i = 0;
1717 while (i < 2)
1718 {
1719 this->WindowCenter[i] = source->WindowCenter[i];
1720 this->ObliqueAngles[i] = source->ObliqueAngles[i];
1721 this->ClippingRange[i] = source->ClippingRange[i];
1722 ++i;
1723 }
1724 i = 0;
1725 while (i < 3)
1726 {
1727 this->FocalPoint[i] = source->FocalPoint[i];
1728 this->Position[i] = source->Position[i];
1729 this->ViewUp[i] = source->ViewUp[i];
1730 this->DirectionOfProjection[i] = source->DirectionOfProjection[i];
1731 this->ViewPlaneNormal[i] = source->ViewPlaneNormal[i];
1732 this->ViewShear[i] = source->ViewShear[i];
1733
1734 this->ScreenBottomLeft[i] = source->ScreenBottomLeft[i];
1735 this->ScreenBottomRight[i] = source->ScreenBottomRight[i];
1736 this->ScreenTopRight[i] = source->ScreenTopRight[i];
1737 ++i;
1738 }
1739
1740 this->ViewAngle = source->ViewAngle;
1741 this->EyeAngle = source->EyeAngle;
1742 this->ParallelProjection = source->ParallelProjection;
1743 this->ParallelScale = source->ParallelScale;
1744 this->Stereo = source->Stereo;
1745 this->LeftEye = source->LeftEye;
1746 this->Thickness = source->Thickness;
1747 this->Distance = source->Distance;
1748 this->UseHorizontalViewAngle = source->UseHorizontalViewAngle;
1749 this->UseOffAxisProjection = source->UseOffAxisProjection;
1750
1751 this->FocalDisk = source->FocalDisk;
1752 this->FocalDistance = source->FocalDistance;
1753 this->EyeSeparation = source->EyeSeparation;
1754 this->WorldToScreenMatrixMTime = source->WorldToScreenMatrixMTime;
1755
1756 this->ViewingRaysMTime = source->ViewingRaysMTime;
1757 }
1758
1759 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1760 void vtkCamera::PrintSelf(ostream& os, vtkIndent indent)
1761 {
1762 this->Superclass::PrintSelf(os, indent);
1763
1764 os << indent << "ClippingRange: (" << this->ClippingRange[0] << ", " << this->ClippingRange[1]
1765 << ")\n";
1766 os << indent << "DirectionOfProjection: (" << this->DirectionOfProjection[0] << ", "
1767 << this->DirectionOfProjection[1] << ", " << this->DirectionOfProjection[2] << ")\n";
1768 os << indent << "Distance: " << this->Distance << "\n";
1769 os << indent << "EyeAngle: " << this->EyeAngle << "\n";
1770 os << indent << "FocalDisk: " << this->FocalDisk << "\n";
1771 os << indent << "FocalDistance: " << this->FocalDistance << "\n";
1772 os << indent << "FocalPoint: (" << this->FocalPoint[0] << ", " << this->FocalPoint[1] << ", "
1773 << this->FocalPoint[2] << ")\n";
1774 os << indent << "ViewShear: (" << this->ViewShear[0] << ", " << this->ViewShear[1] << ", "
1775 << this->ViewShear[2] << ")\n";
1776 os << indent << "ParallelProjection: " << (this->ParallelProjection ? "On\n" : "Off\n");
1777 os << indent << "ParallelScale: " << this->ParallelScale << "\n";
1778 os << indent << "Position: (" << this->Position[0] << ", " << this->Position[1] << ", "
1779 << this->Position[2] << ")\n";
1780 os << indent << "Stereo: " << (this->Stereo ? "On\n" : "Off\n");
1781 os << indent << "Left Eye: " << this->LeftEye << endl;
1782 os << indent << "Thickness: " << this->Thickness << "\n";
1783 os << indent << "ViewAngle: " << this->ViewAngle << "\n";
1784 os << indent << "UseHorizontalViewAngle: " << this->UseHorizontalViewAngle << "\n";
1785 os << indent << "UserTransform: ";
1786 if (this->UserTransform)
1787 {
1788 os << this->UserTransform << "\n";
1789 }
1790 else
1791 {
1792 os << "(none)\n";
1793 }
1794 if (this->UserViewTransform)
1795 {
1796 os << this->UserViewTransform << "\n";
1797 }
1798 else
1799 {
1800 os << "(none)\n";
1801 }
1802 os << indent << "FreezeFocalPoint: ";
1803 if (this->FreezeFocalPoint)
1804 {
1805 os << this->FreezeFocalPoint << "\n";
1806 }
1807 else
1808 {
1809 os << "(none)\n";
1810 }
1811 os << indent << "ViewPlaneNormal: (" << this->ViewPlaneNormal[0] << ", "
1812 << this->ViewPlaneNormal[1] << ", " << this->ViewPlaneNormal[2] << ")\n";
1813 os << indent << "ViewUp: (" << this->ViewUp[0] << ", " << this->ViewUp[1] << ", "
1814 << this->ViewUp[2] << ")\n";
1815 os << indent << "WindowCenter: (" << this->WindowCenter[0] << ", " << this->WindowCenter[1]
1816 << ")\n";
1817
1818 os << indent << "UseOffAxisProjection: (" << this->UseOffAxisProjection << ")\n";
1819
1820 os << indent << "ScreenBottomLeft: (" << this->ScreenBottomLeft[0] << ", "
1821 << this->ScreenBottomLeft[1] << ", " << this->ScreenBottomLeft[2] << ")\n";
1822
1823 os << indent << "ScreenBottomRight: (" << this->ScreenBottomRight[0] << ", "
1824 << this->ScreenBottomRight[1] << ", " << this->ScreenBottomRight[2] << ")\n";
1825
1826 os << indent << "ScreenTopRight: (" << this->ScreenTopRight[0] << ", " << this->ScreenTopRight[1]
1827 << ", " << this->ScreenTopRight[2] << ")\n";
1828
1829 os << indent << "EyeSeparation: (" << this->EyeSeparation << ")\n";
1830
1831 os << indent << "WorldToScreenMatrix: (" << this->WorldToScreenMatrix << "\n";
1832 this->WorldToScreenMatrix->PrintSelf(os, indent.GetNextIndent());
1833 os << indent << ")\n";
1834
1835 os << indent << "EyeTransformMatrix: (" << this->EyeTransformMatrix << "\n";
1836 this->EyeTransformMatrix->PrintSelf(os, indent.GetNextIndent());
1837 os << indent << ")\n";
1838
1839 os << indent << "ModelTransformMatrix: (" << this->ModelTransformMatrix << "\n";
1840 this->ModelTransformMatrix->PrintSelf(os, indent.GetNextIndent());
1841 os << indent << ")\n";
1842
1843 os << indent << "ProjectionTransform: (" << this->ProjectionTransform << "\n";
1844 this->ProjectionTransform->PrintSelf(os, indent.GetNextIndent());
1845 os << indent << ")\n";
1846 }
1847
1848 //------------------------------------------------------------------------------
SetEyePosition(double eyePosition[3])1849 void vtkCamera::SetEyePosition(double eyePosition[3])
1850 {
1851 if (!eyePosition)
1852 {
1853 vtkErrorMacro(<< "ERROR: Invalid or nullptr eye position\n");
1854 return;
1855 }
1856
1857 this->EyeTransformMatrix->SetElement(0, 3, eyePosition[0]);
1858 this->EyeTransformMatrix->SetElement(1, 3, eyePosition[1]);
1859 this->EyeTransformMatrix->SetElement(2, 3, eyePosition[2]);
1860
1861 this->Modified();
1862 }
1863
1864 //------------------------------------------------------------------------------
GetEyePosition(double eyePosition[3])1865 void vtkCamera::GetEyePosition(double eyePosition[3])
1866 {
1867 if (!eyePosition)
1868 {
1869 vtkErrorMacro(<< "ERROR: Invalid or nullptr eye position\n");
1870 return;
1871 }
1872
1873 eyePosition[0] = this->EyeTransformMatrix->GetElement(0, 3);
1874 eyePosition[1] = this->EyeTransformMatrix->GetElement(1, 3);
1875 eyePosition[2] = this->EyeTransformMatrix->GetElement(2, 3);
1876 }
1877
1878 //------------------------------------------------------------------------------
GetEyePlaneNormal(double normal[3])1879 void vtkCamera::GetEyePlaneNormal(double normal[3])
1880 {
1881 if (!normal)
1882 {
1883 vtkErrorMacro(<< "ERROR: Invalid or nullptr normal\n");
1884 return;
1885 }
1886
1887 // Homogeneous normal.
1888 double localNormal[4];
1889
1890 // Get the normal from the screen orientation.
1891 localNormal[0] = this->WorldToScreenMatrix->GetElement(2, 0);
1892 localNormal[1] = this->WorldToScreenMatrix->GetElement(2, 1);
1893 localNormal[2] = this->WorldToScreenMatrix->GetElement(2, 2);
1894 localNormal[3] = 0.0;
1895
1896 // Just to be sure.
1897 vtkMath::Normalize(localNormal);
1898
1899 normal[0] = localNormal[0];
1900 normal[1] = localNormal[1];
1901 normal[2] = localNormal[2];
1902 }
1903
1904 //------------------------------------------------------------------------------
GetModelViewTransformMatrix()1905 vtkMatrix4x4* vtkCamera::GetModelViewTransformMatrix()
1906 {
1907 this->ComputeModelViewMatrix();
1908
1909 return this->ModelViewTransform->GetMatrix();
1910 }
1911
1912 //------------------------------------------------------------------------------
GetModelViewTransformObject()1913 vtkTransform* vtkCamera::GetModelViewTransformObject()
1914 {
1915 this->ComputeModelViewMatrix();
1916
1917 return this->ModelViewTransform;
1918 }
1919
1920 //------------------------------------------------------------------------------
GetViewTransformMatrix()1921 vtkMatrix4x4* vtkCamera::GetViewTransformMatrix()
1922 {
1923 return this->GetModelViewTransformMatrix();
1924 }
1925
1926 //------------------------------------------------------------------------------
GetViewTransformObject()1927 vtkTransform* vtkCamera::GetViewTransformObject()
1928 {
1929 return this->GetModelViewTransformObject();
1930 }
1931
1932 //------------------------------------------------------------------------------
GetOrientation()1933 double* vtkCamera::GetOrientation()
1934 {
1935 return this->ViewTransform->GetOrientation();
1936 }
1937
1938 //------------------------------------------------------------------------------
GetOrientationWXYZ()1939 double* vtkCamera::GetOrientationWXYZ()
1940 {
1941 return this->ViewTransform->GetOrientationWXYZ();
1942 }
1943
1944 //------------------------------------------------------------------------------
SetEyeTransformMatrix(const double elements[16])1945 void vtkCamera::SetEyeTransformMatrix(const double elements[16])
1946 {
1947 this->EyeTransformMatrix->Element[0][0] = elements[0];
1948 this->EyeTransformMatrix->Element[0][1] = elements[1];
1949 this->EyeTransformMatrix->Element[0][2] = elements[2];
1950 this->EyeTransformMatrix->Element[0][3] = elements[3];
1951
1952 this->EyeTransformMatrix->Element[1][0] = elements[4];
1953 this->EyeTransformMatrix->Element[1][1] = elements[5];
1954 this->EyeTransformMatrix->Element[1][2] = elements[6];
1955 this->EyeTransformMatrix->Element[1][3] = elements[7];
1956
1957 this->EyeTransformMatrix->Element[2][0] = elements[8];
1958 this->EyeTransformMatrix->Element[2][1] = elements[9];
1959 this->EyeTransformMatrix->Element[2][2] = elements[10];
1960 this->EyeTransformMatrix->Element[2][3] = elements[11];
1961
1962 this->EyeTransformMatrix->Element[3][0] = elements[12];
1963 this->EyeTransformMatrix->Element[3][1] = elements[13];
1964 this->EyeTransformMatrix->Element[3][2] = elements[14];
1965 this->EyeTransformMatrix->Element[3][3] = elements[15];
1966 this->Modified();
1967 }
1968
1969 //------------------------------------------------------------------------------
SetModelTransformMatrix(const double elements[16])1970 void vtkCamera::SetModelTransformMatrix(const double elements[16])
1971 {
1972 this->ModelTransformMatrix->Element[0][0] = elements[0];
1973 this->ModelTransformMatrix->Element[0][1] = elements[1];
1974 this->ModelTransformMatrix->Element[0][2] = elements[2];
1975 this->ModelTransformMatrix->Element[0][3] = elements[3];
1976
1977 this->ModelTransformMatrix->Element[1][0] = elements[4];
1978 this->ModelTransformMatrix->Element[1][1] = elements[5];
1979 this->ModelTransformMatrix->Element[1][2] = elements[6];
1980 this->ModelTransformMatrix->Element[1][3] = elements[7];
1981
1982 this->ModelTransformMatrix->Element[2][0] = elements[8];
1983 this->ModelTransformMatrix->Element[2][1] = elements[9];
1984 this->ModelTransformMatrix->Element[2][2] = elements[10];
1985 this->ModelTransformMatrix->Element[2][3] = elements[11];
1986
1987 this->ModelTransformMatrix->Element[3][0] = elements[12];
1988 this->ModelTransformMatrix->Element[3][1] = elements[13];
1989 this->ModelTransformMatrix->Element[3][2] = elements[14];
1990 this->ModelTransformMatrix->Element[3][3] = elements[15];
1991 this->Modified();
1992 }
1993