define normals for projection screens

This commit is contained in:
David Rose 2004-04-01 01:58:42 +00:00
parent 2ddaea3a3d
commit 9315342da7
9 changed files with 181 additions and 11 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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());
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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();