| 37 | | class BevelProfile |
| 38 | | { |
| 39 | | public: |
| 40 | | |
| 41 | | typedef std::vector<osg::Vec2> Vertices; |
| 42 | | |
| 43 | | BevelProfile() |
| 44 | | { |
| 45 | | flatBevel(); |
| 46 | | } |
| 47 | | |
| 48 | | void flatBevel(float width=0.25f) |
| 49 | | { |
| 50 | | _vertices.clear(); |
| 51 | | |
| 52 | | if (width>0.5f) width = 0.5f; |
| 53 | | |
| 54 | | _vertices.push_back(osg::Vec2(0.0f,0.0f)); |
| 55 | | |
| 56 | | _vertices.push_back(osg::Vec2(width,1.0f)); |
| 57 | | |
| 58 | | if (width<0.5f) _vertices.push_back(osg::Vec2(1-width,1.0f)); |
| 59 | | |
| 60 | | _vertices.push_back(osg::Vec2(1.0f,0.0f)); |
| 61 | | } |
| 62 | | |
| 63 | | void roundedBevel(float width=0.5f, unsigned int numSteps=10) |
| 64 | | { |
| 65 | | _vertices.clear(); |
| 66 | | |
| 67 | | if (width>0.5f) width = 0.5f; |
| 68 | | |
| 69 | | unsigned int i = 0; |
| 70 | | for(; i<=numSteps; ++i) |
| 71 | | { |
| 72 | | float angle = float(osg::PI)*0.5f*(float(i)/float(numSteps)); |
| 73 | | _vertices.push_back( osg::Vec2((1.0f-cosf(angle))*width, sinf(angle)) ); |
| 74 | | } |
| 75 | | |
| 76 | | // start the second half one into the curve if the width is half way across |
| 77 | | i = width<0.5f ? 0 : 1; |
| 78 | | for(; i<=numSteps; ++i) |
| 79 | | { |
| 80 | | float angle = float(osg::PI)*0.5f*(float(numSteps-i)/float(numSteps)); |
| 81 | | _vertices.push_back( osg::Vec2(1.0-(1.0f-cosf(angle))*width, sin(angle)) ); |
| 82 | | } |
| 83 | | } |
| 84 | | |
| 85 | | void print(std::ostream& fout) |
| 86 | | { |
| 87 | | OSG_NOTICE<<"print bevel"<<std::endl; |
| 88 | | for(Vertices::iterator itr = _vertices.begin(); |
| 89 | | itr != _vertices.end(); |
| 90 | | ++itr) |
| 91 | | { |
| 92 | | OSG_NOTICE<<" "<<*itr<<std::endl; |
| 93 | | } |
| 94 | | } |
| 95 | | |
| 96 | | Vertices& getVertices() { return _vertices; } |
| 97 | | |
| 98 | | protected: |
| 99 | | |
| 100 | | Vertices _vertices; |
| 101 | | }; |
| | 199 | } |
| | 200 | } |
| | 201 | |
| | 202 | bool findMaxThickness(unsigned int& maxThickness_i, float& maxThickness) |
| | 203 | { |
| | 204 | maxThickness_i = _segments.size(); |
| | 205 | for(unsigned int i=0; i<_segments.size(); ++i) |
| | 206 | { |
| | 207 | float thickness = computeThickness(i); |
| | 208 | if (thickness<0.0 && thickness > maxThickness) |
| | 209 | { |
| | 210 | maxThickness = thickness; |
| | 211 | maxThickness_i = i; |
| | 212 | } |
| | 213 | } |
| | 214 | |
| | 215 | return maxThickness_i != _segments.size(); |
| | 216 | } |
| | 217 | |
| | 218 | |
| | 219 | void removeAllSegmentsAboveThickness(float targetThickness) |
| | 220 | { |
| | 221 | // OSG_NOTICE<<"removeAllSegmentsBelowThickness("<<targetThickness<<")"<<std::endl; |
| | 222 | for(;;) |
| | 223 | { |
| | 224 | unsigned int maxThickness_i = _segments.size(); |
| | 225 | float maxThickness = targetThickness; |
| | 226 | if (!findMaxThickness(maxThickness_i,maxThickness)) break; |
| | 227 | |
| | 228 | // OSG_NOTICE<<" removing segment _segments["<<minThickness_i<<"] ("<<_segments[minThickness_i].first<<", "<<_segments[minThickness_i].second<<" with thickness="<<minThickness<<" "<<std::endl; |
| | 229 | _segments.erase(_segments.begin()+maxThickness_i); |
| | 502 | |
| | 503 | osg::Geometry* createShell(osg::Geometry* geometry, float distance) |
| | 504 | { |
| | 505 | if (!geometry) return 0; |
| | 506 | |
| | 507 | osg::Vec3Array* orig_vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); |
| | 508 | if (!orig_vertices) return 0; |
| | 509 | |
| | 510 | osg::Vec3Array* orig_normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray()); |
| | 511 | if (!orig_normals) return 0; |
| | 512 | |
| | 513 | if (orig_vertices->size() != orig_normals->size()) return 0; |
| | 514 | |
| | 515 | osg::Geometry* new_geometry = new osg::Geometry; |
| | 516 | osg::Vec3Array* new_vertices = new osg::Vec3Array(orig_vertices->size()); |
| | 517 | for(unsigned int i=0; i<orig_vertices->size(); ++i) |
| | 518 | { |
| | 519 | (*new_vertices)[i] = (*orig_vertices)[i] + (*orig_normals)[i]*distance; |
| | 520 | } |
| | 521 | |
| | 522 | new_geometry->setVertexArray(new_vertices); |
| | 523 | |
| | 524 | osg::Vec4Array* new_colours = new osg::Vec4Array; |
| | 525 | new_colours->push_back(osg::Vec4(1.0,1.0,1.0,0.2)); |
| | 526 | new_geometry->setColorArray(new_colours); |
| | 527 | new_geometry->setColorBinding(osg::Geometry::BIND_OVERALL); |
| | 528 | |
| | 529 | osg::TriangleIndexFunctor<CollectTriangleIndicesFunctor> ctif; |
| | 530 | geometry->accept(ctif); |
| | 531 | |
| | 532 | // front face |
| | 533 | osg::DrawElementsUInt* shell = new osg::DrawElementsUInt(GL_TRIANGLES); |
| | 534 | new_geometry->addPrimitiveSet(shell); |
| | 535 | CollectTriangleIndicesFunctor::Indices& face = ctif._indices; |
| | 536 | for(unsigned int i=0; i<face.size();++i) |
| | 537 | { |
| | 538 | shell->push_back(face[i]); |
| | 539 | } |
| | 540 | |
| | 541 | osg::StateSet* stateset = new_geometry->getOrCreateStateSet(); |
| | 542 | stateset->setMode(GL_BLEND, osg::StateAttribute::ON); |
| | 543 | stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); |
| | 544 | stateset->setAttributeAndModes(new osg::CullFace, osg::StateAttribute::ON); |
| | 545 | stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); |
| | 546 | return new_geometry; |
| | 547 | } |
| | 548 | |
| | 549 | |
| | 649 | #if 1 |
| | 650 | osg::ref_ptr<osg::Geometry> glyphGeometry = osgText::computeGlyphGeometry(glyph.get(), thickness, width); |
| | 651 | osg::ref_ptr<osg::Geometry> textGeometry = osgText::computeTextGeometry(glyphGeometry.get(), profile, width); |
| | 652 | osg::ref_ptr<osg::Geometry> shellGeometry = osgText::computeShellGeometry(glyphGeometry.get(), profile, width); |
| | 653 | if (textGeometry.valid()) |
| | 654 | { |
| | 655 | geode->addDrawable(textGeometry.get()); |
| | 656 | // create the normals |
| | 657 | if (true) |
| | 658 | { |
| | 659 | osgUtil::SmoothingVisitor smoother; |
| | 660 | smoother.setCreaseAngle(osg::DegreesToRadians(creaseAngle)); |
| | 661 | geode->accept(smoother); |
| | 662 | } |
| | 663 | } |
| | 664 | |
| | 665 | if (shellGeometry.valid()) geode->addDrawable(shellGeometry.get()); |
| | 666 | #else |