1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //
6 //  This software is distributed WITHOUT ANY WARRANTY; without even
7 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 //  PURPOSE.  See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_rendering_MatrixHelpers_h
11 #define vtk_m_rendering_MatrixHelpers_h
12 
13 #include <vtkm/Matrix.h>
14 #include <vtkm/VectorAnalysis.h>
15 
16 namespace vtkm
17 {
18 namespace rendering
19 {
20 
21 struct MatrixHelpers
22 {
CreateOGLMatrixMatrixHelpers23   static VTKM_CONT void CreateOGLMatrix(const vtkm::Matrix<vtkm::Float32, 4, 4>& mtx,
24                                         vtkm::Float32* oglM)
25   {
26     oglM[0] = mtx[0][0];
27     oglM[1] = mtx[1][0];
28     oglM[2] = mtx[2][0];
29     oglM[3] = mtx[3][0];
30     oglM[4] = mtx[0][1];
31     oglM[5] = mtx[1][1];
32     oglM[6] = mtx[2][1];
33     oglM[7] = mtx[3][1];
34     oglM[8] = mtx[0][2];
35     oglM[9] = mtx[1][2];
36     oglM[10] = mtx[2][2];
37     oglM[11] = mtx[3][2];
38     oglM[12] = mtx[0][3];
39     oglM[13] = mtx[1][3];
40     oglM[14] = mtx[2][3];
41     oglM[15] = mtx[3][3];
42   }
43 
ViewMatrixMatrixHelpers44   static VTKM_CONT vtkm::Matrix<vtkm::Float32, 4, 4> ViewMatrix(const vtkm::Vec3f_32& position,
45                                                                 const vtkm::Vec3f_32& lookAt,
46                                                                 const vtkm::Vec3f_32& up)
47   {
48     vtkm::Vec3f_32 viewDir = position - lookAt;
49     vtkm::Vec3f_32 right = vtkm::Cross(up, viewDir);
50     vtkm::Vec3f_32 ru = vtkm::Cross(viewDir, right);
51 
52     vtkm::Normalize(viewDir);
53     vtkm::Normalize(right);
54     vtkm::Normalize(ru);
55 
56     vtkm::Matrix<vtkm::Float32, 4, 4> matrix;
57     vtkm::MatrixIdentity(matrix);
58 
59     matrix(0, 0) = right[0];
60     matrix(0, 1) = right[1];
61     matrix(0, 2) = right[2];
62     matrix(1, 0) = ru[0];
63     matrix(1, 1) = ru[1];
64     matrix(1, 2) = ru[2];
65     matrix(2, 0) = viewDir[0];
66     matrix(2, 1) = viewDir[1];
67     matrix(2, 2) = viewDir[2];
68 
69     matrix(0, 3) = -vtkm::Dot(right, position);
70     matrix(1, 3) = -vtkm::Dot(ru, position);
71     matrix(2, 3) = -vtkm::Dot(viewDir, position);
72 
73     return matrix;
74   }
75 
WorldMatrixMatrixHelpers76   static VTKM_CONT vtkm::Matrix<vtkm::Float32, 4, 4> WorldMatrix(const vtkm::Vec3f_32& neworigin,
77                                                                  const vtkm::Vec3f_32& newx,
78                                                                  const vtkm::Vec3f_32& newy,
79                                                                  const vtkm::Vec3f_32& newz)
80   {
81     vtkm::Matrix<vtkm::Float32, 4, 4> matrix;
82     vtkm::MatrixIdentity(matrix);
83 
84     matrix(0, 0) = newx[0];
85     matrix(0, 1) = newy[0];
86     matrix(0, 2) = newz[0];
87     matrix(1, 0) = newx[1];
88     matrix(1, 1) = newy[1];
89     matrix(1, 2) = newz[1];
90     matrix(2, 0) = newx[2];
91     matrix(2, 1) = newy[2];
92     matrix(2, 2) = newz[2];
93 
94     matrix(0, 3) = neworigin[0];
95     matrix(1, 3) = neworigin[1];
96     matrix(2, 3) = neworigin[2];
97 
98     return matrix;
99   }
100 
CreateScaleMatrixHelpers101   static VTKM_CONT vtkm::Matrix<vtkm::Float32, 4, 4> CreateScale(const vtkm::Float32 x,
102                                                                  const vtkm::Float32 y,
103                                                                  const vtkm::Float32 z)
104   {
105     vtkm::Matrix<vtkm::Float32, 4, 4> matrix;
106     vtkm::MatrixIdentity(matrix);
107     matrix[0][0] = x;
108     matrix[1][1] = y;
109     matrix[2][2] = z;
110 
111     return matrix;
112   }
113 
TrackballMatrixMatrixHelpers114   static VTKM_CONT vtkm::Matrix<vtkm::Float32, 4, 4> TrackballMatrix(vtkm::Float32 p1x,
115                                                                      vtkm::Float32 p1y,
116                                                                      vtkm::Float32 p2x,
117                                                                      vtkm::Float32 p2y)
118   {
119     const vtkm::Float32 RADIUS = 0.80f;     //z value lookAt x = y = 0.0
120     const vtkm::Float32 COMPRESSION = 3.5f; // multipliers for x and y.
121     const vtkm::Float32 AR3 = RADIUS * RADIUS * RADIUS;
122 
123     vtkm::Matrix<vtkm::Float32, 4, 4> matrix;
124 
125     vtkm::MatrixIdentity(matrix);
126     if (p1x == p2x && p1y == p2y)
127     {
128       return matrix;
129     }
130 
131     vtkm::Vec3f_32 p1(p1x, p1y, AR3 / ((p1x * p1x + p1y * p1y) * COMPRESSION + AR3));
132     vtkm::Vec3f_32 p2(p2x, p2y, AR3 / ((p2x * p2x + p2y * p2y) * COMPRESSION + AR3));
133     vtkm::Vec3f_32 axis = vtkm::Normal(vtkm::Cross(p2, p1));
134 
135     vtkm::Vec3f_32 p2_p1(p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);
136     vtkm::Float32 t = vtkm::Magnitude(p2_p1);
137     t = vtkm::Min(vtkm::Max(t, -1.0f), 1.0f);
138     vtkm::Float32 phi = static_cast<vtkm::Float32>(-2.0f * asin(t / (2.0f * RADIUS)));
139     vtkm::Float32 val = static_cast<vtkm::Float32>(sin(phi / 2.0f));
140     axis[0] *= val;
141     axis[1] *= val;
142     axis[2] *= val;
143 
144     //quaternion
145     vtkm::Float32 q[4] = { axis[0], axis[1], axis[2], static_cast<vtkm::Float32>(cos(phi / 2.0f)) };
146 
147     // normalize quaternion to unit magnitude
148     t = 1.0f /
149       static_cast<vtkm::Float32>(sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]));
150     q[0] *= t;
151     q[1] *= t;
152     q[2] *= t;
153     q[3] *= t;
154 
155     matrix(0, 0) = 1 - 2 * (q[1] * q[1] + q[2] * q[2]);
156     matrix(0, 1) = 2 * (q[0] * q[1] + q[2] * q[3]);
157     matrix(0, 2) = (2 * (q[2] * q[0] - q[1] * q[3]));
158 
159     matrix(1, 0) = 2 * (q[0] * q[1] - q[2] * q[3]);
160     matrix(1, 1) = 1 - 2 * (q[2] * q[2] + q[0] * q[0]);
161     matrix(1, 2) = (2 * (q[1] * q[2] + q[0] * q[3]));
162 
163     matrix(2, 0) = (2 * (q[2] * q[0] + q[1] * q[3]));
164     matrix(2, 1) = (2 * (q[1] * q[2] - q[0] * q[3]));
165     matrix(2, 2) = (1 - 2 * (q[1] * q[1] + q[0] * q[0]));
166 
167     return matrix;
168   }
169 };
170 }
171 } //namespace vtkm::rendering
172 
173 #endif // vtk_m_rendering_MatrixHelpers_h
174