add PSphereLens

This commit is contained in:
David Rose 2001-12-12 22:11:37 +00:00
parent eb466653c3
commit 1f3109c18a
5 changed files with 311 additions and 0 deletions

View File

@ -10,6 +10,7 @@
config_distort.cxx config_distort.h \
cylindricalLens.cxx cylindricalLens.h cylindricalLens.I \
fisheyeLens.cxx fisheyeLens.h fisheyeLens.I \
pSphereLens.cxx pSphereLens.h pSphereLens.I \
projectionScreen.cxx projectionScreen.h projectionScreen.I
#define INSTALL_HEADERS

View File

@ -19,6 +19,7 @@
#include "config_distort.h"
#include "cylindricalLens.h"
#include "fisheyeLens.h"
#include "pSphereLens.h"
#include "projectionScreen.h"
#include "dconfig.h"
@ -48,5 +49,6 @@ init_libdistort() {
CylindricalLens::init_type();
FisheyeLens::init_type();
PSphereLens::init_type();
ProjectionScreen::init_type();
}

View File

@ -0,0 +1,46 @@
// Filename: pSphereLens.I
// Created by: drose (12Dec01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PSphereLens::
PSphereLens() {
}
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PSphereLens::
PSphereLens(const PSphereLens &copy) : Lens(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void PSphereLens::
operator = (const PSphereLens &copy) {
Lens::operator = (copy);
}

View File

@ -0,0 +1,180 @@
// Filename: pSphereLens.cxx
// Created by: drose (12Dec01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "pSphereLens.h"
#include "deg_2_rad.h"
TypeHandle PSphereLens::_type_handle;
// This is the focal-length constant for fisheye lenses. See
// fisheyeLens.cxx.
static const float k = 60.0f;
// focal_length = film_size * k / fov;
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::make_copy
// Access: Public, Virtual
// Description: Allocates a new Lens just like this one.
////////////////////////////////////////////////////////////////////
PT(Lens) PSphereLens::
make_copy() const {
return new PSphereLens(*this);
}
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::extrude_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 corresponding vector in space that maps
// to this point, if such a vector can be determined.
// The vector is returned by indicating the points on
// the near plane and far plane that both map to the
// indicated 2-d point.
//
// The z coordinate of the 2-d point is ignored.
//
// Returns true if the vector is defined, or false
// otherwise.
////////////////////////////////////////////////////////////////////
bool PSphereLens::
extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point) 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();
// Rotate the forward vector through the rotation angles
// corresponding to this point.
LPoint3f v = LPoint3f(0.0f, 1.0f, 0.0f) *
LMatrix3f::rotate_mat(f[1] * k / focal_length, LVector3f(1.0f, 0.0f, 0.0f)) *
LMatrix3f::rotate_mat(f[0] * k / focal_length, LVector3f(0.0f, 0.0f, -1.0f));
// And we'll need to account for the lens's rotations, etc. at the
// end of the day.
const LMatrix4f &lens_mat = get_lens_mat();
near_point = (v * get_near()) * lens_mat;
far_point = (v * get_far()) * lens_mat;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::project_impl
// Access: Protected, Virtual
// Description: Given a 3-d point in space, determine the 2-d point
// this maps to, 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.
//
// Some lens types also set the z coordinate of the 2-d
// point to a value in the range (-1, 1), where 1
// represents a point on the near plane, and -1
// represents a point on the far plane.
//
// Returns true if the 3-d point is in front of the lens
// and within the viewing frustum (in which case point2d
// is filled in), or false otherwise.
////////////////////////////////////////////////////////////////////
bool PSphereLens::
project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
// First, account for any rotations, etc. on the lens.
LVector3f v3 = point3d * get_lens_mat_inv();
float dist = v3.length();
if (dist == 0.0f) {
point2d.set(0.0f, 0.0f, 0.0f);
return false;
}
v3 /= dist;
float focal_length = get_focal_length();
// To compute the x position on the frame, we only need to consider
// the angle of the vector about the Z axis. Project the vector
// into the XY plane to do this.
LVector2f xy(v3[0], v3[1]);
// Unroll the Z angle, and the y position is the angle about the X
// axis.
xy.normalize();
LVector2d yz(v3[0]*xy[0] + v3[1]*xy[1], v3[2]);
point2d.set
(
// The x position is the angle about the Z axis.
rad_2_deg(catan2(xy[0], xy[1])) * focal_length / k,
// The y position is the angle about the X axis.
rad_2_deg(catan2(yz[1], yz[0])) * focal_length / k,
// Z is the distance scaled into the range (1, -1).
(get_near() - dist) / (get_far() - get_near())
);
// Now we have to transform the point according to the film
// adjustments.
point2d = point2d * get_film_mat();
return
point2d[0] >= -1.0f && point2d[0] <= 1.0f &&
point2d[1] >= -1.0f && point2d[1] <= 1.0f;
}
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::fov_to_film
// Access: Protected, Virtual
// Description: Given a field of view in degrees and a focal length,
// compute the correspdonding width (or height) on the
// film. If horiz is true, this is in the horizontal
// direction; otherwise, it is in the vertical direction
// (some lenses behave differently in each direction).
////////////////////////////////////////////////////////////////////
float PSphereLens::
fov_to_film(float fov, float focal_length, bool) const {
return focal_length * fov / k;
}
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::fov_to_focal_length
// Access: Protected, Virtual
// Description: Given a field of view in degrees and a width (or
// height) on the film, compute the focal length of the
// lens. If horiz is true, this is in the horizontal
// direction; otherwise, it is in the vertical direction
// (some lenses behave differently in each direction).
////////////////////////////////////////////////////////////////////
float PSphereLens::
fov_to_focal_length(float fov, float film_size, bool) const {
return film_size * k / fov;
}
////////////////////////////////////////////////////////////////////
// Function: PSphereLens::film_to_fov
// Access: Protected, Virtual
// Description: Given a width (or height) on the film and a focal
// length, compute the field of view in degrees. If
// horiz is true, this is in the horizontal direction;
// otherwise, it is in the vertical direction (some
// lenses behave differently in each direction).
////////////////////////////////////////////////////////////////////
float PSphereLens::
film_to_fov(float film_size, float focal_length, bool) const {
return film_size * k / focal_length;
}

View File

@ -0,0 +1,82 @@
// Filename: pSphereLens.h
// Created by: drose (12Dec01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef PSPHERELENS_H
#define PSPHERELENS_H
#include "pandabase.h"
#include "lens.h"
////////////////////////////////////////////////////////////////////
// Class : PSphereLens
// Description : A PSphereLens is a special nonlinear lens that
// doesn't correspond to any real physical lenses. It's
// primarily useful for generating 360-degree wraparound
// images while avoiding the distortion associated with
// fisheye images.
//
// A PSphereLens is similar to a cylindrical lens,
// except it is also curved in the vertical direction.
// This allows it to extend to both poles in the
// vertical direction. The mapping is similar to what
// many modeling packages call a sphere mapping: the x
// coordinate is proportional to azimuth, while the y
// coordinate is proportional to altitude.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAFX PSphereLens : public Lens {
PUBLISHED:
INLINE PSphereLens();
public:
INLINE PSphereLens(const PSphereLens &copy);
INLINE void operator = (const PSphereLens &copy);
public:
virtual PT(Lens) make_copy() const;
protected:
virtual bool extrude_impl(const LPoint3f &point2d,
LPoint3f &near_point, LPoint3f &far_point) const;
virtual bool project_impl(const LPoint3f &point3d, LPoint3f &point2d) const;
virtual float fov_to_film(float fov, float focal_length, bool horiz) const;
virtual float fov_to_focal_length(float fov, float film_size, bool horiz) const;
virtual float film_to_fov(float film_size, float focal_length, bool horiz) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
Lens::init_type();
register_type(_type_handle, "PSphereLens",
Lens::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "pSphereLens.I"
#endif