15 #include "eggMakeTube.h" 17 #include "eggVertexPool.h" 18 #include "eggVertex.h" 19 #include "eggPolygon.h" 20 #include "pointerTo.h" 32 set_program_brief(
"generate a tube or sphere from geometry in an .egg file");
33 set_program_description
34 (
"egg-make-tube generates an egg file representing a \"tube\" model, " 35 "a cylinder capped on both ends by hemispheres. This is similar " 36 "in shape to the CollisionTube object within Panda.\n\n" 37 "This program can also generate spheres if you omit -b; in this " 38 "case, you are generating a degenerate tube of length 0.");
42 "Specify the first endpoint of the tube.",
43 &EggWriter::dispatch_double_triple, NULL, _point_a);
47 "Specify the second endpoint of the tube.",
48 &EggWriter::dispatch_double_triple, &_got_point_b, _point_b);
52 "Specify the radius of the tube. The tube will extend beyond " 53 "the endpoints in each direction by the amount of radius.",
54 &EggWriter::dispatch_double, NULL, &_radius);
57 (
"slices",
"count", 0,
58 "Specify the number of slices appearing radially around the tube.",
59 &EggWriter::dispatch_int, NULL, &_num_slices);
62 (
"crings",
"count", 0,
63 "Specify the number of rings appearing in each endcap of the tube.",
64 &EggWriter::dispatch_int, NULL, &_num_crings);
67 (
"trings",
"count", 0,
68 "Specify the number of rings appearing in the cylindrical body " 70 &EggWriter::dispatch_int, NULL, &_num_trings);
95 _point_b[0] = _point_a[0];
96 _point_b[1] = _point_a[1];
97 _point_b[2] = _point_a[2];
102 LVector3d direction(_point_b[0] - _point_a[0],
103 _point_b[1] - _point_a[1],
104 _point_b[2] - _point_a[2]);
105 _length = direction.length();
109 _data->add_child(_group);
119 for (ri = 0; ri < _num_crings; ri++) {
122 for (si = 0; si <= _num_slices; si++) {
123 EggVertex *vtx_3 = calc_sphere1_vertex(ri, si);
124 EggVertex *vtx_4 = calc_sphere1_vertex(ri + 1, si);
125 add_polygon(vtx_1, vtx_2, vtx_4, vtx_3);
132 if (_length != 0.0) {
133 for (ri = 0; ri < _num_trings; ri++) {
136 for (si = 0; si <= _num_slices; si++) {
137 EggVertex *vtx_3 = calc_tube_vertex(ri, si);
138 EggVertex *vtx_4 = calc_tube_vertex(ri + 1, si);
139 add_polygon(vtx_1, vtx_2, vtx_4, vtx_3);
147 for (ri = _num_crings - 1; ri >= 0; ri--) {
150 for (si = 0; si <= _num_slices; si++) {
151 EggVertex *vtx_3 = calc_sphere2_vertex(ri + 1, si);
152 EggVertex *vtx_4 = calc_sphere2_vertex(ri, si);
153 add_polygon(vtx_1, vtx_2, vtx_4, vtx_3);
161 look_at(mat, direction,
LVector3d(0.0, 0.0, 1.0), CS_zup_right);
175 calc_sphere1_vertex(
int ri,
int si) {
176 double r = (double)ri / (
double)_num_crings;
177 double s = (double)si / (
double)_num_slices;
180 double theta = s * 2.0 * MathNumbers::pi;
181 double x_rim = cos(theta);
182 double z_rim = sin(theta);
185 double phi = r * 0.5 * MathNumbers::pi;
186 double to_pole = sin(phi);
188 double x = _radius * x_rim * to_pole;
189 double y = -_radius * cos(phi);
190 double z = _radius * z_rim * to_pole;
205 calc_tube_vertex(
int ri,
int si) {
206 double r = (double)ri / (
double)_num_trings;
207 double s = (double)si / (
double)_num_slices;
210 double theta = s * 2.0 * MathNumbers::pi;
211 double x_rim = cos(theta);
212 double z_rim = sin(theta);
214 double x = _radius * x_rim;
215 double y = _length * r;
216 double z = _radius * z_rim;
231 calc_sphere2_vertex(
int ri,
int si) {
232 double r = (double)ri / (
double)_num_crings;
233 double s = (double)si / (
double)_num_slices;
236 double theta = s * 2.0 * MathNumbers::pi;
237 double x_rim = cos(theta);
238 double z_rim = sin(theta);
241 double phi = r * 0.5 * MathNumbers::pi;
242 double to_pole = sin(phi);
244 double x = _radius * x_rim * to_pole;
245 double y = _length + _radius * cos(phi);
246 double z = _radius * z_rim * to_pole;
281 int main(
int argc,
char *argv[]) {
void transform(const LMatrix4d &mat)
Applies the indicated transformation to the node and all of its descendants.
This is a 4-by-4 transform matrix.
virtual void parse_command_line(int argc, char **argv)
Dispatches on each of the options on the command line, and passes the remaining parameters to handle_...
void set_pos(double pos)
Sets the vertex position.
void set_row(int row, const LVecBase4d &v)
Replaces the indicated row of the matrix.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
void write_egg_file()
Writes out the egg file as the normal result of the program.
A program to generate an egg file representing a tube model, similar in shape to a CollisionTube...
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
A collection of vertices.
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive's list of vertices, and returns it...