1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4 
5   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6   All rights reserved.
7   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8 
9      This software is distributed WITHOUT ANY WARRANTY; without even
10      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11      PURPOSE.  See the above copyright notice for more information.
12 
13 =========================================================================*/
14 
15 #ifndef vtkPVOpenVROverlayInternal_h
16 #define vtkPVOpenVROverlayInternal_h
17 
18 #include "vtkInteractorStyle3D.h"
19 #include "vtkOpenVRCamera.h"
20 #include "vtkOpenVRRenderWindow.h"
21 #include "vtkRenderWindowInteractor.h"
22 #include "vtkVectorOperators.h"
23 
24 class vtkOpenVRCameraPose
25 {
26 public:
27   double Position[3];
28   double PhysicalViewUp[3];
29   double PhysicalViewDirection[3];
30   double ViewDirection[3];
31   double Translation[3];
32   double Distance;
33   double MotionFactor = 1.0;
34   bool Loaded = false;
35 
36   // return a vector based on in that is orthogonal to normal
SanitizeVector(vtkVector3d & in,vtkVector3d & normal)37   vtkVector3d SanitizeVector(vtkVector3d& in, vtkVector3d& normal)
38   {
39     vtkVector3d result;
40     if (fabs(in.Dot(normal)) > 0.999) // some epsilon
41     {
42       if (fabs(normal[0]) < 0.1)
43       {
44         result.Set(1.0, 0.0, 0.0);
45       }
46       else
47       {
48         result.Set(0.0, 1.0, 0.0);
49       }
50     }
51     else
52     {
53       result = in - (in.Dot(normal)) * normal;
54       result.Normalize();
55     }
56     return result;
57   }
58 
Set(vtkOpenVRCamera * cam,vtkOpenVRRenderWindow * win)59   void Set(vtkOpenVRCamera* cam, vtkOpenVRRenderWindow* win)
60   {
61     win->GetPhysicalTranslation(this->Translation);
62     win->GetPhysicalViewUp(this->PhysicalViewUp);
63     this->Distance = win->GetPhysicalScale();
64     vtkInteractorStyle3D* is =
65       static_cast<vtkInteractorStyle3D*>(win->GetInteractor()->GetInteractorStyle());
66     this->MotionFactor = is->GetDollyPhysicalSpeed();
67 
68     cam->GetPosition(this->Position);
69 
70     win->GetPhysicalViewDirection(this->PhysicalViewDirection);
71     cam->GetDirectionOfProjection(this->ViewDirection);
72 
73     this->Loaded = true;
74   }
75 
Apply(vtkOpenVRCamera * cam,vtkOpenVRRenderWindow * win)76   void Apply(vtkOpenVRCamera* cam, vtkOpenVRRenderWindow* win)
77   {
78 
79     // s = saved values
80     vtkVector3d svup(this->PhysicalViewUp);
81     vtkVector3d svdir(this->ViewDirection);
82     vtkVector3d strans(this->Translation);
83     vtkVector3d spos(this->Position);
84     double sdistance = this->Distance;
85 
86     // c = current values
87     vtkVector3d cvup;
88     win->GetPhysicalViewUp(cvup.GetData());
89     vtkVector3d cpos;
90     cam->GetPosition(cpos.GetData());
91     vtkVector3d ctrans;
92     win->GetPhysicalTranslation(ctrans.GetData());
93     vtkVector3d cvdir;
94     cam->GetDirectionOfProjection(cvdir.GetData());
95     vtkVector3d civdir;
96     win->GetPhysicalViewDirection(civdir.GetData());
97     double cdistance = win->GetPhysicalScale();
98 
99     // n = new values
100     vtkVector3d nvup = svup;
101     win->SetPhysicalViewUp(nvup.GetData());
102 
103     // sanitize the svdir, must be orthogonal to nvup
104     svdir = this->SanitizeVector(svdir, nvup);
105 
106     // make sure cvdir and civdir are orthogonal to our nvup
107     cvdir = this->SanitizeVector(cvdir, nvup);
108     civdir = this->SanitizeVector(civdir, nvup);
109     vtkVector3d civright = civdir.Cross(nvup);
110 
111     // find the new initialvdir
112     vtkVector3d nivdir;
113     double theta = acos(svdir.Dot(cvdir));
114     if (nvup.Dot(cvdir.Cross(svdir)) < 0.0)
115     {
116       theta = -theta;
117     }
118     // rotate civdir by theta
119     nivdir = civdir * cos(theta) - civright * sin(theta);
120     win->SetPhysicalViewDirection(nivdir.GetData());
121     vtkVector3d nivright = nivdir.Cross(nvup);
122 
123     // adjust translation so that we are in the same spot
124     // as when the camera was saved
125     vtkVector3d ntrans;
126     vtkVector3d cppwc;
127     cppwc = cpos + ctrans;
128     double x = cppwc.Dot(civdir) / cdistance;
129     double y = cppwc.Dot(civright) / cdistance;
130 
131     ntrans = strans * nvup + nivdir * (x * sdistance - spos.Dot(nivdir)) +
132       nivright * (y * sdistance - spos.Dot(nivright));
133 
134     win->SetPhysicalTranslation(ntrans.GetData());
135     cam->SetPosition(cpos.GetData());
136 
137     // this really only sets the distance as the render loop
138     // sets focal point and position every frame
139     vtkVector3d nfp;
140     nfp = cpos + nivdir * sdistance;
141     cam->SetFocalPoint(nfp.GetData());
142     win->SetPhysicalScale(sdistance);
143 
144 #if 0
145     win->SetPhysicalViewDirection(this->PhysicalViewDirection);
146     cam->SetTranslation(this->Translation);
147     cam->SetFocalPoint(this->FocalPoint);
148     cam->SetPosition(
149       this->FocalPoint[0] - this->PhysicalViewDirection[0]*this->Distance,
150       this->FocalPoint[1] - this->PhysicalViewDirection[1]*this->Distance,
151       this->FocalPoint[2] - this->PhysicalViewDirection[2]*this->Distance);
152 #endif
153 
154     win->SetPhysicalViewUp(this->PhysicalViewUp);
155     vtkInteractorStyle3D* is =
156       static_cast<vtkInteractorStyle3D*>(win->GetInteractor()->GetInteractorStyle());
157     is->SetDollyPhysicalSpeed(this->MotionFactor);
158   }
159 };
160 
161 class vtkOpenVROverlaySpot
162 {
163 public:
vtkOpenVROverlaySpot(int x1,int x2,int y1,int y2,vtkCommand * cb)164   vtkOpenVROverlaySpot(int x1, int x2, int y1, int y2, vtkCommand* cb)
165   {
166     this->xmin = x1;
167     this->xmax = x2;
168     this->ymin = y1;
169     this->ymax = y2;
170     this->Callback = cb;
171     cb->Register(nullptr);
172     this->Active = false;
173   }
~vtkOpenVROverlaySpot()174   ~vtkOpenVROverlaySpot()
175   {
176     if (this->Callback)
177     {
178       this->Callback->Delete();
179       this->Callback = nullptr;
180     }
181   }
182   bool Active;
183   int xmin;
184   int xmax;
185   int ymin;
186   int ymax;
187   vtkCommand* Callback;
188   std::string Group;
189   int GroupId;
190 
vtkOpenVROverlaySpot(const vtkOpenVROverlaySpot & in)191   vtkOpenVROverlaySpot(const vtkOpenVROverlaySpot& in)
192   {
193     this->xmin = in.xmin;
194     this->xmax = in.xmax;
195     this->ymin = in.ymin;
196     this->ymax = in.ymax;
197     this->Callback = in.Callback;
198     this->Callback->Register(0);
199     this->Active = in.Active;
200     this->Group = in.Group;
201     this->GroupId = in.GroupId;
202   }
203   vtkOpenVROverlaySpot& operator=(const vtkOpenVROverlaySpot&) = delete;
204 };
205 
206 #endif // vtkPVOpenVROverlayInternal_h
207 
208 //****************************************************************************
209 // VTK-HeaderTest-Exclude: vtkOpenVROverlayInternal.h
210