new distort library, separate out pandafx

This commit is contained in:
David Rose 2001-12-12 19:49:15 +00:00
parent b7857c9a34
commit c5ec803f6f
25 changed files with 1520 additions and 46 deletions

View File

@ -15,7 +15,7 @@
gsgmisc light linmath mathutil net \
parametrics pnm \
pnmimagetypes pnmimage sgattrib sgmanip sgraph sgraphutil \
switchnode text tform tiff lerp loader putil effects \
switchnode text tform tiff lerp loader putil \
audio pgui pandabase

View File

@ -0,0 +1,16 @@
// DIR_TYPE "metalib" indicates we are building a shared library that
// consists mostly of references to other shared libraries. Under
// Windows, this directly produces a DLL (as opposed to the regular
// src libraries, which don't produce anything but a pile of OBJ files
// under Windows).
#define DIR_TYPE metalib
#define BUILDING_DLL BUILDING_PANDAFX
#define COMPONENT_LIBS \
distort effects
#begin metalib_target
#define TARGET pandafx
#define SOURCES pandafx.cxx
#end metalib_target

View File

@ -0,0 +1,21 @@
// Filename: pandafx.cxx
// Created by: drose (11Dec01)
//
////////////////////////////////////////////////////////////////////
#include "pandafx.h"
#include <config_distort.h>
////////////////////////////////////////////////////////////////////
// Function: init_libpandafx
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_libpandafx() {
init_libdistort();
}

View File

@ -0,0 +1,13 @@
// Filename: pandafx.h
// Created by: drose (11Dec01)
//
////////////////////////////////////////////////////////////////////
#ifndef PANDAFX_H
#define PANDAFX_H
#include <pandabase.h>
EXPCL_PANDAFX void init_libpandafx();
#endif

View File

@ -0,0 +1,20 @@
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
dtoolutil:c dtoolbase:c dtool:m
#begin lib_target
#define TARGET distort
#define LOCAL_LIBS \
sgraphutil sgraph sgattrib gobj linmath
#define SOURCES \
config_distort.cxx config_distort.h \
cylindricalLens.cxx cylindricalLens.h cylindricalLens.I \
fisheyeLens.cxx fisheyeLens.h fisheyeLens.I \
projectionScreen.cxx projectionScreen.h projectionScreen.I
#define INSTALL_HEADERS
#define IGATESCAN all
#end lib_target

View File

@ -0,0 +1,52 @@
// Filename: config_distort.cxx
// Created by: drose (11Dec01)
//
////////////////////////////////////////////////////////////////////
//
// 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 "config_distort.h"
#include "cylindricalLens.h"
#include "fisheyeLens.h"
#include "projectionScreen.h"
#include "dconfig.h"
Configure(config_distort);
NotifyCategoryDef(distort, "");
ConfigureFn(config_distort) {
init_libdistort();
}
////////////////////////////////////////////////////////////////////
// Function: init_libdistort
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_libdistort() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
CylindricalLens::init_type();
FisheyeLens::init_type();
ProjectionScreen::init_type();
}

View File

@ -0,0 +1,29 @@
// Filename: config_distort.h
// Created by: drose (11Dec01)
//
////////////////////////////////////////////////////////////////////
//
// 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 CONFIG_DISTORT_H
#define CONFIG_DISTORT_H
#include "pandabase.h"
#include "notifyCategoryProxy.h"
NotifyCategoryDecl(distort, EXPCL_PANDAFX, EXPTP_PANDAFX);
extern EXPCL_PANDAFX void init_libdistort();
#endif /* CONFIG_DISTORT_H */

View File

@ -0,0 +1,46 @@
// Filename: cylindricalLens.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: CylindricalLens::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CylindricalLens::
CylindricalLens() {
}
////////////////////////////////////////////////////////////////////
// Function: CylindricalLens::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CylindricalLens::
CylindricalLens(const CylindricalLens &copy) : Lens(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: CylindricalLens::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CylindricalLens::
operator = (const CylindricalLens &copy) {
Lens::operator = (copy);
}

View File

@ -0,0 +1,190 @@
// Filename: cylindricalLens.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 "cylindricalLens.h"
#include "deg_2_rad.h"
TypeHandle CylindricalLens::_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: CylindricalLens::make_copy
// Access: Public, Virtual
// Description: Allocates a new Lens just like this one.
////////////////////////////////////////////////////////////////////
PT(Lens) CylindricalLens::
make_copy() const {
return new CylindricalLens(*this);
}
////////////////////////////////////////////////////////////////////
// Function: CylindricalLens::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 CylindricalLens::
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] * k / focal_length;
float sinAngle, cosAngle;
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.
LPoint3f v(sinAngle, cosAngle, 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 = (v * get_near()) * lens_mat;
far_point = (v * get_far()) * lens_mat;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CylindricalLens::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 CylindricalLens::
project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
// First, account for any rotations, etc. on the lens.
LPoint3f p = point3d * get_lens_mat_inv();
// 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(p[0], p[1]);
// The perspective distance is the length of this vector in the XY
// plane.
float pdist = xy.length();
if (pdist == 0.0f) {
point2d.set(0.0f, 0.0f, 0.0f);
return false;
}
float focal_length = get_focal_length();
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 Z height divided by the perspective
// distance.
p[2] * focal_length / pdist,
// Z is the perspective distance scaled into the range (1, -1).
(get_near() - pdist) / (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: CylindricalLens::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 CylindricalLens::
fov_to_film(float fov, float focal_length, bool horiz) const {
if (horiz) {
return focal_length * fov / k;
} else {
return (ctan(deg_2_rad(fov * 0.5f)) * focal_length) * 2.0f;
}
}
////////////////////////////////////////////////////////////////////
// Function: CylindricalLens::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 CylindricalLens::
fov_to_focal_length(float fov, float film_size, bool horiz) const {
if (horiz) {
return film_size * k / fov;
} else {
return film_size * 0.5f / ctan(deg_2_rad(fov * 0.5f));
}
}
////////////////////////////////////////////////////////////////////
// Function: CylindricalLens::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 CylindricalLens::
film_to_fov(float film_size, float focal_length, bool horiz) const {
if (horiz) {
return film_size * k / focal_length;
} else {
return rad_2_deg(catan(film_size * 0.5f / focal_length)) * 2.0f;
}
}

View File

@ -0,0 +1,84 @@
// Filename: cylindricalLens.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 CYLINDRICALLENS_H
#define CYLINDRICALLENS_H
#include "pandabase.h"
#include "lens.h"
////////////////////////////////////////////////////////////////////
// Class : CylindricalLens
// Description : A cylindrical lens. This is the kind of lens
// generally used for extremely wide panoramic shots.
// It behaves like a normal perspective lens in the
// vertical direction, but it is non-linear in the
// horizontal dimension: a point on the film corresponds
// to a point in space in linear proportion to its angle
// to the camera, not to its straight-line distance from
// the center.
//
// This allows up to 360 degree lenses in the horizontal
// dimension, with relatively little distortion. The
// distortion is not very apparent between two
// relatively nearby points on the film, but it becomes
// increasingly evident as you compare points widely
// spaced on the film.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAFX CylindricalLens : public Lens {
PUBLISHED:
INLINE CylindricalLens();
public:
INLINE CylindricalLens(const CylindricalLens &copy);
INLINE void operator = (const CylindricalLens &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, "CylindricalLens",
Lens::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "cylindricalLens.I"
#endif

View File

@ -0,0 +1,46 @@
// Filename: fisheyeLens.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: FisheyeLens::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE FisheyeLens::
FisheyeLens() {
}
////////////////////////////////////////////////////////////////////
// Function: FisheyeLens::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE FisheyeLens::
FisheyeLens(const FisheyeLens &copy) : Lens(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: FisheyeLens::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FisheyeLens::
operator = (const FisheyeLens &copy) {
Lens::operator = (copy);
}

View File

@ -0,0 +1,228 @@
// Filename: fisheyeLens.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 "fisheyeLens.h"
#include "deg_2_rad.h"
TypeHandle FisheyeLens::_type_handle;
// This is the focal-length constant for fisheye lenses. The focal
// length of a fisheye lens relates to its fov by the equation:
// w = Fd/k
// Where w is the width of the negative, F is the focal length, and d
// is the total field of view in degrees.
// k is chosen to make the focal lengths for a fisheye lens roughly
// correspond to the equivalent field of view for a conventional,
// perspective lens. It was determined empirically by simple
// examination of a couple of actual lenses for 35mm film. I don't
// know how well this extends to other lenses and other negative
// sizes.
static const float k = 60.0f;
// focal_length = film_size * k / fov;
////////////////////////////////////////////////////////////////////
// Function: FisheyeLens::make_copy
// Access: Public, Virtual
// Description: Allocates a new Lens just like this one.
////////////////////////////////////////////////////////////////////
PT(Lens) FisheyeLens::
make_copy() const {
return new FisheyeLens(*this);
}
////////////////////////////////////////////////////////////////////
// Function: FisheyeLens::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 FisheyeLens::
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();
// First, get the vector from the center of the film to the point,
// and normalize it.
LVector2f v2(f[0], f[1]);
LPoint3f v;
float r = v2.length();
if (r == 0.0f) {
// Special case: directly forward.
v.set(0.0f, 1.0f, 0.0f);
} else {
v2 /= r;
// Now get the point r units around the circle in the YZ plane.
float focal_length = get_focal_length();
float angle = r * k / focal_length;
float sinAngle, cosAngle;
csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
LVector3f p(0.0, cosAngle, sinAngle);
// And rotate this point around the Y axis.
v.set(p[0]*v2[1] + p[2]*v2[0],
p[1],
p[2]*v2[1] - p[0]*v2[0]);
}
// 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: FisheyeLens::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 FisheyeLens::
project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
// First, account for any rotations, etc. on the lens.
LVector3f v2 = point3d * get_lens_mat_inv();
// A fisheye lens projection has the property that the distance from
// the center point to any other point on the projection is
// proportional to the actual distance on the sphere along the great
// circle. Also, the angle to the point on the projection is equal
// to the angle to the point on the sphere.
// First, get the straight-line distance from the lens, and use it
// to normalize the vector.
float dist = v2.length();
v2 /= dist;
// Now, project the point into the XZ plane and measure its angle
// to the Z axis. This is the same angle it will have to the
// vertical axis on the film.
LVector2f y(v2[0], v2[2]);
y.normalize();
if (y == LVector2f(0.0f, 0.0f)) {
// Special case. This point is either directly ahead or directly
// behind.
point2d.set(0.0f, 0.0f,
(get_near() - dist) / (get_far() - get_near()));
return v2[1] >= 0.0f;
}
// Now bring the vector into the YZ plane by rotating about the Y
// axis.
LVector2f x(v2[1], v2[0]*y[0]+v2[2]*y[1]);
// Now the angle of x to the forward vector represents the distance
// along the great circle to the point.
float r = 90.0f - rad_2_deg(catan2(x[0], x[1]));
float focal_length = get_focal_length();
float factor = r * focal_length / k;
point2d.set
(y[0] * factor,
y[1] * factor,
// 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: FisheyeLens::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 FisheyeLens::
fov_to_film(float fov, float focal_length, bool) const {
return focal_length * fov / k;
}
////////////////////////////////////////////////////////////////////
// Function: FisheyeLens::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 FisheyeLens::
fov_to_focal_length(float fov, float film_size, bool) const {
return film_size * k / fov;
}
////////////////////////////////////////////////////////////////////
// Function: FisheyeLens::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 FisheyeLens::
film_to_fov(float film_size, float focal_length, bool) const {
return film_size * k / focal_length;
}

View File

@ -0,0 +1,74 @@
// Filename: fisheyeLens.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 FISHEYELENS_H
#define FISHEYELENS_H
#include "pandabase.h"
#include "lens.h"
////////////////////////////////////////////////////////////////////
// Class : FisheyeLens
// Description : A fisheye lens. This nonlinear lens introduces a
// spherical distortion to the image, which is minimal
// at small angles from the lens, and increases at
// larger angles from the lens. The field of view may
// extend to 360 degrees.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAFX FisheyeLens : public Lens {
PUBLISHED:
INLINE FisheyeLens();
public:
INLINE FisheyeLens(const FisheyeLens &copy);
INLINE void operator = (const FisheyeLens &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, "FisheyeLens",
Lens::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "fisheyeLens.I"
#endif

View File

@ -0,0 +1,133 @@
// Filename: projectionScreen.I
// Created by: drose (11Dec01)
//
////////////////////////////////////////////////////////////////////
//
// 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: ProjectionScreen::set_projector
// Access: Published
// Description: Specifies the LensNode that is to serve as the
// projector for this screen. The relative position of
// the LensNode to the ProjectionScreen, as well as the
// properties of the lens associated with the LensNode,
// determines the UV's that will be assigned to the
// geometry within the ProjectionScreen.
////////////////////////////////////////////////////////////////////
INLINE void ProjectionScreen::
set_projector(LensNode *projector) {
_projector = projector;
_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::get_projector
// Access: Published
// Description: Returns the LensNode that is to serve as the
// projector for this screen, or NULL if no LensNode is
// associated.
////////////////////////////////////////////////////////////////////
INLINE LensNode *ProjectionScreen::
get_projector() const {
return _projector;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::set_vignette_on
// Access: Published
// Description: Specifies whether vertex-based vignetting should be
// on. When this is enabled, vertex color will be set
// on the screen vertices to color the screen two
// distinct colors, usually white and black, for the
// parts of the screen in front of and outside the lens'
// frustum, respectively. When this is not enabled, the
// screen color will be left alone.
//
// This effect generally looks terrible, but it does
// at least make the boundaries of the lens clear.
////////////////////////////////////////////////////////////////////
INLINE void ProjectionScreen::
set_vignette_on(bool vignette_on) {
_vignette_on = vignette_on;
_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::get_vignette_on
// Access: Published
// Description: Returns true if vertex-based vignetting is on, false
// otherwise. See set_vignette_on().
////////////////////////////////////////////////////////////////////
INLINE bool ProjectionScreen::
get_vignette_on() const {
return _vignette_on;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::set_vignette_color
// Access: Published
// Description: Specifies the color the screen will be painted at the
// portions outside of the lens' frustum; i.e. where the
// lens can't see it or illuminate it. This color is
// only used if the vignette_on flag is true; see
// set_vignette_on().
////////////////////////////////////////////////////////////////////
INLINE void ProjectionScreen::
set_vignette_color(const Colorf &vignette_color) {
_vignette_color = vignette_color;
_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::get_vignette_color
// Access: Published
// Description: Returns the color the screen will be painted at the
// portions outside of the lens' frustum. See
// set_vignette_color().
////////////////////////////////////////////////////////////////////
INLINE const Colorf &ProjectionScreen::
get_vignette_color() const {
return _vignette_color;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::set_frame_color
// Access: Published
// Description: Specifies the color the screen will be painted at the
// portions outside of the lens' frustum; i.e. where the
// lens can't see it or illuminate it. This color is
// only used if the vignette_on flag is true; see
// set_vignette_on().
////////////////////////////////////////////////////////////////////
INLINE void ProjectionScreen::
set_frame_color(const Colorf &frame_color) {
_frame_color = frame_color;
_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::get_frame_color
// Access: Published
// Description: Returns the color the screen will be painted at the
// portions outside of the lens' frustum. See
// set_frame_color().
////////////////////////////////////////////////////////////////////
INLINE const Colorf &ProjectionScreen::
get_frame_color() const {
return _frame_color;
}

View File

@ -0,0 +1,376 @@
// Filename: projectionScreen.cxx
// Created by: drose (11Dec01)
//
////////////////////////////////////////////////////////////////////
//
// 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 "projectionScreen.h"
#include "geomNode.h"
#include "geom.h"
#include "geomTristrip.h"
#include "renderRelation.h"
#include "transformTransition.h"
#include "get_rel_pos.h"
TypeHandle ProjectionScreen::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
ProjectionScreen::
ProjectionScreen(const string &name) : NamedNode(name)
{
_vignette_on = false;
_vignette_color.set(0.0f, 0.0f, 0.0f, 1.0f);
_frame_color.set(1.0f, 1.0f, 1.0f, 1.0f);
_computed_rel_top_mat = false;
_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
ProjectionScreen::
~ProjectionScreen() {
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
ProjectionScreen::
ProjectionScreen(const ProjectionScreen &copy) :
NamedNode(copy),
_projector(copy._projector),
_vignette_on(copy._vignette_on),
_vignette_color(copy._vignette_color),
_frame_color(copy._frame_color)
{
_computed_rel_top_mat = false;
_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void ProjectionScreen::
operator = (const ProjectionScreen &copy) {
NamedNode::operator = (copy);
_projector = copy._projector;
_vignette_on = copy._vignette_on;
_vignette_color = copy._vignette_color;
_frame_color = copy._frame_color;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::make_copy
// Access: Public, Virtual
// Description: Returns a newly-allocated Node that is a shallow copy
// of this one. It will be a different Node pointer,
// but its internal data may or may not be shared with
// that of the original Node.
////////////////////////////////////////////////////////////////////
Node *ProjectionScreen::
make_copy() const {
return new ProjectionScreen(*this);
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::app_traverse
// Access: Public, Virtual
// Description: This is called by the App traversal by virtue of the
// ProjectionScreen node's being present in the scene graph.
////////////////////////////////////////////////////////////////////
void ProjectionScreen::
app_traverse(const ArcChain &) {
recompute_if_stale();
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::generate_screen
// Access: Published
// Description: Synthesizes a polygon mesh based on the projection
// area of the indicated projector. This generates a
// new GeomNode and automatically parents it to the
// ProjectionScreen; the new GeomNode is also returned
// for reference.
//
// The specified projector need not be the same as the
// projector given to the ProjectionScreen with
// set_projector() (although this is often what you
// want).
//
// num_x_verts and num_y_verts specify the number of
// vertices to make in the grid across the horizontal
// and vertical dimension of the projector,
// respectively; distance represents the approximate
// distance of the screen from the lens center.
////////////////////////////////////////////////////////////////////
GeomNode *ProjectionScreen::
generate_screen(LensNode *projector, const string &screen_name,
int num_x_verts, int num_y_verts, float distance) {
nassertr(projector != (LensNode *)NULL, NULL);
nassertr(projector->get_lens() != NULL, NULL);
// First, get the relative coordinate space of the projector.
LMatrix4f rel_mat;
get_rel_mat(projector, this, rel_mat);
// Now compute all the vertices for the screen. These are arranged
// in order from left to right and bottom to top.
int num_verts = num_x_verts * num_y_verts;
Lens *lens = projector->get_lens();
float t = (distance - lens->get_near()) / (lens->get_far() - lens->get_near());
PTA_Vertexf coords;
coords.reserve(num_verts);
float x_scale = 2.0f / (num_x_verts - 1);
float y_scale = 2.0f / (num_y_verts - 1);
for (int yi = 0; yi < num_y_verts; yi++) {
for (int xi = 0; xi < num_x_verts; xi++) {
LPoint2f film = LPoint2f((float)xi * x_scale - 1.0f,
(float)yi * y_scale - 1.0f);
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);
}
}
nassertr((int)coords.size() == num_verts, NULL);
// Now synthesize a triangle mesh. We run triangle strips
// horizontally across the grid.
int num_tstrips = (num_y_verts-1);
int tstrip_length = 2*(num_x_verts-1)+2;
PTA_int lengths;
PTA_ushort vindex;
// Set the lengths array. we are creating num_tstrips t-strips,
// each of which has tstrip_length vertices.
lengths.reserve(num_tstrips);
int n;
for (n = 0; n < num_tstrips; n++) {
lengths.push_back(tstrip_length);
}
nassertr((int)lengths.size() == num_tstrips, NULL);
// Now fill up the index array into the vertices. This lays out the
// order of the vertices in each t-strip.
vindex.reserve(num_tstrips * tstrip_length);
n = 0;
int ti, si;
for (ti = 1; ti < num_y_verts; ti++) {
vindex.push_back(ti * num_x_verts);
for (si = 1; si < num_x_verts; si++) {
vindex.push_back((ti - 1) * num_x_verts + (si-1));
vindex.push_back(ti * num_x_verts + si);
}
vindex.push_back((ti - 1) * num_x_verts + (num_x_verts-1));
}
nassertr((int)vindex.size() == num_tstrips * tstrip_length, NULL);
GeomTristrip *geom = new GeomTristrip;
geom->set_num_prims(num_tstrips);
geom->set_lengths(lengths);
geom->set_coords(coords, G_PER_VERTEX, vindex);
// Make it white.
PTA_Colorf colors;
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
geom->set_colors(colors, G_OVERALL);
// Now create a GeomNode to hold this mesh.
GeomNode *geom_node = new GeomNode(screen_name);
geom_node->add_geom(geom);
// And parent it to ourselves.
new RenderRelation(this, geom_node);
_stale = true;
return geom_node;
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::recompute
// Access: Published
// Description: Recomputes all the UV's for geometry below the
// ProjectionScreen node, as if the texture were
// projected from the associated projector.
//
// This function is normally called automatically
// whenever the relevant properties change, so it should
// not normally need to be called directly by the user.
// However, it does no harm to call this if there is any
// doubt.
////////////////////////////////////////////////////////////////////
void ProjectionScreen::
recompute() {
if (_projector != (LensNode *)NULL &&
_projector->get_lens() != (Lens *)NULL) {
_colors.clear();
_colors.push_back(_vignette_color);
_colors.push_back(_frame_color);
recompute_node(this, _rel_top_mat, _computed_rel_top_mat);
// Make sure this flag is set to false for next time.
_computed_rel_top_mat = false;
_projector_lens_change = _projector->get_lens()->get_last_change();
_stale = false;
}
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::recompute_if_stale
// Access: Private
// Description: Calls recompute() only if the relative transform
// between the ProjectionScreen and the projector has
// changed, or if any other relevant property has
// changed.
////////////////////////////////////////////////////////////////////
void ProjectionScreen::
recompute_if_stale() {
if (_projector != (LensNode *)NULL &&
_projector->get_lens() != (Lens *)NULL) {
UpdateSeq lens_change = _projector->get_lens()->get_last_change();
if (_stale || lens_change != _projector_lens_change) {
recompute();
} else {
// Get the relative transform to ensure it hasn't changed.
LMatrix4f top_mat;
get_rel_mat(this, _projector, top_mat);
if (!_rel_top_mat.almost_equal(top_mat)) {
_rel_top_mat = top_mat;
_computed_rel_top_mat = true;
recompute();
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::recompute_node
// Access: Private
// Description: Recurses over all geometry at the indicated node and
// below, looking for GeomNodes that want to have new
// UV's computed. When a new transform space is
// encountered, a new relative matrix is computed.
////////////////////////////////////////////////////////////////////
void ProjectionScreen::
recompute_node(Node *node, LMatrix4f &rel_mat, bool &computed_rel_mat) {
if (node->is_of_type(GeomNode::get_class_type())) {
recompute_geom_node(DCAST(GeomNode, node), rel_mat, computed_rel_mat);
}
// Now recurse on children.
int num_children = node->get_num_children(RenderRelation::get_class_type());
for (int i = 0; i < num_children; i++) {
NodeRelation *arc = node->get_child(RenderRelation::get_class_type(), i);
if (arc->has_transition(TransformTransition::get_class_type())) {
// This arc has a transform; therefore, we must recompute the
// relative matrix from this point.
LMatrix4f new_rel_mat;
bool computed_new_rel_mat = false;
recompute_node(arc->get_child(), new_rel_mat, computed_new_rel_mat);
} else {
// This arc has no transform, so we can use the same transform
// space from before.
recompute_node(arc->get_child(), rel_mat, computed_rel_mat);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::recompute_geom_node
// Access: Private
// Description: Recomputes the UV's just for the indicated GeomNode.
////////////////////////////////////////////////////////////////////
void ProjectionScreen::
recompute_geom_node(GeomNode *node, LMatrix4f &rel_mat, bool &computed_rel_mat) {
if (!computed_rel_mat) {
// All right, time to compute the matrix.
get_rel_mat(node, _projector, rel_mat);
computed_rel_mat = true;
}
int num_geoms = node->get_num_geoms();
for (int i = 0; i < num_geoms; i++) {
dDrawable *drawable = node->get_geom(i);
if (drawable->is_of_type(Geom::get_class_type())) {
recompute_geom(DCAST(Geom, drawable), rel_mat);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: ProjectionScreen::recompute_geom
// Access: Private
// Description: Recomputes the UV's just for the indicated Geom.
////////////////////////////////////////////////////////////////////
void ProjectionScreen::
recompute_geom(Geom *geom, const LMatrix4f &rel_mat) {
static const LMatrix3f LensToUv
(0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 1.0f);
PTA_TexCoordf uvs;
PTA_ushort color_index;
Lens *lens = _projector->get_lens();
nassertv(lens != (Lens *)NULL);
// Iterate through all the vertices in the Geom.
int num_vertices = geom->get_num_vertices();
Geom::VertexIterator vi = geom->make_vertex_iterator();
for (int i = 0; i < num_vertices; i++) {
const Vertexf &vert = geom->get_next_vertex(vi);
// For each vertex, project to the film plane.
LPoint2f film(0.0, 0.0);
bool good = lens->project(vert * rel_mat, film);
// Now the lens gives us coordinates in the range [-1, 1].
// Rescale these to [0, 1].
uvs.push_back(film * LensToUv);
// If we have vignette color in effect, color the vertex according
// to whether it fell in front of the lens or not.
if (_vignette_on) {
color_index.push_back(good ? 1 : 0);
}
}
// Now set the UV's.
geom->set_texcoords(uvs, G_PER_VERTEX);
if (_vignette_on) {
geom->set_colors(_colors, G_PER_VERTEX, color_index);
}
}

View File

@ -0,0 +1,114 @@
// Filename: projectionScreen.h
// Created by: drose (11Dec01)
//
////////////////////////////////////////////////////////////////////
//
// 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 PROJECTIONSCREEN_H
#define PROJECTIONSCREEN_H
#include "pandabase.h"
#include "namedNode.h"
#include "lensNode.h"
class GeomNode;
class Geom;
////////////////////////////////////////////////////////////////////
// Class : ProjectionScreen
// Description : A ProjectionScreen implements a simple system for
// projective texturing. The ProjectionScreen node is
// the parent of a hierarchy of geometry that is
// considered a "screen"; the ProjectionScreen will
// automatically recompute all the UV's on its
// subordinate geometry according to the relative
// position and lens parameters of the indicated
// LensNode.
//
// This does not take advantage of any hardware-assisted
// projective texturing; nor does it presently support
// multitexturing. However, it does support any kind of
// lens, linear or nonlinear, that might be defined
// using the Lens interface, including fisheye and
// cylindrical lenses.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAFX ProjectionScreen : public NamedNode {
PUBLISHED:
ProjectionScreen(const string &name = "");
virtual ~ProjectionScreen();
public:
ProjectionScreen(const ProjectionScreen &copy);
void operator = (const ProjectionScreen &copy);
virtual Node *make_copy() const;
virtual void app_traverse(const ArcChain &chain);
PUBLISHED:
INLINE void set_projector(LensNode *projector);
INLINE LensNode *get_projector() const;
GeomNode *generate_screen(LensNode *projector, const string &screen_name,
int num_x_verts, int num_y_verts, float distance);
INLINE void set_vignette_on(bool vignette_on);
INLINE bool get_vignette_on() const;
INLINE void set_vignette_color(const Colorf &vignette_color);
INLINE const Colorf &get_vignette_color() const;
INLINE void set_frame_color(const Colorf &frame_color);
INLINE const Colorf &get_frame_color() const;
void recompute();
private:
void recompute_if_stale();
void recompute_node(Node *node, LMatrix4f &rel_mat, bool &computed_rel_mat);
void recompute_geom_node(GeomNode *node, LMatrix4f &rel_mat, bool &computed_rel_mat);
void recompute_geom(Geom *geom, const LMatrix4f &rel_mat);
PT(LensNode) _projector;
bool _vignette_on;
Colorf _vignette_color;
Colorf _frame_color;
PTA_Colorf _colors;
LMatrix4f _rel_top_mat;
bool _computed_rel_top_mat;
bool _stale;
UpdateSeq _projector_lens_change;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
NamedNode::init_type();
register_type(_type_handle, "ProjectionScreen",
NamedNode::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "projectionScreen.I"
#endif

View File

@ -14,5 +14,7 @@
#define INSTALL_HEADERS \
config_effects.h lensFlareNode.I lensFlareNode.h
#define IGATESCAN all
#end lib_target

View File

@ -25,6 +25,19 @@ Configure(config_effects);
NotifyCategoryDef(effects, "");
ConfigureFn(config_effects) {
init_libeffects();
}
////////////////////////////////////////////////////////////////////
// Function: init_libeffects
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_libeffects() {
LensFlareNode::init_type();
//Registration of writeable object's creation

View File

@ -23,6 +23,8 @@
#include <pandabase.h>
#include <notifyCategoryProxy.h>
NotifyCategoryDecl(effects, EXPCL_PANDA, EXPTP_PANDA);
NotifyCategoryDecl(effects, EXPCL_PANDAFX, EXPTP_PANDAFX);
extern EXPCL_PANDAFX void init_libeffects();
#endif /* CONFIG_EFFECTS_H */

View File

@ -32,7 +32,7 @@
class GraphicsStateGuardian;
class ClockObject;
class EXPCL_PANDA LensFlareNode : public Node
class EXPCL_PANDAFX LensFlareNode : public Node
{
PUBLISHED:
INLINE LensFlareNode(void);
@ -41,7 +41,6 @@ PUBLISHED:
PTA_float angle_scales, PTA_Colorf colors);
void add_blind(PT(Texture) blind);
INLINE void set_angle_scale(float scale);
INLINE void set_texel_scale(float texel_to_world);
INLINE void set_global_scale(float scale);

View File

@ -47,10 +47,10 @@ PUBLISHED:
ImageBuffer( void ) : dDrawable() { }
virtual ~ImageBuffer( void ) { }
public:
virtual bool read( const string& name ) = 0;
virtual bool write( const string& name = "" ) const = 0;
public:
virtual void config( void ) { WritableConfigurable::config(); }
virtual void copy(GraphicsStateGuardianBase *, const DisplayRegion *)=0;

View File

@ -70,16 +70,16 @@ extrude(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point) cons
//
// 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.
// is filled in), or false otherwise (in which case
// point2d will be filled in with something, which may
// or may not be meaningful).
////////////////////////////////////////////////////////////////////
INLINE bool Lens::
project(const LPoint3f &point3d, LPoint2f &point2d) const {
LPoint3f result;
if (project_impl(point3d, result)) {
point2d.set(result[0], result[1]);
return true;
}
return false;
bool okflag = project_impl(point3d, result);
point2d.set(result[0], result[1]);
return okflag;
}
////////////////////////////////////////////////////////////////////
@ -90,14 +90,15 @@ project(const LPoint3f &point3d, LPoint2f &point2d) const {
// 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.
// The z coordinate will also be set 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.
// is filled in), or false otherwise (in which case
// point2d will be filled in with something, which may
// or may not be meaningful).
////////////////////////////////////////////////////////////////////
INLINE bool Lens::
project(const LPoint3f &point3d, LPoint3f &point2d) const {

View File

@ -1034,7 +1034,7 @@ get_lens_mat_inv() const {
}
////////////////////////////////////////////////////////////////////
// Function: Lens::extrude
// Function: Lens::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
@ -1080,14 +1080,15 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
// 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.
// The z coordinate will also be set 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.
// is filled in), or false otherwise (in which case
// point2d will be filled in with something, which may
// or may not be meaningful).
////////////////////////////////////////////////////////////////////
bool Lens::
project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
@ -1095,10 +1096,13 @@ project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
LVecBase4f full(point3d[0], point3d[1], point3d[2], 1.0f);
full = projection_mat.xform(full);
if (full[3] == 0.0f) {
point2d.set(0.0f, 0.0f, 0.0f);
return false;
}
point2d.set(full[0] / full[3], full[1] / full[3], full[2] / full[3]);
return point2d[0] >= -1.0f && point2d[0] <= 1.0f &&
return
full[3] > 0.0f &&
point2d[0] >= -1.0f && point2d[0] <= 1.0f &&
point2d[1] >= -1.0f && point2d[1] <= 1.0f;
}

View File

@ -58,8 +58,8 @@ compute_projection_mat() {
}
float fl = get_focal_length();
float a = (_far_distance + _near_distance) / (_far_distance - _near_distance);
float b = -2.0f * _far_distance * _near_distance / (_far_distance - _near_distance);
float a = (get_far() + get_near()) / (get_far() - get_near());
float b = -2.0f * get_far() * get_near() / (get_far() - get_near());
LMatrix4f canonical;
switch (cs) {

View File

@ -31,12 +31,12 @@
#define EXPTP_PANDA extern
#endif
#ifdef BUILDING_PANDAEXPRESS
#define EXPCL_PANDAEXPRESS __declspec(dllexport)
#define EXPTP_PANDAEXPRESS
#ifdef BUILDING_PANDADX
#define EXPCL_PANDADX __declspec(dllexport)
#define EXPTP_PANDADX
#else
#define EXPCL_PANDAEXPRESS __declspec(dllimport)
#define EXPTP_PANDAEXPRESS extern
#define EXPCL_PANDADX __declspec(dllimport)
#define EXPTP_PANDADX extern
#endif
#ifdef BUILDING_PANDAEGG
@ -47,12 +47,20 @@
#define EXPTP_PANDAEGG extern
#endif
#ifdef BUILDING_PANDAPHYSICS
#define EXPCL_PANDAPHYSICS __declspec(dllexport)
#define EXPTP_PANDAPHYSICS
#ifdef BUILDING_PANDAEXPRESS
#define EXPCL_PANDAEXPRESS __declspec(dllexport)
#define EXPTP_PANDAEXPRESS
#else
#define EXPCL_PANDAPHYSICS __declspec(dllimport)
#define EXPTP_PANDAPHYSICS extern
#define EXPCL_PANDAEXPRESS __declspec(dllimport)
#define EXPTP_PANDAEXPRESS extern
#endif
#ifdef BUILDING_PANDAFX
#define EXPCL_PANDAFX __declspec(dllexport)
#define EXPTP_PANDAFX
#else
#define EXPCL_PANDAFX __declspec(dllimport)
#define EXPTP_PANDAFX extern
#endif
#ifdef BUILDING_PANDAGL
@ -71,12 +79,12 @@
#define EXPTP_PANDAGLUT extern
#endif
#ifdef BUILDING_PANDADX
#define EXPCL_PANDADX __declspec(dllexport)
#define EXPTP_PANDADX
#ifdef BUILDING_PANDAPHYSICS
#define EXPCL_PANDAPHYSICS __declspec(dllexport)
#define EXPTP_PANDAPHYSICS
#else
#define EXPCL_PANDADX __declspec(dllimport)
#define EXPTP_PANDADX extern
#define EXPCL_PANDAPHYSICS __declspec(dllimport)
#define EXPTP_PANDAPHYSICS extern
#endif
#ifdef BUILDING_PANDARIB
@ -116,14 +124,17 @@
#define EXPCL_PANDA
#define EXPTP_PANDA
#define EXPCL_PANDAEXPRESS
#define EXPTP_PANDAEXPRESS
#define EXPCL_PANDADX
#define EXPTP_PANDADX
#define EXPCL_PANDAEGG
#define EXPTP_PANDAEGG
#define EXPCL_PANDAPHYSICS
#define EXPTP_PANDAPHYSICS
#define EXPCL_PANDAEXPRESS
#define EXPTP_PANDAEXPRESS
#define EXPCL_PANDAFX
#define EXPTP_PANDAFX
#define EXPCL_PANDAGL
#define EXPTP_PANDAGL
@ -131,8 +142,8 @@
#define EXPCL_PANDAGLUT
#define EXPTP_PANDAGLUT
#define EXPCL_PANDADX
#define EXPTP_PANDADX
#define EXPCL_PANDAPHYSICS
#define EXPTP_PANDAPHYSICS
#define EXPCL_PANDARIB
#define EXPTP_PANDARIB