mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -04:00
FisheyeMaker
This commit is contained in:
parent
4cc9dba771
commit
180bf37cf5
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
cardMaker.I cardMaker.h \
|
cardMaker.I cardMaker.h \
|
||||||
|
fisheyeMaker.I fisheyeMaker.h \
|
||||||
config_grutil.h \
|
config_grutil.h \
|
||||||
frameRateMeter.I frameRateMeter.h \
|
frameRateMeter.I frameRateMeter.h \
|
||||||
lineSegs.I lineSegs.h \
|
lineSegs.I lineSegs.h \
|
||||||
@ -20,6 +21,7 @@
|
|||||||
|
|
||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
cardMaker.cxx \
|
cardMaker.cxx \
|
||||||
|
fisheyeMaker.cxx \
|
||||||
config_grutil.cxx \
|
config_grutil.cxx \
|
||||||
frameRateMeter.cxx \
|
frameRateMeter.cxx \
|
||||||
openCVTexture.cxx \
|
openCVTexture.cxx \
|
||||||
@ -28,6 +30,7 @@
|
|||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
cardMaker.I cardMaker.h \
|
cardMaker.I cardMaker.h \
|
||||||
|
fisheyeMaker.I fisheyeMaker.h \
|
||||||
frameRateMeter.I frameRateMeter.h \
|
frameRateMeter.I frameRateMeter.h \
|
||||||
lineSegs.I lineSegs.h \
|
lineSegs.I lineSegs.h \
|
||||||
multitexReducer.I multitexReducer.h \
|
multitexReducer.I multitexReducer.h \
|
||||||
|
74
panda/src/grutil/fisheyeMaker.I
Normal file
74
panda/src/grutil/fisheyeMaker.I
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Filename: fisheyeMaker.I
|
||||||
|
// Created by: drose (3Oct05)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE FisheyeMaker::
|
||||||
|
FisheyeMaker(const string &name) : Namable(name) {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE FisheyeMaker::
|
||||||
|
~FisheyeMaker() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::set_num_vertices
|
||||||
|
// Access: Public
|
||||||
|
// Description: Specifies the approximate number of vertices to be
|
||||||
|
// used to generate the rose. This is the approximate
|
||||||
|
// number of vertices that will be located within the
|
||||||
|
// rose's unit circle, not counting the inscribing
|
||||||
|
// square (if any). The actual number of vertices used
|
||||||
|
// may be +/- 25% of this value.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FisheyeMaker::
|
||||||
|
set_num_vertices(int num_vertices) {
|
||||||
|
_num_vertices = num_vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::set_square_inscribed
|
||||||
|
// Access: Public
|
||||||
|
// Description: Sets the flag that indicates whether the rose should
|
||||||
|
// be inscribed within a square. When this is true, an
|
||||||
|
// additional square is generated to inscribed the
|
||||||
|
// circular rose, with the indicated "radius" (the sides
|
||||||
|
// of the square will be 2 * square_radius). The
|
||||||
|
// texture coordinates of the square will uniformly map
|
||||||
|
// to the back pole of the cube map.
|
||||||
|
//
|
||||||
|
// This is mainly useful to provide a good uniform
|
||||||
|
// background color for a sphere map so that it does not
|
||||||
|
// have a sharp circular edge that might produce
|
||||||
|
// artifacts due to numerical imprecision when mapping.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FisheyeMaker::
|
||||||
|
set_square_inscribed(bool square_inscribed, float square_radius) {
|
||||||
|
_square_inscribed = true;
|
||||||
|
_square_radius = square_radius;
|
||||||
|
}
|
410
panda/src/grutil/fisheyeMaker.cxx
Normal file
410
panda/src/grutil/fisheyeMaker.cxx
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
// Filename: fisheyeMaker.cxx
|
||||||
|
// Created by: drose (3Oct05)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "fisheyeMaker.h"
|
||||||
|
#include "geomNode.h"
|
||||||
|
#include "geom.h"
|
||||||
|
#include "geomTristrips.h"
|
||||||
|
#include "geomVertexWriter.h"
|
||||||
|
#include "geomVertexFormat.h"
|
||||||
|
#include "geomVertexArrayFormat.h"
|
||||||
|
#include "internalName.h"
|
||||||
|
#include "luse.h"
|
||||||
|
#include "cmath.h"
|
||||||
|
#include "mathNumbers.h"
|
||||||
|
#include "graphicsStateGuardian.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::reset
|
||||||
|
// Access: Public
|
||||||
|
// Description: Resets all the parameters to their initial defaults.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FisheyeMaker::
|
||||||
|
reset() {
|
||||||
|
set_fov(360.0);
|
||||||
|
_num_vertices = 1000;
|
||||||
|
_square_inscribed = false;
|
||||||
|
_square_radius = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::set_fov
|
||||||
|
// Access: Public
|
||||||
|
// Description: Specifies the field of view of the fisheye
|
||||||
|
// projection. A sphere map will have a 360-degree
|
||||||
|
// field of view (and this is the default).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FisheyeMaker::
|
||||||
|
set_fov(float fov) {
|
||||||
|
_fov = fov;
|
||||||
|
_half_fov_rad = deg_2_rad(_fov * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::generate
|
||||||
|
// Access: Public
|
||||||
|
// Description: Generates a GeomNode that renders the specified
|
||||||
|
// geometry.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(PandaNode) FisheyeMaker::
|
||||||
|
generate() {
|
||||||
|
// Get some system-imposed limits.
|
||||||
|
int max_vertices_per_array = 100;
|
||||||
|
int max_vertices_per_primitive = 10000;
|
||||||
|
bool prefers_triangle_strips = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
GraphicsStateGuardian *global_gsg = GraphicsStateGuardian::get_global_gsg();
|
||||||
|
if (global_gsg != (GraphicsStateGuardian *)NULL) {
|
||||||
|
max_vertices_per_array = global_gsg->get_max_vertices_per_array();
|
||||||
|
max_vertices_per_primitive = global_gsg->get_max_vertices_per_primitive();
|
||||||
|
prefers_triangle_strips = global_gsg->prefers_triangle_strips();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// We will generate a rose of radius 1, with vertices approximately
|
||||||
|
// evenly distributed throughout.
|
||||||
|
|
||||||
|
// Since we will have _num_vertices filling the circle, and the area
|
||||||
|
// of a circle of radius 1 is A = pi*r^2 = pi, it follows that the
|
||||||
|
// number of vertices per square unit is (_num_vertices / pi), and
|
||||||
|
// thus the number of vertices per linear unit is the square root of
|
||||||
|
// that.
|
||||||
|
float vertices_per_unit = csqrt(_num_vertices / MathNumbers::pi_f);
|
||||||
|
float two_pi = 2.0f * MathNumbers::pi_f;
|
||||||
|
|
||||||
|
// The rose will be made up of concentric rings, originating from
|
||||||
|
// the center, to a radius of 1.0.
|
||||||
|
int num_rings = (int)floor(vertices_per_unit + 0.5f);
|
||||||
|
|
||||||
|
CPT(GeomVertexFormat) format = GeomVertexFormat::register_format
|
||||||
|
(new GeomVertexArrayFormat
|
||||||
|
(InternalName::get_vertex(), 3,
|
||||||
|
Geom::NT_float32, Geom::C_point,
|
||||||
|
InternalName::get_texcoord(), 3,
|
||||||
|
Geom::NT_float32, Geom::C_texcoord));
|
||||||
|
|
||||||
|
PT(GeomVertexData) vdata =
|
||||||
|
new GeomVertexData(get_name(), format, Geom::UH_static);
|
||||||
|
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||||
|
GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||||
|
|
||||||
|
PT(Geom) geom = new Geom(vdata);
|
||||||
|
PT(GeomPrimitive) tristrips = new GeomTristrips(Geom::UH_static);
|
||||||
|
tristrips->set_shade_model(Geom::SM_uniform);
|
||||||
|
|
||||||
|
PT(GeomNode) geom_node = new GeomNode(get_name());
|
||||||
|
|
||||||
|
int last_ring_size = 3;
|
||||||
|
int last_ring_vertex = 0;
|
||||||
|
float last_r = 1.0f / (float)num_rings;
|
||||||
|
|
||||||
|
// Make the first triangle. We actually make a one-triangle strip,
|
||||||
|
// but that seems more sensible than making a single isolated
|
||||||
|
// triangle.
|
||||||
|
for (int vi = 0; vi < last_ring_size; ++vi) {
|
||||||
|
add_vertex(vertex, texcoord, last_r,
|
||||||
|
two_pi * (float)vi / (float)last_ring_size);
|
||||||
|
tristrips->add_vertex(vi);
|
||||||
|
}
|
||||||
|
// Actually, we need to add one more degenerate triangle to make it
|
||||||
|
// an even-length tristrip.
|
||||||
|
tristrips->add_vertex(2);
|
||||||
|
tristrips->close_primitive();
|
||||||
|
|
||||||
|
// Now make all of the rings.
|
||||||
|
for (int ri = 1; ri < num_rings; ++ri) {
|
||||||
|
float r = (float)(ri + 1) / (float)num_rings;
|
||||||
|
|
||||||
|
// The circumference of a ring of radius r is 2*pi*r.
|
||||||
|
float c = two_pi * r;
|
||||||
|
int ring_size = (int)floor(c * vertices_per_unit + 0.5f);
|
||||||
|
|
||||||
|
// Each ring must either have exactly the same number of vertices
|
||||||
|
// as the previous ring, or exactly double.
|
||||||
|
if (ring_size < last_ring_size * 2) {
|
||||||
|
// This one will be the same.
|
||||||
|
ring_size = last_ring_size;
|
||||||
|
} else {
|
||||||
|
// This one will be double.
|
||||||
|
ring_size = last_ring_size * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vdata->get_num_rows() + ring_size > max_vertices_per_array) {
|
||||||
|
// Too many vertices; we need to start a new VertexData.
|
||||||
|
if (tristrips->get_num_vertices() != 0) {
|
||||||
|
geom->add_primitive(tristrips);
|
||||||
|
}
|
||||||
|
if (geom->get_num_primitives() != 0) {
|
||||||
|
if (prefers_triangle_strips) {
|
||||||
|
geom_node->add_geom(geom);
|
||||||
|
} else {
|
||||||
|
geom_node->add_geom(geom->decompose());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vdata = new GeomVertexData(get_name(), format, Geom::UH_static);
|
||||||
|
vertex = GeomVertexWriter(vdata, InternalName::get_vertex());
|
||||||
|
texcoord = GeomVertexWriter(vdata, InternalName::get_texcoord());
|
||||||
|
geom = new Geom(vdata);
|
||||||
|
tristrips = new GeomTristrips(Geom::UH_static);
|
||||||
|
tristrips->set_shade_model(Geom::SM_uniform);
|
||||||
|
|
||||||
|
// Now we need to re-make the previous ring in this VertexData.
|
||||||
|
last_ring_vertex = 0;
|
||||||
|
for (int vi = 0; vi < last_ring_size; ++vi) {
|
||||||
|
add_vertex(vertex, texcoord, last_r,
|
||||||
|
two_pi * (float)vi / (float)last_ring_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now make this ring.
|
||||||
|
int ring_vertex = vdata->get_num_rows();
|
||||||
|
for (int vi = 0; vi < ring_size; ++vi) {
|
||||||
|
add_vertex(vertex, texcoord, r,
|
||||||
|
two_pi * (float)vi / (float)ring_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now draw the triangle strip to connect the rings.
|
||||||
|
if (ring_size == last_ring_size) {
|
||||||
|
// Exactly the same size ring. This one is easy.
|
||||||
|
if ((ring_size + 1) * 2 > max_vertices_per_primitive) {
|
||||||
|
// Actually, we need to subdivide the ring to fit within the
|
||||||
|
// GSG's advertised limits.
|
||||||
|
int piece_size = max_vertices_per_primitive / 2 - 1;
|
||||||
|
int vi = 0;
|
||||||
|
while (vi < ring_size) {
|
||||||
|
int piece_end = min(ring_size + 1, piece_size + 1 + vi);
|
||||||
|
for (int pi = vi; pi < piece_end; ++pi) {
|
||||||
|
tristrips->add_vertex(last_ring_vertex + pi % last_ring_size);
|
||||||
|
tristrips->add_vertex(ring_vertex + pi % ring_size);
|
||||||
|
}
|
||||||
|
tristrips->close_primitive();
|
||||||
|
vi += piece_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// We can fit the entire ring.
|
||||||
|
if (tristrips->get_num_vertices() > 0 &&
|
||||||
|
tristrips->get_num_vertices() + ring_size * 2 > max_vertices_per_primitive) {
|
||||||
|
geom->add_primitive(tristrips);
|
||||||
|
tristrips = new GeomTristrips(Geom::UH_static);
|
||||||
|
tristrips->set_shade_model(Geom::SM_uniform);
|
||||||
|
}
|
||||||
|
for (int vi = 0; vi < ring_size; ++vi) {
|
||||||
|
tristrips->add_vertex(last_ring_vertex + vi);
|
||||||
|
tristrips->add_vertex(ring_vertex + vi);
|
||||||
|
}
|
||||||
|
tristrips->add_vertex(last_ring_vertex);
|
||||||
|
tristrips->add_vertex(ring_vertex);
|
||||||
|
tristrips->close_primitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Exactly double size ring. This is harder; we can't make a
|
||||||
|
// single tristrip that goes all the way around the ring.
|
||||||
|
// Instead, we'll make an alternating series of four-triangle
|
||||||
|
// strips and two-triangle strips around the ring.
|
||||||
|
int vi = 0;
|
||||||
|
while (vi < last_ring_size) {
|
||||||
|
if (tristrips->get_num_vertices() + 10 > max_vertices_per_primitive) {
|
||||||
|
geom->add_primitive(tristrips);
|
||||||
|
tristrips = new GeomTristrips(Geom::UH_static);
|
||||||
|
tristrips->set_shade_model(Geom::SM_uniform);
|
||||||
|
}
|
||||||
|
tristrips->add_vertex(ring_vertex + (vi * 2 + 1) % ring_size);
|
||||||
|
tristrips->add_vertex(ring_vertex + (vi * 2 + 2) % ring_size);
|
||||||
|
tristrips->add_vertex(last_ring_vertex + (vi + 1) % last_ring_size);
|
||||||
|
tristrips->add_vertex(ring_vertex + (vi * 2 + 3) % ring_size);
|
||||||
|
tristrips->add_vertex(last_ring_vertex + (vi + 2) % last_ring_size);
|
||||||
|
tristrips->add_vertex(ring_vertex + (vi * 2 + 4) % ring_size);
|
||||||
|
tristrips->close_primitive();
|
||||||
|
|
||||||
|
tristrips->add_vertex(ring_vertex + (vi * 2 + 4) % ring_size);
|
||||||
|
tristrips->add_vertex(ring_vertex + (vi * 2 + 5) % ring_size);
|
||||||
|
tristrips->add_vertex(last_ring_vertex + (vi + 2) % last_ring_size);
|
||||||
|
tristrips->add_vertex(last_ring_vertex + (vi + 3) % last_ring_size);
|
||||||
|
tristrips->close_primitive();
|
||||||
|
|
||||||
|
vi += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last_ring_size = ring_size;
|
||||||
|
last_ring_vertex = ring_vertex;
|
||||||
|
last_r = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_square_inscribed) {
|
||||||
|
// Make one more "ring", which extends out to the edges of a squre.
|
||||||
|
int ring_size = last_ring_size;
|
||||||
|
|
||||||
|
if (vdata->get_num_rows() + ring_size > max_vertices_per_array) {
|
||||||
|
// Too many vertices; we need to start a new VertexData.
|
||||||
|
if (tristrips->get_num_vertices() != 0) {
|
||||||
|
geom->add_primitive(tristrips);
|
||||||
|
}
|
||||||
|
if (geom->get_num_primitives() != 0) {
|
||||||
|
if (prefers_triangle_strips) {
|
||||||
|
geom_node->add_geom(geom);
|
||||||
|
} else {
|
||||||
|
geom_node->add_geom(geom->decompose());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vdata = new GeomVertexData(get_name(), format, Geom::UH_static);
|
||||||
|
vertex = GeomVertexWriter(vdata, InternalName::get_vertex());
|
||||||
|
texcoord = GeomVertexWriter(vdata, InternalName::get_texcoord());
|
||||||
|
geom = new Geom(vdata);
|
||||||
|
tristrips = new GeomTristrips(Geom::UH_static);
|
||||||
|
tristrips->set_shade_model(Geom::SM_uniform);
|
||||||
|
|
||||||
|
// Now we need to re-make the previous ring in this VertexData.
|
||||||
|
last_ring_vertex = 0;
|
||||||
|
for (int vi = 0; vi < last_ring_size; ++vi) {
|
||||||
|
add_vertex(vertex, texcoord, last_r,
|
||||||
|
two_pi * (float)vi / (float)last_ring_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now make this ring.
|
||||||
|
int ring_vertex = vdata->get_num_rows();
|
||||||
|
for (int vi = 0; vi < ring_size; ++vi) {
|
||||||
|
add_square_vertex(vertex, texcoord,
|
||||||
|
two_pi * (float)vi / (float)ring_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now draw the triangle strip to connect the rings.
|
||||||
|
if ((ring_size + 1) * 2 > max_vertices_per_primitive) {
|
||||||
|
// Actually, we need to subdivide the ring to fit within the
|
||||||
|
// GSG's advertised limits.
|
||||||
|
int piece_size = max_vertices_per_primitive / 2 - 1;
|
||||||
|
int vi = 0;
|
||||||
|
while (vi < ring_size) {
|
||||||
|
int piece_end = min(ring_size + 1, piece_size + 1 + vi);
|
||||||
|
for (int pi = vi; pi < piece_end; ++pi) {
|
||||||
|
tristrips->add_vertex(last_ring_vertex + pi % last_ring_size);
|
||||||
|
tristrips->add_vertex(ring_vertex + pi % ring_size);
|
||||||
|
}
|
||||||
|
tristrips->close_primitive();
|
||||||
|
vi += piece_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// We can fit the entire ring.
|
||||||
|
if (tristrips->get_num_vertices() > 0 &&
|
||||||
|
tristrips->get_num_vertices() + ring_size * 2 > max_vertices_per_primitive) {
|
||||||
|
geom->add_primitive(tristrips);
|
||||||
|
tristrips = new GeomTristrips(Geom::UH_static);
|
||||||
|
tristrips->set_shade_model(Geom::SM_uniform);
|
||||||
|
}
|
||||||
|
for (int vi = 0; vi < ring_size; ++vi) {
|
||||||
|
tristrips->add_vertex(last_ring_vertex + vi);
|
||||||
|
tristrips->add_vertex(ring_vertex + vi);
|
||||||
|
}
|
||||||
|
tristrips->add_vertex(last_ring_vertex);
|
||||||
|
tristrips->add_vertex(ring_vertex);
|
||||||
|
tristrips->close_primitive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tristrips->get_num_vertices() != 0) {
|
||||||
|
geom->add_primitive(tristrips);
|
||||||
|
}
|
||||||
|
if (geom->get_num_primitives() != 0) {
|
||||||
|
if (prefers_triangle_strips) {
|
||||||
|
geom_node->add_geom(geom);
|
||||||
|
} else {
|
||||||
|
geom_node->add_geom(geom->decompose());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return geom_node.p();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::add_vertex
|
||||||
|
// Access: Private
|
||||||
|
// Description: Given a point defined by a radius and an angle in
|
||||||
|
// radians, compute the 2-d coordinates for the vertex
|
||||||
|
// as well as the 3-d texture coordinates, and add both
|
||||||
|
// to the VertexData.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FisheyeMaker::
|
||||||
|
add_vertex(GeomVertexWriter &vertex, GeomVertexWriter &texcoord,
|
||||||
|
float r, float a) {
|
||||||
|
float sina, cosa;
|
||||||
|
csincos(a, &sina, &cosa);
|
||||||
|
|
||||||
|
// The 2-d point is just a point r units from the center of the
|
||||||
|
// circle.
|
||||||
|
LPoint3f point(r * cosa, 0.0f, r * sina);
|
||||||
|
vertex.add_data3f(point);
|
||||||
|
|
||||||
|
// The 3-d point is the same thing, bent through the third dimension
|
||||||
|
// around the surface of a sphere to the point in the back.
|
||||||
|
float b = r * _half_fov_rad;
|
||||||
|
if (b >= MathNumbers::pi_f) {
|
||||||
|
// Special case: we want to stop at the back pole, not continue
|
||||||
|
// around it.
|
||||||
|
texcoord.add_data3f(0, -1, 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
float sinb, cosb;
|
||||||
|
csincos(b, &sinb, &cosb);
|
||||||
|
LPoint3f tc(sinb * cosa, cosb, sinb * sina);
|
||||||
|
texcoord.add_data3f(tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FisheyeMaker::add_square_vertex
|
||||||
|
// Access: Private
|
||||||
|
// Description: Similar to add_vertex(), but it draws the vertex all
|
||||||
|
// the way out to the edge of the square we are
|
||||||
|
// inscribed within, and the texture coordinate is
|
||||||
|
// always the back pole.
|
||||||
|
//
|
||||||
|
// This is just for the purpose of drawing the
|
||||||
|
// inscribing square.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FisheyeMaker::
|
||||||
|
add_square_vertex(GeomVertexWriter &vertex, GeomVertexWriter &texcoord,
|
||||||
|
float a) {
|
||||||
|
float sina, cosa;
|
||||||
|
csincos(a, &sina, &cosa);
|
||||||
|
|
||||||
|
// Extend the 2-d point to the edge of the square of the indicated
|
||||||
|
// size.
|
||||||
|
if (cabs(sina) > cabs(cosa)) {
|
||||||
|
float y = (sina > 0.0f) ? _square_radius : -_square_radius;
|
||||||
|
float x = y * cosa / sina;
|
||||||
|
LPoint3f point(x, 0.0f, y);
|
||||||
|
vertex.add_data3f(point);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
float x = (cosa > 0.0f) ? _square_radius : -_square_radius;
|
||||||
|
float y = x * sina / cosa;
|
||||||
|
LPoint3f point(x, 0.0f, y);
|
||||||
|
vertex.add_data3f(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
texcoord.add_data3f(0, -1, 0);
|
||||||
|
}
|
||||||
|
|
72
panda/src/grutil/fisheyeMaker.h
Normal file
72
panda/src/grutil/fisheyeMaker.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Filename: fisheyeMaker.h
|
||||||
|
// Created by: drose (3Oct05)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef FISHEYEMAKER_H
|
||||||
|
#define FISHEYEMAKER_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "pandaNode.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
#include "namable.h"
|
||||||
|
|
||||||
|
class GeomVertexWriter;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : FisheyeMaker
|
||||||
|
// Description : This class is similar to CardMaker, but instead of
|
||||||
|
// generating ordinary cards, it generates a circular
|
||||||
|
// rose that represents the projection of a 3-D scene
|
||||||
|
// through a fisheye lens. The texture coordinates of
|
||||||
|
// the rose are defined so that each 2-D vertex has a
|
||||||
|
// 3-D UVW that reflects the corresponding position in
|
||||||
|
// 3-D space of that particular vertex.
|
||||||
|
//
|
||||||
|
// This class is particularly suited for converting cube
|
||||||
|
// maps to sphere maps.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA FisheyeMaker : public Namable {
|
||||||
|
PUBLISHED:
|
||||||
|
INLINE FisheyeMaker(const string &name);
|
||||||
|
INLINE ~FisheyeMaker();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void set_fov(float fov);
|
||||||
|
INLINE void set_num_vertices(int num_vertices);
|
||||||
|
INLINE void set_square_inscribed(bool square_inscribed, float square_radius);
|
||||||
|
|
||||||
|
PT(PandaNode) generate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void add_vertex(GeomVertexWriter &vertex, GeomVertexWriter &texcoord,
|
||||||
|
float r, float a);
|
||||||
|
|
||||||
|
void add_square_vertex(GeomVertexWriter &vertex, GeomVertexWriter &texcoord,
|
||||||
|
float a);
|
||||||
|
|
||||||
|
float _fov;
|
||||||
|
float _half_fov_rad;
|
||||||
|
int _num_vertices;
|
||||||
|
bool _square_inscribed;
|
||||||
|
float _square_radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "fisheyeMaker.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
#include "cardMaker.cxx"
|
#include "cardMaker.cxx"
|
||||||
#include "config_grutil.cxx"
|
#include "config_grutil.cxx"
|
||||||
#include "lineSegs.cxx"
|
#include "lineSegs.cxx"
|
||||||
|
#include "fisheyeMaker.cxx"
|
||||||
#include "frameRateMeter.cxx"
|
#include "frameRateMeter.cxx"
|
||||||
#include "openCVTexture.cxx"
|
#include "openCVTexture.cxx"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user