#include <OSGExtrusionGeometry.h>
Public Member Functions | |
Constructors | |
| * | ExtrusionSurface (const std::vector< Pnt2f > &crossSection, const std::vector< Quaternion > &orientation, const std::vector< Vec2f > &scale, const std::vector< Pnt3f > &spine, Real32 creaseAngle=0.f, bool beginCap=true, bool endCap=true, bool ccw=true, bool convex=true, bool buildNormal=true, bool buildTexCoord=true) |
| Constructor initializing an extrusion surface. | |
Access | |
| *GeometryPtr | createGeometry (UInt32 nSubDivisions) |
| Creates a multi-indexed Geometry representing the extrusion surface Invoked by the construction function makeExtrusionGeo and makeExtrusion. | |
Private Types | |
| typedef std::vector< Pnt3f >::const_iterator | Pnt3fConstIt |
| typedef std::vector< Matrix >::const_iterator | MatrixConstIt |
| typedef std::pair< Pnt3fConstIt, Pnt3fConstIt > | Pnt3fConstItPair |
| typedef std::vector< std::vector< Vertex > > | VertexGrid |
| typedef std::map< Pnt3f, UInt32, vecless< Pnt3f > > | PositionMap |
| typedef std::map< Vec3f, UInt32, vecless< Vec3f > > | NormalMap |
| typedef std::map< Vec2f, UInt32, vecless< Vec2f > > | TexCoordMap |
Private Member Functions | |
| ExtrusionSurface (const ExtrusionSurface &source) | |
| prohibit default function (move to 'public' if needed) | |
| void | operator= (const ExtrusionSurface &source) |
| prohibit default function (move to 'public' if needed) | |
| void | calcXAxes (void) |
| void | calcYAxes (void) |
| void | calcZAxes (void) |
| void | calcTransforms (void) |
| void | calcSweepSurfacePositions (void) |
| void | calcSweepSurfaceFaceNormals (void) |
| void | calcSweepSurfaceTexCoords (void) |
| void | determineTopology (void) |
| void | initGrid (void) |
| bool | verifyInput (void) |
| void | refineCrossSection (UInt32 nTimes) |
| void | refineOrientation (UInt32 nTimes) |
| void | refineScale (UInt32 nTimes) |
| void | refineSpine (UInt32 nTimes) |
| void | storeConvexCap (UInt32 spineIndex, bool invertNormal, GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr) |
| void | storeSweepSurfaceWithNormals (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr) |
| void | storeSweepSurfaceWithoutNormals (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr) |
| void | storeMaps (GeoPositions3fPtr positionsPtr, GeoNormals3fPtr normalsPtr, GeoTexCoords2fPtr texCoordsPtr) |
| void | storeVertex (const Vertex &vertex, GeoIndicesUI32Ptr indicesPtr) |
| void | storePrimitive (GLenum type, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr) |
| template<typename PType> | |
| UInt32 | store (PType property, std::map< PType, UInt32, vecless< PType > > &propertyIndexMap) |
| template<typename PType> | |
| void | store (const PType property, std::map< PType, UInt32, vecless< PType > > &propertyIndexMap, GeoIndicesUI32Ptr indicesPtr) |
| Pnt3fConstItPair | getPrevAndNextIt (const Pnt3fConstIt &pIt) |
| Vec3f | calcNonUnitYAxis (const Pnt3fConstIt &pIt) |
| Vec3f | calcNonUnitZAxis (const Pnt3fConstIt &pIt) |
| Vec3f | calcXAxis (const MatrixConstIt &pIt) |
| Vec3f | calcTriangleFaceNormal (const Pnt3f &a, const Pnt3f &b, const Pnt3f &c) |
| Vec3f | calcQuadFaceNormal (const Pnt3f &a, const Pnt3f &b, const Pnt3f &c, const Pnt3f &d) |
| void | calcVertexNormal (Vertex *vertexPtr, UInt32 faceIndex) |
| bool | isLeft (const Pnt2f &a, const Pnt2f &b) |
| Real32 | computeMinYAbs (const std::vector< Pnt2f > &contour, Real32 alpha) |
| Real32 | calcBetterRotationAngle (const std::vector< Pnt2f > &contour, UInt32 nAngles) |
| bool | calcOptimizedContour (const std::vector< Pnt2f > &contour, const Pnt2f &point, std::vector< Pnt2f > *optimizedContour) |
| Int32 | calcWindingNumber (const std::vector< Pnt2f > &contour, const Pnt2f &point) |
| void | storeFaceNormalGeo (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr) |
| void | storeVertexNormalGeo (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr) |
Constructors | |
| * | ExtrusionSurface (void) |
| prohibit default function (move to 'public' if needed) | |
Private Attributes | |
| std::vector< Pnt2f > | _crossSection |
| std::vector< Quaternion > | _orientation |
| std::vector< Vec2f > | _scale |
| std::vector< Pnt3f > | _spine |
| Real32 | _creaseAngle |
| bool | _beginCap |
| bool | _endCap |
| bool | _ccw |
| bool | _convex |
| bool | _crossSectionClosed |
| bool | _spineClosed |
| bool | _spineCollinear |
| bool | _revolutionSurface |
| bool | _createNormals |
| bool | _createTexCoords |
| std::vector< Matrix > | _transform |
| VertexGrid | _grid |
| PositionMap | _posMap |
| NormalMap | _normalMap |
| TexCoordMap | _texCoordMap |
| UInt32 | _vertexCount |
| UInt32 | _totalVertexCount |
| UInt32 | _primitiveCount |
Classes | |
| struct | vecless |
| struct | Vertex |
Definition at line 140 of file OSGExtrusionGeometry.h.
|
|
Definition at line 249 of file OSGExtrusionGeometry.h. |
|
|
Definition at line 250 of file OSGExtrusionGeometry.h. |
|
|
Definition at line 251 of file OSGExtrusionGeometry.h. |
|
|
Definition at line 253 of file OSGExtrusionGeometry.h. |
|
|
Definition at line 255 of file OSGExtrusionGeometry.h. |
|
|
Definition at line 256 of file OSGExtrusionGeometry.h. |
|
|
Definition at line 257 of file OSGExtrusionGeometry.h. |
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 125 of file OSGExtrusionGeometry.cpp. References _crossSection, _orientation, _scale, _spine, osg::DEF_CROSS_SECTION, osg::DEF_N_CROSS_SECTION_POINTS, osg::DEF_N_ORIENTATION_PARAMS, osg::DEF_N_SCALE_PARAMS, osg::DEF_N_SPINE_POINTS, osg::DEF_ORIENTATION, osg::DEF_SCALE, osg::DEF_SPINE, and FDEBUG. 00135 : 00136 00137 _creaseAngle(creaseAngle), 00138 _beginCap(beginCap), 00139 _endCap(endCap), 00140 _ccw(ccw), 00141 _convex(convex), 00142 _createNormals(buildNormal), 00143 _createTexCoords(buildTexCoord), 00144 _primitiveCount(0), 00145 _vertexCount(0), 00146 _totalVertexCount(0) 00147 { 00148 // initialize cross section 00149 if(!crossSection.empty()) 00150 { 00151 // copy argument 00152 _crossSection.assign(crossSection.begin(), crossSection.end()); 00153 } 00154 else 00155 { 00156 // copy default 00157 FDEBUG(("OSGExtrusion: Empty cross section. Using default.\n")); 00158 for(UInt32 i = 0; i < DEF_N_CROSS_SECTION_POINTS; i++) 00159 _crossSection.push_back(Pnt2f(DEF_CROSS_SECTION[i])); 00160 } 00161 00162 // initialize orientations 00163 if(!orientation.empty()) 00164 { 00165 // copy argument 00166 _orientation.assign(orientation.begin(), orientation.end()); 00167 } 00168 else 00169 { 00170 // copy default 00171 FDEBUG(("OSGExtrusion: Empty orientation. Using default.\n")); 00172 for(UInt32 i = 0; i < DEF_N_ORIENTATION_PARAMS; i++) 00173 _orientation.push_back(Quaternion(Vec3f(DEF_ORIENTATION[i]), 00174 DEF_ORIENTATION[i][3])); 00175 } 00176 00177 // initialize scale parameters 00178 if(!scale.empty()) 00179 { 00180 // copy argument 00181 _scale.assign(scale.begin(), scale.end()); 00182 } 00183 else 00184 { 00185 // copy default 00186 FDEBUG(("OSGExtrusion: Empty scale parameter. Using default.\n")); 00187 for(UInt32 i = 0; i < DEF_N_SCALE_PARAMS; i++) 00188 _scale.push_back(Vec2f(DEF_SCALE[i])); 00189 } 00190 00191 00192 // initialize spine 00193 if(!spine.empty()) 00194 { 00195 // copy argument 00196 _spine.assign(spine.begin(), spine.end()); 00197 } 00198 else 00199 { 00200 // copy default 00201 FDEBUG(("OSGExtrusion: Empty spine. Using default.\n")); 00202 for(UInt32 i = 0; i < DEF_N_SPINE_POINTS; i++) 00203 _spine.push_back(Pnt3f(DEF_SPINE[i])); 00204 } 00205 }
|
|
|
|
|
|
|
|
|
Definition at line 1477 of file OSGExtrusionGeometry.cpp. References _beginCap, _convex, _createNormals, _createTexCoords, _endCap, _normalMap, _orientation, _posMap, _primitiveCount, _spine, _texCoordMap, _totalVertexCount, osg::beginEditCP(), calcSweepSurfacePositions(), calcSweepSurfaceTexCoords(), osg::GeometryBase::create(), osg::GeoProperty< GeoPropertyDesc >::create(), determineTopology(), osg::endEditCP(), FDEBUG, FFATAL, FINFO, FWARNING, osg::GeoProperty< GeoPropertyDesc >::GeoPropDataFieldMask, osg::GeometryBase::IndexMappingFieldMask, osg::GeometryBase::IndicesFieldMask, initGrid(), osg::GeometryBase::LengthsFieldMask, osg::Geometry::MapNormal, osg::Geometry::MapPosition, osg::Geometry::MapTexCoords, osg::GeometryBase::NormalsFieldMask, osg::NullFC, osg::GeometryBase::PositionsFieldMask, refineCrossSection(), refineScale(), refineSpine(), SINFO, storeConvexCap(), storeFaceNormalGeo(), storeMaps(), storeSweepSurfaceWithNormals(), storeSweepSurfaceWithoutNormals(), storeVertexNormalGeo(), osg::GeometryBase::TexCoordsFieldMask, osg::GeometryBase::TypesFieldMask, and verifyInput(). Referenced by osg::makeExtrusionGeo(). 01478 { 01479 // do some sanity checks on and determines the topology 01480 // of the _spine and _crossSection member fields 01481 if(!verifyInput()) 01482 { 01483 FWARNING(("OSGExtrusion:createGeometry: Invalid input. Returning NullFC\n")); 01484 return NullFC; 01485 } 01486 01487 // initialize topology flags (i.e spine/_crossSection closure) 01488 determineTopology(); 01489 01490 // optionally subdivide input data 01491 if(nSubdivs > 0) 01492 { 01493 refineCrossSection(nSubdivs); 01494 01495 if(_orientation.size() == 1) 01496 { 01497 refineSpine(nSubdivs); 01498 refineScale(nSubdivs); 01499 } 01500 else // more than 1 orientation 01501 { 01502 // It'd be necessary to refine the orientations in order to get 01503 // a consistent result, but this is not implemented yet. 01504 FINFO(("OSGExtrusion:createGeometry: Too many orientations. Not refining along spine\n")); 01505 } 01506 } 01507 01508 // allocate vertex grid structure 01509 initGrid(); 01510 calcSweepSurfacePositions(); 01511 01512 if(_createTexCoords) 01513 { 01514 calcSweepSurfaceTexCoords(); 01515 } 01516 01517 // create opensg geometry field containers 01518 GeoPositions3fPtr posPtr = GeoPositions3f::create(); 01519 GeoPLengthsUI32Ptr lensPtr = GeoPLengthsUI32::create(); 01520 GeoIndicesUI32Ptr indicesPtr = GeoIndicesUI32::create(); 01521 GeoPTypesUI8Ptr typesPtr = GeoPTypesUI8::create(); 01522 GeoNormals3fPtr normalsPtr = NullFC; 01523 GeoTexCoords2fPtr texPtr = NullFC; 01524 01525 if(_createNormals) 01526 normalsPtr = GeoNormals3f::create(); 01527 01528 if(_createTexCoords) 01529 texPtr = GeoTexCoords2f::create(); 01530 01531 beginEditCP(indicesPtr, GeoIndicesUI32::GeoPropDataFieldMask); 01532 beginEditCP(lensPtr, GeoPLengthsUI32::GeoPropDataFieldMask); 01533 beginEditCP(typesPtr, GeoPTypesUI8::GeoPropDataFieldMask); 01534 01535 if(_createNormals) 01536 { 01537 // store sweep surface as triangle strips with vertex normals 01538 storeSweepSurfaceWithNormals(indicesPtr, lensPtr, typesPtr); 01539 } 01540 else 01541 { 01542 // store sweep surface as triangle strips without vertex normals 01543 storeSweepSurfaceWithoutNormals(indicesPtr, lensPtr, typesPtr); 01544 } 01545 01546 if(_convex) 01547 { 01548 // calculate and store caps as triangle fans 01549 if(_beginCap) 01550 { 01551 FDEBUG(("OSGExtrusion:createGeometry: Creating begin cap\n")); 01552 storeConvexCap(0, // spine section 0 01553 true, // flip normal 01554 indicesPtr, 01555 lensPtr, 01556 typesPtr); 01557 } 01558 01559 if(_endCap) 01560 { 01561 FDEBUG(("OSGExtrusion:createGeometry: Creating end cap\n")); 01562 storeConvexCap(_spine.size() - 1, // last spine section 01563 false, // don't flip normal 01564 indicesPtr, 01565 lensPtr, 01566 typesPtr); 01567 } 01568 } 01569 else // non-convex case 01570 { 01571 FFATAL(("OSGExtrusion:createGeometry: Support for non-convex caps not implemented\n")); 01572 } 01573 01574 #ifdef DEBUG_VERTEX_NORMALS 01575 // add surface normals for debugging purposes 01576 storeVertexNormalGeo(indicesPtr, lensPtr, typesPtr); 01577 #endif 01578 01579 #ifdef DEBUG_FACE_NORMALS 01580 // add sweep surface face normals for debugging purposes 01581 storeFaceNormalGeo(indicesPtr, lensPtr, typesPtr); 01582 #endif 01583 01584 endEditCP(indicesPtr, GeoIndicesUI32::GeoPropDataFieldMask); 01585 endEditCP(lensPtr, GeoPLengthsUI32::GeoPropDataFieldMask); 01586 endEditCP(typesPtr, GeoPTypesUI8::GeoPropDataFieldMask); 01587 01588 // store the shared vertex data into the vertex data field containers 01589 storeMaps(posPtr, normalsPtr, texPtr); 01590 01591 // create a new OpenSG geometry 01592 GeometryPtr geoPtr = Geometry::create(); 01593 01594 beginEditCP(geoPtr, Geometry::TypesFieldMask | 01595 Geometry::LengthsFieldMask | 01596 Geometry::IndicesFieldMask | 01597 Geometry::IndexMappingFieldMask | 01598 Geometry::PositionsFieldMask | 01599 Geometry::NormalsFieldMask | 01600 Geometry::TexCoordsFieldMask ); 01601 01602 // The interleaved multi-index blocks have one of the following 01603 // layouts (depending on _createNormals and _createTexCoords): 01604 // 01605 // 1. (Position) 01606 // 2. (Position, Normal) 01607 // 3. (Position, TexCoord) 01608 // 4. (Position, Normal, TexCoord) 01609 geoPtr->getIndexMapping().push_back(Geometry::MapPosition); 01610 if(_createNormals) 01611 geoPtr->getIndexMapping().push_back(Geometry::MapNormal); 01612 if(_createTexCoords) 01613 geoPtr->getIndexMapping().push_back(Geometry::MapTexCoords); 01614 01615 // set primitive data field containers 01616 geoPtr->setLengths(lensPtr); 01617 geoPtr->setIndices(indicesPtr); 01618 geoPtr->setTypes(typesPtr); 01619 01620 // set vertex data field containers 01621 geoPtr->setPositions(posPtr); 01622 geoPtr->setNormals(normalsPtr); 01623 geoPtr->setTexCoords(texPtr); 01624 01625 endEditCP(geoPtr, Geometry::TypesFieldMask | 01626 Geometry::LengthsFieldMask | 01627 Geometry::IndicesFieldMask | 01628 Geometry::IndexMappingFieldMask | 01629 Geometry::PositionsFieldMask | 01630 Geometry::NormalsFieldMask | 01631 Geometry::TexCoordsFieldMask ); 01632 01633 01634 SINFO << "OSGExtrusion:createGeometry: Stats: (" 01635 << _primitiveCount << '/' 01636 << _totalVertexCount << '/' 01637 << _posMap.size() << '/' 01638 << _normalMap.size() << '/' 01639 << _texCoordMap.size() << ')' 01640 << "(Prims/Verts/Pos/Norms/TexCoords)" 01641 << std::endl; 01642 01643 return geoPtr; 01644 }
|
|
|
|
|
|
Calculates the X-Axes of the CP to SCP transforms Definition at line 331 of file OSGExtrusionGeometry.cpp. References _revolutionSurface, _spineCollinear, _transform, and calcXAxis(). Referenced by calcTransforms(). 00332 { 00333 std::vector<Matrix>::iterator tIt = _transform.begin(); 00334 00335 // Either of the two cases below implies the cross product of 00336 // the y- and the z-axis vanish (and so do all x-axes) 00337 if(!_spineCollinear && !_revolutionSurface) 00338 { 00339 for(; tIt != _transform.end(); ++tIt) 00340 { 00341 Vec3f xAxis = calcXAxis(tIt); 00342 (*tIt)[0].setValue(xAxis); 00343 } 00344 } 00345 else 00346 { 00347 (*tIt)[0].setValue(Vec3f(0.f, 0.f, 0.f)); 00348 } 00349 }
|
|
|
Calculates the Y-Axes of the CP to SCP transforms Definition at line 361 of file OSGExtrusionGeometry.cpp. References _revolutionSurface, _spine, _transform, calcNonUnitYAxis(), osg::Eps, FDEBUG, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::length(), and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(). Referenced by calcTransforms(). 00362 { 00363 bool yAxisDefined = false; 00364 00365 std::vector<Pnt3f>::const_iterator spineIt = _spine.begin(); 00366 std::vector<Matrix>::iterator tIt = _transform.begin(); 00367 for(; spineIt != _spine.end(); ++spineIt, ++tIt) 00368 { 00369 Vec3f yAxis = calcNonUnitYAxis(spineIt); 00370 if(yAxis.length() > Eps) // we have found a valid tangent 00371 { 00372 yAxis.normalize(); 00373 if(!yAxisDefined) 00374 { 00375 FDEBUG(("OSGExtrusion:calcYAxes: yAxis is defined\n")); 00376 yAxisDefined = true; 00377 00378 // assign found y-axis to all transforms 00379 // up to and including the current one 00380 std::vector<Matrix>::iterator yIt; 00381 for(yIt = _transform.begin(); yIt != (tIt + 1); ++yIt) 00382 (*yIt)[1].setValue(yAxis); 00383 } 00384 else 00385 { 00386 // assign found y-axis to the current transform only 00387 (*tIt)[1].setValue(yAxis); 00388 } 00389 } 00390 else if(yAxisDefined) 00391 { 00392 // reuse y-axis determined during last step 00393 (*tIt)[1] = (*(tIt - 1))[1]; 00394 } 00395 } 00396 00397 // all spine points coincided => surface of revolution 00398 _revolutionSurface = !yAxisDefined; 00399 }
|
|
|
Calculates the Z-Axes of the CP to SCP transforms Definition at line 410 of file OSGExtrusionGeometry.cpp. References _spine, _spineCollinear, _transform, calcNonUnitZAxis(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::Eps, FDEBUG, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::length(), osg::PointInterface< ValueTypeT, StorageInterfaceT >::negate(), and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize(). Referenced by calcTransforms(). 00411 { 00412 bool zAxisDefined = false; 00413 00414 std::vector<Pnt3f>::const_iterator spineIt = _spine.begin(); 00415 std::vector<Matrix>::iterator tIt = _transform.begin(); 00416 for(; spineIt != _spine.end(); ++spineIt, ++tIt) 00417 { 00418 Vec3f zAxis = calcNonUnitZAxis(spineIt); 00419 if(zAxis.length() > Eps) 00420 { 00421 zAxis.normalize(); 00422 if(!zAxisDefined) 00423 { 00424 FDEBUG(("OSGExtrusion:calcZAxes: zAxis is defined\n")); 00425 zAxisDefined = true; 00426 00427 // set the current z-Axis for the current transform 00428 (*tIt)[2].setValue(zAxis); 00429 00430 // assign found z-axis to all previous transforms 00431 std::vector<Matrix>::iterator zIt; 00432 for(zIt = _transform.begin(); zIt != tIt; ++zIt) 00433 { 00434 (*zIt)[2].setValue(zAxis); 00435 } 00436 } 00437 else // assign found z-axis to this basis _only_ 00438 { 00439 (*tIt)[2].setValue(zAxis); 00440 00441 // as the zAxis is defined tIt - 1 contains a valid value 00442 Vec3f prevZAxis((*(tIt - 1))[2][0], 00443 (*(tIt - 1))[2][1], 00444 (*(tIt - 1))[2][2]); 00445 00446 // check whether the z-axis needs to be flipped 00447 if(prevZAxis.dot(zAxis) + Eps < 0.f) 00448 { 00449 FDEBUG(("OSGExtrusion:calcZAxes: Flipping z-axis\n")); 00450 zAxis.negate(); 00451 } 00452 00453 // assign zAxis to current transform 00454 (*tIt)[2].setValue(zAxis); 00455 } 00456 } 00457 else if(zAxisDefined) 00458 { 00459 // reuse previous value 00460 (*tIt)[2] = (*(tIt - 1))[2]; 00461 } 00462 } // end for 00463 00464 // All cross products vanished => spine has no non-collinear part 00465 // and is thus composed of collinear parts and revolutions only 00466 _spineCollinear = !zAxisDefined; 00467 }
|
|
|
Calculates the affine transformations from CP to SCP Definition at line 480 of file OSGExtrusionGeometry.cpp. References _orientation, _revolutionSurface, _scale, _spine, _spineCollinear, _transform, calcXAxes(), calcYAxes(), calcZAxes(), FDEBUG, osg::QuaternionBase< ValueTypeT >::getValue(), osg::TransformationMatrix< ValueTypeT >::multLeft(), and osg::QuaternionBase< ValueTypeT >::setValue(). Referenced by calcSweepSurfacePositions(). 00481 { 00482 _transform.clear(); 00483 00484 // initialize the transformations with Id 00485 _transform.resize(_spine.size()); 00486 00487 /* X3D Spec: 00488 * The SCP is computed by first computing its Y-axis and Z-axis, then 00489 * taking the cross product of these to determine the X-axis. These three 00490 * axes are then used to determine the rotation value needed to rotate the 00491 * Y=0 plane to the SCP. This results in a plane that is the approximate 00492 * tangent of the spine at each point, as shown in Figure 13.5. 00493 */ 00494 calcZAxes(); // sets bool _spineCollinear 00495 calcYAxes(); // sets bool _revolutionSurface 00496 00497 // We need to make a difference between surfaces having at least 00498 // one non-trivial collinear part in their spine and surfaces created 00499 // by pure revolution of the crossection. 00500 if(_revolutionSurface) 00501 { 00502 _spineCollinear = false; 00503 } 00504 calcXAxes(); // uses _spineCollinear and _revolutionSurface 00505 00506 /* X3D Spec: 00507 * 00508 * If the entire spine is collinear, the SCP is computed by finding the 00509 * rotation of a vector along the positive Y-axis (v1) to the vector formed 00510 * by the spine points (v2). The Y=0 plane is then rotated by this value. 00511 * 00512 * If two points are coincident, they both have the same SCP. If each point 00513 * has a different orientation value, then the surface is constructed by 00514 * connecting edges of the cross-sections as normal. This is useful in 00515 * creating revolved surfaces. 00516 */ 00517 Matrix rotation; // m = Id and thus ok for revolution case 00518 if(_spineCollinear && !_revolutionSurface) 00519 { 00520 // calculate the rotation that rotates the y unit vector to the 00521 // direction of the spine. 00522 Vec3f v1(0.f, 1.f, 0.f); 00523 Vec3f v2(_transform[0][1]); 00524 00525 Quaternion q; 00526 q.setValue(v1, v2); 00527 q.getValue(rotation); 00528 } 00529 00530 std::vector<Matrix>::iterator tIt = _transform.begin(); 00531 std::vector<Pnt3f>::const_iterator spineIt = _spine.begin(); 00532 std::vector<Vec2f>::const_iterator scaleIt = _scale.begin(); 00533 std::vector<Quaternion>::const_iterator rotIt = _orientation.begin(); 00534 00535 // calculate an affine transformation for the cross-section at 00536 // each spine point 00537 for(; spineIt != _spine.end(); ++spineIt, ++tIt) 00538 { 00539 // special cases 00540 if(_spineCollinear || _revolutionSurface) 00541 { 00542 // defines the x,y and z-axes in this case 00543 *tIt = rotation; 00544 } 00545 00546 // setup transform of the CP 00547 Matrix cSPlaneTransform; 00548 00549 // Scale the x- and z-axes 00550 cSPlaneTransform[0] *= (*scaleIt)[0]; 00551 cSPlaneTransform[2] *= (*scaleIt)[1]; 00552 00553 // apply orientation 00554 Matrix orientationMatrix; 00555 rotIt->getValue(orientationMatrix); 00556 cSPlaneTransform.multLeft(orientationMatrix); 00557 00558 tIt->mult(cSPlaneTransform); 00559 00560 // affine translation to the spine point 00561 tIt->setTranslate(*spineIt); 00562 00563 // The affine transformation *tIt should now 00564 // 00565 // 1. scale the CP 00566 // 2. apply the orientation to the CP 00567 // 2. translate the origin to spine[i] 00568 // 00569 // in exactly this order. 00570 00571 /* X3D Spec quotation: 00572 * 00573 * If the number of scale or orientation values is greater than the 00574 * number of spine points, the excess values are ignored. If they 00575 * contain one value, it is applied at all spine points. The 00576 * results are undefined if the number of scale or orientation 00577 * values is greater than one but less than the number of spine 00578 * points. The scale values shall be positive. 00579 */ 00580 00581 // always use last available value 00582 if(rotIt + 1 != _orientation.end()) { ++rotIt; } 00583 if(scaleIt + 1 != _scale.end()) { ++scaleIt; } 00584 } 00585 00586 FDEBUG(("OSGExtrusion:calcTransforms: spine collinear: %s\n", 00587 (_spineCollinear ? "true" : "false"))); 00588 00589 FDEBUG(("OSGExtrusion:calcTransforms: revolution surface: %s\n", 00590 (_revolutionSurface ? "true" : "false"))); 00591 }
|
|
|
Calculates the positions of the sweep surface and stores them in the _grid Definition at line 624 of file OSGExtrusionGeometry.cpp. References _crossSection, _grid, _posMap, _spine, _transform, calcTransforms(), osg::Eps, FDEBUG, FFATAL, FWARNING, initGrid(), p, and SWARNING. Referenced by createGeometry(). 00625 { 00626 FDEBUG(("OSGExtrusion:calcSweepSurfacePositions: Calculation vertex positions\n")); 00627 00628 if(_grid.size() < _spine.size()) 00629 { 00630 FFATAL(("OSGExtrusion:calcSweepSurfacePositions: Grid not initialized\n")); 00631 return; 00632 } 00633 00634 _posMap.clear(); 00635 00636 // compute transformation matrices 00637 calcTransforms(); 00638 00639 if(_grid.size() < _spine.size()) // grid not yet or incorrectly initialized 00640 { 00641 initGrid(); 00642 } 00643 00644 std::vector<Matrix>::iterator transIt = _transform.begin(); 00645 VertexGrid::iterator gridRowIt = _grid.begin(); 00646 00647 // iterate over the spine points 00648 for(Int32 i = 0; i < _spine.size(); i++, ++gridRowIt) 00649 { 00650 if(transIt->det3() < Eps) // degenerate transform 00651 { 00652 FWARNING(("OSGExtrusion:calcSurfacePositions: Degenerate transformation matrix\n")); 00653 SWARNING << "Degenerate transform[" << i << "]:\n " 00654 << *transIt << std::endl; 00655 } 00656 00657 std::vector<Vertex>::iterator gridColIt = gridRowIt->begin(); 00658 std::vector<Pnt2f>::iterator crossIt; 00659 00660 // iterate over the cross-section curve 00661 for(crossIt = _crossSection.begin(); crossIt != _crossSection.end(); 00662 ++crossIt, ++gridColIt) 00663 { 00664 Pnt3f p = Pnt3f((*crossIt)[0], 0.f, (*crossIt)[1]); 00665 00666 // apply "CP to SCP"-transform 00667 transIt->multMatrixPnt(p, gridColIt->position); 00668 } 00669 00670 // always use last defined transformation matrix 00671 if(transIt + 1 != _transform.end()) { ++transIt; } 00672 } 00673 }
|
|
|
Calculates the face normals of the sweep surface and stores them in the _grid Definition at line 748 of file OSGExtrusionGeometry.cpp. References _crossSection, _crossSectionClosed, _grid, _spine, _spineClosed, calcQuadFaceNormal(), FDEBUG, and FFATAL. Referenced by storeSweepSurfaceWithNormals(). 00749 { 00750 FDEBUG(("OSGExtrusion:calcSweepSurfaceFaceNormals: Calculating sweep surface face normals\n")); 00751 00752 if(_grid.size() < _spine.size()) 00753 { 00754 FFATAL(("OSGExtrusion:calcSweepSurfaceFaceNormals: Grid not initialized\n")); 00755 return; 00756 } 00757 00758 // calculate face normals 00759 for(UInt32 i = 0; i < _spine.size(); ++i) 00760 { 00761 UInt32 iPrev, iNext; 00762 00763 // determine adjacent row indices 00764 if(_spineClosed) 00765 { 00766 // first point == last point 00767 iPrev = (i != 0) ? i - 1 : _spine.size() - 2; 00768 iNext = (i != _spine.size() - 1) ? i + 1 : 1; 00769 } 00770 else 00771 { 00772 iPrev = (i != 0) ? i - 1 : 0; 00773 iNext = (i != _spine.size() - 1) ? i + 1 : i; 00774 } 00775 00776 for(UInt32 j = 0; j < _crossSection.size(); ++j) 00777 { 00778 Vec3f n; 00779 UInt32 jPrev, jNext; 00780 00781 // determine adjacent column indices 00782 if(_crossSectionClosed) 00783 { 00784 // first point == last point 00785 jPrev = (j != 0) ? j - 1 : _crossSection.size() - 2; 00786 jNext = (j != _crossSection.size() - 1) ? j + 1 : 1; 00787 } 00788 else 00789 { 00790 jPrev = (j != 0) ? j - 1 : 0; 00791 jNext = (j != _crossSection.size() - 1) ? j + 1 : j; 00792 } 00793 00794 // upper right face normal (1st quadrant) 00795 _grid[i][j].adjFaceNormals[0] = 00796 calcQuadFaceNormal(_grid[i][j].position, 00797 _grid[i][jNext].position, 00798 _grid[iNext][jNext].position, 00799 _grid[iNext][j].position); 00800 00801 00802 // upper left face normal (2nd quadrant) 00803 _grid[i][j].adjFaceNormals[1] = 00804 calcQuadFaceNormal(_grid[i][j].position, 00805 _grid[iNext][j].position, 00806 _grid[iNext][jPrev].position, 00807 _grid[i][jPrev].position); 00808 00809 00810 // lower left face normal (3nd quadrant) 00811 _grid[i][j].adjFaceNormals[2] = 00812 calcQuadFaceNormal(_grid[i][j].position, 00813 _grid[i][jPrev].position, 00814 _grid[iPrev][jPrev].position, 00815 _grid[iPrev][j].position); 00816 00817 00818 // lower right face normal (4th quadrant) 00819 _grid[i][j].adjFaceNormals[3] = 00820 calcQuadFaceNormal(_grid[i][j].position, 00821 _grid[iPrev][j].position, 00822 _grid[iPrev][jNext].position, 00823 _grid[i][jNext].position); 00824 } 00825 } 00826 }
|
|
|
Definition at line 686 of file OSGExtrusionGeometry.cpp. References _crossSection, _grid, _spine, _texCoordMap, osg::Eps, FDEBUG, and FFATAL. |