vsg 1.1.3
VulkanSceneGraph library
Loading...
Searching...
No Matches
ProjectionMatrix.h
1#pragma once
2
3/* <editor-fold desc="MIT License">
4
5Copyright(c) 2018 Robert Osfield
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
13</editor-fold> */
14
15#include <vsg/app/EllipsoidModel.h>
16#include <vsg/app/ViewMatrix.h>
17#include <vsg/io/Logger.h>
18
19namespace vsg
20{
21
23 class VSG_DECLSPEC ProjectionMatrix : public Inherit<Object, ProjectionMatrix>
24 {
25 public:
26 virtual dmat4 transform() const = 0;
27
28 virtual dmat4 inverse() const
29 {
30 return vsg::inverse(transform());
31 }
32
33 virtual void changeExtent(const VkExtent2D& /*prevExtent*/, const VkExtent2D& /*newExtent*/)
34 {
35 }
36 };
37 VSG_type_name(vsg::ProjectionMatrix);
38
40 class VSG_DECLSPEC Perspective : public Inherit<ProjectionMatrix, Perspective>
41 {
42 public:
43 Perspective() :
44 fieldOfViewY(60.0),
45 aspectRatio(1.0),
46 nearDistance(1.0),
47 farDistance(10000.0)
48 {
49 }
50
51 Perspective(double fov, double ar, double nd, double fd) :
52 fieldOfViewY(fov),
53 aspectRatio(ar),
54 nearDistance(nd),
55 farDistance(fd)
56 {
57 }
58
59 dmat4 transform() const override { return perspective(radians(fieldOfViewY), aspectRatio, nearDistance, farDistance); }
60
61 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
62 {
63 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
64 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
65
66 aspectRatio *= (newRatio / oldRatio);
67 }
68
69 double fieldOfViewY;
70 double aspectRatio;
71 double nearDistance;
72 double farDistance;
73
74 public:
75 void read(Input& input) override;
76 void write(Output& output) const override;
77 };
78 VSG_type_name(vsg::Perspective);
79
81 class VSG_DECLSPEC Orthographic : public Inherit<ProjectionMatrix, Orthographic>
82 {
83 public:
84 Orthographic() :
85 left(-1.0),
86 right(1.0),
87 bottom(-1.0),
88 top(1.0),
89 nearDistance(1.0),
90 farDistance(10000.0)
91 {
92 }
93
94 Orthographic(double l, double r, double b, double t, double nd, double fd) :
95 left(l),
96 right(r),
97 bottom(b),
98 top(t),
99 nearDistance(nd),
100 farDistance(fd)
101 {
102 }
103
104 dmat4 transform() const override { return orthographic(left, right, bottom, top, nearDistance, farDistance); }
105
106 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
107 {
108 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
109 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
110 left *= newRatio / oldRatio;
111 right *= newRatio / oldRatio;
112 }
113
114 double left;
115 double right;
116 double bottom;
117 double top;
118 double nearDistance;
119 double farDistance;
120
121 public:
122 void read(Input& input) override;
123 void write(Output& output) const override;
124 };
125 VSG_type_name(vsg::Orthographic);
126
128 class RelativeProjection : public Inherit<ProjectionMatrix, RelativeProjection>
129 {
130 public:
132 projectionMatrix(pm),
133 matrix(m)
134 {
135 }
136
138 dmat4 transform() const override
139 {
140 return matrix * projectionMatrix->transform();
141 }
142
143 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
144 {
145 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
146 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
147 matrix = scale(oldRatio / newRatio, 1.0, 1.0) * matrix;
148 }
149 ref_ptr<ProjectionMatrix> projectionMatrix;
150 dmat4 matrix;
151 };
152 VSG_type_name(vsg::RelativeProjection);
153
156 class VSG_DECLSPEC EllipsoidPerspective : public Inherit<ProjectionMatrix, EllipsoidPerspective>
157 {
158 public:
160
162 lookAt(la),
163 ellipsoidModel(em)
164 {
165 }
166
167 EllipsoidPerspective(ref_ptr<LookAt> la, ref_ptr<EllipsoidModel> em, double fov, double ar, double nfr, double hmh) :
168 lookAt(la),
169 ellipsoidModel(em),
170 fieldOfViewY(fov),
171 aspectRatio(ar),
172 nearFarRatio(nfr),
173 horizonMountainHeight(hmh)
174 {
175 }
176
177 dmat4 transform() const override
178 {
179 //debug("camera eye : ", lookAt->eye, ", ", ellipsoidModel->convertECEFToLatLongAltitude(lookAt->eye));
180 vsg::dvec3 v = lookAt->eye;
181 vsg::dvec3 lv = vsg::normalize(lookAt->center - lookAt->eye);
182 double R = ellipsoidModel->radiusEquator();
183 double H = ellipsoidModel->convertECEFToLatLongAltitude(v).z;
184 double D = R + H;
185
186 double alpha = (D > R) ? std::acos(R / D) : 0.0;
187
188 double beta_ratio = R / (R + horizonMountainHeight);
189 double beta = beta_ratio < 1.0 ? std::acos(beta_ratio) : 0.0;
190
191 double theta_ratio = -vsg::dot(lv, v) / (vsg::length(lv) * vsg::length(v));
192 double theta = theta_ratio < 1.0 ? std::acos(theta_ratio) : 0.0;
193
194 double l = R * (std::tan(alpha) + std::tan(beta));
195
196 double farDistance = std::cos(theta + alpha - vsg::PI * 0.5) * l;
197 double nearDistance = farDistance * nearFarRatio;
198 //debug("H = ", H, ", l = ", l, ", theta = ", vsg::degrees(theta), ", fd = ", farDistance);
199
200 return perspective(radians(fieldOfViewY), aspectRatio, nearDistance, farDistance);
201 }
202
203 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
204 {
205 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
206 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
207
208 aspectRatio *= (newRatio / oldRatio);
209 }
210
211 ref_ptr<LookAt> lookAt;
212 ref_ptr<EllipsoidModel> ellipsoidModel;
213 double fieldOfViewY = 60.0;
214 double aspectRatio = 1.0;
215 double nearFarRatio = 0.0001;
216 double horizonMountainHeight = 1000.0;
217
218 public:
219 void read(Input& input) override;
220 void write(Output& output) const override;
221 };
222 VSG_type_name(vsg::EllipsoidPerspective);
223
224} // namespace vsg
Definition ProjectionMatrix.h:157
Definition Inherit.h:28
Definition Input.h:44
Orthographic is a ProjectionMatrix that implements the glOrtho model for setting the projection matri...
Definition ProjectionMatrix.h:82
Definition Output.h:41
Perspective is a ProjectionMatrix that implements the gluPerspective model for setting the projection...
Definition ProjectionMatrix.h:41
ProjectionMatrix is a base class for specifying the Camera projection matrix and its inverse.
Definition ProjectionMatrix.h:24
RelativeProjection is a ProjectionMatrix that decorates another ProjectionMatrix and pre-multiplies i...
Definition ProjectionMatrix.h:129
dmat4 transform() const override
returns matrix * projectionMatrix->transform()
Definition ProjectionMatrix.h:138
Definition ref_ptr.h:22