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
00038
00039
00040
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043
00044 #include "OSGConfig.h"
00045 #include <OSGLog.h>
00046 #include <OSGQuaternion.h>
00047 #include <OSGSimpleMaterial.h>
00048 #include <OSGTriangleIterator.h>
00049 #include "OSGSimpleGeometry.h"
00050
00051 OSG_USING_NAMESPACE
00052
00053
00054
00055
00056
00057 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00058 #pragma warning (disable : 383)
00059 #endif
00060
00064 static SimpleMaterialPtr _defaultMaterial;
00065
00071 OSG_SYSTEMLIB_DLLMAPPING MaterialPtr OSG::getDefaultMaterial(void)
00072 {
00073 if(_defaultMaterial == NullFC)
00074 {
00075 _defaultMaterial = SimpleMaterial::create();
00076
00077 beginEditCP(_defaultMaterial);
00078 _defaultMaterial->setDiffuse(Color3f(.7,.7,.5));
00079 _defaultMaterial->setAmbient(Color3f(0.1,0.1,0.1));
00080 _defaultMaterial->setSpecular(Color3f(1,1,1));
00081 _defaultMaterial->setShininess(20);
00082 endEditCP (_defaultMaterial);
00083
00084 addRefCP(_defaultMaterial);
00085 }
00086
00087 return _defaultMaterial;
00088 }
00089
00093 static SimpleMaterialPtr _defaultUnlitMaterial;
00094
00099 OSG_SYSTEMLIB_DLLMAPPING MaterialPtr OSG::getDefaultUnlitMaterial(void)
00100 {
00101 if(_defaultUnlitMaterial == NullFC)
00102 {
00103 _defaultUnlitMaterial = SimpleMaterial::create();
00104
00105 beginEditCP(_defaultUnlitMaterial);
00106 _defaultUnlitMaterial->setDiffuse(Color3f(1,1,.5));
00107 _defaultUnlitMaterial->setLit(false);
00108 endEditCP (_defaultUnlitMaterial);
00109
00110 addRefCP(_defaultUnlitMaterial);
00111 }
00112
00113 return _defaultUnlitMaterial;
00114 }
00115
00116
00117
00124 NodePtr OSG::makePlane(Real32 xsize, Real32 ysize, UInt16 hor, UInt16 vert)
00125 {
00126 GeometryPtr pGeo = makePlaneGeo(xsize, ysize, hor, vert);
00127
00128 if(pGeo == NullFC)
00129 {
00130 return NullFC;
00131 }
00132
00133 NodePtr node = Node::create();
00134
00135 beginEditCP (node);
00136 node->setCore(pGeo);
00137 endEditCP (node);
00138
00139 return node;
00140 }
00141
00146 GeometryPtr OSG::makePlaneGeo(Real32 xsize, Real32 ysize,
00147 UInt16 hor, UInt16 vert)
00148 {
00149 if(! hor || ! vert)
00150 {
00151 SWARNING << "makePlane: illegal parameters hor=" << hor << ", vert="
00152 << vert << std::endl;
00153 return NullFC;
00154 }
00155
00156 GeoPositions3fPtr pnts = GeoPositions3f::create();
00157 GeoNormals3fPtr norms = GeoNormals3f::create();
00158 GeoTexCoords2fPtr tex = GeoTexCoords2f::create();
00159 GeoIndicesUI32Ptr index = GeoIndicesUI32::create();
00160 GeoPLengthsUI32Ptr lens = GeoPLengthsUI32::create();
00161 GeoPTypesUI8Ptr types = GeoPTypesUI8::create();
00162
00163 UInt16 x,y;
00164 Real32 xstep,ystep;
00165 xstep=xsize / hor;
00166 ystep=ysize / vert;
00167
00168
00169
00170 GeoPositions3f::StoredFieldType * p = pnts->getFieldPtr();
00171 GeoNormals3f::StoredFieldType * n = norms->getFieldPtr();
00172 GeoTexCoords2f::StoredFieldType * tx = tex->getFieldPtr();
00173
00174 beginEditCP(pnts);
00175 beginEditCP(norms);
00176 beginEditCP(tex);
00177
00178 for(y = 0; y <= vert; y++)
00179 {
00180 for(x = 0; x <= hor; x++)
00181 {
00182 p->push_back(Pnt3f(x * xstep - xsize / 2, y * ystep - ysize / 2, 0));
00183 n->push_back(Vec3f(0, 0, 1));
00184 tx->push_back(Vec2f(x / (Real32) hor, y / (Real32) vert));
00185 }
00186 }
00187
00188 endEditCP(pnts);
00189 endEditCP(norms);
00190 endEditCP(tex);
00191
00192
00193
00194 GeoIndicesUI32::StoredFieldType * i = index->getFieldPtr();
00195 GeoPLengthsUI32::StoredFieldType * l = lens->getFieldPtr();
00196 GeoPTypesUI8::StoredFieldType * t = types->getFieldPtr();
00197
00198 beginEditCP(index);
00199 beginEditCP(lens);
00200 beginEditCP(types);
00201
00202 for(y = 0; y < vert; y++)
00203 {
00204 t->push_back(GL_TRIANGLE_STRIP);
00205 l->push_back(2 * (hor + 1));
00206
00207 for(x = 0; x <= hor; x++)
00208 {
00209 i->push_back((y + 1) * (hor + 1) + x);
00210 i->push_back( y * (hor + 1) + x);
00211 }
00212 }
00213
00214 endEditCP(index);
00215 endEditCP(lens);
00216 endEditCP(types);
00217
00218
00219
00220 GeometryPtr geo = Geometry::create();
00221
00222 beginEditCP(geo);
00223 geo->setMaterial(getDefaultMaterial());
00224 geo->setPositions(pnts);
00225 geo->setNormals(norms);
00226 geo->setTexCoords(tex);
00227 geo->setIndices(index);
00228 geo->getIndexMapping().push_back(Geometry::MapPosition |
00229 Geometry::MapNormal |
00230 Geometry::MapTexCoords);
00231 geo->setTypes(types);
00232 geo->setLengths(lens);
00233 endEditCP(geo);
00234
00235 return geo;
00236 }
00237
00246 NodePtr OSG::makeCone(Real32 height,
00247 Real32 botradius,
00248 UInt16 sides,
00249 bool doSide,
00250 bool doBottom)
00251 {
00252 return makeConicalFrustum(height,
00253 0,
00254 botradius,
00255 sides,
00256 doSide,
00257 false,
00258 doBottom);
00259 }
00260
00265 GeometryPtr OSG::makeConeGeo(Real32 height,
00266 Real32 botradius,
00267 UInt16 sides,
00268 bool doSide,
00269 bool doBottom)
00270 {
00271 return makeConicalFrustumGeo(height,
00272 0,
00273 botradius,
00274 sides,
00275 doSide,
00276 false,
00277 doBottom);
00278 }
00279
00290 NodePtr OSG::makeCylinder(Real32 height,
00291 Real32 radius,
00292 UInt16 sides,
00293 bool doSide,
00294 bool doTop,
00295 bool doBottom)
00296 {
00297 return makeConicalFrustum(height,
00298 radius,
00299 radius,
00300 sides,
00301 doSide,
00302 doTop,
00303 doBottom);
00304 }
00305
00310 GeometryPtr OSG::makeCylinderGeo(Real32 height,
00311 Real32 radius,
00312 UInt16 sides,
00313 bool doSide,
00314 bool doTop,
00315 bool doBottom)
00316 {
00317 return makeConicalFrustumGeo(height,
00318 radius,
00319 radius,
00320 sides,
00321 doSide,
00322 doTop,
00323 doBottom);
00324 }
00325
00326
00338 NodePtr OSG::makeConicalFrustum(Real32 height,
00339 Real32 topradius,
00340 Real32 botradius,
00341 UInt16 sides,
00342 bool doSide,
00343 bool doTop,
00344 bool doBottom)
00345 {
00346 GeometryPtr pGeo = makeConicalFrustumGeo(height,
00347 topradius,
00348 botradius,
00349 sides,
00350 doSide,
00351 doTop,
00352 doBottom);
00353
00354 if(pGeo == NullFC)
00355 {
00356 return NullFC;
00357 }
00358
00359 NodePtr node = Node::create();
00360
00361 beginEditCP (node);
00362 node->setCore(pGeo);
00363 endEditCP (node);
00364
00365 return node;
00366 }
00367
00372 GeometryPtr OSG::makeConicalFrustumGeo(Real32 height,
00373 Real32 topradius,
00374 Real32 botradius,
00375 UInt16 sides,
00376 bool doSide,
00377 bool doTop,
00378 bool doBottom)
00379 {
00380 if(height <= 0 || topradius < 0 || botradius < 0 || sides < 3)
00381 {
00382 SWARNING << "makeConicalFrustum: illegal parameters height=" << height
00383 << ", topradius=" << topradius
00384 << ", botradius=" << botradius
00385 << ", sides=" << sides
00386 << std::endl;
00387 return NullFC;
00388 }
00389
00390 GeoPositions3fPtr pnts = GeoPositions3f::create();
00391 GeoNormals3fPtr norms = GeoNormals3f::create();
00392 GeoTexCoords2fPtr tex = GeoTexCoords2f::create();
00393 GeoIndicesUI32Ptr index = GeoIndicesUI32::create();
00394 GeoPLengthsUI32Ptr lens = GeoPLengthsUI32::create();
00395 GeoPTypesUI8Ptr types = GeoPTypesUI8::create();
00396
00397 Int16 j;
00398 Real32 delta = 2.f * Pi / sides;
00399 Real32 beta, x, z;
00400 Real32 incl = (botradius - topradius) / height;
00401 Real32 nlen = 1.f / osgsqrt(1 + incl * incl);
00402
00403
00404
00405 GeoPositions3f::StoredFieldType * p = pnts->getFieldPtr();
00406 GeoNormals3f::StoredFieldType * n = norms->getFieldPtr();
00407 GeoTexCoords2f::StoredFieldType * tx = tex->getFieldPtr();
00408
00409
00410
00411 GeoIndicesUI32::StoredFieldType * i = index->getFieldPtr();
00412 GeoPLengthsUI32::StoredFieldType * l = lens->getFieldPtr();
00413 GeoPTypesUI8::StoredFieldType * t = types->getFieldPtr();
00414
00415
00416
00417 beginEditCP(pnts);
00418 beginEditCP(norms);
00419 beginEditCP(tex);
00420
00421 beginEditCP(index);
00422 beginEditCP(lens);
00423 beginEditCP(types);
00424
00425 if(doSide)
00426 {
00427 UInt32 baseindex = p->size();
00428
00429 for(j = 0; j <= sides; j++)
00430 {
00431 beta = j * delta;
00432 x = osgsin(beta);
00433 z = -osgcos(beta);
00434
00435 p->push_back(Pnt3f(x * topradius, height/2, z * topradius));
00436 n->push_back(Vec3f(x/nlen, incl/nlen, z/nlen));
00437 tx->push_back(Vec2f(1.f - j / (Real32) sides, 1));
00438 }
00439
00440 for(j = 0; j <= sides; j++)
00441 {
00442 beta = j * delta;
00443 x = osgsin(beta);
00444 z = -osgcos(beta);
00445
00446 p->push_back(Pnt3f(x * botradius, -height/2, z * botradius));
00447 n->push_back(Vec3f(x/nlen, incl/nlen, z/nlen));
00448 tx->push_back(Vec2f(1.f - j / (Real32) sides, 0));
00449 }
00450
00451 t->push_back(GL_TRIANGLE_STRIP);
00452 l->push_back(2 * (sides + 1));
00453
00454 for(j = 0; j <= sides; j++)
00455 {
00456 i->push_back(baseindex + sides + 1 + j);
00457 i->push_back(baseindex + j);
00458 }
00459 }
00460
00461 if(doTop && topradius > 0)
00462 {
00463 UInt32 baseindex = p->size();
00464
00465
00466
00467 for(j = sides - 1; j >= 0; j--)
00468 {
00469 beta = j * delta;
00470 x = topradius * osgsin(beta);
00471 z = -topradius * osgcos(beta);
00472
00473 p->push_back(Pnt3f(x, height/2, z));
00474 n->push_back(Vec3f(0, 1, 0));
00475 tx->push_back(Vec2f(x / topradius / 2 + .5f, -z / topradius / 2 + .5f));
00476 }
00477
00478 t->push_back(GL_POLYGON);
00479 l->push_back(sides);
00480
00481 for(j = 0; j < sides; j++)
00482 {
00483 i->push_back(baseindex + j);
00484 }
00485 }
00486
00487 if(doBottom && botradius > 0 )
00488 {
00489 UInt32 baseindex = p->size();
00490
00491
00492
00493 for(j = sides - 1; j >= 0; j--)
00494 {
00495 beta = j * delta;
00496 x = botradius * osgsin(beta);
00497 z = -botradius * osgcos(beta);
00498
00499 p->push_back(Pnt3f(x, -height/2, z));
00500 n->push_back(Vec3f(0, -1, 0));
00501 tx->push_back(Vec2f(x / botradius / 2 + .5f, z / botradius / 2 + .5f));
00502 }
00503
00504 t->push_back(GL_POLYGON);
00505 l->push_back(sides);
00506
00507 for(j = 0; j < sides; j++)
00508 {
00509 i->push_back(baseindex + sides - 1 - j);
00510 }
00511 }
00512
00513 endEditCP(pnts);
00514 endEditCP(norms);
00515 endEditCP(tex);
00516
00517 endEditCP(index);
00518 endEditCP(lens);
00519 endEditCP(types);
00520
00521
00522
00523 GeometryPtr geo = Geometry::create();
00524
00525 beginEditCP(geo);
00526 geo->setMaterial(getDefaultMaterial());
00527 geo->setPositions(pnts);
00528 geo->setNormals(norms);
00529 geo->getIndexMapping().push_back(Geometry::MapPosition |
00530 Geometry::MapNormal |
00531 Geometry::MapTexCoords);
00532 geo->setTexCoords(tex);
00533 geo->setIndices(index);
00534 geo->setTypes(types);
00535 geo->setLengths(lens);
00536 endEditCP(geo);
00537
00538 return geo;
00539 }
00540
00547 NodePtr OSG::makeTorus(Real32 innerRadius, Real32 outerRadius, UInt16 sides,
00548 UInt16 rings)
00549 {
00550 GeometryPtr pGeo = makeTorusGeo(innerRadius, outerRadius, sides, rings);
00551
00552 if(pGeo == NullFC)
00553 {
00554 return NullFC;
00555 }
00556
00557 NodePtr node = Node::create();
00558
00559 beginEditCP (node);
00560 node->setCore(pGeo);
00561 endEditCP (node);
00562
00563 return node;
00564 }
00565
00570 GeometryPtr OSG::makeTorusGeo(Real32 innerRadius, Real32 outerRadius, UInt16 sides,
00571 UInt16 rings)
00572 {
00573 if(innerRadius <= 0 || outerRadius <= 0 || sides < 3 || rings < 3)
00574 {
00575 SWARNING << "makeTorus: illegal parameters innerRadius=" << innerRadius
00576 << ", outerRadius=" << outerRadius
00577 << ", sides=" << sides
00578 << ", rings=" << rings
00579 << std::endl;
00580 return NullFC;
00581 }
00582
00583 GeoPositions3fPtr pnts = GeoPositions3f::create();
00584 GeoNormals3fPtr norms = GeoNormals3f::create();
00585 GeoTexCoords2fPtr tex = GeoTexCoords2f::create();
00586 GeoIndicesUI32Ptr index = GeoIndicesUI32::create();
00587 GeoPLengthsUI32Ptr lens = GeoPLengthsUI32::create();
00588 GeoPTypesUI8Ptr types = GeoPTypesUI8::create();
00589
00590 UInt16 a, b;
00591 Real32 theta, phi;
00592 Real32 cosTheta, sinTheta;
00593 Real32 ringDelta, sideDelta;
00594
00595
00596
00597 GeoPositions3f::StoredFieldType * p = pnts->getFieldPtr();
00598 GeoNormals3f::StoredFieldType * n = norms->getFieldPtr();
00599 GeoTexCoords2f::StoredFieldType * tx = tex->getFieldPtr();
00600
00601 beginEditCP(pnts);
00602 beginEditCP(norms);
00603 beginEditCP(tex);
00604
00605 ringDelta = 2.f * Pi / rings;
00606 sideDelta = 2.f * Pi / sides;
00607
00608 for(a = 0, theta = 0.0; a <= rings; a++, theta += ringDelta)
00609 {
00610 cosTheta = osgcos(theta);
00611 sinTheta = osgsin(theta);
00612
00613 for(b = 0, phi = 0; b <= sides; b++, phi += sideDelta)
00614 {
00615 GLfloat cosPhi, sinPhi, dist;
00616
00617 cosPhi = osgcos(phi);
00618 sinPhi = osgsin(phi);
00619 dist = outerRadius + innerRadius * cosPhi;
00620
00621 n->push_back(Vec3f(cosTheta * cosPhi,
00622 -sinTheta * cosPhi,
00623 sinPhi));
00624 p->push_back(Pnt3f(cosTheta * dist,
00625 -sinTheta * dist,
00626 innerRadius * sinPhi));
00627 tx->push_back(Vec2f(- a / (Real32) rings, b / (Real32)sides));
00628 }
00629 }
00630
00631 endEditCP(pnts);
00632 endEditCP(norms);
00633 endEditCP(tex);
00634
00635
00636
00637 GeoIndicesUI32::StoredFieldType * i = index->getFieldPtr();
00638 GeoPLengthsUI32::StoredFieldType * l = lens->getFieldPtr();
00639 GeoPTypesUI8::StoredFieldType * t = types->getFieldPtr();
00640
00641 beginEditCP(index);
00642 beginEditCP(lens);
00643 beginEditCP(types);
00644
00645 for(a = 0; a < sides; a++)
00646 {
00647 t->push_back(GL_TRIANGLE_STRIP);
00648 l->push_back((rings + 1) * 2);
00649
00650 for(b = 0; b <= rings; b++)
00651 {
00652 i->push_back(b * (sides+1) + a);
00653 i->push_back(b * (sides+1) + a + 1);
00654 }
00655 }
00656
00657 endEditCP(index);
00658 endEditCP(lens);
00659 endEditCP(types);
00660
00661
00662
00663 GeometryPtr geo = Geometry::create();
00664
00665 beginEditCP(geo);
00666 geo->setMaterial(getDefaultMaterial());
00667 geo->setPositions(pnts);
00668 geo->setNormals(norms);
00669 geo->getIndexMapping().push_back(Geometry::MapPosition |
00670 Geometry::MapNormal |
00671 Geometry::MapTexCoords);
00672 geo->setTexCoords(tex);
00673 geo->setIndices(index);
00674 geo->setTypes(types);
00675 geo->setLengths(lens);
00676 endEditCP(geo);
00677
00678 return geo;
00679 }
00680
00681 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00682
00683 Real32 setVecLen(Vec3f &vec, Real32 length)
00684 {
00685 Real32 len = vec.length();
00686 if(len == 0.0)
00687 {
00688 len = 1;
00689 }
00690 else
00691 {
00692 len = length / len;
00693 }
00694 vec *= len;
00695
00696 return length;
00697 }
00698
00699 Real32 calcTexS(Vec3f &n, Real32 theta)
00700 {
00701 const Real32 TwoPi = 6.283185307179586;
00702 const Real32 HalfPi = 1.570796326794897;
00703
00704 Real32 phi = osgatan2(-n[2], n[0]) - HalfPi;
00705
00706 if (phi <= -Eps)
00707 phi += TwoPi;
00708 phi /= TwoPi;
00709
00710 return phi;
00711 }
00712
00713 void addPoint(Pnt3f v, UInt32 index, Real32 radius,
00714 GeoPositions3f::StoredFieldType *p,
00715 GeoNormals3f::StoredFieldType *n,
00716 GeoTexCoords2f::StoredFieldType *tx)
00717 {
00718 Vec3f norm(v[0], v[1], v[2]);
00719
00720 norm.normalize();
00721 n->push_back(norm);
00722
00723 Pnt3f pnt(radius * norm);
00724 p->push_back(pnt);
00725
00726 Vec2f texCoord;
00727
00728
00729 texCoord[1] = (Pi - osgacos(norm[1])) / Pi;
00730
00731
00732 texCoord[0] = calcTexS(norm, texCoord[1]);
00733
00734 tx->push_back(texCoord);
00735 }
00736
00737 void subdivideTriangle( UInt32 i1,
00738 UInt32 i2,
00739 UInt32 i3,
00740 Int32 depth,
00741 GeoPositions3f::StoredFieldType *p,
00742 GeoNormals3f::StoredFieldType *n,
00743 GeoTexCoords2f::StoredFieldType *tx,
00744 GeoIndicesUI32::StoredFieldType *i,
00745 UInt32& z, Real32 radius )
00746 {
00747 if (depth == 0)
00748 {
00749 i->push_back(i1);
00750 i->push_back(i1);
00751 i->push_back(i2);
00752 i->push_back(i2);
00753 i->push_back(i3);
00754 i->push_back(i3);
00755
00756 return;
00757 }
00758
00759 Pnt3f v1 = (*p)[i1],
00760 v2 = (*p)[i2],
00761 v3 = (*p)[i3];
00762 Pnt3f v12, v23, v31;
00763
00764 v12 = v1 + (v2 - v1) * .5f;
00765 v23 = v2 + (v3 - v2) * .5f;
00766 v31 = v3 + (v1 - v3) * .5f;
00767
00768 v12 /= 2.0f;
00769 v23 /= 2.0f;
00770 v31 /= 2.0f;
00771
00772 UInt32 i12 = z++, i23 = z++, i31 = z++;
00773
00774 addPoint(v12,i12,radius,p,n,tx);
00775 addPoint(v23,i23,radius,p,n,tx);
00776 addPoint(v31,i31,radius,p,n,tx);
00777
00778 subdivideTriangle( i1, i12, i31, depth - 1, p,n,tx,i, z, radius);
00779 subdivideTriangle( i2, i23, i12, depth - 1, p,n,tx,i, z, radius);
00780 subdivideTriangle( i3, i31, i23, depth - 1, p,n,tx,i, z, radius);
00781 subdivideTriangle(i12, i23, i31, depth - 1, p,n,tx,i, z, radius);
00782 }
00783
00784 #endif // exclude from doc
00785
00793 NodePtr OSG::makeSphere(UInt16 depth, Real32 radius)
00794 {
00795 GeometryPtr pGeo = makeSphereGeo(depth, radius);
00796
00797 if(pGeo == NullFC)
00798 {
00799 return NullFC;
00800 }
00801
00802 NodePtr node = Node::create();
00803
00804 beginEditCP (node);
00805 node->setCore(pGeo);
00806 endEditCP (node);
00807
00808 return node;
00809 }
00810
00815 GeometryPtr OSG::makeSphereGeo(UInt16 depth, Real32 radius)
00816 {
00817 const Real32 X = .525731112119133606;
00818 const Real32 Z = .850650808352039932;
00819 const Real32 HalfPi = 1.570796326794897;
00820
00821 GeoPositions3fPtr pnts = GeoPositions3f::create();
00822 GeoNormals3fPtr norms = GeoNormals3f::create();
00823 GeoTexCoords2fPtr tex = GeoTexCoords2f::create();
00824 GeoIndicesUI32Ptr index = GeoIndicesUI32::create();
00825 GeoPLengthsPtr lens = GeoPLengthsUI32::create();
00826 GeoPTypesPtr types = GeoPTypesUI8::create();
00827 UInt32 j,z;
00828
00829 Vec3f v[12] = { Vec3f(-X, 0., Z),
00830 Vec3f( X, 0., Z),
00831 Vec3f(-X, 0., -Z),
00832 Vec3f( X, 0., -Z),
00833 Vec3f(0., Z, X),
00834 Vec3f(0., Z, -X),
00835 Vec3f(0., -Z, X),
00836 Vec3f(0., -Z, -X),
00837 Vec3f( Z, X, 0.),
00838 Vec3f(-Z, X, 0.),
00839 Vec3f( Z, -X, 0.),
00840 Vec3f(-Z, -X, 0.) };
00841
00842 Quaternion q(Vec3f(0,1,0), osgacos(Z) + HalfPi);
00843 Matrix mat;
00844
00845 mat.setTransform(q);
00846
00847 for (j=0; j<12; j++)
00848 mat.mult(v[j]);
00849
00850 Int32 tr[20][3] = { {1,4,0}, {4,9,0}, {4,5,9}, {8,5,4}, {1,8,4},
00851 {1,10,8}, {10,3,8}, {8,3,5}, {3,2,5}, {3,7,2},
00852 {3,10,7}, {10,6,7}, {6,11,7}, {6,0,11}, {6,1,0},
00853 {10,1,6}, {11,0,9}, {2,11,9}, {5,2,9}, {11,2,7} };
00854
00855 GeoPositions3f::StoredFieldType * p = pnts->getFieldPtr();
00856 GeoNormals3f::StoredFieldType * n = norms->getFieldPtr();
00857 GeoTexCoords2f::StoredFieldType * tx = tex->getFieldPtr();
00858 GeoIndicesUI32::StoredFieldType * i = index->getFieldPtr();
00859
00860 beginEditCP(pnts);
00861 beginEditCP(norms);
00862 beginEditCP(tex);
00863 beginEditCP(index);
00864 beginEditCP(lens);
00865 beginEditCP(types);
00866
00867
00868 UInt32 estimatedSize = UInt32(osgpow(4.f, (Real32) depth) * 20.f);
00869
00870 p->reserve (estimatedSize);
00871 n->reserve (estimatedSize);
00872 tx->reserve(estimatedSize);
00873 i->reserve (estimatedSize);
00874
00875
00876 for (j=0; j<12; j++)
00877 {
00878 Vec3f pnt = v[j];
00879 Vec3f norm = v[j];
00880
00881 setVecLen(pnt, radius);
00882 norm.normalize();
00883
00884 p->push_back(pnt.addToZero());
00885 n->push_back(norm);
00886
00887 Vec2f texCoord;
00888
00889
00890 texCoord[1] = (Pi - osgacos(norm[1])) / Pi;
00891
00892
00893 texCoord[0] = calcTexS(norm, texCoord[1]);
00894
00895 tx->push_back(texCoord);
00896 }
00897
00898
00899 z=12;
00900 for(j=0; j<20; j++)
00901 {
00902 subdivideTriangle(tr[j][0], tr[j][1], tr[j][2],
00903 depth, p, n, tx, i, z, radius);
00904 }
00905
00906 types->push_back(GL_TRIANGLES);
00907 lens->push_back(i->size()/2);
00908
00909 endEditCP(pnts);
00910 endEditCP(norms);
00911 endEditCP(tex);
00912 endEditCP(index);
00913 endEditCP(lens);
00914 endEditCP(types);
00915
00916
00917 GeometryPtr geo = Geometry::create();
00918
00919 beginEditCP(geo);
00920
00921 geo->setMaterial(getDefaultMaterial());
00922 geo->setPositions(pnts);
00923 geo->setNormals(norms);
00924 geo->getIndexMapping().push_back(Geometry::MapPosition |
00925 Geometry::MapNormal);
00926 geo->getIndexMapping().push_back(Geometry::MapTexCoords);
00927 geo->setTexCoords(tex);
00928 geo->setIndices(index);
00929 geo->setTypes(types);
00930 geo->setLengths(lens);
00931
00932 endEditCP(geo);
00933
00934
00935
00936
00937
00938 beginEditCP(geo);
00939
00940 beginEditCP(tex);
00941 beginEditCP(index);
00942
00943 for (TriangleIterator ti = geo->beginTriangles();
00944 ti != geo->endTriangles(); ++ti)
00945 {
00946 Vec3f q[3];
00947 q[0] = ti.getNormal(0);
00948 q[1] = ti.getNormal(1);
00949 q[2] = ti.getNormal(2);
00950
00951
00952 if ( (osgabs(q[0][0]) <= 0.01 && q[0][2] <= Eps) ||
00953 (osgabs(q[1][0]) <= 0.01 && q[1][2] <= Eps) ||
00954 (osgabs(q[2][0]) <= 0.01 && q[2][2] <= Eps) )
00955 {
00956 for (UInt16 i=0; i<3; i++)
00957 {
00958 Vec3f norm(q[i]);
00959
00960 if (osgabs(norm[0]) <= Eps && norm[2] <= Eps)
00961 {
00962
00963 Real32 theta = ti.getTexCoords(i).y();
00964
00965
00966 if ( !(q[0][0] <= -Eps || q[1][0] <= -Eps || q[2][0] <= -Eps) )
00967 {
00968 Vec2f texCoord(1, theta);
00969
00970 if ( osgabs(osgabs(norm[1]) - 1) <= Eps )
00971 texCoord[0] = 0.5;
00972
00973 tex->push_back(texCoord);
00974
00975 index->setValue( tex->size() - 1, ti.getIndexIndex(i) + 1 );
00976 }
00977 else
00978 {
00979 Vec2f texCoord(0, theta);
00980
00981 if ( osgabs(osgabs(norm[1]) - 1) <= Eps )
00982 texCoord[0] = 0.5;
00983
00984 tex->push_back(texCoord);
00985
00986 index->setValue( tex->size() - 1, ti.getIndexIndex(i) + 1 );
00987 }
00988 }
00989 }
00990 }
00991 }
00992
00993 endEditCP(tex);
00994 endEditCP(index);
00995
00996 endEditCP(geo);
00997
00998 return geo;
00999 }
01000
01008 NodePtr OSG::makeLatLongSphere(UInt16 latres, UInt16 longres, Real32 radius)
01009 {
01010 GeometryPtr pGeo = makeLatLongSphereGeo(latres, longres, radius);
01011
01012 if(pGeo == NullFC)
01013 {
01014 return NullFC;
01015 }
01016
01017 NodePtr node = Node::create();
01018
01019 beginEditCP (node);
01020 node->setCore(pGeo);
01021 endEditCP (node);
01022
01023 return node;
01024 }
01025
01030 GeometryPtr OSG::makeLatLongSphereGeo(UInt16 latres, UInt16 longres,
01031 Real32 radius)
01032 {
01033 if(radius <= 0 || latres < 4 || longres < 4)
01034 {
01035 SWARNING << "makeLatLongSphere: illegal parameters "
01036 << "latres=" << latres
01037 << ", longres=" << longres
01038 << ", radius=" << radius
01039 << std::endl;
01040 return NullFC;
01041 }
01042
01043 GeoPositions3fPtr pnts = GeoPositions3f::create();
01044 GeoNormals3fPtr norms = GeoNormals3f::create();
01045 GeoTexCoords2fPtr tex = GeoTexCoords2f::create();
01046 GeoIndicesUI32Ptr index = GeoIndicesUI32::create();
01047 GeoPLengthsUI32Ptr lens = GeoPLengthsUI32::create();
01048 GeoPTypesUI8Ptr types = GeoPTypesUI8::create();
01049
01050 UInt16 a, b;
01051 Real32 theta, phi;
01052 Real32 cosTheta, sinTheta;
01053 Real32 latDelta, longDelta;
01054
01055
01056
01057 GeoPositions3f::StoredFieldType * p = pnts->getFieldPtr();
01058 GeoNormals3f::StoredFieldType * n = norms->getFieldPtr();
01059 GeoTexCoords2f::StoredFieldType * tx = tex->getFieldPtr();
01060
01061 beginEditCP(pnts);
01062 beginEditCP(norms);
01063 beginEditCP(tex);
01064
01065 latDelta = Pi / latres;
01066 longDelta = 2.f * Pi / longres;
01067
01068 for(a = 0, theta = -Pi / 2; a <= latres; a++, theta += latDelta)
01069 {
01070 cosTheta = osgcos(theta);
01071 sinTheta = osgsin(theta);
01072
01073 for(b = 0, phi = -Pi; b <= longres; b++, phi += longDelta)
01074 {
01075 GLfloat cosPhi, sinPhi;
01076
01077 cosPhi = osgcos(phi);
01078 sinPhi = osgsin(phi);
01079
01080 n->push_back(Vec3f( cosTheta * sinPhi,
01081 sinTheta,
01082 cosTheta * cosPhi));
01083 p->push_back(Pnt3f( cosTheta * sinPhi * radius,
01084 sinTheta * radius,
01085 cosTheta * cosPhi * radius));
01086 tx->push_back(Vec2f(b / (Real32)longres,
01087 a / (Real32)latres));
01088 }
01089 }
01090
01091 endEditCP(pnts);
01092 endEditCP(norms);
01093 endEditCP(tex);
01094
01095
01096
01097 GeoIndicesUI32::StoredFieldType * i = index->getFieldPtr();
01098 GeoPLengthsUI32::StoredFieldType * l = lens->getFieldPtr();
01099 GeoPTypesUI8::StoredFieldType * t = types->getFieldPtr();
01100
01101 beginEditCP(index);
01102 beginEditCP(lens);
01103 beginEditCP(types);
01104
01105 for(a = 0; a < longres; a++)
01106 {
01107 t->push_back(GL_TRIANGLE_STRIP);
01108 l->push_back((latres + 1) * 2);
01109
01110 for(b = 0; b <= latres; b++)
01111 {
01112 i->push_back(b * (longres+1) + a);
01113 i->push_back(b * (longres+1) + a + 1);
01114 }
01115 }
01116
01117 endEditCP(index);
01118 endEditCP(lens);
01119 endEditCP(types);
01120
01121
01122
01123 GeometryPtr geo = Geometry::create();
01124
01125 beginEditCP(geo);
01126 geo->setMaterial(getDefaultMaterial());
01127 geo->setPositions(pnts);
01128 geo->setNormals(norms);
01129 geo->getIndexMapping().push_back(Geometry::MapPosition |
01130 Geometry::MapNormal |
01131 Geometry::MapTexCoords);
01132 geo->setTexCoords(tex);
01133 geo->setIndices(index);
01134 geo->setTypes(types);
01135 geo->setLengths(lens);
01136 endEditCP(geo);
01137
01138 return geo;
01139 }
01140
01148 OSG_SYSTEMLIB_DLLMAPPING
01149 NodePtr OSG::makeBox(Real32 xsize, Real32 ysize, Real32 zsize,
01150 UInt16 hor , UInt16 vert , UInt16 depth)
01151 {
01152 GeometryPtr pGeo = makeBoxGeo(xsize, ysize, zsize, hor, vert, depth);
01153
01154 if(pGeo == NullFC)
01155 {
01156 return NullFC;
01157 }
01158
01159 NodePtr node = Node::create();
01160
01161 beginEditCP (node);
01162 node->setCore(pGeo);
01163 endEditCP (node);
01164
01165 return node;
01166 }
01167
01172 OSG_SYSTEMLIB_DLLMAPPING
01173 GeometryPtr OSG::makeBoxGeo(Real32 xsize, Real32 ysize, Real32 zsize,
01174 UInt16 hor , UInt16 vert , UInt16 depth)
01175 {
01176 if(! hor || ! vert || ! depth)
01177 {
01178 SWARNING << "makeBox: illegal parameters hor=" << hor << ", vert="
01179 << vert << ", depth=" << depth << std::endl;
01180 return NullFC;
01181 }
01182
01183 GeoPositions3fPtr pnts = GeoPositions3f::create();
01184 GeoNormals3fPtr norms = GeoNormals3f::create();
01185 GeoTexCoords2fPtr tex = GeoTexCoords2f::create();
01186 GeoIndicesUI32Ptr index = GeoIndicesUI32::create();
01187 GeoPLengthsUI32Ptr lens = GeoPLengthsUI32::create();
01188 GeoPTypesUI8Ptr types = GeoPTypesUI8::create();
01189
01190 UInt16 x,y,pl;
01191 Vec3f size(xsize, ysize, zsize);
01192 Vec3f step(xsize / hor, ysize / vert, zsize / depth);
01193 Vec3f res(hor, vert, depth);
01194
01195
01196
01197 GeoPositions3f::StoredFieldType * p = pnts->getFieldPtr();
01198 GeoNormals3f::StoredFieldType * n = norms->getFieldPtr();
01199 GeoTexCoords2f::StoredFieldType * tx = tex->getFieldPtr();
01200
01201 beginEditCP(pnts);
01202 beginEditCP(norms);
01203 beginEditCP(tex);
01204
01205 static int inds[6][2] = { {0,1}, {0,1}, {2,1}, {2,1}, {0,2}, {0,2} };
01206 static int signs[6][2] = { {1,1}, {-1,1}, {-1,1}, {1,1}, {1,-1}, {1,1} };
01207 static int asigns[6] = { 1, -1, 1, -1, 1, -1 };
01208
01209 for(pl = 0; pl < 6; pl++)
01210 {
01211 UInt16 axis = 3 - inds[pl][0] - inds[pl][1];
01212
01213 for(y = 0; y <= res[inds[pl][1]] ; y++)
01214 {
01215 for(x = 0; x <= res[inds[pl][0]]; x++)
01216 {
01217 Pnt3f pnt;
01218 pnt[ inds[pl][0] ] = (x * step[inds[pl][0]] - size[inds[pl][0]] / 2) *
01219 signs[pl][0];
01220 pnt[ inds[pl][1] ] = (y * step[inds[pl][1]] - size[inds[pl][1]] / 2) *
01221 signs[pl][1];
01222 pnt[ axis ] = size[ axis ] * asigns[ pl ] / 2;
01223 p->push_back(pnt);
01224
01225 Vec3f norm(0, 0, 0);
01226 norm[ axis ] = Real32(asigns[ pl ]);
01227 n->push_back(norm);
01228 tx->push_back(Vec2f(x / (Real32) res[inds[pl][0]],
01229 y / (Real32) res[inds[pl][1]]));
01230 }
01231 }
01232 }
01233
01234 endEditCP(pnts);
01235 endEditCP(norms);
01236 endEditCP(tex);
01237
01238
01239
01240 GeoIndicesUI32::StoredFieldType * i = index->getFieldPtr();
01241 GeoPLengthsUI32::StoredFieldType * l = lens->getFieldPtr();
01242 GeoPTypesUI8::StoredFieldType * t = types->getFieldPtr();
01243
01244 beginEditCP(index);
01245 beginEditCP(lens);
01246 beginEditCP(types);
01247
01248 UInt32 basepoint = 0;
01249
01250 for(pl = 0; pl < 6; pl++)
01251 {
01252 for(y = 0; y < res[inds[pl][1]]; y++)
01253 {
01254 UInt16 h = UInt16(res[inds[pl][0]]);
01255
01256 t->push_back(GL_TRIANGLE_STRIP);
01257 l->push_back(2 * (h + 1));
01258
01259 for(x = 0; x <= h; x++)
01260 {
01261 i->push_back(basepoint + (y + 1) * (h + 1) + x);
01262 i->push_back(basepoint + y * (h + 1) + x);
01263 }
01264 }
01265 basepoint += UInt32((res[inds[pl][0]] + 1.f) *
01266 (res[inds[pl][1]] + 1.f) );
01267 }
01268
01269 endEditCP(index);
01270 endEditCP(lens);
01271 endEditCP(types);
01272
01273
01274
01275 GeometryPtr geo = Geometry::create();
01276
01277 beginEditCP(geo);
01278 geo->setMaterial(getDefaultMaterial());
01279 geo->setPositions(pnts);
01280 geo->setNormals(norms);
01281 geo->getIndexMapping().push_back(Geometry::MapPosition |
01282 Geometry::MapNormal |
01283 Geometry::MapTexCoords);
01284 geo->setTexCoords(tex);
01285 geo->setIndices(index);
01286 geo->setTypes(types);
01287 geo->setLengths(lens);
01288 endEditCP(geo);
01289
01290 return geo;
01291 }
01292
01293 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
01294
01295 OSG_SYSTEMLIB_DLLMAPPING GeoPositions3fPtr OSG::makeGeoPositions3fPtr(UInt32 uiSize)
01296 {
01297 GeoPositions3fPtr returnValue = GeoPositions3f::create();
01298
01299 returnValue->resize(uiSize);
01300
01301 return returnValue;
01302 }
01303
01304 OSG_SYSTEMLIB_DLLMAPPING GeoIndicesUI32Ptr OSG::makeGeoIndicesUI32Ptr(UInt32 uiSize)
01305 {
01306 GeoIndicesUI32Ptr returnValue = GeoIndicesUI32::create();
01307
01308 returnValue->resize(uiSize);
01309
01310 return returnValue;
01311 }
01312
01313 OSG_SYSTEMLIB_DLLMAPPING GeoPLengthsPtr OSG::makeGeoPLengthsPtr(UInt32 uiSize)
01314 {
01315 GeoPLengthsPtr returnValue = GeoPLengthsUI32::create();
01316
01317 returnValue->resize(uiSize);
01318
01319 return returnValue;
01320 }
01321
01322 OSG_SYSTEMLIB_DLLMAPPING GeoPTypesPtr OSG::makeGeoPTypesPtr(UInt32 uiSize)
01323 {
01324 GeoPTypesPtr returnValue = GeoPTypesUI8::create();
01325
01326 returnValue->resize(uiSize);
01327
01328 return returnValue;
01329 }
01330
01331 #endif // exclude from doc