Panda3D
 All Classes Functions Variables Enumerations
pSphereLens.cxx
1 // Filename: pSphereLens.cxx
2 // Created by: drose (12Dec01)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pSphereLens.h"
16 #include "deg_2_rad.h"
17 
18 TypeHandle PSphereLens::_type_handle;
19 
20 // This is the focal-length constant for fisheye lenses. See
21 // fisheyeLens.cxx.
22 static const PN_stdfloat pspherical_k = 60.0f;
23 
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: PSphereLens::make_copy
27 // Access: Public, Virtual
28 // Description: Allocates a new Lens just like this one.
29 ////////////////////////////////////////////////////////////////////
30 PT(Lens) PSphereLens::
31 make_copy() const {
32  return new PSphereLens(*this);
33 }
34 
35 ////////////////////////////////////////////////////////////////////
36 // Function: PSphereLens::do_extrude
37 // Access: Protected, Virtual
38 // Description: Given a 2-d point in the range (-1,1) in both
39 // dimensions, where (0,0) is the center of the
40 // lens and (-1,-1) is the lower-left corner,
41 // compute the corresponding vector in space that maps
42 // to this point, if such a vector can be determined.
43 // The vector is returned by indicating the points on
44 // the near plane and far plane that both map to the
45 // indicated 2-d point.
46 //
47 // The z coordinate of the 2-d point is ignored.
48 //
49 // Returns true if the vector is defined, or false
50 // otherwise.
51 ////////////////////////////////////////////////////////////////////
52 bool PSphereLens::
53 do_extrude(const Lens::CData *lens_cdata,
54  const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const {
55  // Undo the shifting from film offsets, etc. This puts the point
56  // into the range [-film_size/2, film_size/2] in x and y.
57  LPoint3 f = point2d * do_get_film_mat_inv(lens_cdata);
58 
59  PN_stdfloat focal_length = do_get_focal_length(lens_cdata);
60 
61  // Rotate the forward vector through the rotation angles
62  // corresponding to this point.
63  LPoint3 v = LPoint3(0.0f, 1.0f, 0.0f) *
64  LMatrix3::rotate_mat(f[1] * pspherical_k / focal_length, LVector3(1.0f, 0.0f, 0.0f)) *
65  LMatrix3::rotate_mat(f[0] * pspherical_k / focal_length, LVector3(0.0f, 0.0f, -1.0f));
66 
67  // And we'll need to account for the lens's rotations, etc. at the
68  // end of the day.
69  const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
70  const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
71 
72  near_point = (v * do_get_near(lens_cdata)) * proj_inv_mat * lens_mat;
73  far_point = (v * do_get_far(lens_cdata)) * proj_inv_mat * lens_mat;
74  return true;
75 }
76 
77 ////////////////////////////////////////////////////////////////////
78 // Function: PSphereLens::do_project
79 // Access: Protected, Virtual
80 // Description: Given a 3-d point in space, determine the 2-d point
81 // this maps to, in the range (-1,1) in both dimensions,
82 // where (0,0) is the center of the lens and
83 // (-1,-1) is the lower-left corner.
84 //
85 // Some lens types also set the z coordinate of the 2-d
86 // point to a value in the range (-1, 1), where -1
87 // represents a point on the near plane, and 1
88 // represents a point on the far plane.
89 //
90 // Returns true if the 3-d point is in front of the lens
91 // and within the viewing frustum (in which case point2d
92 // is filled in), or false otherwise.
93 ////////////////////////////////////////////////////////////////////
94 bool PSphereLens::
95 do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
96  // First, account for any rotations, etc. on the lens.
97  LVector3 v3 = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
98  PN_stdfloat dist = v3.length();
99  if (dist == 0.0f) {
100  point2d.set(0.0f, 0.0f, 0.0f);
101  return false;
102  }
103 
104  v3 /= dist;
105 
106  PN_stdfloat focal_length = do_get_focal_length(lens_cdata);
107 
108  // To compute the x position on the frame, we only need to consider
109  // the angle of the vector about the Z axis. Project the vector
110  // into the XY plane to do this.
111  LVector2 xy(v3[0], v3[1]);
112 
113  // Unroll the Z angle, and the y position is the angle about the X
114  // axis.
115  xy.normalize();
116  LVector2d yz(v3[0]*xy[0] + v3[1]*xy[1], v3[2]);
117 
118  // Compute the depth as a linear distance in the range 0 .. 1.
119  PN_stdfloat z = (dist - do_get_near(lens_cdata)) / (do_get_far(lens_cdata) - do_get_near(lens_cdata));
120 
121  point2d.set
122  (
123  // The x position is the angle about the Z axis.
124  rad_2_deg(catan2(xy[0], xy[1])) * focal_length / pspherical_k,
125  // The y position is the angle about the X axis.
126  rad_2_deg(catan2(yz[1], yz[0])) * focal_length / pspherical_k,
127  // Z is the distance scaled into the range -1 .. 1.
128  2.0 * z - 1.0
129  );
130 
131  // Now we have to transform the point according to the film
132  // adjustments.
133  point2d = point2d * do_get_film_mat(lens_cdata);
134 
135  return
136  point2d[0] >= -1.0f && point2d[0] <= 1.0f &&
137  point2d[1] >= -1.0f && point2d[1] <= 1.0f;
138 }
139 
140 ////////////////////////////////////////////////////////////////////
141 // Function: PSphereLens::fov_to_film
142 // Access: Protected, Virtual
143 // Description: Given a field of view in degrees and a focal length,
144 // compute the correspdonding width (or height) on the
145 // film. If horiz is true, this is in the horizontal
146 // direction; otherwise, it is in the vertical direction
147 // (some lenses behave differently in each direction).
148 ////////////////////////////////////////////////////////////////////
149 PN_stdfloat PSphereLens::
150 fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool) const {
151  return focal_length * fov / pspherical_k;
152 }
153 
154 ////////////////////////////////////////////////////////////////////
155 // Function: PSphereLens::fov_to_focal_length
156 // Access: Protected, Virtual
157 // Description: Given a field of view in degrees and a width (or
158 // height) on the film, compute the focal length of the
159 // lens. If horiz is true, this is in the horizontal
160 // direction; otherwise, it is in the vertical direction
161 // (some lenses behave differently in each direction).
162 ////////////////////////////////////////////////////////////////////
163 PN_stdfloat PSphereLens::
164 fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool) const {
165  return film_size * pspherical_k / fov;
166 }
167 
168 ////////////////////////////////////////////////////////////////////
169 // Function: PSphereLens::film_to_fov
170 // Access: Protected, Virtual
171 // Description: Given a width (or height) on the film and a focal
172 // length, compute the field of view in degrees. If
173 // horiz is true, this is in the horizontal direction;
174 // otherwise, it is in the vertical direction (some
175 // lenses behave differently in each direction).
176 ////////////////////////////////////////////////////////////////////
177 PN_stdfloat PSphereLens::
178 film_to_fov(PN_stdfloat film_size, PN_stdfloat focal_length, bool) const {
179  return film_size * pspherical_k / focal_length;
180 }
A PSphereLens is a special nonlinear lens that doesn&#39;t correspond to any real physical lenses...
Definition: pSphereLens.h:38
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:45
This is a two-component vector offset.
Definition: lvector2.h:416
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
float length() const
Returns the length of the vector, by the Pythagorean theorem.
Definition: lvecBase3.h:765
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
This is a two-component vector offset.
Definition: lvector2.h:91
static LMatrix3f rotate_mat(float angle)
Returns a matrix that rotates by the given angle in degrees counterclockwise.
Definition: lmatrix.h:4081
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85