Panda3D

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