Browse Source

define normals for projection screens

David Rose 22 years ago
parent
commit
9315342da7

+ 37 - 1
panda/src/distort/cylindricalLens.cxx

@@ -66,7 +66,7 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
   csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
 
   // Define a unit vector (well, a unit vector in the XY plane, at
-  // least) that reprents the vector corresponding to this point.
+  // least) that represents the vector corresponding to this point.
   LPoint3f v(sinAngle, cosAngle, f[1] / focal_length);
 
   // And we'll need to account for the lens's rotations, etc. at the
@@ -78,6 +78,42 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CylindricalLens::extrude_vec_impl
+//       Access: Protected, Virtual
+//  Description: Given a 2-d point in the range (-1,1) in both
+//               dimensions, where (0,0) is the center of the
+//               lens and (-1,-1) is the lower-left corner,
+//               compute the vector that corresponds to the view
+//               direction.  This will be parallel to the normal on
+//               the surface (the far plane) corresponding to the lens
+//               shape at this point.
+//
+//               See the comment block on Lens::extrude_vec_impl() for
+//               a more in-depth comment on the meaning of this
+//               vector.
+//
+//               The z coordinate of the 2-d point is ignored.
+//
+//               Returns true if the vector is defined, or false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool CylindricalLens::
+extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const {
+  // Undo the shifting from film offsets, etc.  This puts the point
+  // into the range [-film_size/2, film_size/2] in x and y.
+  LPoint3f f = point2d * get_film_mat_inv();
+
+  float focal_length = get_focal_length();
+  float angle = f[0] * cylindrical_k / focal_length;
+  float sinAngle, cosAngle;
+  csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
+
+  vec = LVector3f(sinAngle, cosAngle, 0.0f) * get_lens_mat();
+
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CylindricalLens::project_impl
 //       Access: Protected, Virtual

+ 1 - 0
panda/src/distort/cylindricalLens.h

@@ -55,6 +55,7 @@ public:
 protected:
   virtual bool extrude_impl(const LPoint3f &point2d,
                             LPoint3f &near_point, LPoint3f &far_point) const;
+  virtual bool extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const;
   virtual bool project_impl(const LPoint3f &point3d, LPoint3f &point2d) const;
 
   virtual float fov_to_film(float fov, float focal_length, bool horiz) const;

+ 32 - 0
panda/src/distort/fisheyeLens.cxx

@@ -110,6 +110,38 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: FisheyeLens::extrude_vec_impl
+//       Access: Protected, Virtual
+//  Description: Given a 2-d point in the range (-1,1) in both
+//               dimensions, where (0,0) is the center of the
+//               lens and (-1,-1) is the lower-left corner,
+//               compute the vector that corresponds to the view
+//               direction.  This will be parallel to the normal on
+//               the surface (the far plane) corresponding to the lens
+//               shape at this point.
+//
+//               See the comment block on Lens::extrude_vec_impl() for
+//               a more in-depth comment on the meaning of this
+//               vector.
+//
+//               The z coordinate of the 2-d point is ignored.
+//
+//               Returns true if the vector is defined, or false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool FisheyeLens::
+extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const {
+  LPoint3f near_point, far_point;
+  if (!extrude_impl(point2d, near_point, far_point)) {
+    return false;
+  }
+
+  vec = far_point - near_point;
+
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: FisheyeLens::project_impl
 //       Access: Protected, Virtual

+ 1 - 0
panda/src/distort/fisheyeLens.h

@@ -45,6 +45,7 @@ public:
 protected:
   virtual bool extrude_impl(const LPoint3f &point2d,
                             LPoint3f &near_point, LPoint3f &far_point) const;
+  virtual bool extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const;
   virtual bool project_impl(const LPoint3f &point3d, LPoint3f &point2d) const;
 
   virtual float fov_to_film(float fov, float focal_length, bool horiz) const;

+ 14 - 6
panda/src/distort/nonlinearImager.cxx

@@ -259,10 +259,11 @@ set_source_camera(int index, const NodePath &source_camera) {
 void NonlinearImager::
 set_screen_active(int index, bool active) {
   nassertv(index >= 0 && index < (int)_screens.size());
-  _screens[index]._active = active;
+
+  Screen &screen = _screens[index];
+  screen._active = active;
 
   if (!active) {
-    Screen &screen = _screens[index];
     // If we've just made this screen inactive, remove its meshes.
     for (size_t vi = 0; vi < screen._meshes.size(); vi++) {
       screen._meshes[vi]._mesh.remove_node();
@@ -275,9 +276,16 @@ set_screen_active(int index, bool active) {
       nassertv(removed);
     }
 
+    // Hide the screen in the dark room.  This doesn't really matter,
+    // since the dark room isn't normally rendered, but hide it anyway
+    // in case the user stuck a camera in there for fun.
+    screen._screen.hide();
+
   } else {
     // If we've just made it active, it needs to be recomputed.
     _stale = true;
+
+    screen._screen.show();
   }
 }
 
@@ -688,10 +696,10 @@ recompute_screen(NonlinearImager::Screen &screen, size_t vi) {
   if (screen._buffer != (GraphicsOutput *)NULL) {
     screen._meshes[vi]._mesh.set_texture(screen._buffer->get_texture());
 
-    // We don't really need to set the texture on the external screen,
-    // since that's normally not rendered, but we do anyway just for
-    // debugging purposes (in case the user does try to render it, to
-    // see what's going on).
+    // We don't really need to set the texture on the dark room
+    // screen, since that's normally not rendered, but we do anyway
+    // just for debugging purposes (in case the user does try to
+    // render it, to see what's going on).
     screen._screen.set_texture(screen._buffer->get_texture());
   }
 

+ 10 - 4
panda/src/distort/projectionScreen.cxx

@@ -197,6 +197,7 @@ generate_screen(const NodePath &projector, const string &screen_name,
   float t = (distance - lens->get_near()) / (lens->get_far() - lens->get_near());
 
   PTA_Vertexf coords;
+  PTA_Normalf norms;
   coords.reserve(num_verts);
   float x_scale = 2.0f / (num_x_verts - 1);
   float y_scale = 2.0f / (num_y_verts - 1);
@@ -211,11 +212,15 @@ generate_screen(const NodePath &projector, const string &screen_name,
 
       LPoint3f near_point, far_point;
       lens->extrude(film, near_point, far_point);
-      
       LPoint3f point = near_point + t * (far_point - near_point);
-      point = point * rel_mat;
-      
-      coords.push_back(point);
+
+      // Normals aren't often needed on projection screens, but you
+      // never know.
+      LVector3f normal;
+      lens->extrude_vec(film, normal);
+
+      coords.push_back(point * rel_mat);
+      norms.push_back(-normalize(normal * rel_mat));
     }
   }
   nassertr((int)coords.size() == num_verts, NULL);
@@ -257,6 +262,7 @@ generate_screen(const NodePath &projector, const string &screen_name,
   geom->set_lengths(lengths);
 
   geom->set_coords(coords, G_PER_VERTEX, vindex);
+  geom->set_normals(norms, G_PER_VERTEX, vindex);
 
   // Make it white.
   PTA_Colorf colors;

+ 48 - 0
panda/src/gobj/lens.I

@@ -60,6 +60,54 @@ extrude(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point) cons
   return extrude_impl(point2d, near_point, far_point);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Lens::extrude_vec
+//       Access: Published
+//  Description: Given a 2-d point in the range (-1,1) in both
+//               dimensions, where (0,0) is the center of the
+//               lens and (-1,-1) is the lower-left corner,
+//               compute the vector that corresponds to the view
+//               direction.  This will be parallel to the normal on
+//               the surface (the far plane) corresponding to the lens
+//               shape at this point.
+//
+//               See the comment block on Lens::extrude_vec_impl() for
+//               a more in-depth comment on the meaning of this
+//               vector.
+//
+//               Returns true if the vector is defined, or false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool Lens::
+extrude_vec(const LPoint2f &point2d, LVector3f &vec) const {
+  return extrude_vec_impl(LPoint3f(point2d[0], point2d[1], 0.0f), vec);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Lens::extrude_vec
+//       Access: Published
+//  Description: Given a 2-d point in the range (-1,1) in both
+//               dimensions, where (0,0) is the center of the
+//               lens and (-1,-1) is the lower-left corner,
+//               compute the vector that corresponds to the view
+//               direction.  This will be parallel to the normal on
+//               the surface (the far plane) corresponding to the lens
+//               shape at this point.
+//
+//               See the comment block on Lens::extrude_vec_impl() for
+//               a more in-depth comment on the meaning of this
+//               vector.
+//
+//               The z coordinate of the 2-d point is ignored.
+//
+//               Returns true if the vector is defined, or false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool Lens::
+extrude_vec(const LPoint3f &point2d, LVector3f &vec) const {
+  return extrude_vec_impl(point2d, vec);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Lens::project
 //       Access: Published

+ 35 - 0
panda/src/gobj/lens.cxx

@@ -1117,6 +1117,41 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Lens::extrude_vec_impl
+//       Access: Protected, Virtual
+//  Description: Given a 2-d point in the range (-1,1) in both
+//               dimensions, where (0,0) is the center of the
+//               lens and (-1,-1) is the lower-left corner,
+//               compute the vector that corresponds to the view
+//               direction.  This will be parallel to the normal on
+//               the surface (the far plane) corresponding to the lens
+//               shape at this point.
+//
+//               Generally, for all rational lenses, the center of the
+//               film at (0,0) computes a vector that is in the same
+//               direction as the vector specified by
+//               set_view_vector().
+//
+//               For all linear lenses, including perspective and
+//               ortographic lenses, all points on the film compute
+//               this same vector (the far plane is a flat plane, so
+//               the normal is the same everywhere).  For curved
+//               lenses like fisheye and cylindrical lenses, different
+//               points may compute different vectors (the far "plane"
+//               on these lenses is a curved surface).
+//
+//               The z coordinate of the 2-d point is ignored.
+//
+//               Returns true if the vector is defined, or false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool Lens::
+extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const {
+  vec = LVector3f::forward(_cs) * get_lens_mat();
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Lens::project_impl
 //       Access: Protected, Virtual

+ 3 - 0
panda/src/gobj/lens.h

@@ -53,6 +53,8 @@ PUBLISHED:
                       LPoint3f &near_point, LPoint3f &far_point) const;
   INLINE bool extrude(const LPoint3f &point2d,
                       LPoint3f &near_point, LPoint3f &far_point) const;
+  INLINE bool extrude_vec(const LPoint2f &point2d, LVector3f &vec3d) const;
+  INLINE bool extrude_vec(const LPoint3f &point2d, LVector3f &vec3d) const;
   INLINE bool project(const LPoint3f &point3d, LPoint3f &point2d) const;
   INLINE bool project(const LPoint3f &point3d, LPoint2f &point2d) const;
 
@@ -153,6 +155,7 @@ protected:
 
   virtual bool extrude_impl(const LPoint3f &point2d,
                             LPoint3f &near_point, LPoint3f &far_point) const;
+  virtual bool extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const;
   virtual bool project_impl(const LPoint3f &point3d, LPoint3f &point2d) const;
 
   virtual void compute_film_size();