00001 #include "shape.h"
00002
00007 #include <glutm/glut.h>
00008
00009 #include <glt/error.h>
00010
00011 #include <math/plane.h>
00012 #include <math/vector3.h>
00013 #include <math/matrix4.h>
00014 #include <math/volume.h>
00015
00016 #include <vector>
00017 #include <cmath>
00018 #include <iostream>
00019 using namespace std;
00020
00022
00023 GlutSphere::GlutSphere(const bool solid,const GLdouble radius,const GLint slices,const GLint stacks)
00024 : GltShape(solid), _radius(radius), _slices(slices), _stacks(stacks)
00025 {
00026 }
00027
00028 GlutSphere::~GlutSphere()
00029 {
00030 }
00031
00032 void
00033 GlutSphere::draw() const
00034 {
00035 GLERROR;
00036
00037 glPushMatrix();
00038 transformation().glMultMatrix();
00039 glColor();
00040 if (solid())
00041 glutSolidSphere(_radius,_slices,_stacks);
00042 else
00043 glutWireSphere(_radius,_slices,_stacks);
00044 glPopMatrix();
00045
00046 GLERROR;
00047 }
00048
00049 GLdouble
00050 GlutSphere::volume() const
00051 {
00052 return sphereVolume(_radius);
00053 }
00054
00055 bool
00056 GlutSphere::inside(const Vector &pos) const
00057 {
00058 const Vector p = transformation().inverse()*pos;
00059 return (p*p)<_radius*_radius;
00060 }
00061
00062 bool
00063 GlutSphere::povrayExport(ostream &os) const
00064 {
00065 os << "sphere { ";
00066 Vector0.writePov(os) << ", " << _radius << endl;
00067
00068
00069 os << "pigment { color rgb ";
00070 color().writePov(os) << '}' << endl;
00071
00072 transformation().writePov(os) << endl;
00073
00074 os << "}" << endl;
00075
00076 return true;
00077 }
00078
00079 void
00080 GlutSphere::boundingBox(BoundingBox &box) const
00081 {
00082 vector<Vector> p;
00083 p.reserve(8);
00084 p.push_back(Vector( _radius, _radius, _radius));
00085 p.push_back(Vector( _radius, _radius,-_radius));
00086 p.push_back(Vector( _radius,-_radius, _radius));
00087 p.push_back(Vector( _radius,-_radius,-_radius));
00088 p.push_back(Vector(-_radius, _radius, _radius));
00089 p.push_back(Vector(-_radius, _radius,-_radius));
00090 p.push_back(Vector(-_radius,-_radius, _radius));
00091 p.push_back(Vector(-_radius,-_radius,-_radius));
00092 transformPoints(p);
00093
00094 box.reset();
00095 box += p;
00096 }
00097
00098 void
00099 GlutSphere::position(const Vector &pos,const double radius)
00100 {
00101 _radius = radius;
00102 transformation() = matrixTranslate(pos);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 GLdouble &GlutSphere::radius() { return _radius; }
00179 GLint &GlutSphere::slices() { return _slices; }
00180 GLint &GlutSphere::stacks() { return _stacks; }
00181
00182 const GLdouble &GlutSphere::radius() const { return _radius; }
00183 const GLint &GlutSphere::slices() const { return _slices; }
00184 const GLint &GlutSphere::stacks() const { return _stacks; }
00185
00186
00188
00189 GlutCube::GlutCube(const bool solid,const GLdouble size)
00190 : GltShape(solid), _size(size)
00191 {
00192 }
00193
00194 GlutCube::GlutCube(const bool solid,const Vector &min,const Vector &max)
00195 : GltShape(solid), _size(1.0)
00196 {
00197 position(min,max);
00198 }
00199
00200 GlutCube::~GlutCube()
00201 {
00202 }
00203
00204 void
00205 GlutCube::draw() const
00206 {
00207 GLERROR;
00208
00209 glPushMatrix();
00210 transformation().glMultMatrix();
00211 glColor();
00212 if (solid())
00213 glutSolidCube(_size);
00214 else
00215 glutWireCube(_size);
00216 glPopMatrix();
00217
00218 GLERROR;
00219 }
00220
00221 GLdouble
00222 GlutCube::volume() const
00223 {
00224 return boxVolume(_size,_size,_size);
00225 }
00226
00227 void
00228 GlutCube::boundingBox(BoundingBox &box) const
00229 {
00230 const real size = _size*0.5;
00231
00232 vector<Vector> p;
00233 p.reserve(8);
00234 p.push_back(Vector( size, size, size));
00235 p.push_back(Vector( size, size,-size));
00236 p.push_back(Vector( size,-size, size));
00237 p.push_back(Vector( size,-size,-size));
00238 p.push_back(Vector(-size, size, size));
00239 p.push_back(Vector(-size, size,-size));
00240 p.push_back(Vector(-size,-size, size));
00241 p.push_back(Vector(-size,-size,-size));
00242 transformPoints(p);
00243
00244 box.reset();
00245 box += p;
00246 }
00247
00248 bool
00249 GlutCube::povrayExport(ostream &os) const
00250 {
00251 os << "box { ";
00252 (Vector1*_size* 0.5).writePov(os) << ", ";
00253 (Vector1*_size*-0.5).writePov(os) << endl;
00254
00255 os << "pigment { color rgb ";
00256 color().writePov(os) << '}' << endl;
00257
00258 transformation().writePov(os) << endl;
00259
00260 os << "}" << endl;
00261
00262 return true;
00263 }
00264
00265 void
00266 GlutCube::position(const Vector &min,const Vector &max)
00267 {
00268 _size = 1.0;
00269
00270 const Vector center = (min+max)*0.5;
00271 Vector size = max-min;
00272 size.abs();
00273
00274 transformation() = matrixScale(size) * matrixTranslate(center);
00275 }
00276
00277 void
00278 GlutCube::position(const Vector &pos,const real width,const real height,const real depth)
00279 {
00280 _size = 1.0;
00281 Vector size(width,height,depth);
00282 size.abs();
00283 size *= 0.5;
00284
00285 transformation() =
00286 matrixScale(size) *
00287 matrixTranslate(pos);
00288 }
00289
00290 GLdouble &GlutCube::size() { return _size; }
00291 const GLdouble &GlutCube::size() const { return _size; }
00292
00294
00295 GlutCylinder::GlutCylinder(const bool solid,const GLdouble radius,const GLdouble height,const GLint slices,const GLint stacks,const GLint loops)
00296 : GltShape(solid), _radius(radius), _height(height), _slices(slices), _stacks(stacks), _loops(loops)
00297 {
00298 }
00299
00300 GlutCylinder::~GlutCylinder()
00301 {
00302 }
00303
00304 void
00305 GlutCylinder::draw() const
00306 {
00307
00308
00309
00310 GLERROR;
00311
00312 glPushMatrix();
00313 transformation().glMultMatrix();
00314 glColor();
00315 GLUquadricObj *quadObj = gluNewQuadric();
00316 gluQuadricDrawStyle(quadObj, (GLenum) (solid() ? GLU_FILL : GLU_SILHOUETTE));
00317 gluQuadricNormals(quadObj, (GLenum) GLU_SMOOTH);
00318 gluQuadricOrientation(quadObj, (GLenum) GLU_OUTSIDE);
00319 gluCylinder(quadObj, _radius, _radius, _height, _slices,_stacks);
00320 if (solid())
00321 {
00322 gluQuadricOrientation(quadObj, (GLenum) GLU_INSIDE);
00323 gluDisk(quadObj,0.0,_radius,_slices,_loops);
00324 glTranslatef(0.0,0.0,_height);
00325 glRotatef(180,0.0,1.0,0.0);
00326 gluDisk(quadObj,0.0,_radius,_slices,_loops);
00327 }
00328 gluDeleteQuadric(quadObj);
00329 glPopMatrix();
00330
00331 GLERROR;
00332 }
00333
00334 GLdouble
00335 GlutCylinder::volume() const
00336 {
00337 return cylinderVolume(_radius,_height);
00338 }
00339
00340 void
00341 GlutCylinder::boundingBox(BoundingBox &box) const
00342 {
00343 vector<Vector> p;
00344 p.reserve(8);
00345 p.push_back(Vector( _radius, _radius, 0));
00346 p.push_back(Vector( _radius,-_radius, 0));
00347 p.push_back(Vector(-_radius, _radius, 0));
00348 p.push_back(Vector(-_radius,-_radius, 0));
00349 p.push_back(Vector( _radius, _radius, _height));
00350 p.push_back(Vector( _radius,-_radius, _height));
00351 p.push_back(Vector(-_radius, _radius, _height));
00352 p.push_back(Vector(-_radius,-_radius, _height));
00353 transformPoints(p);
00354
00355 box.reset();
00356 box += p;
00357 }
00358
00359 bool
00360 GlutCylinder::povrayExport(ostream &os) const
00361 {
00362 os << "cylinder { ";
00363 Vector0 .writePov(os) << ", ";
00364 (VectorZ*_height).writePov(os) << ", " << _radius << endl;
00365
00366 os << "pigment { color rgb ";
00367 color().writePov(os) << '}' << endl;
00368
00369 transformation().writePov(os) << endl;
00370
00371 os << "}" << endl;
00372
00373 return true;
00374 }
00375
00376 void
00377 GlutCylinder::position(const Vector &begin,const Vector &end,const double radius)
00378 {
00379 Vector dir = end - begin;
00380
00381 _radius = radius;
00382 _height = dir.length();
00383 dir.normalize();
00384
00385
00386
00387
00388
00389 if (fabs(dir.z())>0.8)
00390 {
00391 const Vector a = xProduct(dir,VectorY);
00392 const Vector b = xProduct(dir,a);
00393 transformation() = matrixOrient(a/a.length(),b/b.length(),dir);
00394 }
00395 else
00396 {
00397 const Vector a = xProduct(dir,VectorZ);
00398 const Vector b = xProduct(dir,a);
00399 transformation() = matrixOrient(a/a.length(),b/b.length(),dir);
00400 }
00401
00402 transformation() = transformation() * matrixTranslate(begin);
00403 }
00404
00405 GLdouble &GlutCylinder::radius() { return _radius; }
00406 GLdouble &GlutCylinder::height() { return _height; }
00407 GLint &GlutCylinder::slices() { return _slices; }
00408 GLint &GlutCylinder::stacks() { return _stacks; }
00409 GLint &GlutCylinder::loops() { return _loops; }
00410
00411 const GLdouble &GlutCylinder::radius() const { return _radius; }
00412 const GLdouble &GlutCylinder::height() const { return _height; }
00413 const GLint &GlutCylinder::slices() const { return _slices; }
00414 const GLint &GlutCylinder::stacks() const { return _stacks; }
00415 const GLint &GlutCylinder::loops() const { return _loops; }
00416
00418
00419 GlutCone::GlutCone(const bool solid,const GLdouble base,const GLdouble height,const GLint slices,const GLint stacks)
00420 : GltShape(solid), _base(base), _height(height), _slices(slices), _stacks(stacks)
00421 {
00422 }
00423
00424 GlutCone::~GlutCone()
00425 {
00426 }
00427
00428 void
00429 GlutCone::draw() const
00430 {
00431 GLERROR;
00432
00433 glPushMatrix();
00434 transformation().glMultMatrix();
00435 glColor();
00436 if (solid())
00437 glutSolidCone(_base,_height,_slices,_stacks);
00438 else
00439 glutWireCone(_base,_height,_slices,_stacks);
00440 glPopMatrix();
00441
00442 GLERROR;
00443 }
00444
00445 GLdouble
00446 GlutCone::volume() const
00447 {
00448 return coneVolume(_base,_height);
00449 }
00450
00451 void
00452 GlutCone::boundingBox(BoundingBox &box) const
00453 {
00454 vector<Vector> p;
00455 p.reserve(8);
00456 p.push_back(Vector( _base, _base, 0));
00457 p.push_back(Vector( _base,-_base, 0));
00458 p.push_back(Vector(-_base, _base, 0));
00459 p.push_back(Vector(-_base,-_base, 0));
00460 p.push_back(Vector( 0, 0, _height));
00461 transformPoints(p);
00462
00463 box.reset();
00464 box += p;
00465 }
00466
00467 GLdouble &GlutCone::base() { return _base; }
00468 GLdouble &GlutCone::height() { return _height; }
00469 GLint &GlutCone::slices() { return _slices; }
00470 GLint &GlutCone::stacks() { return _stacks; }
00471
00472 const GLdouble &GlutCone::base() const { return _base; }
00473 const GLdouble &GlutCone::height() const { return _height; }
00474 const GLint &GlutCone::slices() const { return _slices; }
00475 const GLint &GlutCone::stacks() const { return _stacks; }
00476
00478
00479 GlutTorus::GlutTorus(const bool solid,const GLdouble innerRadius,const GLdouble outerRadius,const GLint nsides,const GLint rings)
00480 : GltShape(solid), _innerRadius(innerRadius), _outerRadius(outerRadius), _nsides(nsides), _rings(rings)
00481 {
00482 }
00483
00484 GlutTorus::~GlutTorus()
00485 {
00486 }
00487
00488 void
00489 GlutTorus::draw() const
00490 {
00491 GLERROR;
00492
00493 glPushMatrix();
00494 transformation().glMultMatrix();
00495 glColor();
00496 if (solid())
00497 glutSolidTorus(_innerRadius,_outerRadius,_nsides,_rings);
00498 else
00499 glutWireTorus(_innerRadius,_outerRadius,_nsides,_rings);
00500 glPopMatrix();
00501
00502 GLERROR;
00503 }
00504
00505 GLdouble &GlutTorus::innerRadius() { return _innerRadius; }
00506 GLdouble &GlutTorus::outerRadius() { return _outerRadius; }
00507 GLint &GlutTorus::nsides() { return _nsides; }
00508 GLint &GlutTorus::rings() { return _rings; }
00509
00510 const GLdouble &GlutTorus::innerRadius() const { return _innerRadius; }
00511 const GLdouble &GlutTorus::outerRadius() const { return _outerRadius; }
00512 const GLint &GlutTorus::nsides() const { return _nsides; }
00513 const GLint &GlutTorus::rings() const { return _rings; }
00514
00516
00517 GlutDodecahedron::GlutDodecahedron(const bool solid)
00518 : GltShape(solid)
00519 {
00520 }
00521
00522 GlutDodecahedron::~GlutDodecahedron()
00523 {
00524 }
00525
00526 void
00527 GlutDodecahedron::draw() const
00528 {
00529 GLERROR;
00530
00531 glPushMatrix();
00532 transformation().glMultMatrix();
00533 glColor();
00534 if (solid())
00535 glutSolidDodecahedron();
00536 else
00537 glutWireDodecahedron();
00538 glPopMatrix();
00539
00540 GLERROR;
00541 }
00542
00544
00545 GlutOctahedron::GlutOctahedron(const bool solid)
00546 : GltShape(solid)
00547 {
00548 }
00549
00550 GlutOctahedron::~GlutOctahedron()
00551 {
00552 }
00553
00554 void
00555 GlutOctahedron::draw() const
00556 {
00557 GLERROR;
00558
00559 glPushMatrix();
00560 transformation().glMultMatrix();
00561 glColor();
00562 if (solid())
00563 glutSolidOctahedron();
00564 else
00565 glutWireOctahedron();
00566 glPopMatrix();
00567
00568 GLERROR;
00569 }
00570
00572
00573 GlutTetrahedron::GlutTetrahedron(const bool solid)
00574 : GltShape(solid)
00575 {
00576 }
00577
00578 GlutTetrahedron::~GlutTetrahedron()
00579 {
00580 }
00581
00582 void
00583 GlutTetrahedron::draw() const
00584 {
00585 GLERROR;
00586
00587 glPushMatrix();
00588 transformation().glMultMatrix();
00589 glColor();
00590 if (solid())
00591 glutSolidTetrahedron();
00592 else
00593 glutWireTetrahedron();
00594 glPopMatrix();
00595
00596 GLERROR;
00597 }
00598
00600
00601 GlutIcosahedron::GlutIcosahedron(const bool solid)
00602 : GltShape(solid)
00603 {
00604 }
00605
00606 GlutIcosahedron::~GlutIcosahedron()
00607 {
00608 }
00609
00610 void
00611 GlutIcosahedron::draw() const
00612 {
00613 GLERROR;
00614
00615 glPushMatrix();
00616 transformation().glMultMatrix();
00617 glColor();
00618 if (solid())
00619 glutSolidIcosahedron();
00620 else
00621 glutWireIcosahedron();
00622 glPopMatrix();
00623
00624 GLERROR;
00625 }
00626
00628
00629 GlutTeapot::GlutTeapot(const bool solid,const GLdouble size)
00630 : GltShape(solid), _size(size)
00631 {
00632 }
00633
00634 GlutTeapot::~GlutTeapot()
00635 {
00636 }
00637
00638 void
00639 GlutTeapot::draw() const
00640 {
00641 GLERROR;
00642
00643 glPushMatrix();
00644 transformation().glMultMatrix();
00645 glColor();
00646 if (solid())
00647 glutSolidTeapot(_size);
00648 else
00649 glutWireTeapot(_size);
00650 glPopMatrix();
00651
00652 GLERROR;
00653 }
00654
00655 GLdouble &GlutTeapot::size() { return _size; }
00656 const GLdouble &GlutTeapot::size() const { return _size; }
00657