00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "eggMakeTube.h"
00016 #include "eggGroup.h"
00017 #include "eggVertexPool.h"
00018 #include "eggVertex.h"
00019 #include "eggPolygon.h"
00020 #include "pointerTo.h"
00021 #include "look_at.h"
00022 #include "pystub.h"
00023
00024
00025
00026
00027
00028
00029 EggMakeTube::
00030 EggMakeTube() {
00031
00032 set_program_description
00033 ("egg-make-tube generates an egg file representing a \"tube\" model, "
00034 "a cylinder capped on both ends by hemispheres. This is similar "
00035 "in shape to the CollisionTube object within Panda.\n\n"
00036 "This program can also generate spheres if you omit -b; in this "
00037 "case, you are generating a degenerate tube of length 0.");
00038
00039 add_option
00040 ("a", "x,y,z", 0,
00041 "Specify the first endpoint of the tube.",
00042 &EggWriter::dispatch_double_triple, NULL, _point_a);
00043
00044 add_option
00045 ("b", "x,y,z", 0,
00046 "Specify the second endpoint of the tube.",
00047 &EggWriter::dispatch_double_triple, &_got_point_b, _point_b);
00048
00049 add_option
00050 ("r", "radius", 0,
00051 "Specify the radius of the tube. The tube will extend beyond "
00052 "the endpoints in each direction by the amount of radius.",
00053 &EggWriter::dispatch_double, NULL, &_radius);
00054
00055 add_option
00056 ("slices", "count", 0,
00057 "Specify the number of slices appearing radially around the tube.",
00058 &EggWriter::dispatch_int, NULL, &_num_slices);
00059
00060 add_option
00061 ("crings", "count", 0,
00062 "Specify the number of rings appearing in each endcap of the tube.",
00063 &EggWriter::dispatch_int, NULL, &_num_crings);
00064
00065 add_option
00066 ("trings", "count", 0,
00067 "Specify the number of rings appearing in the cylindrical body "
00068 "of the tube.",
00069 &EggWriter::dispatch_int, NULL, &_num_trings);
00070
00071 _point_a[0] = 0.0;
00072 _point_a[1] = 0.0;
00073 _point_a[2] = 0.0;
00074
00075 _point_b[0] = 0.0;
00076 _point_b[1] = 0.0;
00077 _point_b[2] = 0.0;
00078
00079 _radius = 1.0;
00080
00081 _num_slices = 8;
00082 _num_crings = 4;
00083 _num_trings = 1;
00084 }
00085
00086
00087
00088
00089
00090
00091 void EggMakeTube::
00092 run() {
00093 if (!_got_point_b) {
00094 _point_b[0] = _point_a[0];
00095 _point_b[1] = _point_a[1];
00096 _point_b[2] = _point_a[2];
00097 }
00098
00099
00100
00101 LVector3d direction(_point_b[0] - _point_a[0],
00102 _point_b[1] - _point_a[1],
00103 _point_b[2] - _point_a[2]);
00104 _length = direction.length();
00105
00106
00107 _group = new EggGroup("tube");
00108 _data->add_child(_group);
00109
00110 _vpool = new EggVertexPool("tube");
00111 _group->add_child(_vpool);
00112
00113
00114 int ri, si;
00115 EggVertex *vtx_1;
00116 EggVertex *vtx_2;
00117
00118 for (ri = 0; ri < _num_crings; ri++) {
00119 vtx_1 = NULL;
00120 vtx_2 = NULL;
00121 for (si = 0; si <= _num_slices; si++) {
00122 EggVertex *vtx_3 = calc_sphere1_vertex(ri, si);
00123 EggVertex *vtx_4 = calc_sphere1_vertex(ri + 1, si);
00124 add_polygon(vtx_1, vtx_2, vtx_4, vtx_3);
00125 vtx_1 = vtx_3;
00126 vtx_2 = vtx_4;
00127 }
00128 }
00129
00130
00131 if (_length != 0.0) {
00132 for (ri = 0; ri < _num_trings; ri++) {
00133 vtx_1 = NULL;
00134 vtx_2 = NULL;
00135 for (si = 0; si <= _num_slices; si++) {
00136 EggVertex *vtx_3 = calc_tube_vertex(ri, si);
00137 EggVertex *vtx_4 = calc_tube_vertex(ri + 1, si);
00138 add_polygon(vtx_1, vtx_2, vtx_4, vtx_3);
00139 vtx_1 = vtx_3;
00140 vtx_2 = vtx_4;
00141 }
00142 }
00143 }
00144
00145
00146 for (ri = _num_crings - 1; ri >= 0; ri--) {
00147 vtx_1 = NULL;
00148 vtx_2 = NULL;
00149 for (si = 0; si <= _num_slices; si++) {
00150 EggVertex *vtx_3 = calc_sphere2_vertex(ri + 1, si);
00151 EggVertex *vtx_4 = calc_sphere2_vertex(ri, si);
00152 add_polygon(vtx_1, vtx_2, vtx_4, vtx_3);
00153 vtx_1 = vtx_3;
00154 vtx_2 = vtx_4;
00155 }
00156 }
00157
00158
00159 LMatrix4d mat;
00160 look_at(mat, direction, LVector3d(0.0, 0.0, 1.0), CS_zup_right);
00161 mat.set_row(3, LPoint3d(_point_a[0], _point_a[1], _point_a[2]));
00162 _group->transform(mat);
00163
00164 write_egg_file();
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 EggVertex *EggMakeTube::
00174 calc_sphere1_vertex(int ri, int si) {
00175 double r = (double)ri / (double)_num_crings;
00176 double s = (double)si / (double)_num_slices;
00177
00178
00179 double theta = s * 2.0 * MathNumbers::pi;
00180 double x_rim = cos(theta);
00181 double z_rim = sin(theta);
00182
00183
00184 double phi = r * 0.5 * MathNumbers::pi;
00185 double to_pole = sin(phi);
00186
00187 double x = _radius * x_rim * to_pole;
00188 double y = -_radius * cos(phi);
00189 double z = _radius * z_rim * to_pole;
00190
00191 EggVertex vert;
00192 vert.set_pos(LPoint3d(x, y, z));
00193
00194 return _vpool->create_unique_vertex(vert);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 EggVertex *EggMakeTube::
00204 calc_tube_vertex(int ri, int si) {
00205 double r = (double)ri / (double)_num_trings;
00206 double s = (double)si / (double)_num_slices;
00207
00208
00209 double theta = s * 2.0 * MathNumbers::pi;
00210 double x_rim = cos(theta);
00211 double z_rim = sin(theta);
00212
00213 double x = _radius * x_rim;
00214 double y = _length * r;
00215 double z = _radius * z_rim;
00216
00217 EggVertex vert;
00218 vert.set_pos(LPoint3d(x, y, z));
00219
00220 return _vpool->create_unique_vertex(vert);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 EggVertex *EggMakeTube::
00230 calc_sphere2_vertex(int ri, int si) {
00231 double r = (double)ri / (double)_num_crings;
00232 double s = (double)si / (double)_num_slices;
00233
00234
00235 double theta = s * 2.0 * MathNumbers::pi;
00236 double x_rim = cos(theta);
00237 double z_rim = sin(theta);
00238
00239
00240 double phi = r * 0.5 * MathNumbers::pi;
00241 double to_pole = sin(phi);
00242
00243 double x = _radius * x_rim * to_pole;
00244 double y = _length + _radius * cos(phi);
00245 double z = _radius * z_rim * to_pole;
00246
00247 EggVertex vert;
00248 vert.set_pos(LPoint3d(x, y, z));
00249
00250 return _vpool->create_unique_vertex(vert);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260 void EggMakeTube::
00261 add_polygon(EggVertex *a, EggVertex *b, EggVertex *c, EggVertex *d) {
00262 if (a == (EggVertex *)NULL) {
00263 return;
00264 }
00265
00266 PT(EggPolygon) poly = new EggPolygon;
00267 poly->add_vertex(a);
00268 if (a != b) {
00269 poly->add_vertex(b);
00270 }
00271 poly->add_vertex(c);
00272 if (c != d) {
00273 poly->add_vertex(d);
00274 }
00275
00276 _group->add_child(poly.p());
00277 }
00278
00279
00280 int main(int argc, char *argv[]) {
00281
00282 pystub();
00283
00284 EggMakeTube prog;
00285 prog.parse_command_line(argc, argv);
00286 prog.run();
00287 return 0;
00288 }