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) |
|
|
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::endEditCP(), osg::Plane::getNormal(), osg::TriangleIterator::getPosition(), osg::TriangleIterator::getPositionIndex(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::NullFC, p, and osg::MField< FieldTypeT, fieldNameSpace >::size(). Referenced by osg::calcVertexNormals(), osg::VRMLGeometryPointSetDesc::endNode(), osg::VRMLGeometryDesc::endNode(), 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 }
|
|
||||||||||||
|
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::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::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::NullFC, osg::osgcos(), p, osg::Pi, osg::MField< FieldTypeT, fieldNameSpace >::push_back(), osg::MField< FieldTypeT, fieldNameSpace >::size(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::squareLength(), osg::VecStorage3< ValueTypeT >::x(), osg::VecStorage3< ValueTypeT >::y(), and osg::VecStorage3< ValueTypeT >::z(). 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 }
|
|
|
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::VectorInterface< ValueTypeT, StorageInterfaceT >::cross(), osg::endEditCP(), osg::FaceIterator::getIndexIndex(), osg::FaceIterator::getLength(), osg::FaceIterator::getPosition(), osg::FaceIterator::getPositionIndex(), osg::PrimitiveIterator::getType(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::length(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(), osg::NullFC, osg::MField< FieldTypeT, fieldNameSpace >::push_back(), and osg::MField< FieldTypeT, fieldNameSpace >::size(). 00755 { 00756 GeoIndicesPtr newIndex = GeoIndicesUI32::create(); 00757 GeoNormalsPtr newNormals = GeoNormals3f::create(); 00758 Vec3f normal; 00759 00760 FaceIterator faceIter = geo->beginFaces(); 00761 GeoIndicesPtr oldIndex = geo->getIndices(); 00762 00763 if(oldIndex != NullFC) 00764 { 00765 //Indexed 00766 if(geo->getIndexMapping().size() > 0) 00767 { 00768 //MULTI INDEXED 00769 beginEditCP(newIndex); 00770 00771 MFUInt16 &oldIndexMap = geo->getIndexMapping(); 00772 UInt32 oldIMSize = oldIndexMap.size(); 00773 for(UInt32 i = 0; i < oldIndex->getSize() / oldIMSize; ++i) 00774 { 00775 for(UInt32 k = 0; k < oldIMSize; ++k) 00776 { 00777 newIndex->push_back(oldIndex->getValue(i * oldIMSize + k)); 00778 } 00779 00780 newIndex->push_back(0); //placeholder for normal index 00781 } 00782 00783 beginEditCP(newNormals); 00784 for(UInt32 faceCnt = 0; faceIter != geo->endFaces(); 00785 ++faceIter, ++faceCnt) 00786 { 00787 if(faceIter.getLength() == 3) 00788 { 00789 //Face is a Triangle 00790 normal = 00791 ( 00792 faceIter.getPosition(1) - 00793 faceIter.getPosition(0) 00794 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00795 normal.normalize(); 00796 } 00797 else 00798 { 00799 //Face must be a Quad then 00800 normal = 00801 ( 00802 faceIter.getPosition(1) - 00803 faceIter.getPosition(0) 00804 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00805 if(normal.length() == 0) 00806 { 00807 //Quad is degenerate, choose different points for normal 00808 normal = 00809 ( 00810 faceIter.getPosition(1) - 00811 faceIter.getPosition(2) 00812 ).cross(faceIter.getPosition(3) - 00813 faceIter.getPosition(2)); 00814 } 00815 00816 normal.normalize(); 00817 } 00818 00819 newNormals->push_back(normal); //put the normal into the storage 00820 UInt32 base; 00821 switch(faceIter.getType()) 00822 { 00823 case GL_TRIANGLE_STRIP: 00824 base = faceIter.getIndexIndex(2); //get last point's position in index field 00825 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize); 00826 break; 00827 case GL_TRIANGLE_FAN: 00828 base = faceIter.getIndexIndex(2); //get last point's position in index field 00829 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize); 00830 break; 00831 case GL_QUAD_STRIP: 00832 base = faceIter.getIndexIndex(3); //get last point's position in index field 00833 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize); 00834 break; 00835 default: 00836 for(UInt32 i = 0; i < faceIter.getLength(); ++i) 00837 { 00838 base = faceIter.getIndexIndex(i); 00839 newIndex->setValue(faceCnt, 00840 base + (base / oldIMSize) + oldIMSize); 00841 } 00842 break; 00843 } 00844 } 00845 00846 endEditCP(newNormals); 00847 endEditCP(newIndex); 00848 00849 beginEditCP(geo); 00850 00851 Int16 ni; 00852 ni = geo->calcMappingIndex(Geometry::MapNormal); 00853 if(ni != -1) 00854 { 00855 oldIndexMap[ni] = oldIndexMap[ni] &~Geometry::MapNormal; 00856 } 00857 00858 oldIndexMap.push_back(Geometry::MapNormal); 00859 geo->setNormals(newNormals); 00860 geo->setIndices(newIndex); 00861 endEditCP(geo); 00862 return; 00863 } 00864 } 00865 00866 //SINGLE INDEXED or NON INDEXED 00867 //UInt32 pointCnt = 0; 00868 newNormals->resize(geo->getPositions()->getSize()); 00869 for(; faceIter != geo->endFaces(); ++faceIter) 00870 { 00871 if(faceIter.getLength() == 3) 00872 { 00873 //Face is a Triangle 00874 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00875 normal.normalize(); 00876 } 00877 else 00878 { 00879 //Face must be a Quad then 00880 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0)); 00881 if(normal.length() == 0) 00882 { 00883 //Quad is degenerate, choose different points for normal 00884 normal = 00885 ( 00886 faceIter.getPosition(1) - 00887 faceIter.getPosition(2) 00888 ).cross(faceIter.getPosition(3) - faceIter.getPosition(2)); 00889 } 00890 00891 normal.normalize(); 00892 } 00893 00894 switch(faceIter.getType()) 00895 { 00896 case GL_TRIANGLE_STRIP: 00897 newNormals->setValue(normal, faceIter.getPositionIndex(2)); 00898 break; 00899 case GL_TRIANGLE_FAN: 00900 newNormals->setValue(normal, faceIter.getPositionIndex(2)); 00901 break; 00902 case GL_QUAD_STRIP: 00903 newNormals->setValue(normal, faceIter.getPositionIndex(3)); 00904 break; 00905 default: 00906 for(UInt32 i = 0; i < faceIter.getLength(); ++i) 00907 { 00908 newNormals->setValue(normal, faceIter.getPositionIndex(i)); 00909 } 00910 break; 00911 } 00912 00913 beginEditCP(geo); 00914 geo->setNormals(newNormals); 00915 endEditCP(geo); 00916 } 00917 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
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 936 of file OSGGeoFunctions.cpp. References osg::setIndexFromIndexedX3DData(). Referenced by osg::VRMLGeometryPointSetDesc::endNode(), and osg::VRMLGeometryDesc::endNode(). 00947 { 00948 Int32 primitiveType = faceSet ? GL_POLYGON : GL_LINE; 00949 00950 return setIndexFromIndexedX3DData ( geoPtr, 00951 coordIndex, 00952 normalIndex, 00953 colorIndex, 00954 texCoordIndex, 00955 primitiveType, 00956 convex, 00957 ccw, 00958 normalPerVertex, 00959 colorPerVertex, 00960 createNormal ); 00961 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
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! define the bag type defines the Index Types holds the Index types as str, mainly for log/debug outputs Definition at line 982 of file OSGGeoFunctions.cpp. References osg::beginEditCP(), osg::endEditCP(), FDEBUG, FFATAL, FINFO, FNOTICE, FWARNING, and osg::NullFC. Referenced by osg::setIndexFromVRMLData(). 00993 { 00995 typedef std::vector<Int32> *IndexBagP; 00996 00998 enum IndexType 00999 { 01000 UNKNOWN_IT = 0, 01001 EMPTY_IT, 01002 VERTEX_COORD_IT, 01003 VERTEX_IT, 01004 VERTEX_DUP_IT, 01005 VERTEX_CREATE_IT, 01006 PRIMITIVE_IT, 01007 PRIMITIVE_INDEX_IT, 01008 PRIMITIVE_CREATE_IT 01009 }; 01010 01012 static const char *indexTypeStr[] = 01013 { 01014 "UNKNOWN_IT", 01015 "EMPTY_IT", 01016 "VERTEX_COORD_IT", 01017 "VERTEX_IT", 01018 "VERTEX_DUP_IT", 01019 "VERTEX_CREATE_IT", 01020 "PRIMTIVE_IT", 01021 "PRIMITIVE_INDEX_IT", 01022 "PRIMITIVE_CREATE_IT" 01023 }; 01024 OSG::GeoPositionsPtr posPtr; 01025 OSG::GeoNormalsPtr normalPtr; 01026 OSG::GeoColorsPtr colorPtr; 01027 OSG::GeoTexCoordsPtr texCoordsPtr; 01028 OSG::GeoPLengthsPtr lensPtr; 01029 OSG::GeoPTypesPtr geoTypePtr; 01030 OSG::GeoIndicesPtr indexPtr; 01031 01032 //bool faceSet = (primitiveType == GL_POLYGON); 01033 Int32 index, i, pi, typei, mapi, primitiveN = 0, vN = 0; 01034 Int32 pType = 0, localPType; 01035 Int32 maxPType; // = (faceSet ? 5 : 3); 01036 Int32 minPType; // = (faceSet ? 3 : 2); 01037 Int32 beginIndex, endIndex, step, len, sysPType = 0; 01038 Int32 piN = 0, ciN = 0, niN = 0, tiN = 0; 01039 Int32 pN = 0, nN = 0, cN = 0, tN = 0, tN1 = 0, tN2 = 0, tN3 = 0; 01040 IndexType indexType[4]; 01041 IndexType &coordIT = indexType[0]; 01042 IndexType &normalIT = indexType[1]; 01043 IndexType &colorIT = indexType[2]; 01044 IndexType &textureIT = indexType[3]; 01045 Int32 primitiveTypeCount[6]; 01046 UInt32 triCount = 0; 01047 Int16 indexMap[4], indexMapID[4]; 01048 UInt32 uiNumTextures = 0; 01049 01050 IndexBagP indexBag[4] = 01051 { 01052 &coordIndex, 01053 &normalIndex, 01054 &colorIndex, 01055 &texCoordIndex 01056 }; 01057 01058 //---------------------------------------------------------------------- 01059 // init 01060 coordIT = VERTEX_IT; 01061 indexMap[0] = Geometry::MapPosition; 01062 01063 //---------------------------------------------------------------------- 01064 // set maxPType and minPTypr from primitiveType 01065 switch (primitiveType) { 01066 case GL_POINTS: 01067 minPType = 1; 01068 maxPType = 1; 01069 break; 01070 case GL_LINES: 01071 minPType = 2; 01072 maxPType = 3; 01073 break; 01074 case GL_LINE_STRIP: 01075 minPType = 2; 01076 maxPType = 3; 01077 break; 01078 case GL_LINE_LOOP: 01079 minPType = 2; 01080 maxPType = 3; 01081 break; 01082 case GL_TRIANGLES: 01083 minPType = 3; 01084 maxPType = 3; 01085 break; 01086 case GL_TRIANGLE_STRIP: 01087 minPType = 3; 01088 maxPType = 3; 01089 break; 01090 case GL_TRIANGLE_FAN: 01091 minPType = 3; 01092 maxPType = 3; 01093 break; 01094 case GL_QUADS: 01095 minPType = 3; 01096 maxPType = 4; 01097 break; 01098 case GL_QUAD_STRIP: 01099 minPType = 3; 01100 maxPType = 4; 01101 break; 01102 case GL_POLYGON: 01103 minPType = 3; 01104 maxPType = 5; 01105 break; 01106 default: 01107 FFATAL (( "Can not fill index; Invalid primitiveType: %d\n", 01108 primitiveType )); 01109 break; 01110 } 01111 01112 01113 //---------------------------------------------------------------------- 01114 // get the property pointer and element count 01115 posPtr = geoPtr->getPositions(); 01116 pN = ((posPtr == OSG::NullFC) ? 0 : posPtr->getSize()); 01117 01118 normalPtr = geoPtr->getNormals(); 01119 nN = ((normalPtr == OSG::NullFC) ? 0 : normalPtr->getSize()); 01120 01121 colorPtr = geoPtr->getColors(); 01122 cN = ((colorPtr == OSG::NullFC) ? 0 : colorPtr->getSize()); 01123 01124 texCoordsPtr = geoPtr->getTexCoords(); 01125 tN = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01126 01127 texCoordsPtr = geoPtr->getTexCoords1(); 01128 tN1 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01129 01130 texCoordsPtr = geoPtr->getTexCoords2(); 01131 tN2 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01132 01133 texCoordsPtr = geoPtr->getTexCoords3(); 01134 tN3 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize()); 01135 01136 FDEBUG(("vertex attrib count P/N/C/T: %d/%d/%d/%d\n", pN, nN, cN, tN)); 01137 01138 //---------------------------------------------------------------------- 01139 // check the vertex index and count the primitives 01140 primitiveN = index = 0; 01141 for(pType = 0; pType < 6; pType++) 01142 primitiveTypeCount[pType] = 0; 01143 01144 if(!pN) 01145 { 01146 FINFO(("No points in OSG::setIndexFromVRMLData()\n")); 01147 return 0; 01148 } 01149 else 01150 { 01151 piN = coordIndex.size(); 01152 if(piN) 01153 { 01154 for(i = 0; i <= piN; i++) 01155 { 01156 index = (i == piN) ? -1 : coordIndex[i]; 01157 if((index < 0) && vN) 01158 { 01159 primitiveTypeCount[(vN > maxPType) ? maxPType : vN]++; 01160 primitiveN++; 01161 vN = 0; 01162 } 01163 else 01164 { 01165 if(index >= pN && i != piN) 01166 { 01167 FWARNING(("Point index (%d/%d) out of range", index, pN)); 01168 coordIndex[i] = 0; 01169 } 01170 01171 vN++; 01172 } 01173 } 01174 } 01175 else 01176 { 01177 FWARNING(("No coordIndex in OSG::setIndexFromVRMLData()\n")); 01178 return 0; 01179 } 01180 } 01181 01182 //---------------------------------------------------------------------- 01183 // check the normal index 01184 normalIT = UNKNOWN_IT; 01185 niN = normalIndex.size(); 01186 if(nN) 01187 { // have normal elements 01188 if(normalPerVertex) 01189 { 01190 // normal per vertex 01191 if(niN >= piN) 01192 { 01193 // valid normal index number 01194 for(i = 0; i < piN; i++) 01195 { // check if normal index equals the coord index 01196 if(normalIndex[i] != coordIndex[i]) 01197 { 01198 normalIT = VERTEX_IT; 01199 break; 01200 } 01201 } 01202 01203 if(normalIT == UNKNOWN_IT) 01204 { 01205 // if equal than delete unneeded normal index 01206 normalIT = VERTEX_DUP_IT; 01207 } 01208 } 01209 else 01210 { 01211 // no or not enough normal index 01212 normalIT = VERTEX_COORD_IT; 01213 if(niN) 01214 { 01215 FWARNING(("Not enough normal index (%d,%d)\n", normalIndex. 01216 size(), piN)); 01217 normalIndex.clear(); 01218 } 01219 } 01220 } 01221 else 01222 { 01223 // normal per primitive 01224 if(niN >= primitiveN) 01225 { 01226 // use one normal index per primitive 01227 normalIT = PRIMITIVE_INDEX_IT; 01228 } 01229 else 01230 { 01231 if(nN >= primitiveN) 01232 { 01233 // use one normal per primitive 01234 normalIT = PRIMITIVE_IT; 01235 } 01236 else 01237 { 01238 FINFO(("not enough normal index (%d,%d)\n", nN, primitiveN)); 01239 } 01240 } 01241 } 01242 } 01243 else 01244 { 01245 /* not yet !!! 01246 if (createNormal) 01247 if (normalPerVertex) 01248 normalIT = VERTEX_CREATE_IT; 01249 else 01250 normalIT = PRIMITIVE_CREATE_IT; 01251 else 01252 */ 01253 normalIT = EMPTY_IT; 01254 } 01255 01256 //---------------------------------------------------------------------- 01257 // check the color index 01258 colorIT = UNKNOWN_IT; 01259 ciN = colorIndex.size(); 01260 if(cN) 01261 { // have color elements 01262 if(colorPerVertex) 01263 { 01264 // color per vertex 01265 if(ciN >= piN) 01266 { 01267 // valid color index number 01268 for(i = 0; i < piN; i++) 01269 { // check if color index equals the coord index 01270 if(colorIndex[i] != coordIndex[i]) 01271 { 01272 colorIT = VERTEX_IT; 01273 break; 01274 } 01275 } 01276 01277 if(colorIT == UNKNOWN_IT) 01278 { 01279 // if equal than delete unneeded color index 01280 colorIT = VERTEX_DUP_IT; 01281 } 01282 } 01283 else 01284 { 01285 // no or not enough color index 01286 colorIT = VERTEX_COORD_IT; 01287 if(ciN) 01288 { 01289 FWARNING(("Not enough color index (%d,%d)\n", colorIndex. 01290 size(), piN)); 01291 colorIndex.clear(); 01292 } 01293 } 01294 } 01295 else 01296 { 01297 // color per primitive 01298 if(ciN >= primitiveN) 01299 { 01300 // use one color index per primitive 01301 colorIT = PRIMITIVE_INDEX_IT; 01302 } 01303 else 01304 { 01305 if(cN >= primitiveN) 01306 { 01307 // use one color per primitive 01308 colorIT = PRIMITIVE_IT; 01309 } 01310 else 01311 { 01312 FINFO(("not enough color index (%d,%d)\n", cN, primitiveN)); 01313 } 01314 } 01315 } 01316 } 01317 else 01318 { 01319 colorIT = EMPTY_IT; 01320 } 01321 01322 //---------------------------------------------------------------------- 01323 // check the texture index 01324 textureIT = UNKNOWN_IT; 01325 tiN = texCoordIndex.size(); 01326 if(tN) 01327 { // have texture elemnts 01328 if(tiN >= piN) 01329 { 01330 // valid texture index number 01331 for(i = 0; i < piN; i++) 01332 { // check if texture index equals the coord index 01333 if(texCoordIndex[i] != coordIndex[i]) 01334 { 01335 textureIT = VERTEX_IT; 01336 break; 01337 } 01338 } 01339 01340 if(textureIT == UNKNOWN_IT) 01341 { 01342 // if equal than delete unneeded texture index 01343 textureIT = VERTEX_DUP_IT; 01344 } 01345 } 01346 else 01347 { 01348 // no or not enough texture index 01349 textureIT = VERTEX_COORD_IT; 01350 if(ciN) 01351 { 01352 FWARNING(("Not enough texCoord index (%d,%d)\n", texCoordIndex. 01353 size(), piN)); 01354 texCoordIndex.clear(); 01355 } 01356 } 01357 } 01358 else 01359 { 01360 textureIT = EMPTY_IT; 01361 } 01362 01363 FNOTICE (( "primitiveN: %d, |