add OSphereLens

This commit is contained in:
David Rose 2011-03-14 20:08:15 +00:00
parent f6c6e7eb75
commit 0316dc67e3
7 changed files with 307 additions and 10 deletions

View File

@ -14,11 +14,12 @@
cylindricalLens.h cylindricalLens.I \
fisheyeLens.h fisheyeLens.I \
nonlinearImager.h nonlinearImager.I \
oSphereLens.h oSphereLens.I \
pSphereLens.h pSphereLens.I
#define INCLUDED_SOURCES \
config_distort.cxx cylindricalLens.cxx fisheyeLens.cxx nonlinearImager.cxx \
projectionScreen.cxx pSphereLens.cxx
projectionScreen.cxx oSphereLens.cxx pSphereLens.cxx
#define INSTALL_HEADERS

View File

@ -16,6 +16,7 @@
#include "cylindricalLens.h"
#include "fisheyeLens.h"
#include "pSphereLens.h"
#include "oSphereLens.h"
#include "projectionScreen.h"
#include "dconfig.h"
@ -55,5 +56,6 @@ init_libdistort() {
CylindricalLens::init_type();
FisheyeLens::init_type();
PSphereLens::init_type();
OSphereLens::init_type();
ProjectionScreen::init_type();
}

View File

@ -2,6 +2,7 @@
#include "config_distort.cxx"
#include "cylindricalLens.cxx"
#include "fisheyeLens.cxx"
#include "oSphereLens.cxx"
#include "pSphereLens.cxx"
#include "nonlinearImager.cxx"
#include "projectionScreen.cxx"

42
panda/src/distort/oSphereLens.I Executable file
View File

@ -0,0 +1,42 @@
// Filename: oSphereLens.I
// Created by: drose (25Feb11)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE OSphereLens::
OSphereLens() {
}
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE OSphereLens::
OSphereLens(const OSphereLens &copy) : Lens(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void OSphereLens::
operator = (const OSphereLens &copy) {
Lens::operator = (copy);
}

178
panda/src/distort/oSphereLens.cxx Executable file
View File

@ -0,0 +1,178 @@
// Filename: oSphereLens.cxx
// Created by: drose (25Feb11)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "oSphereLens.h"
#include "deg_2_rad.h"
TypeHandle OSphereLens::_type_handle;
// This is the focal-length constant for fisheye lenses. See
// fisheyeLens.cxx.
static const float ospherical_k = 60.0f;
// focal_length = film_size * ospherical_k / fov;
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::make_copy
// Access: Public, Virtual
// Description: Allocates a new Lens just like this one.
////////////////////////////////////////////////////////////////////
PT(Lens) OSphereLens::
make_copy() const {
return new OSphereLens(*this);
}
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::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 OSphereLens::
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();
float angle = f[0] * cylindrical_k / focal_length;
float sinAngle, cosAngle;
csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
// Define a unit vector that represents the vector corresponding to
// this point.
LPoint3f v(sinAngle, cosAngle, 0.0f);
near_point = (v * get_near());
far_point = (v * get_far());
near_point[2] = f[1] / focal_length;
far_point[2] = f[1] / focal_length;
// 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 = near_point * lens_mat;
far_point = far_point * lens_mat;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::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 OSphereLens::
project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
// First, account for any rotations, etc. on the lens.
LPoint3f p = point3d * get_lens_mat_inv();
float dist = p.length();
if (dist == 0.0f) {
point2d.set(0.0f, 0.0f, 0.0f);
return false;
}
LPoint3f v3 = p / 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]);
point2d.set
(
// The x position is the angle about the Z axis.
rad_2_deg(catan2(xy[0], xy[1])) * focal_length / ospherical_k,
// The y position is the Z height.
// distance.
p[2] * focal_length,
// 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: OSphereLens::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 OSphereLens::
fov_to_film(float fov, float focal_length, bool) const {
return focal_length * fov / ospherical_k;
}
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::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 OSphereLens::
fov_to_focal_length(float fov, float film_size, bool) const {
return film_size * ospherical_k / fov;
}
////////////////////////////////////////////////////////////////////
// Function: OSphereLens::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 OSphereLens::
film_to_fov(float film_size, float focal_length, bool) const {
return film_size * ospherical_k / focal_length;
}

74
panda/src/distort/oSphereLens.h Executable file
View File

@ -0,0 +1,74 @@
// Filename: oSphereLens.h
// Created by: drose (25Feb11)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef OSPHERELENS_H
#define OSPHERELENS_H
#include "pandabase.h"
#include "lens.h"
////////////////////////////////////////////////////////////////////
// Class : OSphereLens
// Description : A OSphereLens 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 OSphereLens is similar to a Cylindrical lens and
// PSphereLens, except that it is orthographic in the
// vertical direction.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAFX OSphereLens : public Lens {
PUBLISHED:
INLINE OSphereLens();
public:
INLINE OSphereLens(const OSphereLens &copy);
INLINE void operator = (const OSphereLens &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, "OSphereLens",
Lens::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "oSphereLens.I"
#endif

View File

@ -19,8 +19,7 @@ TypeHandle PSphereLens::_type_handle;
// This is the focal-length constant for fisheye lenses. See
// fisheyeLens.cxx.
static const float spherical_k = 60.0f;
// focal_length = film_size * spherical_k / fov;
static const float pspherical_k = 60.0f;
////////////////////////////////////////////////////////////////////
@ -61,8 +60,8 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
// 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] * spherical_k / focal_length, LVector3f(1.0f, 0.0f, 0.0f)) *
LMatrix3f::rotate_mat(f[0] * spherical_k / focal_length, LVector3f(0.0f, 0.0f, -1.0f));
LMatrix3f::rotate_mat(f[1] * pspherical_k / focal_length, LVector3f(1.0f, 0.0f, 0.0f)) *
LMatrix3f::rotate_mat(f[0] * pspherical_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.
@ -117,9 +116,9 @@ project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
point2d.set
(
// The x position is the angle about the Z axis.
rad_2_deg(catan2(xy[0], xy[1])) * focal_length / spherical_k,
rad_2_deg(catan2(xy[0], xy[1])) * focal_length / pspherical_k,
// The y position is the angle about the X axis.
rad_2_deg(catan2(yz[1], yz[0])) * focal_length / spherical_k,
rad_2_deg(catan2(yz[1], yz[0])) * focal_length / pspherical_k,
// Z is the distance scaled into the range (1, -1).
(get_near() - dist) / (get_far() - get_near())
);
@ -144,7 +143,7 @@ project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
////////////////////////////////////////////////////////////////////
float PSphereLens::
fov_to_film(float fov, float focal_length, bool) const {
return focal_length * fov / spherical_k;
return focal_length * fov / pspherical_k;
}
////////////////////////////////////////////////////////////////////
@ -158,7 +157,7 @@ fov_to_film(float fov, float focal_length, bool) const {
////////////////////////////////////////////////////////////////////
float PSphereLens::
fov_to_focal_length(float fov, float film_size, bool) const {
return film_size * spherical_k / fov;
return film_size * pspherical_k / fov;
}
////////////////////////////////////////////////////////////////////
@ -172,5 +171,5 @@ fov_to_focal_length(float fov, float film_size, bool) const {
////////////////////////////////////////////////////////////////////
float PSphereLens::
film_to_fov(float film_size, float focal_length, bool) const {
return film_size * spherical_k / focal_length;
return film_size * pspherical_k / focal_length;
}