vsg: include/vsg/app/ProjectionMatrix.h Source File

vsg 1.1.10 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 ProjectionMatrix()
27 {
28 }
29
30 explicit ProjectionMatrix(const ProjectionMatrix& pm, const CopyOp& copyop = {}) :
31 Inherit(pm, copyop)
32 {
33 }
34
35 virtual dmat4 transform() const = 0;
36
37 virtual dmat4 inverse() const
38 {
39 return vsg::inverse(transform());
40 }
41
42 virtual void changeExtent(const VkExtent2D& /*prevExtent*/, const VkExtent2D& /*newExtent*/)
43 {
44 }
45 };
46 VSG_type_name(vsg::ProjectionMatrix);
47
49 class VSG_DECLSPEC Perspective : public Inherit<ProjectionMatrix, Perspective>
50 {
51 public:
52 Perspective() :
53 fieldOfViewY(60.0),
54 aspectRatio(1.0),
55 nearDistance(1.0),
56 farDistance(10000.0)
57 {
58 }
59
60 explicit Perspective(const Perspective& p, const CopyOp& copyop = {}) :
61 Inherit(p, copyop),
62 fieldOfViewY(p.fieldOfViewY),
63 aspectRatio(p.aspectRatio),
64 nearDistance(p.nearDistance),
65 farDistance(p.farDistance)
66 {
67 }
68
69 Perspective(double fov, double ar, double nd, double fd) :
70 fieldOfViewY(fov),
71 aspectRatio(ar),
72 nearDistance(nd),
73 farDistance(fd)
74 {
75 }
76
77 ref_ptr<Object> clone(const CopyOp& copyop = {}) const override { return Perspective::create(*this, copyop); }
78
79 dmat4 transform() const override { return perspective(radians(fieldOfViewY), aspectRatio, nearDistance, farDistance); }
80
81 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
82 {
83 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
84 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
85
86 aspectRatio *= (newRatio / oldRatio);
87 }
88
89 double fieldOfViewY;
90 double aspectRatio;
91 double nearDistance;
92 double farDistance;
93
94 public:
95 void read(Input& input) override;
96 void write(Output& output) const override;
97 };
98 VSG_type_name(vsg::Perspective);
99
101 class VSG_DECLSPEC Orthographic : public Inherit<ProjectionMatrix, Orthographic>
102 {
103 public:
104 Orthographic() :
105 left(-1.0),
106 right(1.0),
107 bottom(-1.0),
108 top(1.0),
109 nearDistance(1.0),
110 farDistance(10000.0)
111 {
112 }
113
114 explicit Orthographic(const Orthographic& o, const CopyOp& copyop = {}) :
115 Inherit(o, copyop),
116 left(o.left),
117 right(o.right),
118 bottom(o.bottom),
119 top(o.top),
120 nearDistance(o.nearDistance),
121 farDistance(o.farDistance)
122 {
123 }
124
125 Orthographic(double l, double r, double b, double t, double nd, double fd) :
126 left(l),
127 right(r),
128 bottom(b),
129 top(t),
130 nearDistance(nd),
131 farDistance(fd)
132 {
133 }
134
135 ref_ptr<Object> clone(const CopyOp& copyop = {}) const override { return Orthographic::create(*this, copyop); }
136
137 dmat4 transform() const override { return orthographic(left, right, bottom, top, nearDistance, farDistance); }
138
139 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
140 {
141 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
142 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
143 left *= newRatio / oldRatio;
144 right *= newRatio / oldRatio;
145 }
146
147 double left;
148 double right;
149 double bottom;
150 double top;
151 double nearDistance;
152 double farDistance;
153
154 public:
155 void read(Input& input) override;
156 void write(Output& output) const override;
157 };
158 VSG_type_name(vsg::Orthographic);
159
161 class RelativeProjection : public Inherit<ProjectionMatrix, RelativeProjection>
162 {
163 public:
164 RelativeProjection(const dmat4& m, ref_ptr<ProjectionMatrix> pm) :
165 projectionMatrix(pm),
166 matrix(m)
167 {
168 }
169
171 dmat4 transform() const override
172 {
173 return matrix * projectionMatrix->transform();
174 }
175
176 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
177 {
178 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
179 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
180 matrix = scale(oldRatio / newRatio, 1.0, 1.0) * matrix;
181 }
182 ref_ptr<ProjectionMatrix> projectionMatrix;
183 dmat4 matrix;
184 };
185 VSG_type_name(vsg::RelativeProjection);
186
189 class VSG_DECLSPEC EllipsoidPerspective : public Inherit<ProjectionMatrix, EllipsoidPerspective>
190 {
191 public:
192 EllipsoidPerspective() {}
193
194 EllipsoidPerspective(ref_ptr<LookAt> la, ref_ptr<EllipsoidModel> em) :
195 lookAt(la),
196 ellipsoidModel(em)
197 {
198 }
199
200 EllipsoidPerspective(ref_ptr<LookAt> la, ref_ptr<EllipsoidModel> em, double fov, double ar, double nfr, double hmh) :
201 lookAt(la),
202 ellipsoidModel(em),
203 fieldOfViewY(fov),
204 aspectRatio(ar),
205 nearFarRatio(nfr),
206 horizonMountainHeight(hmh)
207 {
208 }
209
210 dmat4 transform() const override
211 {
212 //debug("camera eye : ", lookAt->eye, ", ", ellipsoidModel->convertECEFToLatLongAltitude(lookAt->eye));
213 vsg::dvec3 v = lookAt->eye;
214 vsg::dvec3 lv = vsg::normalize(lookAt->center - lookAt->eye);
215 double R = ellipsoidModel->radiusEquator();
216 double H = ellipsoidModel->convertECEFToLatLongAltitude(v).z;
217 double D = R + H;
218
219 double alpha = (D > R) ? std::acos(R / D) : 0.0;
220
221 double beta_ratio = R / (R + horizonMountainHeight);
222 double beta = beta_ratio < 1.0 ? std::acos(beta_ratio) : 0.0;
223
224 double theta_ratio = -vsg::dot(lv, v) / (vsg::length(lv) * vsg::length(v));
225 double theta = theta_ratio < 1.0 ? std::acos(theta_ratio) : 0.0;
226
227 double l = R * (std::tan(alpha) + std::tan(beta));
228
229 double farDistance = std::cos(theta + alpha - vsg::PI * 0.5) * l;
230 double nearDistance = farDistance * nearFarRatio;
231 //debug("H = ", H, ", l = ", l, ", theta = ", vsg::degrees(theta), ", fd = ", farDistance);
232
233 return perspective(radians(fieldOfViewY), aspectRatio, nearDistance, farDistance);
234 }
235
236 void changeExtent(const VkExtent2D& prevExtent, const VkExtent2D& newExtent) override
237 {
238 double oldRatio = static_cast<double>(prevExtent.width) / static_cast<double>(prevExtent.height);
239 double newRatio = static_cast<double>(newExtent.width) / static_cast<double>(newExtent.height);
240
241 aspectRatio *= (newRatio / oldRatio);
242 }
243
244 ref_ptr<LookAt> lookAt;
245 ref_ptr<EllipsoidModel> ellipsoidModel;
246 double fieldOfViewY = 60.0;
247 double aspectRatio = 1.0;
248 double nearFarRatio = 0.0001;
249 double horizonMountainHeight = 1000.0;
250
251 public:
252 void read(Input& input) override;
253 void write(Output& output) const override;
254 };
255 VSG_type_name(vsg::EllipsoidPerspective);
256
257} // namespace vsg
vsg::CopyOp
Definition Object.h:42
vsg::EllipsoidPerspective
Definition ProjectionMatrix.h:190
vsg::Input
Definition Input.h:44
vsg::Orthographic::clone
ref_ptr< Object > clone(const CopyOp &copyop={}) const override
Definition ProjectionMatrix.h:135
vsg::Output
Definition Output.h:41
vsg::Perspective::clone
ref_ptr< Object > clone(const CopyOp &copyop={}) const override
Definition ProjectionMatrix.h:77
vsg::ProjectionMatrix
ProjectionMatrix is a base class for specifying the Camera projection matrix and its inverse.
Definition ProjectionMatrix.h:24
vsg::RelativeProjection::transform
dmat4 transform() const override
returns matrix * projectionMatrix->transform()
Definition ProjectionMatrix.h:171
vsg::ref_ptr
Definition ref_ptr.h:22