Classes | |
| struct | IndexDic |
| class | VolumeDrawWrapper |
Draw Functions | |
| void | osg::drawVolume (const DynamicVolume &volume) |
| void | osg::drawVolume (const BoxVolume &volume) |
| void | osg::drawVolume (const SphereVolume &volume) |
| void | osg::drawVolume (const FrustumVolume &volume) |
| void | osg::drawVolume (const CylinderVolume &volume) |
| void | osg::dropVolume (DrawActionBase *action, NodePtr node, Color3f col) |
| void | osg::dropVolume (DrawActionBase *action, const DynamicVolume &volume, Color3f col) |
Functions | |
| void | osg::calcVertexNormals (GeometryPtr geo) |
| void | osg::calcVertexNormals (GeometryPtr geo, Real32 creaseAngle) |
| void | osg::calcFaceNormals (GeometryPtr geo) |
| Int32 | osg::setIndexFromVRMLData (GeometryPtr geoPtr, std::vector< Int32 > &coordIndex, std::vector< Int32 > &normalIndex, std::vector< Int32 > &colorIndex, std::vector< Int32 > &texCoordIndex, bool convex, bool ccw, bool normalPerVertex, bool colorPerVertex, bool createNormal, bool faceSet) |
| Int32 | osg::setIndexFromIndexedX3DData (GeometryPtr geoPtr, std::vector< Int32 > &coordIndex, std::vector< Int32 > &normalIndex, std::vector< Int32 > &colorIndex, std::vector< Int32 > &texCoordIndex, Int32 primitiveType, bool convex, bool ccw, bool normalPerVertex, bool colorPerVertex, bool createNormal) |
| void | osg::calcVertexTexCoords (GeometryPtr geo, Int32 texIndex) |
| void | osg::calcVertexTangents (GeometryPtr geo, Int32 srcTexIndex, Int32 dstAttribTan, Int32 dstAttribBin) |
| Int32 | osg::createOptimizedPrimitives (GeometryPtr geoPtr, UInt32 iteration, bool createStrips, bool createFans, UInt32 minFanEdgeCount, bool colorCode, bool stitchStrips) |
| void | osg::createConvexPrimitives (GeometryPtr geoPtr) |
| Int32 | osg::createSharedIndex (GeometryPtr geoPtr) |
| Int32 | osg::createSingleIndex (GeometryPtr geoPtr) |
| UInt32 | osg::calcPrimitiveCount (GeometryPtr geoPtr, UInt32 &triangle, UInt32 &line, UInt32 &point) |
| NodePtr | osg::calcVertexNormalsGeo (GeometryPtr geo, Real32 length) |
| NodePtr | osg::calcFaceNormalsGeo (GeometryPtr geo, Real32 length) |
| void | osg::separateProperties (GeometryPtr geo) |
| void osg::calcVertexNormals | ( | GeometryPtr | geo | ) |
calcVertexNormals calculates the normals for the geometry's vertices, see Normal Calculation for a description.
Definition at line 78 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::endEditCP(), osg::Plane::getNormal(), osg::Geometry::MapNormal, osg::Geometry::MapPosition, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::NullFC, p, and osg::MField< FieldTypeT, fieldNameSpace >::size().
Referenced by osg::calcVertexNormals(), osg::OFFSceneFileType::read(), and osg::OBJSceneFileType::read().
00083 { 00084 //Vec3f vec0, vec1,vec2; 00085 GeoPositionsPtr positionPtr; 00086 GeoNormalsPtr normalPtr; 00087 Int32 i, ni, pi, pN, p0, p1, p2, skipN = 0; 00088 TriangleIterator tI; 00089 Real32 x,y,z; 00090 std::vector<Vec3f> normalVec; 00091 00092 if (geo != NullFC) { 00093 00094 // get the pos bag and pos count 00095 positionPtr = geo->getPositions(); 00096 pN = (positionPtr != NullFC) ? positionPtr->getSize() : 0; 00097 00098 FNOTICE (("Create %d normal \n", pN )); 00099 00100 if (pN) { 00101 00102 // init the normal bag 00103 normalVec.resize(pN); 00104 for (i = 0; i < pN; ++i) 00105 normalVec[i].setValues(0,0,0); 00106 00107 // fill the normal bag 00108 for (tI = geo->beginTriangles(); tI != geo->endTriangles(); ++tI) { 00109 00110 if ((p0 == p1) || (p1 == p2) || (p2 == p0)) { 00111 skipN++; 00112 } 00113 else { 00114 00115 // get the tri points 00116 p0 = tI.getPositionIndex(0); 00117 p1 = tI.getPositionIndex(1); 00118 p2 = tI.getPositionIndex(2); 00119 // get the points 00120 // TODO; use assign 00121 Vec3f vec0(tI.getPosition(0)); 00122 Vec3f vec1(tI.getPosition(1)); 00123 Vec3f vec2(tI.getPosition(2)); 00124 00125 // calc the face normal 00126 vec0 -= vec1; 00127 vec1 -= vec2; 00128 vec0.crossThis(vec1); 00129 vec0.normalize(); 00130 00131 // add the normal 00132 normalVec[p0] += vec0; 00133 normalVec[p1] += vec0; 00134 normalVec[p2] += vec0; 00135 } 00136 } 00137 00138 // get/create/resize the normal bag 00139 normalPtr = geo->getNormals(); 00140 if (normalPtr == NullFC) { 00141 normalPtr = GeoNormals3f::create(); 00142 beginEditCP(geo); 00143 { 00144 geo->setNormals( normalPtr ); 00145 } 00146 endEditCP(geo); 00147 } 00148 00149 // get/create/resize the normal bag 00150 normalPtr = geo->getNormals(); 00151 if (normalPtr == NullFC) { 00152 normalPtr = GeoNormals3f::create(); 00153 beginEditCP(geo); 00154 { 00155 geo->setNormals( normalPtr ); 00156 } 00157 endEditCP(geo); 00158 } 00159 00160 // normalize and copy the result 00161 beginEditCP (normalPtr); 00162 { 00163 // resize the bag 00164 normalPtr->resize(pN); 00165 00166 // normalize and copy the result 00167 for (i = 0; i < pN; ++i) { 00168 if (normalize) 00169 normalVec[i].normalize(); 00170 normalPtr->setValue( normalVec[i], i ); 00171 } 00172 } 00173 endEditCP (normalPtr); 00174 00175 // adapting the indexMapping 00176 pi = geo->calcMappingIndex ( Geometry::MapPosition ); 00177 ni = geo->calcMappingIndex ( Geometry::MapNormal ); 00178 if ((geo->getIndexMapping().size() > 1) && (pi >= 0) && (pi != ni)) { 00179 00180 geo->getIndexMapping(ni) &= ~Geometry::MapNormal; 00181 if (geo->getIndexMapping(ni) == 0) { 00182 FFATAL (("Should delete normal entry; do impl !!!\n" )); 00183 geo->getIndexMapping(ni) = Geometry::MapEmpty; 00184 } 00185 else { 00186 FNOTICE (("Keep mindex mapping after createVertexNormal()\n")); 00187 } 00188 00189 geo->getIndexMapping(pi) |= Geometry::MapNormal; 00190 } 00191 else { 00192 FNOTICE (("Keep single index mapping after createVertexNormal()\n")); 00193 } 00194 } 00195 else { 00196 FFATAL (("No valid points setting; can not create normal\n")); 00197 } 00198 if (skipN) { 00199 FNOTICE (( "Skip %d invalid triangles in createVertexNormal()\n", 00200 skipN)); 00201 } 00202 } 00203 else { 00204 FFATAL (("No valid geometry; can not create normal\n")); 00205 } 00206 00207 } 00208 00209 */ 00210 { 00211 GeoNormalsPtr norms; 00212 typedef std::set<UInt32> IndexSet; 00213 IndexSet used_indices; 00214 00215 if(geo->getNormals() == NullFC) 00216 { 00217 norms = GeoNormals3f::create(); 00218 } 00219 else 00220 { 00221 norms = geo->getNormals(); 00222 } 00223 beginEditCP(norms); 00224 00225 norms->resize(geo->getPositions()->getSize()); 00226 00227 // problem: not all of the points of the property might be used by this 00228 // geometry. If the property has more than 1 users, be careful. 00229 if(norms->getParents().size() > 1) 00230 { 00231 for(TriangleIterator t = geo->beginTriangles(); t != geo->endTriangles(); 00232 ++t) 00233 { 00234 used_indices.insert(t.getPositionIndex(0)); 00235 used_indices.insert(t.getPositionIndex(1)); 00236 used_indices.insert(t.getPositionIndex(2)); 00237 } 00238 00239 for (IndexSet::iterator i = used_indices.begin(); 00240 i != used_indices.end(); 00241 ++i) 00242 { 00243 norms->setValue(Vec3f(0, 0, 0), *i); 00244 } 00245 } 00246 else // just one user, can clear all 00247 { 00248 for(unsigned i = 0; i < geo->getPositions()->getSize(); i++) 00249 { 00250 norms->setValue(Vec3f(0, 0, 0), i); 00251 } 00252 } 00253 00254 for(TriangleIterator t = geo->beginTriangles(); t != geo->endTriangles(); 00255 ++t) 00256 { 00257 Pnt3f p0 = t.getPosition(0); 00258 Pnt3f p1 = t.getPosition(1); 00259 Pnt3f p2 = t.getPosition(2); 00260 Plane p(p0, p1, p2); 00261 00262 Int32 i0 = t.getPositionIndex(0); 00263 Int32 i1 = t.getPositionIndex(1); 00264 Int32 i2 = t.getPositionIndex(2); 00265 norms->setValue( norms->getValue(i0) + p.getNormal(), i0 ); 00266 norms->setValue( norms->getValue(i1) + p.getNormal(), i1 ); 00267 norms->setValue( norms->getValue(i2) + p.getNormal(), i2 ); 00268 } 00269 if(norms->getParents().size() > 1) 00270 { 00271 std::set < UInt32 >::iterator i = used_indices.begin(); 00272 std::set < UInt32 >::iterator end = used_indices.end(); 00273 00274 while(i != end) 00275 { 00276 Vec3f n = norms->getValue(*i); 00277 n.normalize(); 00278 norms->setValue(n, *i); 00279 00280 ++i; 00281 } 00282 } 00283 else // just one user, can clear all 00284 { 00285 for(unsigned i = 0; i < geo->getPositions()->getSize(); i++) 00286 { 00287 Vec3f n = norms->getValue(i); 00288 n.normalize(); 00289 norms->setValue(n, i); 00290 } 00291 } 00292 endEditCP(norms); 00293 00294 beginEditCP(geo); 00295 { 00296 geo->setNormals(norms); 00297 00298 MFUInt16 &im = geo->getIndexMapping(); 00299 if(im.size() > 0) 00300 { 00301 Int16 pi, ni; 00302 pi = geo->calcMappingIndex(Geometry::MapPosition); 00303 ni = geo->calcMappingIndex(Geometry::MapNormal); 00304 00305 if(ni >= 0) 00306 { 00307 im[ni] = im[ni] &~Geometry::MapNormal; 00308 } 00309 if(pi >= 0) 00310 { 00311 im[pi] = im[pi] | Geometry::MapNormal; 00312 } 00313 } 00314 } 00315 endEditCP(geo); 00316 }
| void osg::calcVertexNormals | ( | GeometryPtr | geo, | |
| Real32 | creaseAngle | |||
| ) |
calcVertexNormals calculates the normals for the geometry's vertices, see Normal Calculation for a description.
Definition at line 385 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::calcVertexNormals(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::crossThis(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::endEditCP(), FINFO, FWARNING, osg::TriangleIterator::getIndex(), osg::TriangleIterator::getIndexIndex(), osg::TriangleIterator::getNormalIndex(), osg::TriangleIterator::getPosition(), osg::TriangleIterator::getPositionIndex(), osg::Geometry::MapColor, osg::Geometry::MapNormal, osg::Geometry::MapPosition, osg::Geometry::MapTexCoords, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::NullFC, osg::osgcos(), p, osg::Pi, osg::MField< FieldTypeT, fieldNameSpace >::push_back(), osg::MField< FieldTypeT, fieldNameSpace >::size(), and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::squareLength().
Referenced by osg::VRMLGeometryPointSetDesc::endNode(), and osg::VRMLGeometryDesc::endNode().
00387 { 00388 GeoNormalsPtr norms; 00389 GeoPositionsPtr positions; 00390 00391 if(creaseAngle >= Pi) 00392 { 00393 calcVertexNormals(geo); 00394 return; 00395 } 00396 00397 // Get the positions property 00398 if(geo->getPositions() == NullFC) 00399 { 00400 FINFO(("Geo without positions in calcVertexNormals()\n")); 00401 return; 00402 } 00403 else 00404 { 00405 positions = geo->getPositions(); 00406 } 00407 00408 if(positions->size() < 3) 00409 { 00410 FINFO(("Geo with less than 3 positions in calcVertexNormals()\n")); 00411 return; 00412 } 00413 00414 // Get normal property, create if needed 00415 if(geo->getNormals() == NullFC) 00416 { 00417 norms = GeoNormals3f::create(); 00418 } 00419 else 00420 { 00421 norms = geo->getNormals(); 00422 } 00423 00424 // need to set it early, is used below 00425 beginEditCP(geo); 00426 { 00427 geo->setNormals(norms); 00428 } 00429 00430 endEditCP(geo); 00431 00432 // Do the normals have their own index? 00433 MFUInt16 &im = geo->getIndexMapping(); 00434 Int16 ni = geo->calcMappingIndex(Geometry::MapNormal); 00435 GeoIndicesPtr ip = geo->getIndices(); 00436 00437 // HACK but without indices it crashes. 00438 if(ip == NullFC || ip->size() == 0) 00439 { 00440 FINFO(("Geo without indices in calcVertexNormals()\n")); 00441 return; 00442 } 00443 00444 UInt32 nind = ip->size() / (im.size() ? im.size() : 1); 00445 int imsize = 0; 00446 if(ni < 0 || im[ni] != Geometry::MapNormal) 00447 { 00448 // normals need their own index 00449 if(ni >= 0) 00450 { 00451 im[ni] = im[ni] &~Geometry::MapNormal; 00452 } 00453 00454 // need to be multi-indexed? 00455 if(im.size() == 0) 00456 { 00457 UInt32 map = Geometry::MapPosition; 00458 00459 if(geo->getTexCoords() != NullFC) 00460 map |= Geometry::MapTexCoords; 00461 00462 if(geo->getColors() != NullFC) 00463 map |= Geometry::MapColor; 00464 00465 im.push_back(map); 00466 } 00467 00468 ni = im.size(); 00469 im.push_back(Geometry::MapNormal); 00470 00471 // add an entry to the indices for the normals 00472 imsize = im.size(); 00473 00474 beginEditCP(ip); 00475 ip->resize(nind * imsize); 00476 00477 for(UInt32 i = nind - 1; i > 0; --i) 00478 { 00479 for(Int16 j = imsize - 2; j >= 0; --j) 00480 { 00481 UInt32 val; 00482 ip->getValue(val, i * (imsize - 1) + j); 00483 ip->setValue(val, i * imsize + j); 00484 } 00485 00486 ip->setValue(i, i * imsize + imsize - 1); 00487 } 00488 00489 ip->setValue(0, imsize - 1); 00490 endEditCP(ip); 00491 } 00492 else // set the normal indices 00493 { 00494 imsize = im.size(); 00495 beginEditCP(ip); 00496 for(UInt32 i = 0; i < nind; ++i) 00497 { 00498 ip->setValue(i, i * imsize + ni); 00499 } 00500 00501 endEditCP(ip); 00502 } 00503 00504 // now calc the normals 00505 // if creaseAngle is 0, it's simple: every face uses its own. 00506 if(creaseAngle == 0) 00507 { 00508 beginEditCP(norms); 00509 beginEditCP(ip); 00510 00511 norms->resize(nind); 00512 00513 for(TriangleIterator ti = geo->beginTriangles(); 00514 ti != geo->endTriangles(); ++ti) 00515 { 00516 Vec3f d1 = ti.getPosition(1) - ti.getPosition(0); 00517 Vec3f d2 = ti.getPosition(2) - ti.getPosition(0); 00518 d1.crossThis(d2); 00519 00520 d1.normalize(); 00521 00522 norms->setValue(d1, ti.getNormalIndex(0)); 00523 norms->setValue(d1, ti.getNormalIndex(1)); 00524 norms->setValue(d1, ti.getNormalIndex(2)); 00525 } 00526 00527 endEditCP(norms); 00528 endEditCP(ip); 00529 return; 00530 } 00531 00532 // creaseAngle > 0, need to calculate 00533 #if 0 00534 // orig pngMap based code (written by dirk) 00535 // collect a map from points to faces using this point 00536 // collect the face normals in a separate vector 00537 std::vector < Vec3f > faceNormals; 00538 std::multimap<Pnt3f, UInt32, vecless<Pnt3f> > pntMap; 00539 00540 TriangleIterator ti; 00541 00542 for(ti = geo->beginTriangles(); ti != geo->endTriangles(); ++ti) 00543 { 00544 Vec3f d1 = ti.getPosition(1) - ti.getPosition(0); 00545 Vec3f d2 = ti.getPosition(2) - ti.getPosition(0); 00546 d1.crossThis(d2); 00547 00548 d1.normalize(); 00549 faceNormals.push_back(d1); 00550 00551 pntMap.insert(std::pair< Pnt3f, UInt32 > 00552 (ti.getPosition(0), faceNormals.size() - 1)); 00553 pntMap.insert(std::pair< Pnt3f, UInt32 > 00554 (ti.getPosition(1), faceNormals.size() - 1)); 00555 pntMap.insert(std::pair< Pnt3f, UInt32 > 00556 (ti.getPosition(2), faceNormals.size() - 1)); 00557 } 00558 00559 // now walk through the geometry again and calc the normals 00560 beginEditCP(norms); 00561 beginEditCP(ip); 00562 00563 norms->resize(nind); 00564 00565 Real32 cosCrease = osgcos(creaseAngle); 00566 00567 for(ti = geo->beginTriangles(); ti != geo->endTriangles(); ++ti) 00568 { 00569 Int32 tind = ti.getIndex(); 00570 Vec3f mynorm = faceNormals[tind]; 00571 00572 std::multimap<Pnt3f, UInt32, vecless<Pnt3f> >::iterator st, en; 00573 00574 for(UInt16 i = 0; i < 3; ++i) 00575 { 00576 // calculate the normal: average all different normals 00577 // that use a point. Simple addition or weighted addition 00578 // doesn't work, as it depends on the triangulation 00579 // of the object. :( 00580 std::set<Vec3f, vecless<Vec3f> > normset; 00581 00582 st = pntMap.lower_bound(ti.getPosition(i)); 00583 en = pntMap.upper_bound(ti.getPosition(i)); 00584 00585 for(; st != en; st++) 00586 { 00587 if(mynorm.dot(faceNormals[(*st).second]) > cosCrease) 00588 { 00589 normset.insert(faceNormals[(*st).second]); 00590 } 00591 } 00592 00593 Vec3f norm(0, 0, 0); 00594 typedef std::set<Vec3f, vecless<Vec3f> >::iterator NormSetIt; 00595 00596 for(NormSetIt it = normset.begin(); it != normset.end(); ++it) 00597 { 00598 norm += (*it); 00599 } 00600 00601 norm.normalize(); 00602 norms->setValue(norm, ti.getNormalIndex(i)); 00603 } 00604 } 00605 00606 endEditCP(ip); 00607 endEditCP(norms); 00608 00609 #else 00610 // opt + normal share code (written by jbehr) 00611 // collect a map from points to faces using this point 00612 // collect the face normals in a separate vector 00613 //FLOG (("Run calcVertexNormals(%g)\n", creaseAngle)); 00614 std::vector < Vec3f > faceNormals; 00615 std::vector < std::vector < UInt32 > > pntFaceDic; 00616 00617 TriangleIterator ti; 00618 UInt32 i, pN = positions->size(); 00619 00620 pntFaceDic.resize(pN); 00621 for(ti = geo->beginTriangles(), i = 0; ti != geo->endTriangles(); ++ti, ++i) 00622 { 00623 Int32 v0 = ti.getPositionIndex(0); 00624 Int32 v1 = ti.getPositionIndex(1); 00625 Int32 v2 = ti.getPositionIndex(2); 00626 00627 if(v0 != v1 && v0 != v2) 00628 { 00629 Vec3f d1 = ti.getPosition(1) - ti.getPosition(0); 00630 Vec3f d2 = ti.getPosition(2) - ti.getPosition(0); 00631 d1.crossThis(d2); 00632 00633 if(d1.squareLength() >= 0) 00634 { 00635 d1.normalize(); 00636 faceNormals.push_back(d1); 00637 00638 pntFaceDic[ti.getPositionIndex(0)].push_back(i); 00639 pntFaceDic[ti.getPositionIndex(1)].push_back(i); 00640 pntFaceDic[ti.getPositionIndex(2)].push_back(i); 00641 } 00642 else 00643 { 00644 faceNormals.push_back(Vec3f(0, 0, 0)); 00645 } 00646 } 00647 else 00648 { 00649 faceNormals.push_back(Vec3f(0, 0, 0)); 00650 } 00651 } 00652 00653 // now walk through the geometry again and calc the normals 00654 beginEditCP(norms); 00655 beginEditCP(ip); 00656 00657 norms->clear(); 00658 00659 Real32 cosCrease = osgcos(creaseAngle); 00660 Vec3f norm; 00661 std::vector < UInt32 > normset; 00662 std::vector < std::map < std::vector < UInt32 > , UInt32 > > normDic; 00663 std::map < std::vector < UInt32 > , UInt32 >::iterator ndI; 00664 00665 UInt32 normalIndex = 0; 00666 00667 normDic.resize(pN); 00668 00669 for(ti = geo->beginTriangles(); ti != geo->endTriangles(); ++ti) 00670 { 00671 Int32 tind = ti.getIndex(); 00672 Vec3f faceNorm(faceNormals[tind]); 00673 00674 if(faceNorm.squareLength() != 0.0) 00675 { 00676 for(UInt16 i = 0; i < 3; ++i) 00677 { 00678 // calculate the normal: average all different normals 00679 // that use a point. Simple addition or weighted addition 00680 // doesn't work, as it depends on the triangulation 00681 // of the object. :( 00682 UInt32 p = ti.getPositionIndex(i); 00683 UInt32 pf, f, fN = pntFaceDic[p].size(); 00684 UInt32 n, nN; 00685 00686 normset.clear(); 00687 for(f = 0; f < fN; f++) 00688 { 00689 if(((pf = pntFaceDic[p][f]) == tind) || 00690 (faceNorm.dot(faceNormals[pf]) > cosCrease)) 00691 normset.push_back(pf); 00692 } 00693 00694 if((nN = normset.size())) 00695 { 00696 // find normal 00697 //std::sort ( normset.begin(), normset.end() ); 00698 ndI = normDic[p].find(normset); 00699 if(ndI == normDic[p].end()) 00700 { 00701 norm = faceNormals[normset[0]]; 00702 for(n = 1; n < nN; ++n) 00703 norm += faceNormals[normset[n]]; 00704 norm.normalize(); 00705 normalIndex = norms->size(); 00706 norms->push_back(norm); 00707 normDic[p][normset] = normalIndex; 00708 } 00709 else 00710 { 00711 normalIndex = ndI->second; 00712 } 00713 } 00714 else 00715 { 00716 // keep normalIndex 00717 FWARNING(("Empty normset for %d faces pos %d: %f/%f/%f\n", 00718 fN, i, ti.getPosition(i).x(), 00719 ti.getPosition(i).y(), ti.getPosition(i).z() 00720 )); 00721 } 00722 00723 ip->setValue(normalIndex, ti.getIndexIndex(i) + ni); 00724 } 00725 } 00726 else 00727 { 00728 // keep normal for degenerated triangle 00729 00730 normalIndex = norms->size(); 00731 norms->push_back(norm); 00732 00733 ip->setValue ( normalIndex, ti.getIndexIndex(0) + ni ); 00734 ip->setValue ( normalIndex, ti.getIndexIndex(1) + ni ); 00735 ip->setValue ( normalIndex, ti.getIndexIndex(2) + ni ); 00736 } 00737 } 00738 00739 endEditCP(ip); 00740 endEditCP(norms); 00741 #endif 00742 }
| void osg::calcFaceNormals | ( | GeometryPtr | geo | ) |
calcFaceNormals calculates the normals for the geometry's faces, see Normal Calculation for a description.
Definition at line 754 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::endEditCP(), FINFO, osg::FaceIterator::getIndexIndex(), osg::FaceIterator::getLength(), osg::FaceIterator::getPosition(), osg::FaceIterator::getPositionIndex(), osg::PrimitiveIterator::getType(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::length(), osg::Geometry::MapNormal, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::NullFC, osg::MField< FieldTypeT, fieldNameSpace >::push_back(), and osg::MField< FieldTypeT, fieldNameSpace >::size().
00755 { 00756 if(geo->getPositions() == NullFC || 00757 geo->getPositions()->size() == 0) 00758 { 00759 FINFO(("Geo without positions in calcFaceNormals()\n")); 00760 return; 00761 } 00762 00763 GeoIndicesPtr newIndex = GeoIndicesUI32::create(); 00764 GeoNormalsPtr newNormals = GeoNormals3f::create(); 00765 Vec3f normal; 00766 00767 FaceIterator faceIter = geo->beginFaces(); 00768 GeoIndicesPtr oldIndex = geo->getIndices(); 00769 00770 if(oldIndex != NullFC) 00771 { 00772 //Indexed 00773 if(geo->getIndexMapping().size() > 0) 00774 { 00775 //MULTI INDEXED 00776 beginEditCP(newIndex); 00777 00778 MFUInt16 &oldIndexMap = geo->getIndexMapping(); 00779 UInt32 oldIMSize = oldIndexMap.size(); 00780 for(UInt32 i = 0; i < oldIndex->getSize() / oldIMSize; ++i) 00781 { 00782 for(UInt32 k = 0; k < oldIMSize; ++k) 00783 { 00784 newIndex->push_back(oldIndex->getValue(i * oldIMSize + k)); 00785 } 00786 00787 newIndex->push_back(0); //placeholder for normal index 00788 } 00789 00790 beginEditCP(newNormals); 00791 for(UInt32 faceCnt = 0; faceIter != geo->endFaces(); 00792 ++faceIter, ++faceCnt) 00793 { 00794 if(faceIter.getLength() == 3) 00795 { 00796 //Face is a Triangle 00797 normal = 00798 ( 00799 faceIter.getPosition(1) - 00800 faceIter.getPosition(0) 00801 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00802 normal.normalize(); 00803 } 00804 else 00805 { 00806 //Face must be a Quad then 00807 normal = 00808 ( 00809 faceIter.getPosition(1) - 00810 faceIter.getPosition(0) 00811 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00812 if(normal.length() == 0) 00813 { 00814 //Quad is degenerate, choose different points for normal 00815 normal = 00816 ( 00817 faceIter.getPosition(1) - 00818 faceIter.getPosition(2) 00819 ).cross(faceIter.getPosition(3) - 00820 faceIter.getPosition(2)); 00821 } 00822 00823 normal.normalize(); 00824 } 00825 00826 newNormals->push_back(normal); //put the normal into the storage 00827 UInt32 base; 00828 switch(faceIter.getType()) 00829 { 00830 case GL_TRIANGLE_STRIP: 00831 base = faceIter.getIndexIndex(2); //get last point's position in index field 00832 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize); 00833 break; 00834 case GL_TRIANGLE_FAN: 00835 base = faceIter.getIndexIndex(2); //get last point's position in index field 00836 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize); 00837 break; 00838 case GL_QUAD_STRIP: 00839 base = faceIter.getIndexIndex(3); //get last point's position in index field 00840 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize); 00841 break; 00842 default: 00843 for(UInt32 i = 0; i < faceIter.getLength(); ++i) 00844 { 00845 base = faceIter.getIndexIndex(i); 00846 newIndex->setValue(faceCnt, 00847 base + (base / oldIMSize) + oldIMSize); 00848 } 00849 break; 00850 } 00851 } 00852 00853 endEditCP(newNormals); 00854 endEditCP(newIndex); 00855 00856 beginEditCP(geo); 00857 00858 Int16 ni; 00859 ni = geo->calcMappingIndex(Geometry::MapNormal); 00860 if(ni != -1) 00861 { 00862 oldIndexMap[ni] = oldIndexMap[ni] &~Geometry::MapNormal; 00863 } 00864 00865 oldIndexMap.push_back(Geometry::MapNormal); 00866 geo->setNormals(newNormals); 00867 geo->setIndices(newIndex); 00868 endEditCP(geo); 00869 return; 00870 } 00871 } 00872 00873 //SINGLE INDEXED or NON INDEXED 00874 //UInt32 pointCnt = 0; 00875 newNormals->resize(geo->getPositions()->getSize()); 00876 for(; faceIter != geo->endFaces(); ++faceIter) 00877 { 00878 if(faceIter.getLength() == 3) 00879 { 00880 //Face is a Triangle 00881 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00882 normal.normalize(); 00883 } 00884 else 00885 { 00886 //Face must be a Quad then 00887 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00888 if(normal.length() == 0) 00889 { 00890 //Quad is degenerate, choose different points for normal 00891 normal = 00892 ( 00893 faceIter.getPosition(1) - 00894 faceIter.getPosition(2) 00895 ).cross(faceIter.getPosition(3) - faceIter.getPosition(2)); 00896 } 00897 00898 normal.normalize(); 00899 } 00900 00901 switch(faceIter.getType()) 00902 { 00903 case GL_TRIANGLE_STRIP: 00904 newNormals->setValue(normal, faceIter.getPositionIndex(2)); 00905 break; 00906 case GL_TRIANGLE_FAN: 00907 newNormals->setValue(normal, faceIter.getPositionIndex(2)); 00908 break; 00909 case GL_QUAD_STRIP: 00910 newNormals->setValue(normal, faceIter.getPositionIndex(3)); 00911 break; 00912 default: 00913 for(UInt32 i = 0; i < faceIter.getLength(); ++i) 00914 { 00915 newNormals->setValue(normal, faceIter.getPositionIndex(i)); 00916 } 00917 break; 00918 } 00919 00920 beginEditCP(geo); 00921 geo->setNormals(newNormals); 00922 endEditCP(geo); 00923 } 00924 }
| Int32 osg::setIndexFromVRMLData | ( | GeometryPtr | geoPtr, | |
| std::vector< Int32 > & | coordIndex, | |||
| std::vector< Int32 > & | normalIndex, | |||
| std::vector< Int32 > & | colorIndex, | |||
| std::vector< Int32 > & | texCoordIndex, | |||
| bool | convex, | |||
| bool | ccw, | |||
| bool | normalPerVertex, | |||
| bool | colorPerVertex, | |||
| bool | createNormal, | |||
| bool | faceSet | |||
| ) |
setIndexFromVRMLData creates an osg::Geometry's interleaved index data from VRML-style separate indices, see Geometry Creation for a description.
coordIndex, normalIndex, colorIndex and texCoordIndex are VRML97-style indices. ccw sets whether poylgons are defined counter-clockwise or clockwise, normalPerVertex and colorPerVertex specify bindings, and faceSet defines whether a VRML IndexedFaceSet or an IndexedLineSet is being generated. See the VRML97 specification at http://www.web3d.org for details.
Note: the convex and createNormals parameters are ignored right now!
Definition at line 943 of file OSGGeoFunctions.cpp.
References osg::setIndexFromIndexedX3DData().
Referenced by osg::VRMLGeometryPointSetDesc::endNode(), and osg::VRMLGeometryDesc::endNode().
00954 { 00955 Int32 primitiveType = faceSet ? GL_POLYGON : GL_LINE_STRIP; 00956 00957 return setIndexFromIndexedX3DData ( geoPtr, 00958 coordIndex, 00959 normalIndex, 00960 colorIndex, 00961 texCoordIndex, 00962 primitiveType, 00963 convex, 00964 ccw, 00965 normalPerVertex, 00966 colorPerVertex, 00967 createNormal ); 00968 }
| Int32 osg::setIndexFromIndexedX3DData | ( | GeometryPtr | geoPtr, | |
| std::vector< Int32 > & | coordIndex, | |||
| std::vector< Int32 > & | normalIndex, | |||
| std::vector< Int32 > & | colorIndex, | |||
| std::vector< Int32 > & | texCoordIndex, | |||
| Int32 | primitiveType, | |||
| bool | convex, | |||
| bool | ccw, | |||
| bool | normalPerVertex, | |||
| bool | colorPerVertex, | |||
| bool | createNormal | |||
| ) |
setIndexFromIndexedX3DData creates an osg::Geometry's interleaved index data from X3D-style separate indices, see Geometry Creation for a description.
The primitiveType defines the GL-Primtive (e.g. GL_LINE, GL_TRIANGLE_STRIP, GL_POLYGON) which should be used.
coordIndex, normalIndex, colorIndex and texCoordIndex are X3D-style indices. ccw sets whether poylgons are defined counter-clockwise or clockwise, normalPerVertex and colorPerVertex specify bindings. See the X3D specification at http://www.web3d.org for details.
Note: the convex and createNormals parameters are ignored right now!
Definition at line 989 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::endEditCP(), FDEBUG, FFATAL, FINFO, FNOTICE, FWARNING, osg::Geometry::MapColor, osg::Geometry::MapNormal, osg::Geometry::MapPosition, osg::Geometry::MapTexCoords, osg::Geometry::MapTexCoords1, osg::Geometry::MapTexCoords2, osg::Geometry::MapTexCoords3, osg::Geometry::MapTexCoords4, osg::Geometry::MapTexCoords5, osg::Geometry::MapTexCoords6, osg::Geometry::MapTexCoords7, and osg::NullFC.
Referenced by osg::setIndexFromVRMLData().
01000 { 01002 typedef std::vector<Int32> *IndexBagP; 01003 01005 enum IndexType 01006 { 01007 UNKNOWN_IT = 0, 01008 EMPTY_IT, 01009 VERTEX_COORD_IT, 01010 VERTEX_IT, 01011 VERTEX_DUP_IT, 01012 VERTEX_CREATE_IT, 01013 PRIMITIVE_IT, 01014 PRIMITIVE_INDEX_IT, 01015 PRIMITIVE_CREATE_IT 01016 }; 01017 01019 static const char *indexTypeStr[] = 01020 { 01021 "UNKNOWN_IT", 01022 "EMPTY_IT", 01023 "VERTEX_COORD_IT", 01024 "VERTEX_IT", 01025 "VERTEX_DUP_IT", 01026 "VERTEX_CREATE_IT", 01027 "PRIMTIVE_IT", 01028 "PRIMITIVE_INDEX_IT", 01029 "PRIMITIVE_CREATE_IT" 01030 }; 01031 OSG::GeoPositionsPtr posPtr; 01032 OSG::GeoNormalsPtr normalPtr; 01033 OSG::GeoColorsPtr colorPtr; 01034 OSG::GeoTexCoordsPtr texCoordsPtr; 01035 OSG::GeoPLengthsPtr lensPtr; 01036 OSG::GeoPTypesPtr geoTypePtr; 01037 OSG::GeoIndicesPtr indexPtr; 01038 01039 //bool faceSet = (primitiveType == GL_POLYGON); 01040 Int32 index, i, pi, typei, mapi, primitiveN = 0, vN = 0; 01041 Int32 pType = 0, localPType; 01042 Int32 maxPType; // = (faceSet ? 5 : 3); 01043 Int32 minPType; // = (faceSet ? 3 : 2); 01044 Int32 beginIndex, endIndex, step, len, sysPType = 0; 01045 Int32 piN = 0, ciN = 0, niN = 0, tiN = 0; 01046 Int32 pN = 0, nN = 0, cN = 0, tN = 0, tN1 = 0, tN2 = 0, tN3 = 0, 01047 tN4 = 0, tN5 = 0, tN6 = 0, tN7 = 0; 01048 IndexType indexType[4]; 01049 IndexType &coordIT = indexType[0]; 01050 IndexType &normalIT = indexType[1]; 01051 IndexType &colorIT = indexType[2]; 01052 IndexType &textureIT = indexType[3]; 01053 Int32 primitiveTypeCount[6]; 01054 UInt32 triCount = 0; 01055 Int16 indexMap[4], indexMapID[4]; 01056 UInt32 uiNumTextures = 0; 01057 01058 IndexBagP indexBag[4] = 01059 { 01060 &coordIndex, 01061 &normalIndex, 01062 &colorIndex, 01063 &texCoordIndex 01064 }; 01065 01066 //---------------------------------------------------------------------- 01067 // init 01068 coordIT = VERTEX_IT; 01069 indexMap[0] = Geometry::MapPosition; 01070 01071 //---------------------------------------------------------------------- 01072 // set maxPType and minPTypr from primitiveType 01073 switch (primitiveType) { 01074 case GL_POINTS: 01075 minPType = 1; 01076 maxPType = 1; 01077 break; 01078 case GL_LINES: 01079 minPType = 2; 01080 maxPType = 3; 01081 break; 01082 case GL_LINE_STRIP: 01083 minPType = 2; 01084 maxPType = 3; 01085 break; 01086 case GL_LINE_LOOP: 01087 minPType = 2; 01088 maxPType = 3; 01089 break; 01090 case GL_TRIANGLES: 01091 minPType = 3; 01092 maxPType = 3; 01093 break; 01094 case GL_TRIANGLE_STRIP: 01095 minPType = 3; 01096 maxPType = 3; 01097 break; 01098 case GL_TRIANGLE_FAN: 01099 minPType = 3; 01100 maxPType = 3; 01101 break; 01102 case GL_QUADS: 01103 minPType = 3; 01104 maxPType = 4; 01105 break; 01106 case GL_QUAD_STRIP: 01107 minPType = 3; 01108 maxPType = 4; 01109 break; 01110 case GL_POLYGON: 01111 minPType = 3; 01112 maxPType = 5; 01113 break; 01114 default: 01115 FFATAL (( "Can not fill index; Invalid primitiveType: %d\n", 01116 primitiveType )); 01117 break; 01118 } 01119 01120 01121 //---------------------------------------------------------------------- 01122 // get the property pointer and element count 01123 posPtr = geoPtr->getPositions(); 01124 pN = ((posPtr == OSG::NullFC) ? 0 : posPtr->getSize()); 01125 01126 normalPtr = geoPtr->getNormals(); 01127 nN = ((normalPtr == OSG::NullFC) ? 0 : normalPtr->getSize()); 01128 01129 colorPtr = geoPtr->getColors(); 01130 cN = ((colorPtr == OSG::NullFC) ? 0 : colorPtr->getSize()); 01131 01132 texCoordsPtr = geoPtr->getTexCoords(); 01133 tN = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01134 01135 texCoordsPtr = geoPtr->getTexCoords1(); 01136 tN1 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01137 01138 texCoordsPtr = geoPtr->getTexCoords2(); 01139 tN2 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01140 01141 texCoordsPtr = geoPtr->getTexCoords3(); 01142 tN3 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01143 01144 texCoordsPtr = geoPtr->getTexCoords4(); 01145 tN4 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01146 01147 texCoordsPtr = geoPtr->getTexCoords5(); 01148 tN5 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01149 01150 texCoordsPtr = geoPtr->getTexCoords6(); 01151 tN6 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01152 01153 texCoordsPtr = geoPtr->getTexCoords7(); 01154 tN7 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01155 01156 FDEBUG(("vertex attrib count P/N/C/T: %d/%d/%d/%d\n", pN, nN, cN, tN)); 01157 01158 //---------------------------------------------------------------------- 01159 // check the vertex index and count the primitives 01160 primitiveN = index = 0; 01161 for(pType = 0; pType < 6; pType++) 01162 primitiveTypeCount[pType] = 0; 01163 01164 if(!pN) 01165 { 01166 FINFO(("No points in OSG::setIndexFromVRMLData()\n")); 01167 return 0; 01168 } 01169 else 01170 { 01171 piN = coordIndex.size(); 01172 if(piN) 01173 { 01174 for(i = 0; i <= piN; i++) 01175 { 01176 index = (i == piN) ? -1 : coordIndex[i]; 01177 if((index < 0) && vN) 01178 { 01179 primitiveTypeCount[(vN > maxPType) ? maxPType : vN]++; 01180 primitiveN++; 01181 vN = 0; 01182 } 01183 else 01184 { 01185 if(index >= pN && i != piN) 01186 { 01187 FWARNING(("Point index (%d/%d) out of range", index, pN)); 01188 coordIndex[i] = 0; 01189 } 01190 01191 vN++; 01192 } 01193 } 01194 } 01195 else 01196 { 01197 FWARNING(("No coordIndex in OSG::setIndexFromVRMLData()\n")); 01198 return 0; 01199 } 01200 } 01201 01202 //---------------------------------------------------------------------- 01203 // check the normal index 01204 normalIT = UNKNOWN_IT; 01205 niN = normalIndex.size(); 01206 if(nN) 01207 { // have normal elements 01208 if(normalPerVertex) 01209 { 01210 // normal per vertex 01211 if(niN >= piN) 01212 { 01213 // valid normal index number 01214 for(i = 0; i < piN; i++) 01215 { // check if normal index equals the coord index 01216 if(normalIndex[i] != coordIndex[i]) 01217 { 01218 normalIT = VERTEX_IT; 01219 break; 01220 } 01221 } 01222 01223 if(normalIT == UNKNOWN_IT) 01224 { 01225 // if equal than delete unneeded normal index 01226 normalIT = VERTEX_DUP_IT; 01227 } 01228 } 01229 else 01230 { 01231 // no or not enough normal index 01232 normalIT = VERTEX_COORD_IT; 01233 if(niN) 01234 { 01235 FWARNING(("Not enough normal index (%d,%d)\n", normalIndex. 01236 size(), piN)); 01237 normalIndex.clear(); 01238 } 01239 } 01240 } 01241 else 01242 { 01243 // normal per primitive 01244 if(niN >= primitiveN) 01245 { 01246 // use one normal index per primitive 01247 normalIT = PRIMITIVE_INDEX_IT; 01248 } 01249 else 01250 { 01251 if(nN >= primitiveN) 01252 { 01253 // use one normal per primitive 01254 normalIT = PRIMITIVE_IT; 01255 } 01256 else 01257 { 01258 FINFO(("not enough normal index (%d,%d)\n", nN, primitiveN)); 01259 } 01260 } 01261 } 01262 } 01263 else 01264 { 01265 /* not yet !!! 01266 if (createNormal) 01267 if (normalPerVertex) 01268 normalIT = VERTEX_CREATE_IT; 01269 else 01270 normalIT = PRIMITIVE_CREATE_IT; 01271 else 01272 */ 01273 normalIT = EMPTY_IT; 01274 } 01275 01276 //---------------------------------------------------------------------- 01277 // check the color index 01278 colorIT = UNKNOWN_IT; 01279 ciN = colorIndex.size(); 01280 if(cN) 01281 { // have color elements 01282 if(colorPerVertex) 01283 { 01284 // color per vertex 01285 if(ciN >= piN) 01286 { 01287 // valid color index number 01288 for(i = 0; i < piN; i++) 01289 { // check if color index equals the coord index 01290 if(colorIndex[i] != coordIndex[i]) 01291 { 01292 colorIT = VERTEX_IT; 01293 break; 01294 } 01295 } 01296 01297 if(colorIT == UNKNOWN_IT) 01298 { 01299 // if equal than delete unneeded color index 01300 colorIT = VERTEX_DUP_IT; 01301 } 01302 } 01303 else 01304 { 01305 // no or not enough color index 01306 colorIT = VERTEX_COORD_IT; 01307 if(ciN) 01308 { 01309 FWARNING(("Not enough color index (%d,%d)\n", colorIndex. 01310 size(), piN)); 01311 colorIndex.clear(); 01312 } 01313 } 01314 } 01315 else 01316 { 01317 // color per primitive 01318 if(ciN >= primitiveN) 01319 { 01320 // use one color index per primitive 01321 colorIT = PRIMITIVE_INDEX_IT; 01322 } 01323 else 01324 { 01325 if(cN >= primitiveN) 01326 { 01327 // use one color per primitive 01328 colorIT = PRIMITIVE_IT; 01329 } 01330 else 01331 { 01332 FINFO(("not enough color index (%d,%d)\n", cN, primitiveN)); 01333 } 01334 } 01335 } 01336 } 01337 else 01338 { 01339 colorIT = EMPTY_IT; 01340 } 01341 01342 //---------------------------------------------------------------------- 01343 // check the texture index 01344 textureIT = UNKNOWN_IT; 01345 tiN = texCoordIndex.size(); 01346 if(tN) 01347 { // have texture elemnts 01348 if(tiN >= piN) 01349 { 01350 // valid texture index number 01351 for(i = 0; i < piN; i++) 01352 { // check if texture index equals the coord index 01353 if(texCoordIndex[i] != coordIndex[i]) 01354 { 01355 textureIT = VERTEX_IT; 01356 break; 01357 } 01358 } 01359 01360 if(textureIT == UNKNOWN_IT) 01361 { 01362 // if equal than delete unneeded texture index 01363 textureIT = VERTEX_DUP_IT; 01364 } 01365 } 01366 else 01367 { 01368 // no or not enough texture index 01369 textureIT = VERTEX_COORD_IT; 01370 if(ciN) 01371 { 01372 FWARNING(("Not enough texCoord index (%d,%d)\n", texCoordIndex. 01373 size(), piN)); 01374 texCoordIndex.clear(); 01375 } 01376 } 01377 } 01378 else 01379 { 01380 textureIT = EMPTY_IT; 01381 } 01382 01383 FNOTICE (( "primitiveN: %d, %d, 0/%d 1/%d 2/%d 3/%d 4/%d 5/%d\n", 01384 primitiveType, 01385 primitiveN, primitiveTypeCount[0], 01386 primitiveTypeCount[1], primitiveTypeCount[2], 01387 primitiveTypeCount[3], primitiveTypeCount[4], 01388 primitiveTypeCount[5])); 01389 01390 FNOTICE (( "IndexType: coord: %s, color: %s, normal: %s, texture: %s \n", 01391 indexTypeStr[coordIT], indexTypeStr[colorIT], 01392 indexTypeStr[normalIT], indexTypeStr[textureIT])); 01393 01394 //---------------------------------------------------------------------- 01395 // check/create the indexPtr/lengthsPtr/geoTypePtr 01396 indexPtr = geoPtr->getIndices(); 01397 if(indexPtr == OSG::NullFC) 01398 { 01399 indexPtr = OSG::GeoIndicesUI32::create(); 01400 } 01401 else 01402 { 01403 OSG::beginEditCP(indexPtr); 01404 indexPtr->clear(); 01405 OSG::endEditCP(indexPtr); 01406 } 01407 01408 lensPtr = geoPtr->getLengths(); 01409 if(lensPtr == OSG::NullFC) 01410 { 01411 lensPtr = OSG::GeoPLengthsUI32::create(); 01412 } 01413 else 01414 { 01415 OSG::beginEditCP(lensPtr); 01416 lensPtr->clear(); 01417 OSG::endEditCP(lensPtr); 01418 } 01419 01420 geoTypePtr = geoPtr->getTypes(); 01421 if(geoTypePtr == OSG::NullFC) 01422 { 01423 geoTypePtr = OSG::GeoPTypesUI8::create(); 01424 } 01425 else 01426 { 01427 OSG::beginEditCP(geoTypePtr); 01428 geoTypePtr->clear(); 01429 OSG::endEditCP(geoTypePtr); 01430 } 01431 01432 //---------------------------------------------------------------------- 01433 // create the index mapping 01434 indexMapID[0] = Geometry::MapPosition; 01435 indexMapID[1] = Geometry::MapNormal; 01436 indexMapID[2] = Geometry::MapColor; 01437 indexMapID[3] = Geometry::MapTexCoords; 01438 01439 for(mapi = i = 1; i <= 3; i++) 01440 { 01441 indexMap[i] = 0; 01442 switch(indexType[i]) 01443 { 01444 case UNKNOWN_IT: 01445 case EMPTY_IT: 01446 break; 01447 case VERTEX_COORD_IT: 01448 case VERTEX_DUP_IT: 01449 //case VERTEX_CREATE_IT: 01450 indexMap[0] |= indexMapID[i]; 01451 break; 01452 case VERTEX_IT: 01453 case PRIMITIVE_IT: 01454 case PRIMITIVE_INDEX_IT: 01455 //case PRIMITIVE_CREATE_IT: 01456 indexMap[mapi++] = indexMapID[i]; 01457 break; 01458 default: //X_CREATE_IT 01459 break; 01460 } 01461 } 01462 01463 //---------------------------------------------------------------------- 01464 // set lens/geoType/index/mapping the index mapping 01465 OSG::beginEditCP(geoPtr); 01466 { 01467 geoPtr->setLengths(lensPtr); 01468 geoPtr->setTypes(geoTypePtr); 01469 geoPtr->setIndices(indexPtr); 01470 geoPtr->getIndexMapping().clear(); 01471 01472 // TODO: check for multiindex mapping ? 01473 // if (indexMap[1]) 01474 for(i = 0; ((i <= 3) && indexMap[i]); i++) 01475 { 01476 if(i == 0) 01477 { 01478 if(indexMap[i] & Geometry::MapTexCoords) 01479 { 01480 ++uiNumTextures; 01481 01482 if(tN1 != 0) 01483 { 01484 indexMap[i] |= Geometry::MapTexCoords1; 01485 } 01486 01487 if(tN2 != 0) 01488 { 01489 indexMap[i] |= Geometry::MapTexCoords2; 01490 } 01491 01492 if(tN3 != 0) 01493 { 01494 indexMap[i] |= Geometry::MapTexCoords3; 01495 } 01496 01497 if(tN4 != 0) 01498 { 01499 indexMap[i] |= Geometry::MapTexCoords4; 01500 } 01501 01502 if(tN5 != 0) 01503 { 01504 indexMap[i] |= Geometry::MapTexCoords5; 01505 } 01506 01507 if(tN6 != 0) 01508 { 01509 indexMap[i] |= Geometry::MapTexCoords6; 01510 } 01511 01512 if(tN7 != 0) 01513 { 01514 indexMap[i] |= Geometry::MapTexCoords7; 01515 } 01516 } 01517 01518 geoPtr->getIndexMapping().push_back(indexMap[i]); 01519 } 01520 else 01521 { 01522 geoPtr->getIndexMapping().push_back(indexMap[i]); 01523 01524 if(indexMap[i] & Geometry::MapTexCoords) 01525 { 01526 ++uiNumTextures; 01527 01528 if(tN1 != 0) 01529 { 01530 geoPtr->getIndexMapping().push_back( 01531 Geometry::MapTexCoords1); 01532 01533 ++uiNumTextures; 01534 } 01535 01536 if(tN2 != 0) 01537 { 01538 geoPtr->getIndexMapping().push_back( 01539 Geometry::MapTexCoords2); 01540 01541 ++uiNumTextures; 01542 } 01543 01544 if(tN3 != 0) 01545 { 01546 geoPtr->getIndexMapping().push_back( 01547 Geometry::MapTexCoords3); 01548 01549 ++uiNumTextures; 01550 } 01551 01552 if(tN4 != 0) 01553 { 01554 geoPtr->getIndexMapping().push_back( 01555 Geometry::MapTexCoords4); 01556 01557 ++uiNumTextures; 01558 } 01559 01560 if(tN5 != 0) 01561 { 01562 geoPtr->getIndexMapping().push_back( 01563 Geometry::MapTexCoords5); 01564 01565 ++uiNumTextures; 01566 } 01567 01568 if(tN6 != 0) 01569 { 01570 geoPtr->getIndexMapping().push_back( 01571 Geometry::MapTexCoords6); 01572 01573 ++uiNumTextures; 01574 } 01575 01576 if(tN7 != 0) 01577 { 01578 geoPtr->getIndexMapping().push_back( 01579 Geometry::MapTexCoords7); 01580 01581 ++uiNumTextures; 01582 } 01583 } 01584 } 01585 } 01586 } 01587 OSG::endEditCP(geoPtr); 01588 01589 //---------------------------------------------------------------------- 01590 // create index face/line data 01591 OSG::beginEditCP(indexPtr); 01592 OSG::beginEditCP(lensPtr); 01593 OSG::beginEditCP(geoTypePtr); 01594 01595 for(pType = minPType; pType <= maxPType; pType++) 01596 { 01597 // check for the pType count 01598 if(primitiveTypeCount[pType]) 01599 { 01600 // calc len/sysPType 01601 01602 if(pType < maxPType) 01603 { 01604 len = primitiveTypeCount[pType] * pType; 01605 switch (pType) 01606 { 01607 case 1: 01608 sysPType = GL_POINTS; 01609 break; 01610 case 2: 01611 sysPType = GL_LINES; 01612 break; 01613 case 3: 01614 sysPType = GL_TRIANGLES; 01615 break; 01616 case 4: 01617 sysPType = GL_QUADS; 01618 break; 01619 } 01620 } 01621 else 01622 { 01623 sysPType = 0; 01624 } 01625 01626 // set len/sysPType 01627 if(sysPType) 01628 { 01629 lensPtr->push_back(len); 01630 geoTypePtr->push_back(sysPType); 01631 } 01632 01633 primitiveN = 0; 01634 beginIndex = endIndex = -1; 01635 for(i = 0; i <= piN; i++) 01636 { 01637 if(((i == piN) && (coordIndex[i - 1] >= 0)) || 01638 ((i < piN) && (coordIndex[i] < 0))) 01639 { 01640 len = i - beginIndex; 01641 if(ccw) 01642 { 01643 endIndex = i; 01644 step = 1; 01645 } 01646 else 01647 { 01648 endIndex = beginIndex - 1; 01649 beginIndex = i - 1; 01650 step = -1; 01651 } 01652 01653 localPType = (len > maxPType) ? maxPType : len; 01654 if((beginIndex >= 0) && (localPType == pType)) 01655 { 01656 if(len >= maxPType) 01657 { 01658 sysPType = primitiveType; 01659 lensPtr->push_back(len); 01660 geoTypePtr->push_back(sysPType); 01661 } 01662 01663 // add index data 01664 for(pi = beginIndex; pi != endIndex; pi += step) 01665 { 01666 indexPtr->push_back(coordIndex[pi]); 01667 for(mapi = 1; (mapi <= 3) && (indexMap[mapi]); 01668 mapi++) 01669 { 01670 for(typei = 1; typei <= 3; typei++) 01671 { 01672 if(indexMap[mapi] & indexMapID[typei]) 01673 { 01674 switch(indexType[typei]) 01675 { 01676 case UNKNOWN_IT: 01677 case EMPTY_IT: 01678 case VERTEX_COORD_IT: 01679 case VERTEX_DUP_IT: 01680 FFATAL(("Fatal index mapping error \n")); 01681 break; 01682 case VERTEX_IT: 01683 index = (*indexBag[typei])[pi]; 01684 break; 01685 case PRIMITIVE_IT: 01686 index = primitiveN; 01687 break; 01688 case PRIMITIVE_INDEX_IT: 01689 index = (*indexBag[typei])[primitiveN]; 01690 break; 01691 default: //X_CREATE_IT 01692 break; 01693 } 01694 01695 indexPtr->push_back(index); 01696 01697 if(indexMap[mapi] & Geometry::MapTexCoords) 01698 { 01699 for(UInt32 ti = 0; ti < uiNumTextures - 1; ++ti) 01700 { 01701 indexPtr->push_back(index); 01702 } 01703 } 01704 } 01705 01706 } 01707 } 01708 } 01709 01710 triCount += len - 2; 01711 } 01712 01713 primitiveN++; 01714 beginIndex = endIndex = -1; 01715 } 01716 else if(beginIndex < 0) 01717 beginIndex = i; 01718 } 01719 } 01720 } 01721 01722 OSG::endEditCP(geoTypePtr); 01723 OSG::endEditCP(lensPtr); 01724 OSG::endEditCP(indexPtr); 01725 01726 return triCount; 01727 }
| void osg::calcVertexTexCoords | ( | GeometryPtr | geo, | |
| Int32 | texIndex | |||
| ) |
calcVertexTexCoords calculates the texCoords for the geometry's vertices, see PageSystemGeoFunctionsCalcTexCoords for a description.
Definition at line 1788 of file OSGGeoFunctions.cpp.
References osg::MField< FieldTypeT, fieldNameSpace >::begin(), osg::beginEditCP(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::endEditCP(), osg::MField< FieldTypeT, fieldNameSpace >::erase(), FFATAL, FWARNING, osg::DynamicVolume::getBounds(), osg::Geometry::MapPosition, osg::Geometry::MapTexCoords, osg::Geometry::MapTexCoords1, osg::Geometry::MapTexCoords2, osg::Geometry::MapTexCoords3, osg::Geometry::MapTexCoords4, osg::Geometry::MapTexCoords5, osg::Geometry::MapTexCoords6, osg::Geometry::MapTexCoords7, osg::NullFC, osg::MField< FieldTypeT, fieldNameSpace >::push_back(), and osg::MField< FieldTypeT, fieldNameSpace >::size().
01789 { 01790 struct Key { 01791 Real32 value; 01792 Int32 pos; 01793 } key[3], rem; 01794 01795 Int32 S = -1, T = -1, n = 3, i, j; 01796 Real32 sDenom, tDenom, sMin, tMin; 01797 01798 MFUInt16 &im = geo->getIndexMapping(); 01799 UInt16 mapTex = 0; 01800 01801 GeoIndicesPtr ip = geo->getIndices(); 01802 GeoPositionsPtr posP = geo->getPositions(); 01803 GeoTexCoordsPtr texP; 01804 01805 if (posP == NullFC || !posP->size() || ip == NullFC || !ip->size()) 01806 { 01807 FFATAL(("Geo without indices/ positions in calcVertexTexCoords()\n")); 01808 return; 01809 } 01810 01811 for (MFNodePtr::iterator pnI = geo->getMFParents()->begin(); 01812 pnI != geo->getMFParents()->end(); ++pnI) 01813 { 01814 NodePtr node = *pnI; 01815 01816 if (node != NullFC) 01817 { 01818 DynamicVolume &dVol = node->getVolume(true); 01819 Pnt3f min, max; 01820 dVol.getBounds(min, max); 01821 01822 Vec3f dia(max - min); 01823 for (i=0; i<3; i++) 01824 { 01825 key[i].value = dia[i]; 01826 key[i].pos = i; 01827 } 01828 01829 for (i=1; i<n; i++) 01830 { 01831 for (j=n-1; j>=i; j--) 01832 { 01833 if (key[j-1].value > key[j].value) 01834 { 01835 rem = key[j]; 01836 key[j] = key[j-1]; 01837 key[j-1] = rem; 01838 } 01839 } 01840 } 01841 01842 S = key[2].pos; 01843 T = key[1].pos; 01844 sDenom = dia[S]; 01845 tDenom = dia[T]; 01846 sMin = min[S]; 01847 tMin = min[T]; 01848 01849 break; 01850 } 01851 } 01852 01853 if (S < 0 || T < 0) 01854 { 01855 FFATAL(("Geo without parents in calcVertexTexCoords()\n")); 01856 return; 01857 } 01858 01859 switch (texIndex) 01860 { 01861 case 0: 01862 if (geo->getTexCoords() == osg::NullFC) 01863 { 01864 texP = GeoTexCoords2f::create(); 01865 beginEditCP(geo); 01866 geo->setTexCoords(texP); 01867 endEditCP(geo); 01868 } 01869 else 01870 { 01871 texP = geo->getTexCoords(); 01872 } 01873 mapTex = Geometry::MapTexCoords; 01874 break; 01875 case 1: 01876 if (geo->getTexCoords1() == osg::NullFC) 01877 { 01878 texP = GeoTexCoords2f::create(); 01879 beginEditCP(geo); 01880 geo->setTexCoords1(texP); 01881 endEditCP(geo); 01882 } 01883 else 01884 { 01885 texP = geo->getTexCoords1(); 01886 } 01887 mapTex = Geometry::MapTexCoords1; 01888 break; 01889 case 2: 01890 if (geo->getTexCoords2() == osg::NullFC) 01891 { 01892 texP = GeoTexCoords2f::create(); 01893 beginEditCP(geo); 01894 geo->setTexCoords2(texP); 01895 endEditCP(geo); 01896 } 01897 else 01898 { 01899 texP = geo->getTexCoords2(); 01900 } 01901 mapTex = Geometry::MapTexCoords2; 01902 break; 01903 case 3: 01904 if (geo->getTexCoords3() == osg::NullFC) 01905 { 01906 texP = GeoTexCoords2f::create(); 01907 beginEditCP(geo); 01908 geo->setTexCoords3(texP); 01909 endEditCP(geo); 01910 } 01911 else 01912 { 01913 texP = geo->getTexCoords3(); 01914 } 01915 mapTex = Geometry::MapTexCoords3; 01916 break; 01917 case 4: 01918 if (geo->getTexCoords4() == osg::NullFC) 01919 { 01920 texP = GeoTexCoords2f::create(); 01921 beginEditCP(geo); 01922 geo->setTexCoords4(texP); 01923 endEditCP(geo); 01924 } 01925 else 01926 { 01927 texP = geo->getTexCoords4(); 01928 } 01929 mapTex = Geometry::MapTexCoords4; 01930 break; 01931 case 5: 01932 if (geo->getTexCoords5() == osg::NullFC) 01933 { 01934 texP = GeoTexCoords2f::create(); 01935 beginEditCP(geo); 01936 geo->setTexCoords5(texP); 01937 endEditCP(geo); 01938 } 01939 else 01940 { 01941 texP = geo->getTexCoords5(); 01942 } 01943 mapTex = Geometry::MapTexCoords5; 01944 break; 01945 case 6: 01946 if (geo->getTexCoords6() == osg::NullFC) 01947 { 01948 texP = GeoTexCoords2f::create(); 01949 beginEditCP(geo); 01950 geo->setTexCoords6(texP); 01951 endEditCP(geo); 01952 } 01953 else 01954 { 01955 texP = geo->getTexCoords6(); 01956 } 01957 mapTex = Geometry::MapTexCoords6; 01958 break; 01959 case 7: 01960 if (geo->getTexCoords7() == osg::NullFC) 01961 { 01962 texP = GeoTexCoords2f::create(); 01963 beginEditCP(geo); 01964 geo->setTexCoords7(texP); 01965 endEditCP(geo); 01966 } 01967 else 01968 { 01969 texP = geo->getTexCoords7(); 01970 } 01971 mapTex = Geometry::MapTexCoords7; 01972 break; 01973 default: 01974 FWARNING(("Parameters are [0|1|2|3|4|5|6|7] in calcVertexTexCoords()\n")); 01975 return; 01976 } 01977 01978 Int16 niTex = geo->calcMappingIndex(mapTex), 01979 niPos = geo->calcMappingIndex(Geometry::MapPosition); 01980 Int32 len = posP->size(), indexMapSize = im.size(), imsize = 0, ibsize; 01981 UInt32 nind = ip->size() / (indexMapSize ? indexMapSize : 1); 01982 01983 Pnt3f point; 01984 Vec2f texCoord; 01985 01986 if (indexMapSize > 1) 01987 { 01988 MFUInt16::iterator imIt = im.begin(); 01989 std::vector<UInt32> indexBuffer; 01990 01991 if (niTex >= 0) 01992 im[niTex] = im[niTex] &~ mapTex; 01993 01994 im.push_back(mapTex); 01995 01996 for (i=0; i<nind; i++) 01997 { 01998 for (j=0; j<indexMapSize; j++) 01999 { 02000 if (j != niTex || im[niTex] >= 1) 02001 indexBuffer.push_back(ip->getValue(i*indexMapSize + j)); 02002 } 02003 indexBuffer.push_back(ip->getValue(i*indexMapSize + niPos)); 02004 } 02005 02006 if (niTex >= 0 && im[niTex] < 1) 02007 im.erase(imIt + niTex); 02008 02009 imsize = im.size(); 02010 ibsize = indexBuffer.size(); 02011 02012 beginEditCP(ip); 02013 { 02014 ip->clear(); 02015 02016 if (imsize != indexMapSize) 02017 ip->resize(ibsize); 02018 02019 for (i=0; i<ibsize; i++) 02020 ip->setValue(indexBuffer[i], i); 02021 } 02022 endEditCP(ip); 02023 02024 niTex = imsize ? imsize - 1 : 0; 02025 } 02026 02027 beginEditCP(texP); 02028 { 02029 niPos = geo->calcMappingIndex(Geometry::MapPosition); 02030 niPos = (niPos >= 0) ? niPos : 0; 02031 02032 if (texP->size() != len) 02033 texP->resize(len); 02034 02035 beginEditCP(ip); 02036 { 02037 for (i=0; i<len; i++) 02038 { 02039 posP->getValue(point, i); 02040 02041 texCoord[0] = (point[S] - sMin) / sDenom; 02042 texCoord[1] = (point[T] - tMin) / tDenom; 02043 02044 texP->setValue(texCoord, i); 02045 } 02046 } 02047 endEditCP(ip); 02048 } 02049 endEditCP(texP); 02050 }
| void osg::calcVertexTangents | ( | GeometryPtr | geo, | |
| Int32 | srcTexIndex, | |||
| Int32 | dstAttribTan, | |||
| Int32 | dstAttribBin | |||
| ) |
calcVertexTangents calculates the tangents/ binormals for the geometry's vertices, see PageSystemGeoFunctionsCalcTangents for a description.
Definition at line 2059 of file OSGGeoFunctions.cpp.
References B, osg::MField< FieldTypeT, fieldNameSpace >::begin(), osg::beginEditCP(), osg::GeometryBase::ColorsFieldId, osg::GeoProperty< GeoPropertyDesc >::create(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::cross(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::endEditCP(), IndexDic::entry(), osg::MField< FieldTypeT, fieldNameSpace >::erase(), FFATAL, FWARNING, osg::TriangleIterator::getIndexIndex(), osg::TriangleIterator::getNormal(), osg::TriangleIterator::getPosition(), osg::TriangleIterator::getPositionIndex(), osg::TriangleIterator::getTexCoords(), osg::TriangleIterator::getTexCoords1(), osg::TriangleIterator::getTexCoords2(), osg::TriangleIterator::getTexCoords3(), osg::TriangleIterator::getTexCoords4(), osg::TriangleIterator::getTexCoords5(), osg::TriangleIterator::getTexCoords6(), osg::TriangleIterator::getTexCoords7(), osg::GeometryBase::IndexMappingFieldMask, osg::GeometryBase::IndicesFieldMask, osg::Geometry::MapNormal, osg::Geometry::MapPosition, osg::Geometry::MapTexCoords, osg::Geometry::MapTexCoords1, osg::Geometry::MapTexCoords2, osg::Geometry::MapTexCoords3, osg::Geometry::MapTexCoords4, osg::Geometry::MapTexCoords5, osg::Geometry::MapTexCoords6, osg::Geometry::MapTexCoords7, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::GeometryBase::NormalsFieldId, osg::NullFC, osg::GeometryBase::PositionsFieldId, osg::MField< FieldTypeT, fieldNameSpace >::push_back(), osg::GeometryBase::SecondaryColorsFieldId, osg::MField< FieldTypeT, fieldNameSpace >::size(), osg::GeometryBase::TexCoords1FieldId, osg::GeometryBase::TexCoords2FieldId, osg::GeometryBase::TexCoords3FieldId, osg::GeometryBase::TexCoords4FieldId, osg::GeometryBase::TexCoords5FieldId, osg::GeometryBase::TexCoords6FieldId, osg::GeometryBase::TexCoords7FieldId, and osg::GeometryBase::TexCoordsFieldId.
02063 { 02064 GeoTexCoords4fPtr tangentP, binormalP; 02065 std::vector<Vec3f> tangent, binormal, normal; 02066 UInt16 mapTan = 0, mapBin = 0, mapTex = 0; 02067 02068 // fallback in case of user error: use none mode 02069 if (dstAttribTan == dstAttribBin) 02070 dstAttribBin = -1; 02071 02072 switch (srcTexIndex) 02073 { 02074 case 0: 02075 mapTex = Geometry::MapTexCoords; 02076 break; 02077 case 1: 02078 mapTex = Geometry::MapTexCoords1; 02079 break; 02080 case 2: 02081 mapTex = Geometry::MapTexCoords2; 02082 break; 02083 case 3: 02084 mapTex = Geometry::MapTexCoords3; 02085 break; 02086 case 4: 02087 mapTex = Geometry::MapTexCoords4; 02088 break; 02089 case 5: 02090 mapTex = Geometry::MapTexCoords5; 02091 break; 02092 case 6: 02093 mapTex = Geometry::MapTexCoords6; 02094 break; 02095 case 7: 02096 mapTex = Geometry::MapTexCoords7; 02097 break; 02098 default: 02099 FWARNING(("Currently only 8 TexCoords allowed in GeoPtr\n")); 02100 srcTexIndex = 0; 02101 mapTex = Geometry::MapTexCoords; 02102 break; 02103 } 02104 02105 switch (dstAttribTan) 02106 { 02107 case Geometry::TexCoordsFieldId: 02108 beginEditCP(geo); 02109 { 02110 // because we need more than 2 coords, as is usual, 02111 // it is safer & easier to set a new texCoordsPtr 02112 tangentP = GeoTexCoords4f::create(); 02113 geo->setTexCoords(tangentP); 02114 } 02115 endEditCP(geo); 02116 mapTan = Geometry::MapTexCoords; 02117 break; 02118 case Geometry::TexCoords1FieldId: 02119 beginEditCP(geo); 02120 { 02121 tangentP = GeoTexCoords4f::create(); 02122 geo->setTexCoords1(tangentP); 02123 } 02124 endEditCP(geo); 02125 mapTan = Geometry::MapTexCoords1; 02126 break; 02127 case Geometry::TexCoords2FieldId: 02128 beginEditCP(geo); 02129 { 02130 tangentP = GeoTexCoords4f::create(); 02131 geo->setTexCoords2(tangentP); 02132 } 02133 endEditCP(geo); 02134 mapTan = Geometry::MapTexCoords2; 02135 break; 02136 case Geometry::TexCoords3FieldId: 02137 beginEditCP(geo); 02138 { 02139 tangentP = GeoTexCoords4f::create(); 02140 geo->setTexCoords3(tangentP); 02141 } 02142 endEditCP(geo); 02143 mapTan = Geometry::MapTexCoords3; 02144 break; 02145 case Geometry::TexCoords4FieldId: 02146 beginEditCP(geo); 02147 { 02148 tangentP = GeoTexCoords4f::create(); 02149 geo->setTexCoords4(tangentP); 02150 } 02151 endEditCP(geo); 02152 mapTan = Geometry::MapTexCoords4; 02153 break; 02154 case Geometry::TexCoords5FieldId: 02155 beginEditCP(geo); 02156 { 02157 tangentP = GeoTexCoords4f::create(); 02158 geo->setTexCoords5(tangentP); 02159 } 02160 endEditCP(geo); 02161 mapTan = Geometry::MapTexCoords5; 02162 break; 02163 case Geometry::TexCoords6FieldId: 02164 beginEditCP(geo); 02165 { 02166 tangentP = GeoTexCoords4f::create(); 02167 geo->setTexCoords6(tangentP); 02168 } 02169 endEditCP(geo); 02170 mapTan = Geometry::MapTexCoords6; 02171 break; 02172 case Geometry::TexCoords7FieldId: 02173 beginEditCP(geo); 02174 { 02175 tangentP = GeoTexCoords4f::create(); 02176 geo->setTexCoords7(tangentP); 02177 } 02178 endEditCP(geo); 02179 mapTan = Geometry::MapTexCoords7; 02180 break; 02181 02182 case Geometry::PositionsFieldId: 02183 case Geometry::NormalsFieldId: 02184 case Geometry::ColorsFieldId: 02185 case Geometry::SecondaryColorsFieldId: 02186 FWARNING(("Case currently not treated, using NONE\n")); 02187 dstAttribTan = -1; 02188 02189 case -1: 02190 tangentP = GeoTexCoords4f::create(); // to be deleted 02191 break; 02192 } 02193 02194 switch (dstAttribBin) 02195 { 02196 case Geometry::TexCoordsFieldId: 02197 beginEditCP(geo); 02198 { 02199 binormalP = GeoTexCoords4f::create(); 02200 geo->setTexCoords(binormalP); 02201 } 02202 endEditCP(geo); 02203 mapBin = Geometry::MapTexCoords; 02204 break; 02205 case Geometry::TexCoords1FieldId: 02206 beginEditCP(geo); 02207 { 02208 binormalP = GeoTexCoords4f::create(); 02209 geo->setTexCoords1(binormalP); 02210 } 02211 endEditCP(geo); 02212 mapBin = Geometry::MapTexCoords1; 02213 break; 02214 case Geometry::TexCoords2FieldId: 02215 beginEditCP(geo); 02216 { 02217 binormalP = GeoTexCoords4f::create(); 02218 geo->setTexCoords2(binormalP); 02219 } 02220 endEditCP(geo); 02221 mapBin = Geometry::MapTexCoords2; 02222 break; 02223 case Geometry::TexCoords3FieldId: 02224 beginEditCP(geo); 02225 { 02226 binormalP = GeoTexCoords4f::create(); 02227 geo->setTexCoords3(binormalP); 02228 } 02229 endEditCP(geo); 02230 mapBin = Geometry::MapTexCoords3; 02231 break; 02232 case Geometry::TexCoords4FieldId: 02233 beginEditCP(geo); 02234 { 02235 binormalP = GeoTexCoords4f::create(); 02236 geo->setTexCoords4(binormalP); 02237 } 02238 endEditCP(geo); 02239 mapBin = Geometry::MapTexCoords4; 02240 break; 02241 case Geometry::TexCoords5FieldId: 02242 beginEditCP(geo); 02243 { 02244 binormalP = GeoTexCoords4f::create(); 02245 geo->setTexCoords5(binormalP); 02246 } 02247 endEditCP(geo); 02248 mapBin = Geometry::MapTexCoords5; 02249 break; 02250 case Geometry::TexCoords6FieldId: 02251 beginEditCP(geo); 02252 { 02253 binormalP = GeoTexCoords4f::create(); 02254 geo->setTexCoords6(binormalP); 02255 } 02256 endEditCP(geo); 02257 mapBin = Geometry::MapTexCoords6; 02258 break; 02259 case Geometry::TexCoords7FieldId: 02260 beginEditCP(geo); 02261 { 02262 binormalP = GeoTexCoords4f::create(); 02263 geo->setTexCoords7(binormalP); 02264 } 02265 endEditCP(geo); 02266 mapBin = Geometry::MapTexCoords7; 02267 break; 02268 02269 case Geometry::PositionsFieldId: 02270 case Geometry::NormalsFieldId: 02271 case Geometry::ColorsFieldId: 02272 case Geometry::SecondaryColorsFieldId: 02273 FWARNING(("Case currently not treated, using NONE\n")); 02274 dstAttribBin = -1; 02275 02276 case -1: 02277 binormalP = GeoTexCoords4f::create(); 02278 break; 02279 } 02280 02281 // can't eval what combination was meant 02282 if ( srcTexIndex < 0 || srcTexIndex > 3 || 02283 (dstAttribTan == -1 && dstAttribBin == -1)) 02284 { 02285 FFATAL(("Index set not supported in calcVertexTangents()\n")); 02286 return; 02287 } 02288 02289 GeoIndicesPtr ip = geo->getIndices(); 02290 02291 // HACK but without indices it crashes 02292 if (ip == NullFC || ip->size() == 0) 02293 { 02294 FFATAL(("Geo without indices in calcVertexTangents()\n")); 02295 return; 02296 } 02297 02298 GeoPositionsPtr positions = geo->getPositions(); 02299 02300 // Get the positions property 02301 if (positions == NullFC) 02302 { 02303 FFATAL(("Geo without positions in calcVertexTangents()\n")); 02304 return; 02305 } 02306 02307 MFUInt16 &im = geo->getIndexMapping(); 02308 Int16 niTan = (mapTan > 0) ? geo->calcMappingIndex(mapTan) : -1, 02309 niBin = (mapBin > 0) ? geo->calcMappingIndex(mapBin) : -1; 02310 02311 Int32 indexMapSize = im.size(), j, imsize = 0; 02312 UInt32 i, val, nind = ip->size() / (indexMapSize ? indexMapSize : 1); 02313 bool multiIndex = (indexMapSize > 1) ? true : false; 02314 02315 beginEditCP(geo, Geometry::IndexMappingFieldMask | 02316 Geometry::IndicesFieldMask ); 02317 02318 if (multiIndex) 02319 { 02320 // separate the attrib's index if exist 02321 if (niTan >= 0) 02322 im[niTan] = im[niTan] & ~mapTan; 02323 if (niBin >= 0) 02324 im[niBin] = im[niBin] & ~mapBin; 02325 02326 // if im[ni] < 1 erase because index is unused 02327 MFUInt16::iterator imIt = im.begin(); 02328 if (niTan == niBin) 02329 { 02330 if (niTan >= 0 && im[niTan] < 1) 02331 im.erase(imIt + niTan); 02332 else 02333 niTan = niBin = -1; // not deleted 02334 } 02335 else if (niTan < niBin) 02336 { 02337 if (niBin >= 0 && im[niBin] < 1) 02338 im.erase(imIt + niBin); 02339 else 02340 niBin = -1; 02341 if (niTan >= 0 && im[niTan] < 1) 02342 im.erase(imIt + niTan); 02343 else 02344 niTan = -1; 02345 } 02346 else 02347 { 02348 if (niTan >= 0 && im[niTan] < 1) 02349 im.erase(imIt + niTan); 02350 else 02351 niTan = -1; 02352 if (niBin >= 0 && im[niBin] < 1) 02353 im.erase(imIt + niBin); 02354 else 02355 niBin = -1; 02356 } 02357 02358 // create new mapping for attribs 02359 UInt16 map = 0; 02360 if (mapTan > 0) 02361 map |= mapTan; 02362 if (mapBin > 0) 02363 map |= mapBin; 02364 if (map > 0) 02365 im.push_back(map); 02366 imsize = im.size(); 02367 02368 // add an entry to the indices for the attribs 02369 std::vector<UInt32> indexBuffer; 02370 int status, l = 0, g = 0, ibSize; 02371 02372 if (niTan < 0 && niBin < 0) 02373 { 02374 status = 0; 02375 } 02376 else if (niBin < 0 && niTan >= 0 || 02377 niBin >= 0 && niTan < 0 || 02378 niBin >= 0 && niBin == niTan) 02379 { 02380 status = 1; 02381 l = (niBin < niTan) ? niTan : niBin; 02382 } 02383 else /*if (niBin > 0 && niTan > 0)*/ 02384 { 02385 status = 2; 02386 l = (niBin < niTan) ? niBin : niTan; 02387 g = (niBin < niTan) ? niTan : niBin; 02388 } 02389 02390 // discard positions l and g and provide index for tangent|binormal 02391 for (i=0; i<nind; i++) 02392 { 02393 for (j=0; j<indexMapSize; j++) 02394 { 02395 switch (status) 02396 { 02397 case 0: 02398 indexBuffer.push_back(ip->getValue(i*indexMapSize+j)); 02399 break; 02400 case 1: 02401 if (j != l) 02402 indexBuffer.push_back(ip->getValue(i*indexMapSize+j)); 02403 break; 02404 case 2: 02405 if (j != l && j != g) 02406 indexBuffer.push_back(ip->getValue(i*indexMapSize+j)); 02407 break; 02408 } 02409 } 02410 indexBuffer.push_back(0); // will be tangent|binormal index 02411 } 02412 ibSize = indexBuffer.size(); 02413 02414 beginEditCP(ip); 02415 { 02416 ip->clear(); 02417 ip->resize(ibSize); 02418 02419 for (i=0; i<ibSize; i++) 02420 ip->setValue(indexBuffer[i], i); 02421 } 02422 endEditCP(ip); 02423 02424 } // multiIndex 02425 else 02426 { 02427 // add index map for single index. 02428 if(im.size() > 0) 02429 im[0] |= (mapTan | mapBin); 02430 } 02431 02432 endEditCP(geo, Geometry::IndexMappingFieldMask | 02433 Geometry::IndicesFieldMask ); 02434 02435 TriangleIterator tI; 02436 IndexDic indexDic; 02437 Int32 k, index, v[3]; 02438 Vec4f vect(0, 0, 0, 0); 02439 02440 std::vector<Int32>indexVec; 02441 Int16 niPos = geo->calcMappingIndex(Geometry::MapPosition), 02442 niNorm = geo->calcMappingIndex(Geometry::MapNormal), 02443 niTex = geo->calcMappingIndex(mapTex); 02444 02445 indexVec.resize(3); 02446 02447 beginEditCP(ip); 02448 02449 // calc max index. 02450 UInt32 maxindex = 0; 02451 for(i=0;i<ip->size();++i) 02452 maxindex = ip->getValue(i) > maxindex ? ip->getValue(i) : maxindex; 02453 02454 // init property arrays 02455 // amz we can't use the indices size (nind) here! 02456 tangent.resize(maxindex + 1); 02457 binormal.resize(maxindex + 1); 02458 normal.resize(maxindex + 1); 02459 02460 for (tI=geo->beginTriangles(), i=0; tI!=geo->endTriangles(); ++tI, ++i) 02461 { 02462 // first, get index for every vertex 02463 for (k=0; k<3; ++k) 02464 { 02465 index = tI.getIndexIndex(k); 02466 02467 if (multiIndex) 02468 { 02469 // make vertex unique with resp. to Position, Normal, TexCoord 02470 for (j=0; j<imsize; j++) 02471 { 02472 if (j == niPos || j == niNorm || j == niTex) 02473 indexVec[j] = ip->getValue(index + j); 02474 } 02475 v[k] = indexDic.entry(indexVec); 02476 } 02477 else 02478 { 02479 v[k] = tI.getPositionIndex(k); //index; 02480 } 02481 } 02482 02483 // second, calculate tangent and binormal for every tri 02484 Int32 v0 = tI.getPositionIndex(0), 02485 v1 = tI.getPositionIndex(1), 02486 v2 = tI.getPositionIndex(2); 02487 Vec2f t0, t1, t2, tex1, tex2; 02488 Vec3f edge1, edge2, sdir, tdir; 02489 02490 switch (srcTexIndex) 02491 { 02492 case 0: 02493 t0 = tI.getTexCoords(0); 02494 t1 = tI.getTexCoords(1); 02495 t2 = tI.getTexCoords(2); 02496 break; 02497 case 1: 02498 t0 = tI.getTexCoords1(0); 02499 t1 = tI.getTexCoords1(1); 02500 t2 = tI.getTexCoords1(2); 02501 break; 02502 case 2: 02503 t0 = tI.getTexCoords2(0); 02504 t1 = tI.getTexCoords2(1); 02505 t2 = tI.getTexCoords2(2); 02506 break; 02507 case 3: 02508 t0 = tI.getTexCoords3(0); 02509 t1 = tI.getTexCoords3(1); 02510 t2 = tI.getTexCoords3(2); 02511 break; 02512 case 4: 02513 t0 = tI.getTexCoords4(0); 02514 t1 = tI.getTexCoords4(1); 02515 t2 = tI.getTexCoords4(2); 02516 break; 02517 case 5: 02518 t0 = tI.getTexCoords5(0); 02519 t1 = tI.getTexCoords5(1); 02520 t2 = tI.getTexCoords5(2); 02521 break; 02522 case 6: 02523 t0 = tI.getTexCoords6(0); 02524 t1 = tI.getTexCoords6(1); 02525 t2 = tI.getTexCoords6(2); 02526 break; 02527 case 7: 02528 t0 = tI.getTexCoords7(0); 02529 t1 = tI.getTexCoords7(1); 02530 t2 = tI.getTexCoords7(2); 02531 break; 02532 } 02533 02534 edge1 = tI.getPosition(1) - tI.getPosition(0), 02535 edge2 = tI.getPosition(2) - tI.getPosition(0); 02536 tex1 = t1 - t0; 02537 tex2 = t2 - t0; 02538 02539 // in rare cases this is zero! 02540 Real32 invDet = (tex1[0]*tex2[1] - tex2[0]*tex1[1]); 02541 if(invDet != 0.0f) 02542 invDet = 1.0f / invDet; 02543 else 02544 invDet = 0.0f; 02545 02546 sdir = invDet * (tex2[1]*edge1 - tex1[1]*edge2); // tangent 02547 tdir = invDet * (tex1[0]*edge2 - tex2[0]*edge1); // binormal 02548 02549 // set value for every vertex 02550 int tanOffset = (imsize == 0) ? 0 : imsize-1; 02551 02552 for (k=0; k<3; ++k) 02553 { 02554 tangent[v[k]] += sdir; 02555 binormal[v[k]] += tdir; 02556 normal[v[k]] = tI.getNormal(k); 02557 ip->setValue(v[k], tI.getIndexIndex(k) + tanOffset); 02558 } 02559 } 02560 endEditCP(ip); 02561 02562 // orthogonalize vectors (Gram-Schmidt) and calc handedness 02563 Vec3f T, B, N; 02564 Real32 sign = 0, l1, l2; 02565 tangentP->clear(); 02566 binormalP->clear(); 02567 02568 beginEditCP(tangentP); 02569 beginEditCP(binormalP); 02570 02571 for (i=0;i < tangent.size();++i) 02572 { 02573 T = tangent [i]; 02574 B = binormal[i]; 02575 N = normal [i]; // must be normalized: n*n = 1 02576 02577 sign = ((N.cross(T)).dot(B) < 0) ? -1 : 1; 02578 02579 T = T - N.dot(T) * N; 02580 T.normalize(); 02581 B = B - N.dot(B) * N - T.dot(B) * T; 02582 B.normalize(); 02583 02584 vect.setValues(T[0], T[1], T[2], sign); 02585 tangentP->getField().push_back(vect); 02586 02587 vect.setValues(B[0], B[1], B[2], sign); 02588 binormalP->getField().push_back(vect); 02589 } 02590 02591 endEditCP(tangentP); 02592 endEditCP(binormalP); 02593 }
| Int32 osg::createOptimizedPrimitives | ( | GeometryPtr | geoPtr, | |
| UInt32 | iteration, | |||
| bool | createStrips, | |||
| bool | createFans, | |||
| UInt32 | minFanEdgeCount, | |||
| bool | colorCode, | |||
| bool | stitchStrips | |||
| ) |
createOptimizedPrimitives changes the Geometry to make it faster to render by creating triangle strips and fans, see Geometry Optimization for a description.
geoPtr is the Geometry to optimize and iteration is the number of iteratiosn that are tried to find the best solution. createStripes and createFans defines whether stripes, fans or both should be created, with minFanEdgeCount giving the number of adjacent edges a vertex need to be considered for a fan. For visualising the results, a random colorCode can be assigned to each generated primitive.
It returns the number of vertex transformations needed to render the Geometry.
Definition at line 2614 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::calcPrimitiveCount(), osg::endEditCP(), IndexDic::entry(), IndexDic::entryCount(), FDEBUG, FINFO, FNOTICE, FWARNING, osg::getSystemTime(), osg::NullFC, and osg::osgMin().
Referenced by osg::StripeGraphOp::travNodeEnter().
02621 { 02622 if (geoPtr == NullFC) 02623 { 02624 return 0; 02625 } 02626 02627 HalfEdgeGraph graph; 02628 02629 UInt32 cost = 0, startCost, bestCost = 0, worstCost = 0, best = 0; 02630 02631 GeoPLengthsPtr lensPtr; 02632 GeoPTypesPtr geoTypePtr; 02633 Time time, inputT, optimizeT, outputT; 02634 02635 IndexDic indexDic; 02636 int invalidTriCount = 0; 02637 02638 GeoPositionsPtr posPtr = geoPtr->getPositions(); 02639 UInt32 pN = ((posPtr == OSG::NullFC) ? 0 : posPtr->getSize()); 02640 UInt32 indexMapSize = (geoPtr->getIndexMapping().size()); 02641 bool remapIndex = (indexMapSize > 1) ? true : false; 02642 02643 UInt32 triN, lineN, pointN; 02644 calcPrimitiveCount(geoPtr, triN, lineN, pointN); 02645 02646 GeoIndicesPtr indexPtr = geoPtr->getIndices(); 02647 02648 // Calculate startCost. 02649 if(indexPtr == NullFC) 02650 startCost = pN; 02651 else 02652 { 02653 if(indexMapSize) 02654 { 02655 startCost = indexPtr->size() / indexMapSize; 02656 } 02657 else 02658 startCost = indexPtr->size(); 02659 } 02660 02661 // Leave early if we have no indices or positions. 02662 if (pN == 0 || indexPtr == NullFC) 02663 { 02664 return 0; 02665 } 02666 02667 FDEBUG(("GeoOpt: start/tri cost: %d/%d imp: %d tri/line/point: %d/%d/%d\n", 02668 startCost, (triN * 3), indexMapSize, triN, lineN, pointN)); 02669 02670 inputT = getSystemTime(); 02671 02672 invalidTriCount = 0; 02673 02674 if (!remapIndex && (pN > (triN * 3))) 02675 { 02676 FINFO (( "Force index remap for unusual vertex/tri count: %d/%d\n", 02677 pN, triN )); 02678 indexMapSize = 1; 02679 remapIndex = true; 02680 } 02681 02682 if(remapIndex) 02683 { 02684 graph.reserve(triN * 3, triN, 8); 02685 std::vector < Int32 > indexVec(indexMapSize); 02686 UInt32 triCount = 0; 02687 for(TriangleIterator tI = geoPtr->beginTriangles(); (triCount < triN) && (tI != geoPtr->endTriangles()); 02688 ++tI) 02689 { 02690 Int32 v[3]; 02691 for(Int32 i = 0; i < 3; i++) 02692 { 02693 Int32 index = tI.getIndexIndex(i); 02694 for(Int32 j = 0; j < indexMapSize; j++) 02695 { 02696 indexVec[j] = indexPtr->getValue(index + j); 02697 } 02698 02699 v[i] = indexDic.entry(indexVec); 02700 } 02701 02702 invalidTriCount += graph.addTriangle(v[0], v[1], v[2]) ? 0 : 1; 02703 ++triCount; 02704 } 02705 02706 FDEBUG(("Multi-index dic entry: %d/%d\n", indexDic.entryCount(), 02707 (triN * 3))); 02708 } 02709 else 02710 { 02711 graph.reserve(osgMin(pN, triN * 3), triN, 8); 02712 UInt32 triCount = 0; 02713 for(TriangleIterator tI = geoPtr->beginTriangles(); (triCount < triN) && (tI != geoPtr->endTriangles()); 02714 ++tI) 02715 { 02716 invalidTriCount += graph.addTriangle(tI.getPositionIndex(0), 02717 tI.getPositionIndex(1), 02718 tI.getPositionIndex(2)) ? 0 : 1; 02719 ++triCount; 02720 } 02721 } 02722 02723 if(invalidTriCount) 02724 { 02725 FNOTICE(("%d invalid tri during halfegde construction found\n", 02726 invalidTriCount)); 02727 } 02728 02729 #ifdef OSG_DEBUG 02730 graph.verify(); 02731 #endif 02732 02733 time = getSystemTime(); 02734 inputT = time - inputT; 02735 optimizeT = time; 02736 bestCost = triN * 3 + 1; 02737 worstCost = 0; 02738 cost = graph.calcOptPrim(iteration, createStrips, createFans, minFanEdgeCount); 02739 if(cost) 02740 { 02741 if(cost < bestCost) 02742 bestCost = cost; 02743 02744 if(cost > worstCost) 02745 worstCost = cost; 02746 } 02747 else 02748 { 02749 bestCost = worstCost = 0; 02750 } 02751 02752 // valid result 02753 if(bestCost && (bestCost < startCost)) 02754 { 02755 // check/create the indexPtr/lengthsPtr/geoTypePtr 02756 OSG::beginEditCP(geoPtr, OSG::Geometry::LengthsFieldMask | 02757 OSG::Geometry::TypesFieldMask); 02758 02759 lensPtr = geoPtr->getLengths(); 02760 if(lensPtr == OSG::NullFC) 02761 { 02762 lensPtr = OSG::GeoPLengthsUI32::create(); 02763 geoPtr->setLengths(lensPtr); 02764 } 02765 02766 geoTypePtr = geoPtr->getTypes(); 02767 if(geoTypePtr == OSG::NullFC) 02768 { 02769 geoTypePtr = OSG::GeoPTypesUI8::create(); 02770 geoPtr->setTypes(geoTypePtr); 02771 } 02772 02773 OSG::endEditCP(geoPtr, OSG::Geometry::LengthsFieldMask | 02774 OSG::Geometry::TypesFieldMask); 02775 02776 time = getSystemTime(); 02777 optimizeT = time - optimizeT; 02778 outputT = time; 02779 02780 beginEditCP(lensPtr); 02781 beginEditCP(geoTypePtr); 02782 beginEditCP(indexPtr); 02783 02784 lensPtr->clear(); 02785 geoTypePtr->clear(); 02786 indexPtr->clear(); 02787 02788 FDEBUG(("Start graph.getPrimitive() loop (triN: %d)\n", triN)); 02789 02790 UInt32 numPrimitives = graph.primitiveCount(); 02791 std::vector<std::vector<UInt32> > primIndex(numPrimitives); 02792 02793 const Int32 typeVec[] = { GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN }; 02794 const Int32 typeN = sizeof(typeVec) / sizeof(Int32); 02795 02796 cost = 0; 02797 02798 for(Int32 t = 0; t < typeN; ++t) 02799 { 02800 UInt32 triCount = 0; 02801 02802 bool stitch = false; 02803 UInt32 windingCorrection = 0; 02804 UInt32 lastTriStripIndex = 0; 02805 UInt32 totalTriStripLength = 0; 02806 02807 for(Int32 i = 0; i < Int32(numPrimitives); ++i) 02808 { 02809 graph.getPrimitive(primIndex[i], typeVec[t]); 02810 const Int32 n = primIndex[i].size(); 02811 cost += n; 02812 02813 if(!n) 02814 { 02815 break; 02816 } 02817 02818 if(typeVec[t] == GL_TRIANGLES) 02819 { 02820 triCount += (n / 3); 02821 } 02822 else if (typeVec[t] == GL_TRIANGLE_STRIP) 02823 { 02824 if (stitchStrips) 02825 { 02826 if (stitch) 02827 { 02828 // add the previous index and the first of the 02829 // new one, but make sure winding is still correct. 02830 if (remapIndex) 02831 { 02832 for (int j = 0; j < 1 + windingCorrection; ++j) 02833 { 02834 for (int k = 0; k < indexMapSize; ++k) 02835 { 02836 indexPtr->push_back(indexDic.entry(lastTriStripIndex)[k]); 02837 } 02838 } 02839 for (int k = 0; k < indexMapSize; ++k) 02840 { 02841 indexPtr->push_back(indexDic.entry(primIndex[i][0])[k]); 02842 } 02843 } 02844 else 02845 { 02846 for (int j = 0; j < 1 + windingCorrection; ++j) 02847 { 02848 indexPtr->push_back(lastTriStripIndex); 02849 } 02850 indexPtr->push_back(primIndex[i][0]); 02851 } 02852 totalTriStripLength += 2 + windingCorrection; 02853 } 02854 stitch = true; 02855 windingCorrection = n % 2; 02856 lastTriStripIndex = primIndex[i][n - 1]; 02857 } 02858 else 02859 { 02860 lensPtr->push_back(n); 02861 geoTypePtr->push_back(typeVec[t]); 02862 } 02863 } 02864 else 02865 { 02866 lensPtr->push_back(n); 02867 geoTypePtr->push_back(typeVec[t]); 02868 } 02869 02870 if(remapIndex) 02871 { 02872 for(Int32 j = 0; j < n; ++j) 02873 { 02874 for(Int32 k = 0; k < indexMapSize; ++k) 02875 { 02876 Int32 index = indexDic.entry(primIndex[i][j])[k]; 02877 indexPtr->push_back(index); 02878 } 02879 } 02880 } 02881 else 02882 { 02883 for(Int32 j = 0; j < n; ++j) 02884 { 02885 indexPtr->push_back(primIndex[i][j]); 02886 } 02887 } 02888 totalTriStripLength += n; 02889 } 02890 02891 if(triCount && typeVec[t] == GL_TRIANGLES) 02892 { 02893 lensPtr->push_back(triCount * 3); 02894 geoTypePtr->push_back(GL_TRIANGLES); 02895 } 02896 02897 if(stitchStrips && totalTriStripLength && 02898 typeVec[t] == GL_TRIANGLE_STRIP) 02899 { 02900 lensPtr->push_back(totalTriStripLength); 02901 geoTypePtr->push_back(GL_TRIANGLE_STRIP); 02902 } 02903 } 02904 02905 endEditCP(lensPtr); 02906 endEditCP(geoTypePtr); 02907 endEditCP(indexPtr); 02908 02909 time = getSystemTime(); 02910 outputT = time - outputT; 02911 02912 FNOTICE(("Graph in/opt/out timing: %g/%g/%g \n", inputT, optimizeT, 02913 outputT)); 02914 02915 if(cost != bestCost) 02916 { 02917 FWARNING(("cost != bestCost: %d/%d; we lost some nodes !\n", 02918 cost, bestCost)); 02919 } 02920 else 02921 { 02922 FINFO(("OptResult: %2g%%, Sampling (%di): cost %d/%d \n", 02923 double(double(bestCost) / double( 02924 startCost) * 100.0 02925 ), iteration, bestCost, worstCost)); 02926 } 02927 } 02928 else 02929 { 02930 FINFO(("startCost (%d) <= bestCost (%d), triCost(%d); keep geo data\n", 02931 startCost, bestCost, (triN * 3))); 02932 } 02933 02934 return bestCost; 02935 }
| void osg::createConvexPrimitives | ( | GeometryPtr | geoPtr | ) |
createConvexPrimitives iterates over all primitives of the passed geometry tesselating them with the aid of the GLU tesselator. As a result every planar polygon is tesselated into a sequence of triangles covering it.
In case of nonplanar Polygons the results are not guaranteed to be correct.
Simple, i.e non-indexed geometries are not supported.
Definition at line 3005 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::FCPtr< BasePtrTypeT, FieldContainerTypeT >::dcast(), osg::endEditCP(), FDEBUG, FFATAL, FINFO, FWARNING, osg::PrimitiveIterator::getIndex(), osg::PrimitiveIterator::getIndexIndex(), osg::PrimitiveIterator::getLength(), osg::PrimitiveIterator::getType(), GLenum, osg::gluTessBeginDataCB(), gluTessEdgeFlagCB(), gluTessEndCB(), gluTessErrorCB(), osg::gluTessVertexDataCB(), and osg::NullFC.
Referenced by osg::VRMLGeometryDesc::endNode().
03006 { 03007 FINFO(("Entering createConvexPrimitives()\n")); 03008 03009 GLenum windingRule = GLU_TESS_WINDING_ODD; 03010 03011 OSG::GeoIndicesUI32Ptr indexPtr; 03012 OSG::GeoIndicesUI32Ptr newIndexPtr = GeoIndicesUI32::create(); 03013 OSG::GeoPTypesPtr newTypesPtr = GeoPTypesUI8::create(); 03014 OSG::GeoPLengthsPtr newLengthsPtr = GeoPLengthsUI32::create(); 03015 03016 bool indexed = true; 03017 03018 std::vector< UInt32 > inIndexV; 03019 std::vector< UInt32 > outIndexV; 03020 std::vector< GLdouble > positionV; 03021 03022 inIndexV.reserve(4096); 03023 outIndexV.reserve(4096); 03024 positionV.reserve(4096); 03025 03026 if(geoPtr == NullFC) 03027 { 03028 FINFO(("Invalid geoPtr in createConvexPrimitives()\n")); 03029 return; 03030 } 03031 03032 //scan the geometry for GL_POLYGONs 03033 bool containsPolygon = false; 03034 PrimitiveIterator primI = geoPtr->beginPrimitives(); 03035 for(;primI != geoPtr->endPrimitives(); ++primI) 03036 { 03037 if(primI.getType() == GL_POLYGON) 03038 { 03039 containsPolygon = true; 03040 break; 03041 } 03042 } 03043 03044 // skip geometry if it doesn't contain a GL_POLYGON 03045 if(!containsPolygon) 03046 { 03047 FINFO(("Geometry with no GL_POLYGONs in createConvexPrimitives:\n")); 03048 FINFO(("Nothing to do for createConvexPrimitives: Returning\n")); 03049 return; 03050 } 03051 03052 // determine whether the geometry is indexed 03053 indexPtr = GeoIndicesUI32Ptr::dcast(geoPtr->getIndices()); 03054 indexed = (indexPtr == NullFC) ? false : true; 03055 FDEBUG(("Indexed: %d\n",indexed)); 03056 03057 // skip geometry if it is empty or not indexed 03058 if(!indexed) 03059 { 03060 FINFO(("Skipping nonindexed geometry in createConvexPrimitives()\n")); 03061 return; 03062 } 03063 else 03064 { 03065 if(geoPtr->getIndices()->size() == 0) 03066 { 03067 FINFO(("Skipping empty geometry in createConvexPrimitives()\n")); 03068 return; 03069 } 03070 } 03071 03072 // convert function pointers to the type expected by the GLU Tesselator 03073 OSGGLUfuncptr gluTessBeginDataCBPtr = 03074 reinterpret_cast<OSGGLUfuncptr>(gluTessBeginDataCB); 03075 03076 OSGGLUfuncptr gluTessEdgeFlagCBPtr = 03077 reinterpret_cast<OSGGLUfuncptr>(gluTessEdgeFlagCB); 03078 03079 OSGGLUfuncptr gluTessVertexDataCBPtr = 03080 reinterpret_cast<OSGGLUfuncptr>(gluTessVertexDataCB); 03081 03082 OSGGLUfuncptr gluTessEndCBPtr = 03083 reinterpret_cast<OSGGLUfuncptr>(gluTessEndCB); 03084 03085 OSGGLUfuncptr gluTessErrorCBPtr = 03086 reinterpret_cast<OSGGLUfuncptr>(gluTessErrorCB); 03087 03088 // create and setup a new GLU Tesselator 03089 FDEBUG(("gluNewTess()\n")); 03090 GLUtesselator* tess = gluNewTess(); 03091 03092 if(tess == NULL) 03093 { 03094 FFATAL(("Creation of GLUtesselator failed\n")); 03095 return; 03096 } 03097 else 03098 FINFO(("Created GLU Tesselator (%p)\n", tess)); 03099 03100 // set the specified winding rule 03101 FDEBUG(("gluTessProperty(%p, GLU_TESS_WINDING_RULE, %d)\n", 03102 tess, windingRule)); 03103 gluTessProperty(tess, GLU_TESS_WINDING_RULE, windingRule); 03104 03105 // register self defined GLU Tesselator callback methods 03106 FDEBUG(("gluTessCallback(%p, GLU_TESS_ERROR, %p)\n", 03107 tess, gluTessErrorCBPtr)); 03108 gluTessCallback(tess, GLU_TESS_ERROR, gluTessErrorCBPtr); 03109 03110 FDEBUG(("gluTessCallback(%p, GLU_TESS_BEGIN_DATA, %p)\n", 03111 tess, gluTessBeginDataCBPtr)); 03112 gluTessCallback(tess, GLU_TESS_BEGIN_DATA, gluTessBeginDataCBPtr); 03113 03114 FDEBUG(("gluTessCallback(%p, GLU_TESS_EDGE_FLAG, %p)\n", 03115 tess, gluTessEdgeFlagCBPtr)); 03116 gluTessCallback(tess, GLU_TESS_EDGE_FLAG, gluTessEdgeFlagCBPtr); 03117 03118 FDEBUG(("gluTessCallback(%p, GLU_TESS_VERTEX_DATA, %p)\n", 03119 tess, gluTessVertexDataCBPtr)); 03120 gluTessCallback(tess, GLU_TESS_VERTEX_DATA, gluTessVertexDataCBPtr); 03121 03122 FDEBUG(("gluTessCallback(%p, GLU_TESS_END, %p)\n", 03123 tess, gluTessEndCBPtr)); 03124 gluTessCallback(tess, GLU_TESS_END, gluTessEndCBPtr); 03125 03126 beginEditCP(newTypesPtr); 03127 beginEditCP(newIndexPtr); 03128 beginEditCP(newLengthsPtr); 03129 03130 primI = geoPtr->beginPrimitives(); 03131 for(;primI != geoPtr->endPrimitives(); ++primI) 03132 { 03133 FDEBUG(("Primitive index: %d\n", primI.getIndex())); 03134 03135 // if the primitive is not of type GL_POLYGON just copy its contents 03136 if(primI.getType() != GL_POLYGON) 03137 { 03138 FDEBUG(("Not a GL_POLYGON. Copying properties\n")); 03139 if(!indexed) 03140 { 03141 FWARNING(("createConvexPrimitives(): Nonindexed geometries are not implemented!\n")); 03142 } 03143 else 03144 { 03145 newTypesPtr->push_back(primI.getType()); 03146 03147 // maybe we should use memcpy here instead of explicitly copying 03148 // each multiindex 03149 for(UInt32 i = 0; i < primI.getLength(); i++) 03150 { 03151 Int32 curIndex = primI.getIndexIndex(i); 03152 for(UInt32 j = 0; j < geoPtr->getIndexMapping().size(); j++) 03153 { 03154 UInt32 val = indexPtr->getValue(curIndex + j); 03155 newIndexPtr->push_back(val); 03156 } 03157 } 03158 newLengthsPtr->push_back(primI.getLength()); 03159 } 03160 } 03161 // Process GL_POLYGONs i.e. tesselate them 03162 else 03163 { 03164 FDEBUG(("Tesselating GL_POLYGON (PrimitiveIndex: %d, Vertices %d)\n", 03165 primI.getIndex(), primI.getLength())); 03166 03167 inIndexV.clear(); 03168 outIndexV.clear(); 03169 positionV.clear(); 03170 03171 for(UInt32 i = 0; i < primI.getLength(); i++) 03172 { 03173 // Convert the vertices to double precision 03174 // (the tesselator expects them that way) 03175 positionV.push_back(static_cast< GLdouble >(primI. 03176 getPosition(i)[0])); 03177 positionV.push_back(static_cast< GLdouble >(primI. 03178 getPosition(i)[1])); 03179 positionV.push_back(static_cast< GLdouble >(primI. 03180 getPosition(i)[2])); 03181 03182 // Store the start index of the current multi index 03183 // to pass it as "meta data" to the tesselator later on 03184 UInt32 curIndex = indexed ? primI.getIndexIndex(i) : i; 03185 inIndexV.push_back(curIndex); 03186 } 03187 03188 #ifdef OSG_DEBUG 03189 03190 for(UInt32 i = 0; i < primI.getLength(); i++) 03191 { 03192 03193 int index = inIndexV.at(i); 03194 double x = positionV.at(3*i); 03195 double y = positionV.at(3*i + 1); 03196 double z = positionV.at(3*i + 2); 03197 03198 FDEBUG(("Position index: %i Position: (%f,%f,%f)\n", 03199 index, x, y, z)); 03200 } 03201 #endif 03202 03203 // cast the address of the std::vector which stores the 03204 // tesselator output to a GLvoid * 03205 GLvoid* outIndexPtr = reinterpret_cast< GLvoid* >(&outIndexV); 03206 03207 FDEBUG(("gluTessBeginPolygon(%p, %p)\n", tess, outIndexPtr)); 03208 gluTessBeginPolygon(tess, outIndexPtr); 03209 03210 FDEBUG(("gluTessBeginContour(%p)\n", tess)); 03211 gluTessBeginContour(tess); 03212 03213 03214 for(UInt32 i = 0; i < primI.getLength(); i++) 03215 { 03216 GLvoid* curIndexPtr = reinterpret_cast< GLvoid* >(&inIndexV[i]); 03217 FDEBUG(("gluTessVertex(%p, %p, %p)\n", 03218 tess, &positionV[i * 3], curIndexPtr)); 03219 03220 // feed the prepared position data and the according beginning 03221 // of its multiindex in the index property to the tesselator 03222 gluTessVertex(tess, &positionV[i * 3], curIndexPtr); 03223 } 03224 03225 FDEBUG(("gluTessEndContour(%p)\n", tess)); 03226 gluTessEndContour(tess); 03227 03228 FDEBUG(("gluTessEndPolygon(%p)\n", tess)); 03229 // trigger the tesselator action 03230 gluTessEndPolygon(tess); 03231 03232 newTypesPtr->push_back(GL_TRIANGLES); 03233 03234 if(!indexed) 03235 { 03236 FWARNING(("createConvexPrimitives(): Nonindexed geometries are not implemented!\n")); 03237 } 03238 else 03239 { 03240 FDEBUG(("Rebuilding multi indices ...\n")); 03241 // copy the indices gathered during the tesselator run 03242 // into a new index container 03243 for(UInt32 i = 0; i < outIndexV.size(); i++) 03244 { 03245 UInt32 vII = outIndexV[i]; 03246 for(UInt32 j = 0; j < geoPtr->getIndexMapping().size(); j++) 03247 { 03248 FDEBUG(("Index in tesselated data %d\n",vII + j)); 03249 Int32 curIndex = indexPtr->getValue(vII + j); 03250 03251 FDEBUG(("newIndexPtr->push_back(%d)\n", curIndex)); 03252 newIndexPtr->push_back(curIndex); 03253 } 03254 } 03255 } 03256 FINFO(("Vertex count: %d/%d (before/after tesselation)\n", 03257 primI.getLength(), outIndexV.size())); 03258 newLengthsPtr->push_back(outIndexV.size()); 03259 } 03260 } 03261 03262 endEditCP(newTypesPtr); 03263 endEditCP(newIndexPtr); 03264 endEditCP(newLengthsPtr); 03265 03266 beginEditCP(geoPtr); 03267 03268 // update the geometry properties 03269 geoPtr->setTypes(newTypesPtr); 03270 geoPtr->setIndices(newIndexPtr); 03271 geoPtr->setLengths(newLengthsPtr); 03272 03273 endEditCP(geoPtr); 03274 03275 FDEBUG(("gluDeleteTess(%p)\n", tess)); 03276 gluDeleteTess(tess); 03277 03278 FDEBUG(("Exiting from createConvexPrimitives()\n")); 03279 }
| Int32 osg::createSharedIndex | ( | GeometryPtr | geoPtr | ) |
createSharedIndex tries to merge identical elements in the Geometry's Properties, see Geometry Optimization for a description.
Definition at line 3288 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::endEditCP(), FFATAL, FINFO, FNOTICE, FWARNING, osg::GeoPropertyArrayInterface::getData(), osg::GeoPropertyArrayInterface::getDimension(), osg::GeoPropertyArrayInterface::getFormatSize(), osg::GeoPropertyArrayInterface::getStride(), iN, osg::Geometry::MapEmpty, osg::NullFC, and osg::GeoPropertyArrayInterface::size().
Referenced by osg::VRMLGeometryDesc::endNode(), osg::MergeGraphOp::processGeometries(), osg::OFFSceneFileType::read(), osg::OBJSceneFileType::read(), and osg::StripeGraphOp::travNodeEnter().
03289 { 03290 #ifndef OSG_SUPPORT_NO_GEO_INTERFACE 03291 UInt32 indexSharedCount = 0, dataRemapCount = 0, indexRemapCount = 0; 03292 UInt32 i, iN, index, si, sN; 03293 UInt32 indexMapSize, indexBlock = 0, masterDSize; 03294 GeoPropertyArrayInterface *masterProp = 0, *slaveProp = 0; 03295 UInt8 *masterData; 03296 std::vector < UInt32 > slaveDSizeVec; 03297 std::vector < UInt8 * > slaveDataVec; 03298 03299 UInt16 mapMask, propMask, masterPropMask; 03300 typedef std::pair<UInt8 *, UInt32> Mem; 03301 Mem mem; 03302 std::map<Mem, UInt32, memless<Mem> > memMap; 03303 std::map<Mem, UInt32, memless<Mem> >::iterator mmI; 03304 03305 GeoIndicesPtr indexPtr; 03306 UChar8 *dataElem; 03307 std::vector < Int32 > indexRemap; 03308 03309 if(geoPtr != NullFC) 03310 { 03311 if(geoPtr->getPositions() != NullFC) 03312 { 03313 // check/create indexPtr 03314 iN = geoPtr->getPositions()->size(); 03315 indexPtr = geoPtr->getIndices(); 03316 if(indexPtr == NullFC) 03317 { 03318 indexPtr = GeoIndicesUI32::create(); 03319 indexPtr->resize(iN); 03320 for(i = 0; i < iN; i++) 03321 indexPtr->setValue(i, i); 03322 beginEditCP(geoPtr); 03323 { 03324 geoPtr->setIndices(indexPtr); 03325 } 03326 03327 endEditCP(geoPtr); 03328 } 03329 } 03330 else 03331 { 03332 FNOTICE(("Invalid geoPtr->getPositions() in createSharedIndex()\n")); 03333 } 03334 } 03335 else 03336 { 03337 FNOTICE(("Invalid geoPtr in createSharedIndex()\n")); 03338 } 03339 03340 if(indexPtr != NullFC) 03341 { 03342 // get the index count 03343 indexMapSize = geoPtr->getIndexMapping().size(); 03344 03345 // find first propMask; 03346 if(indexMapSize) 03347 { 03348 propMask = geoPtr->getIndexMapping()[0]; 03349 } 03350 else 03351 { 03352 // no index geo; find valid property 03353 for(mapMask = 1, propMask = 0; mapMask && mapMask != Geometry::MapEmpty; 03354 mapMask <<= 1) 03355 { 03356 if(geoPtr->getProperty(mapMask)) 03357 propMask |= mapMask; 03358 } 03359 03360 indexMapSize = 1; 03361 } 03362 03363 // remap the index for a single index block 03364 for(indexBlock = 0; propMask;) 03365 { 03366 // reset stat counter 03367 indexSharedCount = 0; 03368 dataRemapCount = 0; 03369 indexRemapCount = 0; 03370 03371 // find master property 03372 for(masterPropMask = 1; (propMask & masterPropMask) == 0;) 03373 masterPropMask <<= 1; 03374 03375 if((masterProp = geoPtr->getProperty(masterPropMask)) && 03376 (masterData = masterProp->getData())) 03377 { 03378 // calc master data element size 03379 masterDSize = masterProp->getFormatSize() * 03380 masterProp->getDimension() + 03381 masterProp->getStride(); 03382 03383 // find and store slave property data and size 03384 slaveDataVec.clear(); 03385 slaveDSizeVec.clear(); 03386 for(mapMask = 1; mapMask && mapMask != Geometry::MapEmpty; 03387 mapMask <<= 1) 03388 { 03389 if((mapMask != masterPropMask) && (mapMask & propMask)) 03390 { 03391 if((slaveProp = geoPtr->getProperty(mapMask & propMask))) 03392 { 03393 slaveDataVec.push_back(slaveProp->getData()); 03394 slaveDSizeVec.push_back(slaveProp->getFormatSize() * 03395 slaveProp->getDimension()); 03396 } 03397 else 03398 { 03399 FWARNING(("Invalid slaveProp %d\n", (mapMask & propMask) 03400 )); 03401 } 03402 } 03403 } 03404 03405 sN = slaveDataVec.size(); 03406 iN = indexPtr->size() / indexMapSize; 03407 memMap.clear(); 03408 indexRemap.clear(); 03409 indexRemap.resize(masterProp->size(), -1); 03410 mem.second = masterProp->getFormatSize() * masterProp->getDimension(); 03411 03412 for(i = 0; i < iN; i++) 03413 { 03414 index = indexPtr->getValue(i * indexMapSize + indexBlock); 03415 if(indexRemap[index] >= 0) 03416 { 03417 if(indexRemap[index] == index) 03418 { 03419 indexSharedCount++; 03420 } 03421 else 03422 { 03423 indexPtr->setValue(indexRemap[index], 03424 i * indexMapSize + indexBlock); 03425 indexRemapCount++; 03426 } 03427 } 03428 else 03429 { 03430 // find/include the data block 03431 dataElem = masterData + (index * masterDSize); 03432 mem.first = dataElem; 03433 mmI = memMap.find(mem); 03434 if(mmI == memMap.end()) 03435 { 03436 // index not found; store new data/index 03437 memMap[mem] = index; 03438 indexRemap[index] = index; 03439 } 03440 else 03441 { 03442 // data found; check slave property 03443 for(si = 0; si < sN; si++) 03444 { 03445 if(memcmp(slaveDataVec[si] + 03446 (index * slaveDSizeVec[si]), 03447 slaveDataVec[si] + 03448 (mmI->second * slaveDSizeVec[si]), 03449 slaveDSizeVec[si])) 03450 break; 03451 } 03452 03453 if(si == sN) 03454 { 03455 // no or valid slave data; remap the index 03456 indexPtr->setValue(mmI->second, 03457 i * indexMapSize + indexBlock); 03458 indexRemap[index] = mmI->second; 03459 dataRemapCount++; 03460 } 03461 else 03462 { 03463 // invalid slave data; cannot remap index 03464 indexRemap[index] = index; 03465 } 03466 } 03467 } 03468 } 03469 } 03470 else 03471 { 03472 FWARNING(("Invalid masterProp %p, mask: %d, block: %d\n", 03473 masterProp, propMask, indexBlock)); 03474 } 03475 03476 FINFO(("Create sharedIndex: %d/%d pass; " 03477 "data/index remap: %d/%d \n", 03478 indexBlock, int(propMask), dataRemapCount, 03479 indexRemapCount)); 03480 03481 // get next propery Mask 03482 if(++indexBlock < indexMapSize) 03483 { 03484 propMask = geoPtr->getIndexMapping()[indexBlock]; 03485 } 03486 else 03487 propMask = 0; 03488 } 03489 } 03490 03491 return indexRemapCount + dataRemapCount; 03492 03493 #else 03494 FFATAL(("Cannot run createSharedIndex: NO_GEO_INFACE\n")); 03495 return -1; 03496 #endif 03497 }
| Int32 osg::createSingleIndex | ( | GeometryPtr | geoPtr | ) |
createSingleIndex manipulates the Geometry's Properties to only use a single index, see Geometry Optimization for a description.
It returns the number of property values kept.
Definition at line 3508 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::endEditCP(), IndexDic::entry(), IndexDic::entryCount(), FFATAL, FWARNING, osg::GeoPropertyArrayInterface::getData(), osg::GeoPropertyArrayInterface::getDimension(), osg::GeoPropertyArrayInterface::getFormatSize(), osg::GeoPropertyArrayInterface::getStride(), osg::GeometryBase::IndexMappingFieldMask, osg::GeometryBase::IndicesFieldMask, osg::NullFC, osg::GeoPropertyArrayInterface::resize(), and osg::GeoPropertyArrayInterface::size().
03509 { 03510 #ifndef OSG_SUPPORT_NO_GEO_INTERFACE 03511 Int16 mask, maskID, finalMask = 0; 03512 Int32 indexMapSize, indexCount, i, j, vCount = 0; 03513 Int32 index; 03514 Int32 memSize, valueSize; 03515 UInt8 *pData, *data; 03516 GeoIndicesPtr indexPtr; 03517 IndexDic indexDic; 03518 std::vector < Int32 > 03519 03520 indexVec, sIndex; 03521 GeoPropertyArrayInterface *pP = 0; 03522 03523 if((geoPtr != NullFC) && 03524 (indexMapSize = (geoPtr->getIndexMapping().size()))) 03525 { 03526 beginEditCP(geoPtr, Geometry::IndexMappingFieldMask | 03527 Geometry::IndicesFieldMask); 03528 03529 indexPtr = geoPtr->getIndices(); 03530 indexVec.resize(indexMapSize); 03531 03532 // fill the indexDic 03533 if(indexPtr != NullFC) 03534 { 03535 indexCount = indexPtr->size() / indexMapSize; 03536 sIndex.resize(indexCount); 03537 for(i = 0; i < indexCount; i++) 03538 { 03539 for(j = 0; j < indexMapSize; j++) 03540 { 03541 indexVec[j] = indexPtr->getValue(i * indexMapSize + j); 03542 } 03543 03544 sIndex[i] = indexDic.entry(indexVec); 03545 } 03546 03547 vCount = indexDic.entryCount(); 03548 } 03549 else 03550 vCount = 0; 03551 03552 // sort/copy property values 03553 finalMask = 0; 03554 if(vCount) 03555 { 03556 for(i = 0; i < indexMapSize; i++) 03557 { 03558 mask = geoPtr->getIndexMapping()[i]; 03559 for(maskID = 1; maskID; maskID <<= 1) 03560 { 03561 if((mask & maskID) && (pP = geoPtr->getProperty(maskID))) 03562 { 03563 valueSize = pP->getFormatSize() * 03564 pP->getDimension() + 03565 pP->getStride(); 03566 finalMask |= maskID; 03567 memSize = pP->size() * valueSize; 03568 data = new UInt8[memSize]; 03569 pData = pP->getData(); 03570 memcpy(data, pData, memSize); 03571 pP->resize(vCount); 03572 pData = pP->getData(); 03573 for(j = 0; j < vCount; j++) 03574 { 03575 index = indexDic.entry(j)[i]; 03576 memcpy(pData + (valueSize * j), 03577 data + (valueSize * index), 03578 valueSize); 03579 } 03580 03581 delete[] data; 03582 } 03583 } 03584 } 03585 } 03586 03587 // copy single index and set the single mask 03588 if(finalMask) 03589 { 03590 indexPtr->clear(); 03591 for(i = 0; i < indexCount; i++) 03592 { 03593 indexPtr->push_back(sIndex[i]); 03594 } 03595 03596 geoPtr->getIndexMapping().clear(); 03597 geoPtr->getIndexMapping().push_back(finalMask); 03598 } 03599 else 03600 { 03601 FWARNING(("No valid finalMask in createSingleIndex()\n")); 03602 } 03603 03604 endEditCP(geoPtr, Geometry::IndexMappingFieldMask | 03605 Geometry::IndicesFieldMask); 03606 } 03607 03608 return vCount; 03609 03610 #else 03611 FFATAL(("Cannot run createSingleIndex: NO_GEO_INFACE\n")); 03612 return -1; 03613 #endif 03614 }
| UInt32 osg::calcPrimitiveCount | ( | GeometryPtr | geoPtr, | |
| UInt32 & | triangle, | |||
| UInt32 & | line, | |||
| UInt32 & | point | |||
| ) |
calcPrimitiveCount calculates some statistical information about the Geometry, see Geometry Optimization for a description.
It returns the sum of the primitives found, and the separate counts in teh passed-in references.
Definition at line 3626 of file OSGGeoFunctions.cpp.
References osg::FCPtr< BasePtrTypeT, FieldContainerTypeT >::dcast(), FINFO, FWARNING, and osg::NullFC.
Referenced by osg::createOptimizedPrimitives(), and osg::Geometry::drawPrimitives().
03630 { 03631 GeoPTypesUI8Ptr geoTypePtr; 03632 GeoPLengthsUI32Ptr lens32Ptr; 03633 GeoPLengthsUI16Ptr lens16Ptr; 03634 GeoPTypesUI8Ptr::StoredObjectType::StoredFieldType::iterator typeI, endTypeI; 03635 GeoPLengthsUI32Ptr::StoredObjectType::StoredFieldType::iterator len32I; 03636 GeoPLengthsUI16Ptr::StoredObjectType::StoredFieldType::iterator len16I; 03637 03638 UInt32 lN, tN, len, type; 03639 03640 // TODO; should we really reset the values ? 03641 triangle = line = point = 0; 03642 03643 if(geoPtr == OSG::NullFC) 03644 { 03645 FINFO(("No geo in calcPrimitiveCount\n")); 03646 } 03647 else 03648 { 03649 lens32Ptr = GeoPLengthsUI32Ptr::dcast(geoPtr->getLengths()); 03650 03651 if(lens32Ptr == NullFC) 03652 { 03653 lens16Ptr = GeoPLengthsUI16Ptr::dcast(geoPtr->getLengths()); 03654 lN = (lens16Ptr == OSG::NullFC) ? 0 : lens16Ptr->getSize(); 03655 } 03656 else 03657 { 03658 lN = (lens32Ptr == OSG::NullFC) ? 0 : lens32Ptr->getSize(); 03659 } 03660 03661 geoTypePtr = GeoPTypesUI8Ptr::dcast(geoPtr->getTypes()); 03662 tN = (geoTypePtr == OSG::NullFC) ? 0 : geoTypePtr->getSize(); 03663 03664 if((tN == 0) || (lN != 0 && tN != lN) || (lN == 0 && tN != 1)) 03665 { 03666 return 0; 03667 } 03668 03669 typeI = geoTypePtr->getField().begin(); 03670 if(lN != 0) 03671 { 03672 if(lens32Ptr != NullFC) 03673 len32I = lens32Ptr->getField().begin(); 03674 else 03675 len16I = lens16Ptr->getField().begin(); 03676 } 03677 03678 endTypeI = geoTypePtr->getField().end(); 03679 while(typeI != endTypeI) 03680 { 03681 type = *typeI; 03682 if(lN != 0) 03683 { 03684 if(lens32Ptr != NullFC) 03685 len = *len32I; 03686 else 03687 len = *len16I; 03688 } 03689 else 03690 { 03691 GeoPositionsPtr pos = geoPtr->getPositions(); 03692 03693 if(pos == OSG::NullFC) 03694 { 03695 FINFO(("calcPrimitiveCount: no Points!\n")); 03696 return 0; 03697 } 03698 03699 len = pos->size(); 03700 } 03701 03702 switch(type) 03703 { 03704 case GL_POINTS: 03705 point += len; 03706 break; 03707 case GL_LINES: 03708 line += len / 2; 03709 break; 03710 case GL_LINE_LOOP: 03711 line += len; 03712 break; 03713 case GL_LINE_STRIP: 03714 line += len - 1; 03715 break; 03716 case GL_TRIANGLES: 03717 triangle += len / 3; 03718 break; 03719 case GL_TRIANGLE_STRIP: 03720 triangle += len - 2; 03721 break; 03722 case GL_TRIANGLE_FAN: 03723 triangle += len - 2; 03724 break; 03725 case GL_QUADS: 03726 triangle += len / 2; 03727 break; 03728 case GL_QUAD_STRIP: 03729 triangle += len - 2; 03730 break; 03731 case GL_POLYGON: 03732 triangle += len - 2; 03733 break; 03734 default: 03735 FWARNING(("calcPrimitiveCount(): Invalid geoType: %d\n", type)); 03736 break; 03737 } 03738 03739 ++typeI; 03740 if (lN > 0) 03741 { 03742 if(lens32Ptr != NullFC) 03743 ++len32I; 03744 else if(lens16Ptr != NullFC) 03745 ++len16I; 03746 } 03747 } 03748 } 03749 03750 return triangle + line + point; 03751 }
| NodePtr osg::calcVertexNormalsGeo | ( | GeometryPtr | geo, | |
| Real32 | length | |||
| ) |
calcVertexNormalsGeo creates a geometry object that shows the geo's normals, see Normal Visualisation for a description.
geo is the geometry whose normals should be displayed, length is the length of the normals. The new geometry is created in the local coordinate system of geo.
Definition at line 3766 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::GeometryBase::create(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::endEditCP(), osg::PrimitiveIterator::getLength(), osg::PrimitiveIterator::getNormal(), osg::PrimitiveIterator::getPosition(), and osg::makeNodeFor().
03767 { 03768 GeoPositions3f::PtrType pnts = GeoPositions3f::create(); 03769 // calculate 03770 beginEditCP(pnts); 03771 03772 PrimitiveIterator pi(geo); 03773 03774 if(1 /* no easy way to check right now */ ) 03775 { 03776 for(pi = geo->beginPrimitives(); pi != geo->endPrimitives(); ++pi) 03777 { 03778 for(UInt32 k = 0; k < pi.getLength(); k++) 03779 { 03780 pnts->push_back(pi.getPosition(k)); 03781 pnts->push_back(pi.getPosition(k) + length * pi.getNormal(k)); 03782 } 03783 } 03784 } 03785 else 03786 { 03787 Pnt3f center(0, 0, 0); 03788 03789 for(pi = geo->beginPrimitives(); pi != geo->endPrimitives(); ++pi) 03790 { 03791 for(UInt32 k = 0; k < pi.getLength(); k++) 03792 { 03793 center[0] += pi.getPosition(k)[0]; 03794 center[1] += pi.getPosition(k)[1]; 03795 center[2] += pi.getPosition(k)[2]; 03796 } 03797 03798 pnts->push_back(center); 03799 pnts->push_back(center + length * pi.getNormal(0)); 03800 } 03801 } 03802 03803 endEditCP(pnts); 03804 03805 GeoPTypesPtr type = GeoPTypesUI8::create(); 03806 beginEditCP(type); 03807 type->push_back(GL_LINES); 03808 endEditCP(type); 03809 03810 GeoPLengthsPtr lens = GeoPLengthsUI32::create(); 03811 beginEditCP(lens); 03812 lens->push_back(pnts->getSize()); 03813 endEditCP(lens); 03814 03815 GeometryPtr g = Geometry::create(); 03816 beginEditCP(g); 03817 g->setTypes(type); 03818 g->setLengths(lens); 03819 g->setPositions(pnts); 03820 endEditCP(g); 03821 03822 return makeNodeFor(g); 03823 }
| NodePtr osg::calcFaceNormalsGeo | ( | GeometryPtr | geo, | |
| Real32 | length | |||
| ) |
calcFaceNormalsGeo creates a geometry object that shows the geo's normals, see Normal Visualisation for a description.
geo is the geometry whose normals should be displayed, length is the length of the normals. The new geometry is created in the local coordinate system of geo.
Definition at line 3840 of file OSGGeoFunctions.cpp.
References osg::beginEditCP(), osg::GeoProperty< GeoPropertyDesc >::create(), osg::GeometryBase::create(), osg::Node::create(), osg::endEditCP(), osg::FaceIterator::getLength(), osg::FaceIterator::getNormal(), osg::FaceIterator::getPosition(), osg::PrimitiveIterator::getType(), and p.
03841 { 03842 NodePtr p = Node::create(); 03843 GeometryPtr g = Geometry::create(); 03844 GeoPositions3f::PtrType pnts = GeoPositions3f::create(); 03845 GeoIndicesUI32Ptr index = GeoIndicesUI32::create(); 03846 GeoPTypesPtr type = GeoPTypesUI8::create(); 03847 GeoPLengthsPtr lens = GeoPLengthsUI32::create(); 03848 03849 // calculate 03850 FaceIterator faceIter = geo->beginFaces(); 03851 Pnt3f center; 03852 03853 beginEditCP(pnts); 03854 for(; faceIter != geo->endFaces(); ++faceIter) 03855 { 03856 center[0] = 0; 03857 center[1] = 0; 03858 center[2] = 0; 03859 for(UInt16 i = 0; i < faceIter.getLength(); ++i) 03860 { 03861 center[0] += faceIter.getPosition(i)[0] / faceIter.getLength(); 03862 center[1] += faceIter.getPosition(i)[1] / faceIter.getLength(); 03863 center[2] += faceIter.getPosition(i)[2] / faceIter.getLength(); 03864 } 03865 03866 pnts->push_back(center); 03867 switch(faceIter.getType()) 03868 { 03869 case GL_TRIANGLE_STRIP: 03870 pnts->push_back(center + length * faceIter.getNormal(2)); 03871 break; 03872 case GL_TRIANGLE_FAN: 03873 pnts->push_back(center + length * faceIter.getNormal(2)); 03874 break; 03875 case GL_QUAD_STRIP: 03876 pnts->push_back(center + length * faceIter.getNormal(3)); 03877 break; 03878 default: 03879 //does not matter which point's normal 03880 pnts->push_back(center + length * faceIter.getNormal(0)); 03881 break; 03882 } 03883 } 03884 03885 endEditCP(pnts); 03886 03887 beginEditCP(index); 03888 for(UInt32 i = 0; i < pnts->getSize(); i++) 03889 index->push_back(i); 03890 endEditCP(index); 03891 03892 beginEditCP(type); 03893 type->push_back(GL_LINES); 03894 endEditCP(type); 03895 03896 beginEditCP(lens); 03897 lens->push_back(index->getSize()); 03898 endEditCP(lens); 03899 03900 beginEditCP(g); 03901 g->setTypes(type); 03902 g->setLengths(lens); 03903 g->setIndices(index); 03904 g->setPositions(pnts); 03905 endEditCP(g); 03906 03907 beginEditCP(p); 03908 p->setCore(g); 03909 endEditCP(p); 03910 03911 return p; 03912 }
| void osg::separateProperties | ( | GeometryPtr | geo | ) |
Separates shared geometry properties.
Definition at line 3975 of file OSGGeoFunctions.cpp.
References separateProperty.
03976 { 03977 separateProperty(PTypes, Types) 03978 separateProperty(PLengths, Lengths) 03979 separateProperty(Positions, Positions) 03980 separateProperty(Normals, Normals) 03981 separateProperty(Colors, Colors) 03982 separateProperty(Colors, SecondaryColors) 03983 separateProperty(TexCoords, TexCoords) 03984 separateProperty(TexCoords, TexCoords1) 03985 separateProperty(TexCoords, TexCoords2) 03986 separateProperty(TexCoords, TexCoords3) 03987 separateProperty(TexCoords, TexCoords4) 03988 separateProperty(TexCoords, TexCoords5) 03989 separateProperty(TexCoords, TexCoords6) 03990 separateProperty(TexCoords, TexCoords7) 03991 separateProperty(Indices, Indices) 03992 }
| void osg::drawVolume | ( | const DynamicVolume & | volume | ) |
Draw the given DynamicVolume using direct OpenGL calls.
Definition at line 65 of file OSGVolumeDraw.cpp.
References osg::DynamicVolume::getInstance().
Referenced by VolumeDrawWrapper::draw(), and osg::DrawActionBase::stop().
00066 { 00067 const Volume *v = &volume.getInstance(); 00068 const BoxVolume *bv; 00069 const SphereVolume *sv; 00070 const CylinderVolume *cv; 00071 const FrustumVolume *fv; 00072 00073 if((bv = dynamic_cast<const BoxVolume*>(v))) 00074 { 00075 drawVolume(*bv); 00076 } 00077 else if((sv = dynamic_cast<const SphereVolume*>(v))) 00078 { 00079 drawVolume(*sv); 00080 } 00081 else if((cv = dynamic_cast<const CylinderVolume*>(v))) 00082 { 00083 drawVolume(*cv); 00084 } 00085 else if((fv = dynamic_cast<const FrustumVolume*>(v))) 00086 { 00087 drawVolume(*fv); 00088 } 00089 }
| void osg::drawVolume | ( | const BoxVolume & | volume | ) |
Draw the given BoxVolume using direct OpenGL calls.
Definition at line 95 of file OSGVolumeDraw.cpp.
References osg::BoxVolume::getBounds().
00096 { 00097 Pnt3f min,max; 00098 volume.getBounds(min, max); 00099 00100 glBegin(GL_LINE_LOOP); 00101 glVertex3f(min[0], min[1], min[2]); 00102 glVertex3f(max[0], min[1], min[2]); 00103 glVertex3f(max[0], max[1], min[2]); 00104 glVertex3f(min[0], max[1], min[2]); 00105 glVertex3f(min[0], min[1], min[2]); 00106 glVertex3f(min[0], min[1], max[2]); 00107 glVertex3f(max[0], min[1], max[2]); 00108 glVertex3f(max[0], max[1], max[2]); 00109 glVertex3f(min[0], max[1], max[2]); 00110 glVertex3f(min[0], min[1], max[2]); 00111 glEnd(); 00112 00113 glBegin(GL_LINES); 00114 glVertex3f(min[0], max[1], min[2]); 00115 glVertex3f(min[0], max[1], max[2]); 00116 glVertex3f(max[0], max[1], min[2]); 00117 glVertex3f(max[0], max[1], max[2]); 00118 glVertex3f(max[0], min[1], min[2]); 00119 glVertex3f(max[0], min[1], max[2]); 00120 glEnd(); 00121 00122 return; 00123 }
| void osg::drawVolume | ( | const SphereVolume & | volume | ) |
Draw the given SphereVolume using direct OpenGL calls.
NOTE: Not implemented yet!
Definition at line 131 of file OSGVolumeDraw.cpp.
References FWARNING.
00132 { 00133 FWARNING(("drawVolume(SphereVolume): not implemented yet!\n")); 00134 return; 00135 }
| void osg::drawVolume | ( | const FrustumVolume & | volume | ) |
Draw the given FrustumVolume using direct OpenGL calls by intersecting near/far with the pairwise intersection of left/right and top/bottom.
Definition at line 142 of file OSGVolumeDraw.cpp.
References FWARNING, osg::FrustumVolume::getBottom(), osg::FrustumVolume::getFar(), osg::FrustumVolume::getLeft(), osg::FrustumVolume::getNear(), osg::FrustumVolume::getRight(), osg::FrustumVolume::getTop(), osg::Plane::intersect(), and osg::Plane::intersectInfinite().
00143 { 00144 Line lines[4]; 00145 00146 // calc the intersection lines between left/right/bottom/top 00147 if(volume.getLeft().intersect(volume.getTop(), lines[0]) == false) 00148 { 00149 FWARNING(("drawVolume(Frustum): left & top parallel ?!?\n")); 00150 return; 00151 } 00152 00153 if(volume.getLeft().intersect(volume.getBottom(), lines[1]) == false) 00154 { 00155 FWARNING(("drawVolume(Frustum): left & bottom parallel ?!?\n")); 00156 return; 00157 } 00158 00159 if(volume.getRight().intersect(volume.getTop(), lines[2]) == false) 00160 { 00161 FWARNING(("drawVolume(Frustum): right & top parallel ?!?\n")); 00162 return; 00163 } 00164 00165 if(volume.getRight().intersect(volume.getBottom(), lines[3]) == false) 00166 { 00167 FWARNING(("drawVolume(Frustum): right & bottom parallel ?!?\n")); 00168 return; 00169 } 00170 00171 // calc the intersection points 00172 Pnt3f pnts[8]; 00173 00174 if(volume.getNear().intersectInfinite(lines[0], pnts[0]) == false) 00175 { 00176 FWARNING(("drawVolume(Frustum): near & left/top parallel ?!?\n")); 00177 return; 00178 } 00179 00180 if(volume.getFar().intersectInfinite(lines[0], pnts[1]) == false) 00181 { 00182 FWARNING(("drawVolume(Frustum): far & left/top parallel ?!?\n")); 00183 return; 00184 } 00185 00186 if(volume.getNear().intersectInfinite(lines[1], pnts[2]) == false) 00187 { 00188 FWARNING(("drawVolume(Frustum): near & left/bottom parallel ?!?\n")); 00189 return; 00190 } 00191 00192 if(volume.getFar().intersectInfinite(lines[1], pnts[3]) == false) 00193 { 00194 FWARNING(("drawVolume(Frustum): far & left/bottom parallel ?!?\n")); 00195 return; 00196 } 00197 00198 if(volume.getNear().intersectInfinite(lines[2], pnts[4]) == false) 00199 { 00200 FWARNING(("drawVolume(Frustum): near & right/top parallel ?!?\n")); 00201 return; 00202 } 00203 00204 if(volume.getFar().intersectInfinite(lines[2], pnts[5]) == false) 00205 { 00206 FWARNING(("drawVolume(Frustum): far & right/top parallel ?!?\n")); 00207 return; 00208 } 00209 00210 if(volume.getNear().intersectInfinite(lines[3], pnts[6]) == false) 00211 { 00212 FWARNING(("drawVolume(Frustum): near & right/bottom parallel ?!?\n")); 00213 return; 00214 } 00215 00216 if(volume.getFar().intersectInfinite(lines[3], pnts[7]) == false) 00217 { 00218 FWARNING(("drawVolume(Frustum): far & right/bottom parallel ?!?\n")); 00219 return; 00220 } 00221 00222 // got the points, draw them 00223 00224 glBegin(GL_LINE_LOOP); 00225 glVertex3fv(pnts[0].getValues()); 00226 glVertex3fv(pnts[1].getValues()); 00227 glVertex3fv(pnts[3].getValues()); 00228 glVertex3fv(pnts[2].getValues()); 00229 glVertex3fv(pnts[6].getValues()); 00230 glVertex3fv(pnts[7].getValues()); 00231 glVertex3fv(pnts[5].getValues()); 00232 glVertex3fv(pnts[4].getValues()); 00233 glEnd(); 00234 00235 glBegin(GL_LINES); 00236 glVertex3fv(pnts[0].getValues()); 00237 glVertex3fv(pnts[2].getValues()); 00238 glVertex3fv(pnts[1].getValues()); 00239 glVertex3fv(pnts[5].getValues()); 00240 glVertex3fv(pnts[2].getValues()); 00241 glVertex3fv(pnts[6].getValues()); 00242 glVertex3fv(pnts[4].getValues()); 00243 glVertex3fv(pnts[6].getValues()); 00244 glEnd(); 00245 00246 return; 00247 }
| void osg::drawVolume | ( | const CylinderVolume & | volume | ) |
Draw the given CylinderVolume using direct OpenGL calls.
NOTE: Not implemented yet!
Definition at line 255 of file OSGVolumeDraw.cpp.
References FWARNING.
00256 { 00257 FWARNING(("drawVolume(CylinderVolume): not implemented yet!\n")); 00258 return; 00259 }
| void osg::dropVolume | ( | DrawActionBase * | action, | |
| NodePtr | node, | |||
| Color3f | col | |||
| ) |
Draw the local Bounding Volume of the current Node given in the Action.
Definition at line 316 of file OSGVolumeDraw.cpp.
References VolumeDrawWrapper::drop().
Referenced by osg::ProxyGroup::draw(), osg::RenderAction::pushVisibility(), and osg::DrawActionBase::selectVisibles().
00317 { 00318 VolumeDrawWrapper::drop(action, node, col); 00319 return; 00320 }
| void osg::dropVolume | ( | DrawActionBase * | action, | |
| const DynamicVolume & | volume, | |||
| Color3f | col | |||
| ) |
Draw the volume.
Definition at line 326 of file OSGVolumeDraw.cpp.
References VolumeDrawWrapper::drop().
00327 { 00328 VolumeDrawWrapper::drop(action, volume, col); 00329 return; 00330 }
1.5.5