diff --git a/pandatool/src/eggbase/Sources.pp b/pandatool/src/eggbase/Sources.pp index f6c782b2e1..a7e6f04d4c 100644 --- a/pandatool/src/eggbase/Sources.pp +++ b/pandatool/src/eggbase/Sources.pp @@ -8,19 +8,24 @@ #define COMBINED_SOURCES $[TARGET]_composite1.cxx #define SOURCES \ - eggBase.h eggConverter.h eggFilter.h eggMultiBase.h \ - eggMultiFilter.h eggReader.h eggSingleBase.h \ + eggBase.h eggConverter.h eggFilter.h \ + eggMakeSomething.h \ + eggMultiBase.h eggMultiFilter.h \ + eggReader.h eggSingleBase.h \ eggToSomething.h eggWriter.h \ somethingToEgg.h #define INCLUDED_SOURCES \ - eggBase.cxx eggConverter.cxx eggFilter.cxx eggMultiBase.cxx \ + eggBase.cxx eggConverter.cxx eggFilter.cxx \ + eggMakeSomething.cxx \ + eggMultiBase.cxx \ eggMultiFilter.cxx eggReader.cxx eggSingleBase.cxx \ eggToSomething.cxx \ eggWriter.cxx somethingToEgg.cxx #define INSTALL_HEADERS \ eggBase.h eggConverter.h eggFilter.h \ + eggMakeSomething.h \ eggMultiBase.h eggMultiFilter.h \ eggReader.h eggSingleBase.h eggToSomething.h eggWriter.h somethingToEgg.h diff --git a/pandatool/src/eggbase/eggMakeSomething.cxx b/pandatool/src/eggbase/eggMakeSomething.cxx new file mode 100644 index 0000000000..e43203a6b6 --- /dev/null +++ b/pandatool/src/eggbase/eggMakeSomething.cxx @@ -0,0 +1,33 @@ +// Filename: eggMakeSomething.cxx +// Created by: drose (01Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "eggMakeSomething.h" + +//////////////////////////////////////////////////////////////////// +// Function: EggMakeSomething::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +EggMakeSomething:: +EggMakeSomething() : + EggWriter(true, true) +{ + add_normals_options(); + add_transform_options(); +} + diff --git a/pandatool/src/eggbase/eggMakeSomething.h b/pandatool/src/eggbase/eggMakeSomething.h new file mode 100644 index 0000000000..f7c5306962 --- /dev/null +++ b/pandatool/src/eggbase/eggMakeSomething.h @@ -0,0 +1,37 @@ +// Filename: eggMakeSomething.h +// Created by: drose (01Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// 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 EGGMAKESOMETHING_H +#define EGGMAKESOMETHING_H + +#include "pandatoolbase.h" + +#include "eggWriter.h" + +//////////////////////////////////////////////////////////////////// +// Class : EggMakeSomething +// Description : A base class for a family of programs that generate +// egg models of various fundamental shapes. +//////////////////////////////////////////////////////////////////// +class EggMakeSomething : public EggWriter { +public: + EggMakeSomething(); +}; + +#endif + diff --git a/pandatool/src/eggbase/eggbase_composite1.cxx b/pandatool/src/eggbase/eggbase_composite1.cxx index 7a051de172..7f2f3a7295 100644 --- a/pandatool/src/eggbase/eggbase_composite1.cxx +++ b/pandatool/src/eggbase/eggbase_composite1.cxx @@ -2,6 +2,7 @@ #include "eggBase.cxx" #include "eggConverter.cxx" #include "eggFilter.cxx" +#include "eggMakeSomething.cxx" #include "eggMultiBase.cxx" #include "eggMultiFilter.cxx" #include "eggReader.cxx" diff --git a/pandatool/src/eggprogs/Sources.pp b/pandatool/src/eggprogs/Sources.pp index c20369bae1..e96dd9fc8a 100644 --- a/pandatool/src/eggprogs/Sources.pp +++ b/pandatool/src/eggprogs/Sources.pp @@ -31,6 +31,14 @@ #end bin_target +#begin bin_target + #define TARGET egg-make-tube + + #define SOURCES \ + eggMakeTube.cxx eggMakeTube.h + +#end bin_target + #begin bin_target #define LOCAL_LIBS eggcharbase $[LOCAL_LIBS] #define TARGET egg-topstrip diff --git a/pandatool/src/eggprogs/eggMakeTube.cxx b/pandatool/src/eggprogs/eggMakeTube.cxx new file mode 100644 index 0000000000..fecd6343e8 --- /dev/null +++ b/pandatool/src/eggprogs/eggMakeTube.cxx @@ -0,0 +1,272 @@ +// Filename: eggMakeTube.cxx +// Created by: drose (01Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "eggMakeTube.h" +#include "eggGroup.h" +#include "eggVertexPool.h" +#include "eggVertex.h" +#include "eggPolygon.h" +#include "pointerTo.h" +#include "look_at.h" + +//////////////////////////////////////////////////////////////////// +// Function: EggMakeTube::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +EggMakeTube:: +EggMakeTube() { + add_option + ("a", "x,y,z", 0, + "Specify the first endpoint of the tube.", + &EggWriter::dispatch_double_triple, NULL, _point_a); + + add_option + ("b", "x,y,z", 0, + "Specify the second endpoint of the tube.", + &EggWriter::dispatch_double_triple, NULL, _point_a); + + add_option + ("r", "radius", 0, + "Specify the radius of the tube. The tube will extend beyond " + "the endpoints in each direction by the amount of radius.", + &EggWriter::dispatch_double, NULL, &_radius); + + add_option + ("slices", "count", 0, + "Specify the number of slices appearing radially around the tube.", + &EggWriter::dispatch_int, NULL, &_num_slices); + + add_option + ("crings", "count", 0, + "Specify the number of rings appearing in each endcap of the tube.", + &EggWriter::dispatch_int, NULL, &_num_crings); + + add_option + ("trings", "count", 0, + "Specify the number of rings appearing in the cylindrical body " + "of the tube.", + &EggWriter::dispatch_int, NULL, &_num_trings); + + _point_a[0] = 0.0; + _point_a[1] = 0.0; + _point_a[2] = 0.0; + + _point_b[0] = 0.0; + _point_b[1] = 0.0; + _point_b[2] = 0.0; + + _radius = 1.0; + + _num_slices = 8; + _num_crings = 4; + _num_trings = 1; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMakeTube::run +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void EggMakeTube:: +run() { + // We will generate the vertices in the canonical space (along the y + // axis), then transform it to the desired point. + LVector3d direction(_point_b[0] - _point_a[0], + _point_b[1] - _point_a[1], + _point_b[2] - _point_a[2]); + _length = direction.length(); + + // First, create an enclosing group and a vertex pool. + _group = new EggGroup("tube"); + _data.add_child(_group); + + _vpool = new EggVertexPool("tube"); + _group->add_child(_vpool); + + // Generate the first endcap. + int ri, si; + EggVertex *vtx_1; + EggVertex *vtx_2; + + for (ri = 0; ri < _num_crings; ri++) { + vtx_1 = NULL; + vtx_2 = NULL; + for (si = 0; si <= _num_slices; si++) { + EggVertex *vtx_3 = calc_sphere1_vertex(ri, si); + EggVertex *vtx_4 = calc_sphere1_vertex(ri + 1, si); + add_polygon(vtx_1, vtx_2, vtx_4, vtx_3); + vtx_1 = vtx_3; + vtx_2 = vtx_4; + } + } + + // Now the cylinder sides. + for (ri = 0; ri < _num_trings; ri++) { + vtx_1 = NULL; + vtx_2 = NULL; + for (si = 0; si <= _num_slices; si++) { + EggVertex *vtx_3 = calc_tube_vertex(ri, si); + EggVertex *vtx_4 = calc_tube_vertex(ri + 1, si); + add_polygon(vtx_1, vtx_2, vtx_4, vtx_3); + vtx_1 = vtx_3; + vtx_2 = vtx_4; + } + } + + // And the second endcap. + for (ri = _num_crings - 1; ri >= 0; ri--) { + vtx_1 = NULL; + vtx_2 = NULL; + for (si = 0; si <= _num_slices; si++) { + EggVertex *vtx_3 = calc_sphere2_vertex(ri + 1, si); + EggVertex *vtx_4 = calc_sphere2_vertex(ri, si); + add_polygon(vtx_1, vtx_2, vtx_4, vtx_3); + vtx_1 = vtx_3; + vtx_2 = vtx_4; + } + } + + // Now transform the vertices out of the canonical position. + LMatrix4d mat; + look_at(mat, direction, LVector3d(0.0, 0.0, 1.0), CS_zup_right); + mat.set_row(3, LPoint3d(_point_a[0], _point_a[1], _point_a[2])); + _group->transform(mat); + + write_egg_file(); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMakeTube::calc_sphere1_vertex +// Access: Private +// Description: Calculates a particular vertex on the surface of the +// first endcap hemisphere. +//////////////////////////////////////////////////////////////////// +EggVertex *EggMakeTube:: +calc_sphere1_vertex(int ri, int si) { + double r = (double)ri / (double)_num_crings; + double s = (double)si / (double)_num_slices; + + // Find the point on the rim, based on the slice. + double theta = s * 2.0 * MathNumbers::pi; + double x_rim = cos(theta); + double z_rim = sin(theta); + + // Now pull that point in towards the pole, based on the ring. + double phi = r * 0.5 * MathNumbers::pi; + double to_pole = sin(phi); + + double x = _radius * x_rim * to_pole; + double y = -_radius * cos(phi); + double z = _radius * z_rim * to_pole; + + EggVertex vert; + vert.set_pos(LPoint3d(x, y, z)); + + return _vpool->create_unique_vertex(vert); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMakeTube::calc_tube_vertex +// Access: Private +// Description: Calculates a vertex on the side of the cylindrical +// body of the tube. +//////////////////////////////////////////////////////////////////// +EggVertex *EggMakeTube:: +calc_tube_vertex(int ri, int si) { + double r = (double)ri / (double)_num_trings; + double s = (double)si / (double)_num_slices; + + // Find the point on the rim, based on the slice. + double theta = s * 2.0 * MathNumbers::pi; + double x_rim = cos(theta); + double z_rim = sin(theta); + + double x = _radius * x_rim; + double y = _length * r; + double z = _radius * z_rim; + + EggVertex vert; + vert.set_pos(LPoint3d(x, y, z)); + + return _vpool->create_unique_vertex(vert); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMakeTube::calc_sphere2_vertex +// Access: Private +// Description: Calculates a particular vertex on the surface of the +// second endcap hemisphere. +//////////////////////////////////////////////////////////////////// +EggVertex *EggMakeTube:: +calc_sphere2_vertex(int ri, int si) { + double r = (double)ri / (double)_num_crings; + double s = (double)si / (double)_num_slices; + + // Find the point on the rim, based on the slice. + double theta = s * 2.0 * MathNumbers::pi; + double x_rim = cos(theta); + double z_rim = sin(theta); + + // Now pull that point in towards the pole, based on the ring. + double phi = r * 0.5 * MathNumbers::pi; + double to_pole = sin(phi); + + double x = _radius * x_rim * to_pole; + double y = _length + _radius * cos(phi); + double z = _radius * z_rim * to_pole; + + EggVertex vert; + vert.set_pos(LPoint3d(x, y, z)); + + return _vpool->create_unique_vertex(vert); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMakeTube::add_polygon +// Access: Private +// Description: Adds the polygon defined by the indicated four +// vertices to the group. If the first vertex is +// NULL, does nothing. +//////////////////////////////////////////////////////////////////// +void EggMakeTube:: +add_polygon(EggVertex *a, EggVertex *b, EggVertex *c, EggVertex *d) { + if (a == (EggVertex *)NULL) { + return; + } + + PT(EggPolygon) poly = new EggPolygon; + poly->add_vertex(a); + if (a != b) { + poly->add_vertex(b); + } + poly->add_vertex(c); + if (c != d) { + poly->add_vertex(d); + } + + _group->add_child(poly.p()); +} + + +int main(int argc, char *argv[]) { + EggMakeTube prog; + prog.parse_command_line(argc, argv); + prog.run(); + return 0; +} diff --git a/pandatool/src/eggprogs/eggMakeTube.h b/pandatool/src/eggprogs/eggMakeTube.h new file mode 100644 index 0000000000..4e2f60fc5c --- /dev/null +++ b/pandatool/src/eggprogs/eggMakeTube.h @@ -0,0 +1,61 @@ +// Filename: eggMakeTube.h +// Created by: drose (01Oct03) +// +//////////////////////////////////////////////////////////////////// +// +// 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 EGGMAKETUBE_H +#define EGGMAKETUBE_H + +#include "pandatoolbase.h" + +#include "eggMakeSomething.h" + +class EggGroup; +class EggVertexPool; +class EggVertex; + +//////////////////////////////////////////////////////////////////// +// Class : EggMakeTube +// Description : A program to generate an egg file representing a tube +// model, similar in shape to a CollisionTube. +//////////////////////////////////////////////////////////////////// +class EggMakeTube : public EggMakeSomething { +public: + EggMakeTube(); + + void run(); + +private: + EggVertex *calc_sphere1_vertex(int ri, int si); + EggVertex *calc_sphere2_vertex(int ri, int si); + EggVertex *calc_tube_vertex(int ri, int si); + void add_polygon(EggVertex *a, EggVertex *b, EggVertex *c, EggVertex *d); + +private: + double _point_a[3]; + double _point_b[3]; + double _radius; + int _num_slices; + int _num_crings; + int _num_trings; + + double _length; + EggGroup *_group; + EggVertexPool *_vpool; +}; + +#endif +