00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifdef WIN32
00038 #pragma warning( disable : 4305 )
00039 #endif
00040
00041
00042
00043
00044
00045 #include <cstdlib>
00046 #include <cstdio>
00047
00048 #include "OSGConfig.h"
00049 #include "OSGLog.h"
00050 #include "OSGQuaternion.h"
00051 #include "OSGMaterial.h"
00052 #include "OSGSimpleMaterial.h"
00053 #include "OSGLineChunk.h"
00054 #include "OSGGeoProperties.h"
00055 #include "OSGSimpleGeometry.h"
00056 #include "OSGTypedGeoIntegralProperty.h"
00057 #include "OSGTypedGeoVectorProperty.h"
00058
00059
00060
00061 OSG_BEGIN_NAMESPACE
00062
00063
00064
00065
00066
00067 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00068 #pragma warning (disable : 383)
00069 #endif
00070
00071
00072
00085 NodeTransitPtr makePlane(Real32 xsize, Real32 ysize, UInt16 hor, UInt16 vert)
00086 {
00087 GeometryTransitPtr pGeo = makePlaneGeo(xsize, ysize, hor, vert);
00088
00089 if(pGeo == NULL)
00090 {
00091 return NodeTransitPtr(NULL);
00092 }
00093
00094 NodeTransitPtr node = Node::create();
00095
00096 node->setCore(pGeo);
00097
00098 return node;
00099 }
00100
00113 GeometryTransitPtr makePlaneGeo(Real32 xsize, Real32 ysize,
00114 UInt16 hor, UInt16 vert)
00115 {
00116 if(! hor || ! vert)
00117 {
00118 SWARNING << "makePlane: illegal parameters hor=" << hor << ", vert="
00119 << vert << std::endl;
00120 return GeometryTransitPtr(NULL);
00121 }
00122
00123 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
00124 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
00125 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
00126 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property::create();
00127 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
00128 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
00129
00130 UInt16 x,y;
00131 Real32 xstep,ystep;
00132 xstep=xsize / hor;
00133 ystep=ysize / vert;
00134
00135
00136
00137 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
00138 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
00139 GeoVec2fProperty::StoredFieldType *tx = tex ->editFieldPtr();
00140
00141 for(y = 0; y <= vert; y++)
00142 {
00143 for(x = 0; x <= hor; x++)
00144 {
00145 p->push_back(Pnt3f(x * xstep - xsize / 2, y * ystep - ysize / 2, 0));
00146 n->push_back(Vec3f(0, 0, 1));
00147 tx->push_back(Vec2f(x / Real32(hor), y / Real32(vert)));
00148 }
00149 }
00150
00151
00152
00153 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
00154 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
00155 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
00156
00157 for(y = 0; y < vert; y++)
00158 {
00159 t->push_back(GL_TRIANGLE_STRIP);
00160 l->push_back(2 * (hor + 1));
00161
00162 for(x = 0; x <= hor; x++)
00163 {
00164 i->push_back((y + 1) * (hor + 1) + x);
00165 i->push_back( y * (hor + 1) + x);
00166 }
00167 }
00168
00169
00170
00171 GeometryTransitPtr geo = Geometry::create();
00172
00173 geo->setMaterial(getDefaultMaterial());
00174 geo->setPositions(pnts);
00175 geo->setNormals(norms);
00176 geo->setTexCoords(tex);
00177 geo->setIndices(index);
00178 geo->setTypes(types);
00179 geo->setLengths(lens);
00180
00181 return geo;
00182 }
00183
00199 NodeTransitPtr makeCone(Real32 height,
00200 Real32 botradius,
00201 UInt16 sides,
00202 bool doSide,
00203 bool doBottom)
00204 {
00205 return makeConicalFrustum(height,
00206 0,
00207 botradius,
00208 sides,
00209 doSide,
00210 false,
00211 doBottom);
00212 }
00213
00227 GeometryTransitPtr makeConeGeo(Real32 height,
00228 Real32 botradius,
00229 UInt16 sides,
00230 bool doSide,
00231 bool doBottom)
00232 {
00233 return makeConicalFrustumGeo(height,
00234 0,
00235 botradius,
00236 sides,
00237 doSide,
00238 false,
00239 doBottom);
00240 }
00241
00259 NodeTransitPtr makeCylinder(Real32 height,
00260 Real32 radius,
00261 UInt16 sides,
00262 bool doSide,
00263 bool doTop,
00264 bool doBottom)
00265 {
00266 return makeConicalFrustum(height,
00267 radius,
00268 radius,
00269 sides,
00270 doSide,
00271 doTop,
00272 doBottom);
00273 }
00274
00289 GeometryTransitPtr makeCylinderGeo(Real32 height,
00290 Real32 radius,
00291 UInt16 sides,
00292 bool doSide,
00293 bool doTop,
00294 bool doBottom)
00295 {
00296 return makeConicalFrustumGeo(height,
00297 radius,
00298 radius,
00299 sides,
00300 doSide,
00301 doTop,
00302 doBottom);
00303 }
00304
00305
00325 NodeTransitPtr makeConicalFrustum(Real32 height,
00326 Real32 topradius,
00327 Real32 botradius,
00328 UInt16 sides,
00329 bool doSide,
00330 bool doTop,
00331 bool doBottom)
00332 {
00333 GeometryTransitPtr pGeo = makeConicalFrustumGeo(height,
00334 topradius,
00335 botradius,
00336 sides,
00337 doSide,
00338 doTop,
00339 doBottom);
00340
00341 if(pGeo == NULL)
00342 {
00343 return NodeTransitPtr(NULL);
00344 }
00345
00346 NodeTransitPtr node = Node::create();
00347
00348 node->setCore(pGeo);
00349
00350 return node;
00351 }
00352
00366 GeometryTransitPtr makeConicalFrustumGeo(Real32 height,
00367 Real32 topradius,
00368 Real32 botradius,
00369 UInt16 sides,
00370 bool doSide,
00371 bool doTop,
00372 bool doBottom)
00373 {
00374 if(height <= 0 || topradius < 0 || botradius < 0 || sides < 3)
00375 {
00376 SWARNING << "makeConicalFrustum: illegal parameters height=" << height
00377 << ", topradius=" << topradius
00378 << ", botradius=" << botradius
00379 << ", sides=" << sides
00380 << std::endl;
00381 return GeometryTransitPtr(NULL);
00382 }
00383
00384 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
00385 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
00386 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
00387 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property::create();
00388 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
00389 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
00390
00391 Int16 j;
00392 Real32 delta = 2.f * Pi / sides;
00393 Real32 beta, x, z;
00394 Real32 incl = (botradius - topradius) / height;
00395 Real32 nlen = 1.f / osgSqrt(1 + incl * incl);
00396
00397
00398
00399 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
00400 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
00401 GeoVec2fProperty::StoredFieldType *tx = tex ->editFieldPtr();
00402
00403
00404
00405 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
00406 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
00407 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
00408
00409 if(doSide)
00410 {
00411 UInt32 baseindex = p->size();
00412
00413 for(j = 0; j <= sides; j++)
00414 {
00415 beta = j * delta;
00416 x = osgSin(beta);
00417 z = -osgCos(beta);
00418
00419 p->push_back(Pnt3f(x * topradius, height/2, z * topradius));
00420 n->push_back(Vec3f(x/nlen, incl/nlen, z/nlen));
00421 tx->push_back(Vec2f(1.f - j / Real32(sides), 1));
00422 }
00423
00424 for(j = 0; j <= sides; j++)
00425 {
00426 beta = j * delta;
00427 x = osgSin(beta);
00428 z = -osgCos(beta);
00429
00430 p->push_back(Pnt3f(x * botradius, -height/2, z * botradius));
00431 n->push_back(Vec3f(x/nlen, incl/nlen, z/nlen));
00432 tx->push_back(Vec2f(1.f - j / Real32(sides), 0));
00433 }
00434
00435 t->push_back(GL_TRIANGLE_STRIP);
00436 l->push_back(2 * (sides + 1));
00437
00438 for(j = 0; j <= sides; j++)
00439 {
00440 i->push_back(baseindex + sides + 1 + j);
00441 i->push_back(baseindex + j);
00442 }
00443 }
00444
00445 if(doTop && topradius > 0)
00446 {
00447 UInt32 baseindex = p->size();
00448
00449
00450
00451 for(j = sides - 1; j >= 0; j--)
00452 {
00453 beta = j * delta;
00454 x = topradius * osgSin(beta);
00455 z = -topradius * osgCos(beta);
00456
00457 p->push_back(Pnt3f(x, height/2, z));
00458 n->push_back(Vec3f(0, 1, 0));
00459 tx->push_back(Vec2f(x / topradius / 2 + .5f, -z / topradius / 2 + .5f));
00460 }
00461
00462 t->push_back(GL_POLYGON);
00463 l->push_back(sides);
00464
00465 for(j = 0; j < sides; j++)
00466 {
00467 i->push_back(baseindex + j);
00468 }
00469 }
00470
00471 if(doBottom && botradius > 0 )
00472 {
00473 UInt32 baseindex = p->size();
00474
00475
00476
00477 for(j = sides - 1; j >= 0; j--)
00478 {
00479 beta = j * delta;
00480 x = botradius * osgSin(beta);
00481 z = -botradius * osgCos(beta);
00482
00483 p->push_back(Pnt3f(x, -height/2, z));
00484 n->push_back(Vec3f(0, -1, 0));
00485 tx->push_back(Vec2f(x / botradius / 2 + .5f, z / botradius / 2 + .5f));
00486 }
00487
00488 t->push_back(GL_POLYGON);
00489 l->push_back(sides);
00490
00491 for(j = 0; j < sides; j++)
00492 {
00493 i->push_back(baseindex + sides - 1 - j);
00494 }
00495 }
00496
00497
00498
00499 GeometryTransitPtr geo = Geometry::create();
00500
00501 geo->setMaterial(getDefaultMaterial());
00502 geo->setPositions(pnts);
00503 geo->setNormals(norms);
00504 geo->setTexCoords(tex);
00505 geo->setIndices(index);
00506 geo->setTypes(types);
00507 geo->setLengths(lens);
00508
00509 return geo;
00510 }
00511
00523 NodeTransitPtr makeTorus(Real32 innerRadius,
00524 Real32 outerRadius,
00525 UInt16 sides,
00526 UInt16 rings)
00527 {
00528 GeometryTransitPtr pGeo = makeTorusGeo(innerRadius,
00529 outerRadius,
00530 sides,
00531 rings);
00532
00533 if(pGeo == NULL)
00534 {
00535 return NodeTransitPtr(NULL);
00536 }
00537
00538 NodeTransitPtr node = Node::create();
00539
00540 node->setCore(pGeo);
00541
00542 return node;
00543 }
00544
00557 GeometryTransitPtr makeTorusGeo(Real32 innerRadius,
00558 Real32 outerRadius,
00559 UInt16 sides,
00560 UInt16 rings)
00561 {
00562 if(innerRadius <= 0 || outerRadius <= 0 || sides < 3 || rings < 3)
00563 {
00564 SWARNING << "makeTorus: illegal parameters innerRadius=" << innerRadius
00565 << ", outerRadius=" << outerRadius
00566 << ", sides=" << sides
00567 << ", rings=" << rings
00568 << std::endl;
00569 return GeometryTransitPtr(NULL);
00570 }
00571
00572 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
00573 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
00574 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
00575 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property::create();
00576 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
00577 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
00578
00579 UInt16 a, b;
00580 Real32 theta, phi;
00581 Real32 cosTheta, sinTheta;
00582 Real32 ringDelta, sideDelta;
00583
00584
00585
00586 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
00587 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
00588 GeoVec2fProperty::StoredFieldType *tx = tex ->editFieldPtr();
00589
00590 ringDelta = 2.f * Pi / rings;
00591 sideDelta = 2.f * Pi / sides;
00592
00593 for(a = 0, theta = 0.0; a <= rings; a++, theta += ringDelta)
00594 {
00595 cosTheta = osgCos(theta);
00596 sinTheta = osgSin(theta);
00597
00598 for(b = 0, phi = 0; b <= sides; b++, phi += sideDelta)
00599 {
00600 GLfloat cosPhi, sinPhi, dist;
00601
00602 cosPhi = osgCos(phi);
00603 sinPhi = osgSin(phi);
00604 dist = outerRadius + innerRadius * cosPhi;
00605
00606 n->push_back(Vec3f(cosTheta * cosPhi,
00607 -sinTheta * cosPhi,
00608 sinPhi));
00609 p->push_back(Pnt3f(cosTheta * dist,
00610 -sinTheta * dist,
00611 innerRadius * sinPhi));
00612 tx->push_back(Vec2f(- a / Real32(rings), b / Real32(sides)));
00613 }
00614 }
00615
00616
00617
00618 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
00619 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
00620 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
00621
00622 for(a = 0; a < sides; a++)
00623 {
00624 t->push_back(GL_TRIANGLE_STRIP);
00625 l->push_back((rings + 1) * 2);
00626
00627 for(b = 0; b <= rings; b++)
00628 {
00629 i->push_back(b * (sides+1) + a);
00630 i->push_back(b * (sides+1) + a + 1);
00631 }
00632 }
00633
00634
00635
00636 GeometryTransitPtr geo = Geometry::create();
00637
00638 geo->setMaterial(getDefaultMaterial());
00639 geo->setPositions(pnts);
00640 geo->setNormals(norms);
00641 geo->setTexCoords(tex);
00642 geo->setIndices(index);
00643 geo->setTypes(types);
00644 geo->setLengths(lens);
00645
00646 return geo;
00647 }
00648
00649 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00650
00658 Real32 setVecLen(Vec3f &vec, Real32 length)
00659 {
00660 Real32 len = vec.length();
00661 if(len == 0.0)
00662 {
00663 len = 1;
00664 }
00665 else
00666 {
00667 len = length / len;
00668 }
00669 vec *= len;
00670
00671 return length;
00672 }
00673
00674 Real32 calcTexS(Vec3f &n, Real32 theta)
00675 {
00676 const Real32 TwoPi = 6.283185307179586f;
00677 const Real32 HalfPi = 1.570796326794897f;
00678
00679 Real32 phi = osgATan2(-n[2], n[0]) - HalfPi;
00680
00681 if (phi <= -Eps)
00682 phi += TwoPi;
00683 phi /= TwoPi;
00684
00685 return phi;
00686 }
00687
00688 void addPoint(Pnt3f v, UInt32 index, Real32 radius,
00689 GeoPnt3fProperty::StoredFieldType *p,
00690 GeoVec3fProperty::StoredFieldType *n,
00691 GeoVec2fProperty::StoredFieldType *tx)
00692 {
00693 Vec3f norm(v[0], v[1], v[2]);
00694
00695 norm.normalize();
00696 n->push_back(norm);
00697
00698 Pnt3f pnt(radius * norm);
00699 p->push_back(pnt);
00700
00701 Vec2f texCoord;
00702
00703
00704 texCoord[1] = (Pi - osgACos(norm[1])) / Pi;
00705
00706 texCoord[0] = calcTexS(norm, texCoord[1]);
00707
00708 tx->push_back(texCoord);
00709 }
00710
00711 void subdivideTriangle( UInt32 i1,
00712 UInt32 i2,
00713 UInt32 i3,
00714 Int32 depth,
00715 GeoPnt3fProperty::StoredFieldType *p,
00716 GeoVec3fProperty::StoredFieldType *n,
00717 GeoVec2fProperty::StoredFieldType *tx,
00718 GeoUInt32Property::StoredFieldType *i,
00719 GeoUInt32Property::StoredFieldType *tci,
00720 UInt32& z, Real32 radius )
00721 {
00722 if (depth == 0)
00723 {
00724 i->push_back(i1);
00725 tci->push_back(i1);
00726 i->push_back(i2);
00727 tci->push_back(i2);
00728 i->push_back(i3);
00729 tci->push_back(i3);
00730
00731 return;
00732 }
00733
00734 Pnt3f v1 = (*p)[i1],
00735 v2 = (*p)[i2],
00736 v3 = (*p)[i3];
00737 Pnt3f v12, v23, v31;
00738
00739 v12 = v1 + (v2 - v1) * .5f;
00740 v23 = v2 + (v3 - v2) * .5f;
00741 v31 = v3 + (v1 - v3) * .5f;
00742
00743 v12 /= 2.0f;
00744 v23 /= 2.0f;
00745 v31 /= 2.0f;
00746
00747 UInt32 i12 = z++, i23 = z++, i31 = z++;
00748
00749 addPoint(v12,i12,radius,p,n,tx);
00750 addPoint(v23,i23,radius,p,n,tx);
00751 addPoint(v31,i31,radius,p,n,tx);
00752
00753 subdivideTriangle( i1, i12, i31, depth - 1, p,n,tx,i,tci, z, radius);
00754 subdivideTriangle( i2, i23, i12, depth - 1, p,n,tx,i,tci, z, radius);
00755 subdivideTriangle( i3, i31, i23, depth - 1, p,n,tx,i,tci, z, radius);
00756 subdivideTriangle(i12, i23, i31, depth - 1, p,n,tx,i,tci, z, radius);
00757 }
00758
00759 #endif // exclude from doc
00760
00771 NodeTransitPtr makeSphere(UInt16 depth, Real32 radius)
00772 {
00773 GeometryTransitPtr pGeo = makeSphereGeo(depth, radius);
00774
00775 if(pGeo == NULL)
00776 {
00777 return NodeTransitPtr(NULL);
00778 }
00779
00780 NodeTransitPtr node = Node::create();
00781
00782 node->setCore(pGeo);
00783
00784 return node;
00785 }
00786
00797 GeometryTransitPtr makeSphereGeo(UInt16 depth, Real32 radius)
00798 {
00799 const Real32 X = .525731112119133606f;
00800 const Real32 Z = .850650808352039932f;
00801 const Real32 HalfPi = 1.570796326794897f;
00802
00803 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
00804 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
00805 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
00806 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property::create();
00807 GeoUInt32PropertyUnrecPtr tcindex = GeoUInt32Property::create();
00808 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
00809 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
00810
00811 UInt32 j,z;
00812
00813 static Vec3f v[12] = { Vec3f(-X, 0., Z),
00814 Vec3f( X, 0., Z),
00815 Vec3f(-X, 0., -Z),
00816 Vec3f( X, 0., -Z),
00817 Vec3f(0., Z, X),
00818 Vec3f(0., Z, -X),
00819 Vec3f(0., -Z, X),
00820 Vec3f(0., -Z, -X),
00821 Vec3f( Z, X, 0.),
00822 Vec3f(-Z, X, 0.),
00823 Vec3f( Z, -X, 0.),
00824 Vec3f(-Z, -X, 0.) };
00825
00826 Quaternion q(Vec3f(0,1,0), osgACos(Z) + HalfPi);
00827 Matrix mat;
00828
00829 mat.setTransform(q);
00830
00831 for (j=0; j<12; j++)
00832 mat.mult(v[j], v[j]);
00833
00834 Int32 tr[20][3] = { {1,4,0}, {4,9,0}, {4,5,9}, {8,5,4}, {1,8,4},
00835 {1,10,8}, {10,3,8}, {8,3,5}, {3,2,5}, {3,7,2},
00836 {3,10,7}, {10,6,7}, {6,11,7}, {6,0,11}, {6,1,0},
00837 {10,1,6}, {11,0,9}, {2,11,9}, {5,2,9}, {11,2,7} };
00838
00839 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
00840 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
00841 GeoVec2fProperty::StoredFieldType *tx = tex ->editFieldPtr();
00842
00843 GeoUInt32Property::StoredFieldType *i = index ->editFieldPtr();
00844 GeoUInt32Property::StoredFieldType *tci = tcindex->editFieldPtr();
00845
00846
00847 UInt32 estimatedSize = UInt32(osgPow(4.f, Real32(depth)) * 20.f);
00848
00849 p->reserve (estimatedSize);
00850 n->reserve (estimatedSize);
00851 tx->reserve(estimatedSize);
00852 i->reserve (estimatedSize);
00853 tci->reserve (estimatedSize);
00854
00855
00856 for (j=0; j<12; j++)
00857 {
00858 Vec3f pnt = v[j];
00859 Vec3f norm = v[j];
00860
00861 setVecLen(pnt, radius);
00862 norm.normalize();
00863
00864 p->push_back(pnt.addToZero());
00865 n->push_back(norm);
00866
00867 Vec2f texCoord;
00868
00869
00870 texCoord[1] = (Pi - osgACos(norm[1])) / Pi;
00871
00872
00873 texCoord[0] = calcTexS(norm, texCoord[1]);
00874
00875 tx->push_back(texCoord);
00876 }
00877
00878
00879 z=12;
00880 for(j=0; j<20; j++)
00881 {
00882 subdivideTriangle(tr[j][0], tr[j][1], tr[j][2],
00883 depth, p, n, tx, i, tci, z, radius);
00884 }
00885
00886 types->push_back(GL_TRIANGLES);
00887 lens->push_back(i->size());
00888
00889
00890 GeometryTransitPtr geo = Geometry::create();
00891
00892 geo->setMaterial(getDefaultMaterial());
00893 geo->setPositions(pnts);
00894 geo->setNormals(norms);
00895 geo->setTexCoords(tex);
00896 geo->setIndices(index);
00897 geo->setIndex(tcindex, Geometry::TexCoordsIndex);
00898 geo->setTypes(types);
00899 geo->setLengths(lens);
00900
00901
00902 #if 0 // not sure what this was needed for??? *DR*
00903
00904 beginEditCP(geo);
00905
00906 for (TriangleIterator ti = geo->beginTriangles();
00907 ti != geo->endTriangles(); ++ti)
00908 {
00909 Vec3f q[3];
00910 q[0] = ti.getNormal(0);
00911 q[1] = ti.getNormal(1);
00912 q[2] = ti.getNormal(2);
00913
00914 if ( (osgAbs(q[0][0]) <= 0.01 && q[0][2] >= Eps) ||
00915 (osgAbs(q[1][0]) <= 0.01 && q[1][2] >= Eps) ||
00916 (osgAbs(q[2][0]) <= 0.01 && q[2][2] >= Eps) )
00917 {
00918 for (UInt16 i=0; i<3; i++)
00919 {
00920 Vec3f norm(q[i]);
00921
00922 if (osgAbs(norm[0]) <= Eps && norm[2] <= Eps)
00923 {
00924 Real32 theta = ti.getTexCoords(i).y();
00925
00926 if( !(q[0][0] <= -Eps ||
00927 q[1][0] <= -Eps ||
00928 q[2][0] <= -Eps ) )
00929 {
00930 Vec2f texCoord(1, theta);
00931
00932 if(osgAbs(osgAbs(norm[1]) - 1) <= Eps)
00933 texCoord[0] = 0.5;
00934
00935 tex->push_back(texCoord);
00936
00937 tcindex->setValue( tex->size() - 1, ti.getTexCoordsIndex(i));
00938 }
00939 else
00940 {
00941 Vec2f texCoord(0, theta);
00942
00943 if (osgAbs(osgAbs(norm[1]) - 1) <= Eps)
00944 texCoord[0] = 0.5;
00945
00946 tex->push_back(texCoord);
00947
00948 index->setValue( tex->size() - 1, ti.getTexCoordsIndex(i));
00949 }
00950 }
00951 }
00952 }
00953 }
00954
00955 endEditCP(geo);
00956 #endif
00957
00958 return geo;
00959 }
00960
00972 NodeTransitPtr makeLatLongSphere(UInt16 latres, UInt16 longres, Real32 radius)
00973 {
00974 GeometryTransitPtr pGeo = makeLatLongSphereGeo(latres, longres, radius);
00975
00976 if(pGeo == NULL)
00977 {
00978 return NodeTransitPtr(NULL);
00979 }
00980
00981 NodeTransitPtr node = Node::create();
00982
00983 node->setCore(pGeo);
00984
00985 return node;
00986 }
00987
00999 GeometryTransitPtr makeLatLongSphereGeo(UInt16 latres,
01000 UInt16 longres,
01001 Real32 radius)
01002 {
01003 if(radius <= 0 || latres < 4 || longres < 4)
01004 {
01005 SWARNING << "makeLatLongSphere: illegal parameters "
01006 << "latres=" << latres
01007 << ", longres=" << longres
01008 << ", radius=" << radius
01009 << std::endl;
01010 return GeometryTransitPtr(NULL);
01011 }
01012
01013 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
01014 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
01015 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
01016 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property::create();
01017 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
01018 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
01019
01020 UInt16 a, b;
01021 Real32 theta, phi;
01022 Real32 cosTheta, sinTheta;
01023 Real32 latDelta, longDelta;
01024
01025
01026
01027 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
01028 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
01029 GeoVec2fProperty::StoredFieldType *tx = tex ->editFieldPtr();
01030
01031 latDelta = Pi / latres;
01032 longDelta = 2.f * Pi / longres;
01033
01034 for(a = 0, theta = -Pi / 2; a <= latres; a++, theta += latDelta)
01035 {
01036 cosTheta = osgCos(theta);
01037 sinTheta = osgSin(theta);
01038
01039 for(b = 0, phi = -Pi; b <= longres; b++, phi += longDelta)
01040 {
01041 GLfloat cosPhi, sinPhi;
01042
01043 cosPhi = osgCos(phi);
01044 sinPhi = osgSin(phi);
01045
01046 n->push_back(Vec3f(cosTheta * sinPhi,
01047 sinTheta,
01048 cosTheta * cosPhi));
01049
01050 p->push_back(Pnt3f( cosTheta * sinPhi * radius,
01051 sinTheta * radius,
01052 cosTheta * cosPhi * radius));
01053
01054 tx->push_back(Vec2f(b / Real32(longres),
01055 a / Real32(latres)));
01056 }
01057 }
01058
01059
01060
01061 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
01062 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
01063 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
01064
01065 for(a = 0; a < longres; a++)
01066 {
01067 t->push_back(GL_TRIANGLE_STRIP);
01068 l->push_back((latres + 1) * 2);
01069
01070 for(b = 0; b <= latres; b++)
01071 {
01072 i->push_back(b * (longres+1) + a);
01073 i->push_back(b * (longres+1) + a + 1);
01074 }
01075 }
01076
01077
01078
01079 GeometryTransitPtr geo = Geometry::create();
01080
01081 geo->setMaterial(getDefaultMaterial());
01082 geo->setPositions(pnts);
01083 geo->setNormals(norms);
01084 geo->setTexCoords(tex);
01085 geo->setIndices(index);
01086 geo->setTypes(types);
01087 geo->setLengths(lens);
01088
01089 return geo;
01090 }
01091
01092
01104 NodeTransitPtr makeLatLongEllipsoid(UInt16 latres,
01105 UInt16 longres,
01106 Real32 rSemiMajorAxis,
01107 Real32 rSemiMinorAxis)
01108 {
01109 GeometryTransitPtr pGeo = makeLatLongEllipsoidGeo(latres,
01110 longres,
01111 rSemiMajorAxis,
01112 rSemiMinorAxis);
01113
01114 if(pGeo == NULL)
01115 {
01116 return NodeTransitPtr(NULL);
01117 }
01118
01119 NodeTransitPtr node = Node::create();
01120
01121 node->setCore(pGeo);
01122
01123 return node;
01124 }
01125
01137 GeometryTransitPtr makeLatLongEllipsoidGeo(UInt16 latres,
01138 UInt16 longres,
01139 Real32 rSemiMajorAxis,
01140 Real32 rSemiMinorAxis)
01141 {
01142 if(rSemiMajorAxis <= 0 || rSemiMinorAxis <= 0 || latres < 4 || longres < 4)
01143 {
01144 SWARNING << "makeLatLongSphere: illegal parameters "
01145 << "latres=" << latres
01146 << ", longres=" << longres
01147 << ", rSemiMajorAxis=" << rSemiMajorAxis
01148 << ", rSemiMinorAxis=" << rSemiMinorAxis
01149 << std::endl;
01150 return GeometryTransitPtr(NULL);
01151 }
01152
01153 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
01154 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
01155 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
01156 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property ::create();
01157 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property ::create();
01158 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
01159
01160 UInt16 a, b;
01161 Real32 theta, phi;
01162 Real32 cosTheta, sinTheta;
01163 Real32 latDelta, longDelta;
01164
01165
01166
01167 GeoPnt3fProperty ::StoredFieldType *p = pnts ->editFieldPtr();
01168 GeoVec3fProperty ::StoredFieldType *n = norms->editFieldPtr();
01169 GeoVec2fProperty ::StoredFieldType *tx = tex ->editFieldPtr();
01170
01171 latDelta = Pi / latres;
01172 longDelta = 2.f * Pi / longres;
01173
01174
01175
01176
01177 float rSemiMajorAxisSquare = rSemiMajorAxis * rSemiMajorAxis;
01178
01179 float e2 = (rSemiMajorAxisSquare -
01180 rSemiMinorAxis * rSemiMinorAxis) / (rSemiMajorAxisSquare);
01181
01182 for(a = 0, theta = -Pi / 2; a <= latres; a++, theta += latDelta)
01183 {
01184 cosTheta = osgCos(theta);
01185 sinTheta = osgSin(theta);
01186
01187 float v = rSemiMajorAxis / osgSqrt(1 - (e2 * sinTheta * sinTheta));
01188
01189 for(b = 0, phi = -Pi; b <= longres; b++, phi += longDelta)
01190 {
01191 GLfloat cosPhi, sinPhi;
01192
01193 cosPhi = osgCos(phi);
01194 sinPhi = osgSin(phi);
01195
01196
01197 n->push_back(Vec3f(cosTheta * sinPhi,
01198 sinTheta,
01199 cosTheta * cosPhi));
01200
01201 p->push_back(Pnt3f(cosTheta * sinPhi * v,
01202 sinTheta * ((1 - e2) * v),
01203 cosTheta * cosPhi * v));
01204
01205 tx->push_back(Vec2f(b / Real32(longres),
01206 a / Real32(latres)));
01207
01208 }
01209 }
01210
01211
01212
01213 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
01214 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
01215 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
01216
01217 for(a = 0; a < longres; a++)
01218 {
01219 t->push_back(GL_TRIANGLE_STRIP);
01220 l->push_back((latres + 1) * 2);
01221
01222 for(b = 0; b <= latres; b++)
01223 {
01224 i->push_back(b * (longres+1) + a);
01225 i->push_back(b * (longres+1) + a + 1);
01226 }
01227 }
01228
01229
01230
01231 GeometryTransitPtr geo = Geometry::create();
01232
01233 geo->setMaterial(getDefaultMaterial());
01234 geo->setPositions(pnts);
01235 geo->setNormals(norms);
01236 geo->setTexCoords(tex);
01237 geo->setIndices(index);
01238 geo->setTypes(types);
01239 geo->setLengths(lens);
01240
01241 return geo;
01242 }
01243
01244
01257 NodeTransitPtr makeLatLongEllipsoidSeg(UInt16 latres,
01258 UInt16 longres,
01259 Real32 rSemiMajorAxis,
01260 Real32 rSemiMinorAxis,
01261 Real32 rStartLatRad,
01262 Real32 rStartLongRad,
01263 Real32 rStopLatRad,
01264 Real32 rStopLongRad)
01265 {
01266 GeometryTransitPtr pGeo = makeLatLongEllipsoidGeoSeg(latres,
01267 longres,
01268 rSemiMajorAxis,
01269 rSemiMinorAxis,
01270 rStartLatRad,
01271 rStartLongRad,
01272 rStopLatRad,
01273 rStopLongRad );
01274
01275 if(pGeo == NULL)
01276 {
01277 return NodeTransitPtr(NULL);
01278 }
01279
01280 NodeTransitPtr node = Node::create();
01281
01282 node->setCore(pGeo);
01283
01284 return node;
01285 }
01286
01298 GeometryTransitPtr makeLatLongEllipsoidGeoSeg(UInt16 latres,
01299 UInt16 longres,
01300 Real32 rSemiMajorAxis,
01301 Real32 rSemiMinorAxis,
01302 Real32 rStartLatRad,
01303 Real32 rStartLongRad,
01304 Real32 rStopLatRad,
01305 Real32 rStopLongRad)
01306 {
01307 if(rSemiMajorAxis <= 0 || rSemiMinorAxis <= 0 || latres < 4 || longres < 4)
01308 {
01309 SWARNING << "makeLatLongSphere: illegal parameters "
01310 << "latres=" << latres
01311 << ", longres=" << longres
01312 << ", rSemiMajorAxis=" << rSemiMajorAxis
01313 << ", rSemiMinorAxis=" << rSemiMinorAxis
01314 << std::endl;
01315 return GeometryTransitPtr(NULL);
01316 }
01317
01318 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
01319 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
01320 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
01321 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property ::create();
01322 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property ::create();
01323 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
01324
01325 UInt16 a, b;
01326 Real32 theta, phi;
01327 Real32 cosTheta, sinTheta;
01328 Real32 latDelta, longDelta;
01329
01330
01331
01332 GeoPnt3fProperty ::StoredFieldType *p = pnts ->editFieldPtr();
01333 GeoVec3fProperty ::StoredFieldType *n = norms->editFieldPtr();
01334 GeoVec2fProperty ::StoredFieldType *tx = tex ->editFieldPtr();
01335
01336 Real32 latDiff = rStopLatRad - rStartLatRad;
01337 Real32 longDiff = rStopLongRad - rStartLongRad;
01338
01339 latDelta = latDiff / latres;
01340 longDelta = longDiff / longres;
01341
01342
01343
01344
01345 float rSemiMajorAxisSquare = rSemiMajorAxis * rSemiMajorAxis;
01346
01347 float e2 = (rSemiMajorAxisSquare -
01348 rSemiMinorAxis * rSemiMinorAxis) / (rSemiMajorAxisSquare);
01349
01350 for(a = 0, theta = rStartLatRad; a <= latres; a++, theta += latDelta)
01351 {
01352 cosTheta = osgCos(theta);
01353 sinTheta = osgSin(theta);
01354
01355 float v = rSemiMajorAxis / osgSqrt(1 - (e2 * sinTheta * sinTheta));
01356
01357 for(b = 0, phi = rStartLongRad; b <= longres; b++, phi += longDelta)
01358 {
01359 GLfloat cosPhi, sinPhi;
01360
01361 cosPhi = osgCos(phi);
01362 sinPhi = osgSin(phi);
01363
01364
01365 n->push_back(Vec3f(cosTheta * sinPhi,
01366 sinTheta,
01367 cosTheta * cosPhi));
01368
01369 p->push_back(Pnt3f(cosTheta * sinPhi * v,
01370 sinTheta * ((1 - e2) * v),
01371 cosTheta * cosPhi * v));
01372
01373 tx->push_back(Vec2f(b / Real32(longres),
01374 a / Real32(latres)));
01375
01376 }
01377 }
01378
01379
01380
01381 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
01382 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
01383 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
01384
01385 for(a = 0; a < longres; a++)
01386 {
01387 t->push_back(GL_TRIANGLE_STRIP);
01388 l->push_back((latres + 1) * 2);
01389
01390 for(b = 0; b <= latres; b++)
01391 {
01392 i->push_back(b * (longres+1) + a);
01393 i->push_back(b * (longres+1) + a + 1);
01394 }
01395 }
01396
01397
01398
01399 GeometryTransitPtr geo = Geometry::create();
01400
01401 geo->setMaterial(getDefaultMaterial());
01402 geo->setPositions(pnts);
01403 geo->setNormals(norms);
01404 geo->setTexCoords(tex);
01405 geo->setIndices(index);
01406 geo->setTypes(types);
01407 geo->setLengths(lens);
01408
01409 return geo;
01410 }
01411
01412
01413 GeometryTransitPtr makeEllipsoidAxisGeo(UInt16 latres,
01414 UInt16 longres,
01415 Real32 rSemiMajorAxis,
01416 Real32 rSemiMinorAxis)
01417 {
01418 if(rSemiMajorAxis <= 0 || rSemiMinorAxis <= 0 || latres < 4 || longres < 4)
01419 {
01420 SWARNING << "makeLatLongSphere: illegal parameters "
01421 << "latres=" << latres
01422 << ", longres=" << longres
01423 << ", rSemiMajorAxis=" << rSemiMajorAxis
01424 << ", rSemiMinorAxis=" << rSemiMinorAxis
01425 << std::endl;
01426 return GeometryTransitPtr(NULL);
01427 }
01428
01429 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
01430 GeoColor3fPropertyUnrecPtr color = GeoColor3fProperty::create();
01431 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property ::create();
01432 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property ::create();
01433 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
01434
01435 UInt16 a, b;
01436 Real32 theta, phi;
01437 Real32 cosTheta, sinTheta;
01438 Real32 latDelta, longDelta;
01439
01440
01441
01442 GeoPnt3fProperty ::StoredFieldType *p = pnts ->editFieldPtr();
01443 GeoColor3fProperty::StoredFieldType *c = color->editFieldPtr();
01444
01445 latDelta = Pi / (2 * latres);
01446 longDelta = Pi / (2 * longres);
01447
01448
01449
01450
01451 float rSemiMajorAxisSquare = rSemiMajorAxis * rSemiMajorAxis;
01452
01453 float e2 = (rSemiMajorAxisSquare -
01454 rSemiMinorAxis * rSemiMinorAxis) / (rSemiMajorAxisSquare);
01455
01456 for(a = 0, theta = 0; a <= latres; a++, theta += latDelta)
01457 {
01458 cosTheta = osgCos(theta);
01459 sinTheta = osgSin(theta);
01460
01461 float v = rSemiMajorAxis / osgSqrt(1 - (e2 * sinTheta * sinTheta));
01462
01463 phi = 0;
01464
01465 GLfloat cosPhi, sinPhi;
01466
01467 cosPhi = osgCos(phi);
01468 sinPhi = osgSin(phi);
01469
01470
01471 p->push_back(Pnt3f(cosTheta * sinPhi * v,
01472 sinTheta * ((1 - e2) * v),
01473 cosTheta * cosPhi * v));
01474
01475 c->push_back(Color3f(0.f, 1.f, 0.f));
01476 }
01477
01478 theta = 0;
01479
01480 cosTheta = osgCos(theta);
01481 sinTheta = osgSin(theta);
01482
01483 float v = rSemiMajorAxis / osgSqrt(1 - (e2 * sinTheta * sinTheta));
01484
01485 for(b = 0, phi = 0; b <= longres; b++, phi += longDelta)
01486 {
01487 GLfloat cosPhi, sinPhi;
01488
01489 cosPhi = osgCos(phi);
01490 sinPhi = osgSin(phi);
01491
01492
01493 p->push_back(Pnt3f(cosTheta * sinPhi * v,
01494 sinTheta * ((1 - e2) * v),
01495 cosTheta * cosPhi * v));
01496
01497 c->push_back(Color3f(1.f, 0.f, 0.f));
01498 }
01499
01500
01501
01502
01503 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
01504 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
01505 GeoUInt8Property ::StoredFieldType *t = types->editFieldPtr();
01506
01507 t->push_back(GL_LINE_STRIP);
01508 l->push_back(latres + 1);
01509
01510 t->push_back(GL_LINE_STRIP);
01511 l->push_back(longres + 1);
01512
01513 for(a = 0; a <= latres; a++)
01514 {
01515 i->push_back(a);
01516 }
01517
01518 for(b = 0; b <= longres; b++)
01519 {
01520 i->push_back(b + a);
01521 }
01522
01523
01524
01525 GeometryUnrecPtr geo = Geometry::create();
01526
01527 geo->setMaterial(getDefaultUnlitMaterial());
01528 geo->setPositions(pnts);
01529 geo->setColors(color);
01530 geo->setIndices(index);
01531 geo->setTypes(types);
01532 geo->setLengths(lens);
01533
01534 return GeometryTransitPtr(geo);
01535 }
01536
01537 NodeTransitPtr makeEllipsoidAxis(UInt16 latres,
01538 UInt16 longres,
01539 Real32 rSemiMajorAxis,
01540 Real32 rSemiMinorAxis)
01541 {
01542 GeometryTransitPtr pGeo = makeEllipsoidAxisGeo(latres,
01543 longres,
01544 rSemiMajorAxis,
01545 rSemiMinorAxis);
01546
01547 if(pGeo == NULL)
01548 {
01549 return NodeTransitPtr(NULL);
01550 }
01551
01552 NodeTransitPtr node = Node::create();
01553
01554 node->setCore(pGeo);
01555
01556 return node;
01557 }
01558
01573 NodeTransitPtr makeBox(Real32 xsize, Real32 ysize, Real32 zsize,
01574 UInt16 hor , UInt16 vert , UInt16 depth)
01575 {
01576 GeometryTransitPtr pGeo = makeBoxGeo(xsize, ysize, zsize, hor, vert, depth);
01577
01578 if(pGeo == NULL)
01579 {
01580 return NodeTransitPtr(NULL);
01581 }
01582
01583 NodeTransitPtr node = Node::create();
01584
01585 node->setCore(pGeo);
01586
01587 return node;
01588 }
01589
01604 GeometryTransitPtr makeBoxGeo(Real32 xsize, Real32 ysize, Real32 zsize,
01605 UInt16 hor , UInt16 vert , UInt16 depth)
01606 {
01607 if(! hor || ! vert || ! depth)
01608 {
01609 SWARNING << "makeBox: illegal parameters hor=" << hor << ", vert="
01610 << vert << ", depth=" << depth << std::endl;
01611 return GeometryTransitPtr(NULL);
01612 }
01613
01614 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
01615 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
01616 GeoVec2fPropertyUnrecPtr tex = GeoVec2fProperty ::create();
01617 GeoUInt32PropertyUnrecPtr index = GeoUInt32Property::create();
01618 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
01619 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
01620
01621 UInt16 x,y,pl;
01622 Vec3f size(xsize, ysize, zsize);
01623 Vec3f step(xsize / hor, ysize / vert, zsize / depth);
01624 Vec3f res(hor, vert, depth);
01625
01626
01627
01628 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
01629 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
01630 GeoVec2fProperty::StoredFieldType *tx = tex ->editFieldPtr();
01631
01632 static int inds[6][2] = { {0,1}, {0,1}, {2,1}, {2,1}, {0,2}, {0,2} };
01633 static int signs[6][2] = { {1,1}, {-1,1}, {-1,1}, {1,1}, {1,-1}, {1,1} };
01634 static int asigns[6] = { 1, -1, 1, -1, 1, -1 };
01635
01636 for(pl = 0; pl < 6; pl++)
01637 {
01638 UInt16 axis = 3 - inds[pl][0] - inds[pl][1];
01639
01640 for(y = 0; y <= res[inds[pl][1]] ; y++)
01641 {
01642 for(x = 0; x <= res[inds[pl][0]]; x++)
01643 {
01644 Pnt3f pnt;
01645 pnt[ inds[pl][0] ] = (x * step[inds[pl][0]] - size[inds[pl][0]] / 2) *
01646 signs[pl][0];
01647 pnt[ inds[pl][1] ] = (y * step[inds[pl][1]] - size[inds[pl][1]] / 2) *
01648 signs[pl][1];
01649 pnt[ axis ] = size[ axis ] * asigns[ pl ] / 2;
01650 p->push_back(pnt);
01651
01652 Vec3f norm(0, 0, 0);
01653 norm[ axis ] = Real32(asigns[ pl ]);
01654 n->push_back(norm);
01655 tx->push_back(Vec2f(x / Real32(res[inds[pl][0]]),
01656 y / Real32(res[inds[pl][1]])));
01657 }
01658 }
01659 }
01660
01661
01662
01663 GeoUInt32Property::StoredFieldType *i = index->editFieldPtr();
01664 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
01665 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
01666
01667 UInt32 basepoint = 0;
01668
01669 for(pl = 0; pl < 6; pl++)
01670 {
01671 for(y = 0; y < res[inds[pl][1]]; y++)
01672 {
01673 UInt16 h = UInt16(res[inds[pl][0]]);
01674
01675 t->push_back(GL_TRIANGLE_STRIP);
01676 l->push_back(2 * (h + 1));
01677
01678 for(x = 0; x <= h; x++)
01679 {
01680 i->push_back(basepoint + (y + 1) * (h + 1) + x);
01681 i->push_back(basepoint + y * (h + 1) + x);
01682 }
01683 }
01684 basepoint += UInt32((res[inds[pl][0]] + 1.f) *
01685 (res[inds[pl][1]] + 1.f) );
01686 }
01687
01688
01689
01690 GeometryTransitPtr geo = Geometry::create();
01691
01692 geo->setMaterial(getDefaultMaterial());
01693 geo->setPositions(pnts);
01694 geo->setNormals(norms);
01695 geo->setTexCoords(tex);
01696 geo->setIndices(index);
01697 geo->setTypes(types);
01698 geo->setLengths(lens);
01699
01700 return geo;
01701 }
01702
01711 NodeTransitPtr makeTeapot(UInt16 depth, Real32 rScale)
01712 {
01713 GeometryTransitPtr pGeo = makeTeapotGeo(depth, rScale);
01714
01715 if(pGeo == NULL)
01716 {
01717 return NodeTransitPtr(NULL);
01718 }
01719
01720 NodeTransitPtr node = Node::create();
01721
01722 node->setCore(pGeo);
01723
01724 return node;
01725 }
01726
01727 namespace {
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740 #define BOTTOM
01741
01742 #ifdef BOTTOM
01743 #define NUM_PATCHES 32
01744 #else
01745 #define NUM_PATCHES 28
01746 #endif
01747
01748 static int Patches[32][4][4] = {
01749
01750 {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}},
01751 {{3, 16, 17, 18}, {7, 19, 20, 21}, {11, 22, 23, 24}, {15, 25, 26, 27}},
01752 {{18, 28, 29, 30}, {21, 31, 32, 33}, {24, 34, 35, 36}, {27, 37, 38, 39}},
01753 {{30, 40, 41, 0}, {33, 42, 43, 4}, {36, 44, 45, 8}, {39, 46, 47, 12}},
01754
01755 {{12, 13, 14, 15}, {48, 49, 50, 51}, {52, 53, 54, 55}, {56, 57, 58, 59}},
01756 {{15, 25, 26, 27}, {51, 60, 61, 62}, {55, 63, 64, 65}, {59, 66, 67, 68}},
01757 {{27, 37, 38, 39}, {62, 69, 70, 71}, {65, 72, 73, 74}, {68, 75, 76, 77}},
01758 {{39, 46, 47, 12}, {71, 78, 79, 48}, {74, 80, 81, 52}, {77, 82, 83, 56}},
01759 {{56, 57, 58, 59}, {84, 85, 86, 87}, {88, 89, 90, 91}, {92, 93, 94, 95}},
01760 {{59, 66, 67, 68}, {87, 96, 97, 98}, {91, 99, 100, 101}, {95, 102, 103, 104}},
01761 {{68, 75, 76, 77}, {98, 105, 106, 107}, {101, 108, 109, 110}, {104, 111, 112, 113}},
01762 {{77, 82, 83, 56}, {107, 114, 115, 84}, {110, 116, 117, 88}, {113, 118, 119, 92}},
01763
01764 {{120, 121, 122, 123}, {124, 125, 126, 127}, {128, 129, 130, 131}, {132, 133, 134, 135}},
01765 {{123, 136, 137, 120}, {127, 138, 139, 124}, {131, 140, 141, 128}, {135, 142, 143, 132}},
01766 {{132, 133, 134, 135}, {144, 145, 146, 147}, {148, 149, 150, 151}, {68, 152, 153, 154}},
01767 {{135, 142, 143, 132}, {147, 155, 156, 144}, {151, 157, 158, 148}, {154, 159, 160, 68}},
01768
01769 {{161, 162, 163, 164}, {165, 166, 167, 168}, {169, 170, 171, 172}, {173, 174, 175, 176}},
01770 {{164, 177, 178, 161}, {168, 179, 180, 165}, {172, 181, 182, 169}, {176, 183, 184, 173}},
01771 {{173, 174, 175, 176}, {185, 186, 187, 188}, {189, 190, 191, 192}, {193, 194, 195, 196}},
01772 {{176, 183, 184, 173}, {188, 197, 198, 185}, {192, 199, 200, 189}, {196, 201, 202, 193}},
01773
01774 {{203, 203, 203, 203}, {204, 205, 206, 207}, {208, 208, 208, 208}, {209, 210, 211, 212}},
01775 {{203, 203, 203, 203}, {207, 213, 214, 215}, {208, 208, 208, 208}, {212, 216, 217, 218}},
01776 {{203, 203, 203, 203}, {215, 219, 220, 221}, {208, 208, 208, 208}, {218, 222, 223, 224}},
01777 {{203, 203, 203, 203}, {221, 225, 226, 204}, {208, 208, 208, 208}, {224, 227, 228, 209}},
01778 {{209, 210, 211, 212}, {229, 230, 231, 232}, {233, 234, 235, 236}, {237, 238, 239, 240}},
01779 {{212, 216, 217, 218}, {232, 241, 242, 243}, {236, 244, 245, 246}, {240, 247, 248, 249}},
01780 {{218, 222, 223, 224}, {243, 250, 251, 252}, {246, 253, 254, 255}, {249, 256, 257, 258}},
01781 {{224, 227, 228, 209}, {252, 259, 260, 229}, {255, 261, 262, 233}, {258, 263, 264, 237}},
01782
01783 {{265, 265, 265, 265}, {266, 267, 268, 269}, {270, 271, 272, 273}, {92, 119, 118, 113}},
01784 {{265, 265, 265, 265}, {269, 274, 275, 276}, {273, 277, 278, 279}, {113, 112, 111, 104}},
01785 {{265, 265, 265, 265}, {276, 280, 281, 282}, {279, 283, 284, 285}, {104, 103, 102, 95}},
01786 {{265, 265, 265, 265}, {282, 286, 287, 266}, {285, 288, 289, 270}, {95, 94, 93, 92}}
01787 };
01788
01789 static Vec3f Verts[290] = {
01790 Vec3f(1.4, 0, 2.4),
01791 Vec3f(1.4, -0.784, 2.4),
01792 Vec3f(0.784, -1.4, 2.4),
01793 Vec3f(0, -1.4, 2.4),
01794 Vec3f(1.3375, 0, 2.53125),
01795 Vec3f(1.3375, -0.749, 2.53125),
01796 Vec3f(0.749, -1.3375, 2.53125),
01797 Vec3f(0, -1.3375, 2.53125),
01798 Vec3f(1.4375, 0, 2.53125),
01799 Vec3f(1.4375, -0.805, 2.53125),
01800 Vec3f(0.805, -1.4375, 2.53125),
01801 Vec3f(0, -1.4375, 2.53125),
01802 Vec3f(1.5, 0, 2.4),
01803 Vec3f(1.5, -0.84, 2.4),
01804 Vec3f(0.84, -1.5, 2.4),
01805 Vec3f(0, -1.5, 2.4),
01806 Vec3f(-0.784, -1.4, 2.4),
01807 Vec3f(-1.4, -0.784, 2.4),
01808 Vec3f(-1.4, 0, 2.4),
01809 Vec3f(-0.749, -1.3375, 2.53125),
01810 Vec3f(-1.3375, -0.749, 2.53125),
01811 Vec3f(-1.3375, 0, 2.53125),
01812 Vec3f(-0.805, -1.4375, 2.53125),
01813 Vec3f(-1.4375, -0.805, 2.53125),
01814 Vec3f(-1.4375, 0, 2.53125),
01815 Vec3f(-0.84, -1.5, 2.4),
01816 Vec3f(-1.5, -0.84, 2.4),
01817 Vec3f(-1.5, 0, 2.4),
01818 Vec3f(-1.4, 0.784, 2.4),
01819 Vec3f(-0.784, 1.4, 2.4),
01820 Vec3f(0, 1.4, 2.4),
01821 Vec3f(-1.3375, 0.749, 2.53125),
01822 Vec3f(-0.749, 1.3375, 2.53125),
01823 Vec3f(0, 1.3375, 2.53125),
01824 Vec3f(-1.4375, 0.805, 2.53125),
01825 Vec3f(-0.805, 1.4375, 2.53125),
01826 Vec3f(0, 1.4375, 2.53125),
01827 Vec3f(-1.5, 0.84, 2.4),
01828 Vec3f(-0.84, 1.5, 2.4),
01829 Vec3f(0, 1.5, 2.4),
01830 Vec3f(0.784, 1.4, 2.4),
01831 Vec3f(1.4, 0.784, 2.4),
01832 Vec3f(0.749, 1.3375, 2.53125),
01833 Vec3f(1.3375, 0.749, 2.53125),
01834 Vec3f(0.805, 1.4375, 2.53125),
01835 Vec3f(1.4375, 0.805, 2.53125),
01836 Vec3f(0.84, 1.5, 2.4),
01837 Vec3f(1.5, 0.84, 2.4),
01838 Vec3f(1.75, 0, 1.875),
01839 Vec3f(1.75, -0.98, 1.875),
01840 Vec3f(0.98, -1.75, 1.875),
01841 Vec3f(0, -1.75, 1.875),
01842 Vec3f(2, 0, 1.35),
01843 Vec3f(2, -1.12, 1.35),
01844 Vec3f(1.12, -2, 1.35),
01845 Vec3f(0, -2, 1.35),
01846 Vec3f(2, 0, 0.9),
01847 Vec3f(2, -1.12, 0.9),
01848 Vec3f(1.12, -2, 0.9),
01849 Vec3f(0, -2, 0.9),
01850 Vec3f(-0.98, -1.75, 1.875),
01851 Vec3f(-1.75, -0.98, 1.875),
01852 Vec3f(-1.75, 0, 1.875),
01853 Vec3f(-1.12, -2, 1.35),
01854 Vec3f(-2, -1.12, 1.35),
01855 Vec3f(-2, 0, 1.35),
01856 Vec3f(-1.12, -2, 0.9),
01857 Vec3f(-2, -1.12, 0.9),
01858 Vec3f(-2, 0, 0.9),
01859 Vec3f(-1.75, 0.98, 1.875),
01860 Vec3f(-0.98, 1.75, 1.875),
01861 Vec3f(0, 1.75, 1.875),
01862 Vec3f(-2, 1.12, 1.35),
01863 Vec3f(-1.12, 2, 1.35),
01864 Vec3f(0, 2, 1.35),
01865 Vec3f(-2, 1.12, 0.9),
01866 Vec3f(-1.12, 2, 0.9),
01867 Vec3f(0, 2, 0.9),
01868 Vec3f(0.98, 1.75, 1.875),
01869 Vec3f(1.75, 0.98, 1.875),
01870 Vec3f(1.12, 2, 1.35),
01871 Vec3f(2, 1.12, 1.35),
01872 Vec3f(1.12, 2, 0.9),
01873 Vec3f(2, 1.12, 0.9),
01874 Vec3f(2, 0, 0.45),
01875 Vec3f(2, -1.12, 0.45),
01876 Vec3f(1.12, -2, 0.45),
01877 Vec3f(0, -2, 0.45),
01878 Vec3f(1.5, 0, 0.225),
01879 Vec3f(1.5, -0.84, 0.225),
01880 Vec3f(0.84, -1.5, 0.225),
01881 Vec3f(0, -1.5, 0.225),
01882 Vec3f(1.5, 0, 0.15),
01883 Vec3f(1.5, -0.84, 0.15),
01884 Vec3f(0.84, -1.5, 0.15),
01885 Vec3f(0, -1.5, 0.15),
01886 Vec3f(-1.12, -2, 0.45),
01887 Vec3f(-2, -1.12, 0.45),
01888 Vec3f(-2, 0, 0.45),
01889 Vec3f(-0.84, -1.5, 0.225),
01890 Vec3f(-1.5, -0.84, 0.225),
01891 Vec3f(-1.5, 0, 0.225),
01892 Vec3f(-0.84, -1.5, 0.15),
01893 Vec3f(-1.5, -0.84, 0.15),
01894 Vec3f(-1.5, 0, 0.15),
01895 Vec3f(-2, 1.12, 0.45),
01896 Vec3f(-1.12, 2, 0.45),
01897 Vec3f(0, 2, 0.45),
01898 Vec3f(-1.5, 0.84, 0.225),
01899 Vec3f(-0.84, 1.5, 0.225),
01900 Vec3f(0, 1.5, 0.225),
01901 Vec3f(-1.5, 0.84, 0.15),
01902 Vec3f(-0.84, 1.5, 0.15),
01903 Vec3f(0, 1.5, 0.15),
01904 Vec3f(1.12, 2, 0.45),
01905 Vec3f(2, 1.12, 0.45),
01906 Vec3f(0.84, 1.5, 0.225),
01907 Vec3f(1.5, 0.84, 0.225),
01908 Vec3f(0.84, 1.5, 0.15),
01909 Vec3f(1.5, 0.84, 0.15),
01910 Vec3f(-1.6, 0, 2.025),
01911 Vec3f(-1.6, -0.3, 2.025),
01912 Vec3f(-1.5, -0.3, 2.25),
01913 Vec3f(-1.5, 0, 2.25),
01914 Vec3f(-2.3, 0, 2.025),
01915 Vec3f(-2.3, -0.3, 2.025),
01916 Vec3f(-2.5, -0.3, 2.25),
01917 Vec3f(-2.5, 0, 2.25),
01918 Vec3f(-2.7, 0, 2.025),
01919 Vec3f(-2.7, -0.3, 2.025),
01920 Vec3f(-3, -0.3, 2.25),
01921 Vec3f(-3, 0, 2.25),
01922 Vec3f(-2.7, 0, 1.8),
01923 Vec3f(-2.7, -0.3, 1.8),
01924 Vec3f(-3, -0.3, 1.8),
01925 Vec3f(-3, 0, 1.8),
01926 Vec3f(-1.5, 0.3, 2.25),
01927 Vec3f(-1.6, 0.3, 2.025),
01928 Vec3f(-2.5, 0.3, 2.25),
01929 Vec3f(-2.3, 0.3, 2.025),
01930 Vec3f(-3, 0.3, 2.25),
01931 Vec3f(-2.7, 0.3, 2.025),
01932 Vec3f(-3, 0.3, 1.8),
01933 Vec3f(-2.7, 0.3, 1.8),
01934 Vec3f(-2.7, 0, 1.575),
01935 Vec3f(-2.7, -0.3, 1.575),
01936 Vec3f(-3, -0.3, 1.35),
01937 Vec3f(-3, 0, 1.35),
01938 Vec3f(-2.5, 0, 1.125),
01939 Vec3f(-2.5, -0.3, 1.125),
01940 Vec3f(-2.65, -0.3, 0.9375),
01941 Vec3f(-2.65, 0, 0.9375),
01942 Vec3f(-2, -0.3, 0.9),
01943 Vec3f(-1.9, -0.3, 0.6),
01944 Vec3f(-1.9, 0, 0.6),
01945 Vec3f(-3, 0.3, 1.35),
01946 Vec3f(-2.7, 0.3, 1.575),
01947 Vec3f(-2.65, 0.3, 0.9375),
01948 Vec3f(-2.5, 0.3, 1.125),
01949 Vec3f(-1.9, 0.3, 0.6),
01950 Vec3f(-2, 0.3, 0.9),
01951 Vec3f(1.7, 0, 1.425),
01952 Vec3f(1.7, -0.66, 1.425),
01953 Vec3f(1.7, -0.66, 0.6),
01954 Vec3f(1.7, 0, 0.6),
01955 Vec3f(2.6, 0, 1.425),
01956 Vec3f(2.6, -0.66, 1.425),
01957 Vec3f(3.1, -0.66, 0.825),
01958 Vec3f(3.1, 0, 0.825),
01959 Vec3f(2.3, 0, 2.1),
01960 Vec3f(2.3, -0.25, 2.1),
01961 Vec3f(2.4, -0.25, 2.025),
01962 Vec3f(2.4, 0, 2.025),
01963 Vec3f(2.7, 0, 2.4),
01964 Vec3f(2.7, -0.25, 2.4),
01965 Vec3f(3.3, -0.25, 2.4),
01966 Vec3f(3.3, 0, 2.4),
01967 Vec3f(1.7, 0.66, 0.6),
01968 Vec3f(1.7, 0.66, 1.425),
01969 Vec3f(3.1, 0.66, 0.825),
01970 Vec3f(2.6, 0.66, 1.425),
01971 Vec3f(2.4, 0.25, 2.025),
01972 Vec3f(2.3, 0.25, 2.1),
01973 Vec3f(3.3, 0.25, 2.4),
01974 Vec3f(2.7, 0.25, 2.4),
01975 Vec3f(2.8, 0, 2.475),
01976 Vec3f(2.8, -0.25, 2.475),
01977 Vec3f(3.525, -0.25, 2.49375),
01978 Vec3f(3.525, 0, 2.49375),
01979 Vec3f(2.9, 0, 2.475),
01980 Vec3f(2.9, -0.15, 2.475),
01981 Vec3f(3.45, -0.15, 2.5125),
01982 Vec3f(3.45, 0, 2.5125),
01983 Vec3f(2.8, 0, 2.4),
01984 Vec3f(2.8, -0.15, 2.4),
01985 Vec3f(3.2, -0.15, 2.4),
01986 Vec3f(3.2, 0, 2.4),
01987 Vec3f(3.525, 0.25, 2.49375),
01988 Vec3f(2.8, 0.25, 2.475),
01989 Vec3f(3.45, 0.15, 2.5125),
01990 Vec3f(2.9, 0.15, 2.475),
01991 Vec3f(3.2, 0.15, 2.4),
01992 Vec3f(2.8, 0.15, 2.4),
01993 Vec3f(0, 0, 3.15),
01994 Vec3f(0.8, 0, 3.15),
01995 Vec3f(0.8, -0.45, 3.15),
01996 Vec3f(0.45, -0.8, 3.15),
01997 Vec3f(0, -0.8, 3.15),
01998 Vec3f(0, 0, 2.85),
01999 Vec3f(0.2, 0, 2.7),
02000 Vec3f(0.2, -0.112, 2.7),
02001 Vec3f(0.112, -0.2, 2.7),
02002 Vec3f(0, -0.2, 2.7),
02003 Vec3f(-0.45, -0.8, 3.15),
02004 Vec3f(-0.8, -0.45, 3.15),
02005 Vec3f(-0.8, 0, 3.15),
02006 Vec3f(-0.112, -0.2, 2.7),
02007 Vec3f(-0.2, -0.112, 2.7),
02008 Vec3f(-0.2, 0, 2.7),
02009 Vec3f(-0.8, 0.45, 3.15),
02010 Vec3f(-0.45, 0.8, 3.15),
02011 Vec3f(0, 0.8, 3.15),
02012 Vec3f(-0.2, 0.112, 2.7),
02013 Vec3f(-0.112, 0.2, 2.7),
02014 Vec3f(0, 0.2, 2.7),
02015 Vec3f(0.45, 0.8, 3.15),
02016 Vec3f(0.8, 0.45, 3.15),
02017 Vec3f(0.112, 0.2, 2.7),
02018 Vec3f(0.2, 0.112, 2.7),
02019 Vec3f(0.4, 0, 2.55),
02020 Vec3f(0.4, -0.224, 2.55),
02021 Vec3f(0.224, -0.4, 2.55),
02022 Vec3f(0, -0.4, 2.55),
02023 Vec3f(1.3, 0, 2.55),
02024 Vec3f(1.3, -0.728, 2.55),
02025 Vec3f(0.728, -1.3, 2.55),
02026 Vec3f(0, -1.3, 2.55),
02027 Vec3f(1.3, 0, 2.4),
02028 Vec3f(1.3, -0.728, 2.4),
02029 Vec3f(0.728, -1.3, 2.4),
02030 Vec3f(0, -1.3, 2.4),
02031 Vec3f(-0.224, -0.4, 2.55),
02032 Vec3f(-0.4, -0.224, 2.55),
02033 Vec3f(-0.4, 0, 2.55),
02034 Vec3f(-0.728, -1.3, 2.55),
02035 Vec3f(-1.3, -0.728, 2.55),
02036 Vec3f(-1.3, 0, 2.55),
02037 Vec3f(-0.728, -1.3, 2.4),
02038 Vec3f(-1.3, -0.728, 2.4),
02039 Vec3f(-1.3, 0, 2.4),
02040 Vec3f(-0.4, 0.224, 2.55),
02041 Vec3f(-0.224, 0.4, 2.55),
02042 Vec3f(0, 0.4, 2.55),
02043 Vec3f(-1.3, 0.728, 2.55),
02044 Vec3f(-0.728, 1.3, 2.55),
02045 Vec3f(0, 1.3, 2.55),
02046 Vec3f(-1.3, 0.728, 2.4),
02047 Vec3f(-0.728, 1.3, 2.4),
02048 Vec3f(0, 1.3, 2.4),
02049 Vec3f(0.224, 0.4, 2.55),
02050 Vec3f(0.4, 0.224, 2.55),
02051 Vec3f(0.728, 1.3, 2.55),
02052 Vec3f(1.3, 0.728, 2.55),
02053 Vec3f(0.728, 1.3, 2.4),
02054 Vec3f(1.3, 0.728, 2.4),
02055 Vec3f(0, 0, 0),
02056 Vec3f(1.425, 0, 0),
02057 Vec3f(1.425, 0.798, 0),
02058 Vec3f(0.798, 1.425, 0),
02059 Vec3f(0, 1.425, 0),
02060 Vec3f(1.5, 0, 0.075),
02061 Vec3f(1.5, 0.84, 0.075),
02062 Vec3f(0.84, 1.5, 0.075),
02063 Vec3f(0, 1.5, 0.075),
02064 Vec3f(-0.798, 1.425, 0),
02065 Vec3f(-1.425, 0.798, 0),
02066 Vec3f(-1.425, 0, 0),
02067 Vec3f(-0.84, 1.5, 0.075),
02068 Vec3f(-1.5, 0.84, 0.075),
02069 Vec3f(-1.5, 0, 0.075),
02070 Vec3f(-1.425, -0.798, 0),
02071 Vec3f(-0.798, -1.425, 0),
02072 Vec3f(0, -1.425, 0),
02073 Vec3f(-1.5, -0.84, 0.075),
02074 Vec3f(-0.84, -1.5, 0.075),
02075 Vec3f(0, -1.5, 0.075),
02076 Vec3f(0.798, -1.425, 0),
02077 Vec3f(1.425, -0.798, 0),
02078 Vec3f(0.84, -1.5, 0.075),
02079 Vec3f(1.5, -0.84, 0.075)
02080 };
02081
02082
02083
02084
02085
02086 static bool
02087 check_for_cusp( int tot_vert, Pnt3f vert[], Vec3f norm[] )
02088 {
02089 int count, i, nv ;
02090
02091 for(count = 0, i = tot_vert; i--; )
02092 {
02093
02094 if(osgAbs(vert[i][0]) < 0.0001 &&
02095 osgAbs(vert[i][1]) < 0.0001 )
02096 {
02097 count++;
02098 nv = i;
02099 }
02100 }
02101
02102 if(count > 1)
02103 {
02104
02105 return false;
02106 }
02107 if(count == 1)
02108 {
02109
02110 if(vert[nv][2] > 1.5)
02111 {
02112
02113 norm[nv].setValues(0.0, 0.0, 1.0);
02114 }
02115 else
02116 {
02117
02118 norm[nv].setValues(0.0, 0.0, -1.0);
02119 }
02120 }
02121 return true;
02122 }
02123
02124 static void
02125 points_from_basis(int tot_vert, Real64 s[], Real64 t[], Matrix mgm[3],
02126 Pnt3f vert[], Vec3f norm[] )
02127 {
02128 int i, num_vert, p;
02129 double sval, tval, dsval, dtval, sxyz, txyz;
02130 Vec3f sdir, tdir;
02131 Vec4f sp, tp, dsp, dtp, tcoord;
02132
02133 for(num_vert = 0; num_vert < tot_vert; num_vert++)
02134 {
02135 sxyz = s[num_vert] ;
02136 txyz = t[num_vert] ;
02137
02138
02139 for(p = 4, sval = tval = 1.0; p--; )
02140 {
02141 sp[p] = sval;
02142 tp[p] = tval;
02143 sval *= sxyz;
02144 tval *= txyz;
02145
02146 if(p == 3)
02147 {
02148 dsp[p] = dtp[p] = 0.0;
02149 dsval = dtval = 1.0;
02150 }
02151 else
02152 {
02153 dsp[p] = dsval * static_cast<double>(3 - p);
02154 dtp[p] = dtval * static_cast<double>(3 - p);
02155 dsval *= sxyz;
02156 dtval *= txyz;
02157 }
02158 }
02159
02160
02161 for(i = 0; i < 3; ++i)
02162 {
02163
02164 mgm[i].mult(sp, tcoord);
02165 vert[num_vert][i] = tcoord.dot(tp);
02166
02167
02168 mgm[i].mult(dsp, tcoord);
02169 sdir[i] = tcoord.dot(tp);
02170
02171 mgm[i].mult(sp, tcoord);
02172 tdir[i] = tcoord.dot(dtp);
02173 }
02174
02175
02176 norm[num_vert] = tdir.cross(sdir);
02177 norm[num_vert].normalize();
02178 }
02179 }
02180
02181 }
02182
02192 GeometryTransitPtr makeTeapotGeo(UInt16 depth, Real32 rScale)
02193 {
02194 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
02195 GeoVec3fPropertyUnrecPtr norms = GeoVec3fProperty ::create();
02196 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
02197 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
02198
02199
02200
02201 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
02202 GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
02203
02204 UInt32 vcount = 0;
02205
02206
02207 static Matrix ms( -1.0, 3.0, -3.0, 1.0,
02208 3.0, -6.0, 3.0, 0.0,
02209 -3.0, 3.0, 0.0, 0.0,
02210 1.0, 0.0, 0.0, 0.0 );
02211 int surf, i, r, c, sstep, tstep, num_tri, num_vert, num_tri_vert;
02212 double s[3], t[3];
02213 Pnt3f vert[4];
02214 Vec3f norm[4];
02215 Matrix mst, g, mgm[3], tmtx;
02216
02217 mst.transposeFrom(ms);
02218
02219 for(surf = 0; surf < NUM_PATCHES; ++surf)
02220 {
02221
02222 for(i = 0; i < 3; ++i)
02223 {
02224
02225 for(r = 0; r < 4 ; ++r)
02226 {
02227 for(c = 0; c < 4; ++c)
02228 {
02229 g[r][c] = Verts[Patches[surf][r][c]][i];
02230 }
02231 }
02232
02233 tmtx = ms;
02234 tmtx.mult(g);
02235 tmtx.mult(mst);
02236 mgm[i] = tmtx;
02237 }
02238
02239
02240 for(sstep = 0; sstep < depth; ++sstep)
02241 {
02242 for(tstep = 0; tstep < depth; ++tstep)
02243 {
02244 for(num_tri = 0; num_tri < 2; ++num_tri)
02245 {
02246 for(num_vert = 0; num_vert < 3; ++num_vert)
02247 {
02248 num_tri_vert = (num_vert + num_tri * 2) % 4;
02249
02250 s[num_vert] = static_cast<double>(
02251 sstep + (num_tri_vert / 2 ? 1 : 0)) /
02252 static_cast<double>(depth);
02253
02254
02255 t[num_vert] = static_cast<double>(
02256 tstep + (num_tri_vert % 3 ? 1 : 0)) /
02257 static_cast<double>(depth);
02258 }
02259 points_from_basis(3, s, t, mgm, vert, norm);
02260
02261 if(check_for_cusp( 3, vert, norm))
02262 {
02263 vert[0] *= rScale;
02264 vert[1] *= rScale;
02265 vert[2] *= rScale;
02266
02267 p->push_back(vert[0]);
02268 p->push_back(vert[1]);
02269 p->push_back(vert[2]);
02270
02271 n->push_back(norm[0]);
02272 n->push_back(norm[1]);
02273 n->push_back(norm[2]);
02274
02275 vcount += 3;
02276 }
02277 }
02278 }
02279 }
02280 }
02281
02282 types->push_back(GL_TRIANGLES);
02283 lens ->push_back(vcount);
02284
02285
02286
02287 GeometryTransitPtr geo = Geometry::create();
02288
02289 geo->setMaterial(getDefaultMaterial());
02290 geo->setPositions(pnts);
02291 geo->setNormals(norms);
02292 geo->setTypes(types);
02293 geo->setLengths(lens);
02294
02295 return geo;
02296 }
02297
02298 NodeTransitPtr makeCoordAxis(Real32 length, Real32 lineWidth, bool showAxisName)
02299 {
02300 GeometryTransitPtr pGeo = makeCoordAxisGeo(length, lineWidth, showAxisName);
02301
02302 if(pGeo == NULL)
02303 {
02304 return NodeTransitPtr(NULL);
02305 }
02306
02307 NodeTransitPtr node = Node::create();
02308
02309 node->setCore(pGeo);
02310
02311 return node;
02312 }
02313
02314 GeometryTransitPtr makeCoordAxisGeo(Real32 length,
02315 Real32 lineWidth,
02316 bool showAxisName)
02317 {
02318 GeoPnt3fPropertyUnrecPtr pnts = GeoPnt3fProperty ::create();
02319 GeoUInt32PropertyUnrecPtr lens = GeoUInt32Property::create();
02320 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property ::create();
02321 GeoColor3fPropertyUnrecPtr colors = GeoColor3fProperty::create();
02322
02323 Int32 pntCnt=0;
02324
02325 GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
02326 GeoUInt32Property::StoredFieldType *l = lens ->editFieldPtr();
02327 GeoUInt8Property::StoredFieldType *t = types->editFieldPtr();
02328 GeoColor3fProperty::StoredFieldType *c = colors->editFieldPtr();
02329
02330
02331 p->push_back( Pnt3f(0,0,0) );
02332 p->push_back( Pnt3f(length,0,0) );
02333 pntCnt += 2;
02334 c->push_back( Color3f(1,0,0) );
02335 c->push_back( Color3f(1,0,0) );
02336
02337
02338 p->push_back( Pnt3f(0,0,0) );
02339 p->push_back( Pnt3f(0,length,0) );
02340 pntCnt += 2;
02341 c->push_back( Color3f(0,1,0) );
02342 c->push_back( Color3f(0,1,0) );
02343
02344
02345 p->push_back( Pnt3f(0,0,0) );
02346 p->push_back( Pnt3f(0,0,length) );
02347 pntCnt += 2;
02348 c->push_back( Color3f(0,0,1) );
02349 c->push_back( Color3f(0,0,1) );
02350
02351 if( showAxisName )
02352 {
02353
02354 p->push_back( Pnt3f(length, 0.125, 0) );
02355 p->push_back( Pnt3f(length+0.25, -0.125, 0) );
02356 p->push_back( Pnt3f(length,-0.125,0) );
02357 p->push_back( Pnt3f(length+0.25,0.125,0) );
02358 pntCnt += 4;
02359 for (unsigned i=0;i<4;i++)
02360 { c->push_back( Color3f(1,0,0) ); }
02361
02362
02363 p->push_back( Pnt3f(-0.125, length, 0) );
02364 p->push_back( Pnt3f( 0.125, length+0.25, 0) );
02365 p->push_back( Pnt3f(-0.125, length+0.25, 0) );
02366 p->push_back( Pnt3f( 0.000, length+0.125,0) );
02367 pntCnt += 4;
02368 for (unsigned i=0;i<4;i++)
02369 { c->push_back( Color3f(0,1,0) ); }
02370
02371
02372 p->push_back( Pnt3f(-0.125, 0, length) );
02373 p->push_back( Pnt3f( 0.125, 0, length) );
02374 p->push_back( Pnt3f( 0.125, 0, length) );
02375 p->push_back( Pnt3f(-0.125, 0, length+0.25) );
02376 p->push_back( Pnt3f(-0.125, 0, length+0.25) );
02377 p->push_back( Pnt3f( 0.125, 0, length+0.25) );
02378 pntCnt += 6;
02379 for (unsigned i=0;i<6;i++)
02380 { c->push_back( Color3f(0,0,1) ); }
02381 }
02382
02383
02384
02385 t->push_back(GL_LINES);
02386 l->push_back(pntCnt);
02387
02388 LineChunkUnrecPtr lineChunk = LineChunk::create();
02389
02390 lineChunk->setWidth(lineWidth);
02391
02392 SimpleMaterialUnrecPtr mat = SimpleMaterial::create();
02393
02394 mat->setLit(false);
02395 mat->addChunk(lineChunk);
02396 mat->setColorMaterial(GL_AMBIENT_AND_DIFFUSE);
02397
02398
02399 GeometryTransitPtr geo = Geometry::create();
02400 geo->setMaterial(mat);
02401 geo->setPositions(pnts);
02402 geo->setTypes(types);
02403 geo->setLengths(lens);
02404 geo->setColors(colors);
02405
02406 return geo;
02407 }
02408 OSG_END_NAMESPACE