Show
Ignore:
Timestamp:
07/26/10 13:12:45 (4 years ago)
Author:
robert
Message:

Added bevel geometry

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgtext3D/osgtext3D.cpp

    r11684 r11685  
    2121#include <osg/Geometry> 
    2222#include <osg/PositionAttitudeTransform> 
     23#include <osgUtil/SmoothingVisitor> 
    2324#include <osgText/Font3D> 
    2425#include <osgDB/WriteFile> 
     
    3334 
    3435 
    35  
    3636class Boundary 
    3737{ 
     
    4141    typedef std::vector<Segment>  Segments; 
    4242    osg::ref_ptr<osg::Vec3Array> _vertices; 
     43    unsigned int _start; 
     44    unsigned int _count; 
    4345    Segments _segments; 
    4446 
     
    4648    { 
    4749        _vertices = vertices; 
     50        _start = start; 
     51        _count = count; 
    4852 
    4953        if ((*_vertices)[start]==(*_vertices)[start+count-1]) 
     
    5761 
    5862        _segments.reserve(count-1); 
    59         for(unsigned int i=start; i<start+count-1; ++i) 
     63        for(unsigned int i=start; i<start+count-2; ++i) 
    6064        { 
    6165            _segments.push_back(Segment(i,i+1)); 
    6266        } 
     67        _segments.push_back(Segment(start+count-2,start)); 
    6368 
    6469    } 
     
    6772    { 
    6873        float denominator = ( cn.x() * an.y() - cn.y() * an.x()); 
    69         if (denominator==0.0) 
     74        if (denominator==0.0f) 
    7075        { 
    7176            //OSG_NOTICE<<"computeRayIntersectionPoint()<<denominator==0.0"<<std::endl; 
    7277            // line segments must be parallel. 
    73             return (a+c)*0.5; 
     78            return (a+c)*0.5f; 
    7479        } 
    7580 
     
    138143        return thickness; 
    139144    } 
     145 
    140146 
    141147    float computeThickness(unsigned int i) 
     
    206212        // OSG_NOTICE<<"bisector_abcd = "<<bisector_abcd<<", ab_sidevector="<<ab_sidevector<<", b-a="<<b-a<<", scale_factor="<<scale_factor<<std::endl; 
    207213 
    208         new_vertex.z() += 0.5f; 
     214        new_vertex.z() += 5.0f; 
    209215        return new_vertex; 
    210216    } 
     
    217223        osg::Vec3Array* new_vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); 
    218224 
    219         unsigned int first = new_vertices->size(); 
    220         unsigned int count = 0; 
     225        // allocate the primitive set to store the face geometry 
     226        osg::DrawElementsUShort* face = new osg::DrawElementsUShort(GL_POLYGON); 
     227        face->setName("face"); 
    221228 
    222229        // reserve enough space in the vertex array to accomodate the vertices associated with the segments 
    223         // new_vertices->reserve(new_vertices->size()+_segments.size()+1); 
     230        new_vertices->reserve(new_vertices->size() + _segments.size()+1 + _count); 
    224231 
    225232        // create vertices 
    226233        unsigned int previous_second = _segments[0].second; 
    227234        osg::Vec3 newPoint = computeBisectorPoint(0, targetThickness); 
     235        unsigned int first = new_vertices->size(); 
    228236        new_vertices->push_back(newPoint); 
    229         ++count; 
     237 
     238        if (_segments[0].first != _start) 
     239        { 
     240            //OSG_NOTICE<<"We have pruned from the start"<<std::endl; 
     241            for(unsigned int j=_start; j<=_segments[0].first;++j) 
     242            { 
     243                face->push_back(first); 
     244            } 
     245        } 
     246        else 
     247        { 
     248            face->push_back(first); 
     249        } 
     250 
    230251 
    231252        for(unsigned int i=1; i<_segments.size(); ++i) 
    232253        { 
     254            newPoint = computeBisectorPoint(i, targetThickness); 
     255            unsigned int vi = new_vertices->size(); 
     256            new_vertices->push_back(newPoint); 
     257 
     258            if (previous_second != _segments[i].first) 
     259            { 
     260                //OSG_NOTICE<<"Gap in boundary"<<previous_second<<" to "<<_segments[i].first<<std::endl; 
     261                for(unsigned int j=previous_second; j<=_segments[i].first;++j) 
     262                { 
     263                    face->push_back(vi); 
     264                } 
     265            } 
     266            else 
     267            { 
     268                face->push_back(vi); 
     269            } 
     270 
    233271            previous_second = _segments[i].second; 
    234             newPoint = computeBisectorPoint(i, targetThickness); 
    235             new_vertices->push_back(newPoint); 
    236             ++count; 
    237         } 
    238  
    239         // repeat the first point to make it a full closed loop 
    240         new_vertices->push_back((*new_vertices)[first]); 
    241         ++count; 
    242  
    243         // add DrawArrays primitive set for polygon 
    244         if (count!=0) geometry->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON, first, count)); 
     272        } 
     273 
     274        // fill the end of the polygon with repititions of the first index in the polygon to ensure 
     275        // that the orignal and new boundary polygons have the same number and pairing of indices. 
     276        // This ensures that the bevel can be created coherently. 
     277        while(face->size() < _count) 
     278        { 
     279            face->push_back(first); 
     280        } 
     281 
     282        // add face primitive set for polygon 
     283        geometry->addPrimitiveSet(face); 
     284 
     285        osg::DrawElementsUShort* bevel = new osg::DrawElementsUShort(GL_QUAD_STRIP); 
     286        bevel->setName("bevel"); 
     287        bevel->reserve(_count*2); 
     288        for(unsigned int i=0; i<_count; ++i) 
     289        { 
     290            unsigned int vi = new_vertices->size(); 
     291            new_vertices->push_back((*_vertices)[_start+i]); 
     292            bevel->push_back(vi); 
     293            bevel->push_back((*face)[i]); 
     294        } 
     295        geometry->addPrimitiveSet(bevel); 
    245296    } 
    246297 
    247298}; 
     299 
     300osg::Geometry* getGeometryComponent(osg::Geometry* geometry, bool bevel) 
     301{ 
     302    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); 
     303    if (!vertices) return 0; 
     304 
     305    osg::Geometry* new_geometry = new osg::Geometry; 
     306    osg::Vec3Array* new_vertices = new osg::Vec3Array(*vertices); 
     307    new_geometry->setVertexArray(new_vertices); 
     308 
     309    for(unsigned int i=0; i<geometry->getNumPrimitiveSets(); ++i) 
     310    { 
     311        osg::PrimitiveSet* primitiveSet = geometry->getPrimitiveSet(i); 
     312        if (primitiveSet->getName()=="bevel") 
     313        { 
     314            if (bevel) new_geometry->addPrimitiveSet(primitiveSet); 
     315        } 
     316        else 
     317        { 
     318            if (!bevel) new_geometry->addPrimitiveSet(primitiveSet); 
     319        } 
     320    } 
     321 
     322    osg::Vec4Array* new_colours = new osg::Vec4Array; 
     323    new_colours->push_back(bevel ? osg::Vec4(1.0,1.0,0.0,1.0) : osg::Vec4(1.0,0.0,0.0,1.0)); 
     324    new_geometry->setColorArray(new_colours); 
     325    new_geometry->setColorBinding(osg::Geometry::BIND_OVERALL); 
     326 
     327    if (!bevel) 
     328    { 
     329        osg::Vec3Array* normals = new osg::Vec3Array; 
     330        normals->push_back(osg::Vec3(0.0,0.0,1.0)); 
     331        new_geometry->setNormalArray(normals); 
     332        new_geometry->setNormalBinding(osg::Geometry::BIND_OVERALL); 
     333    } 
     334 
     335    return new_geometry; 
     336} 
    248337 
    249338 
     
    256345    osg::Geometry* new_geometry = new osg::Geometry; 
    257346 
    258     osg::Vec4Array* new_colours = new osg::Vec4Array; 
    259     new_colours->push_back(osg::Vec4(1.0,1.0,0.0,1.0)); 
    260     new_geometry->setColorArray(new_colours); 
    261     new_geometry->setColorBinding(osg::Geometry::BIND_OVERALL); 
    262  
    263347    for(osg::Geometry::PrimitiveSetList::iterator itr = orig_primitives.begin(); 
    264348        itr != orig_primitives.end(); 
     
    269353        { 
    270354            Boundary boundary(orig_vertices, drawArray->getFirst(), drawArray->getCount()); 
    271             boundary.computeAllThickness(); 
    272  
    273355            boundary.removeAllSegmentsBelowThickness(thickness); 
    274356            boundary.addBoundaryToGeometry(new_geometry, thickness); 
     
    344426        geometry->setColorBinding(osg::Geometry::BIND_OVERALL); 
    345427 
    346         osg::Geometry* bevel = computeThickness(geometry, thickness); 
    347  
    348         if (bevel) geode->addDrawable(bevel); 
    349  
     428        osg::ref_ptr<osg::Geometry> face_and_bevel = computeThickness(geometry, thickness); 
     429 
     430        osg::Geometry* bevel = getGeometryComponent(face_and_bevel, true); 
     431        if (bevel) 
     432        { 
     433            geode->addDrawable(bevel); 
     434            osgUtil::SmoothingVisitor smoother; 
     435            smoother.smooth(*bevel); 
     436        } 
     437 
     438        osg::Geometry* face = getGeometryComponent(face_and_bevel, false); 
     439        if (face) geode->addDrawable(face); 
     440 
     441     
    350442        if (useTessellator) 
    351443        { 
     
    358450            } 
    359451 
    360             if (bevel) 
     452            if (face) 
    361453            { 
    362454                osgUtil::Tessellator ts; 
    363455                ts.setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE); 
    364456                ts.setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY); 
    365                 ts.retessellatePolygons(*bevel); 
     457                ts.retessellatePolygons(*face); 
    366458            } 
    367459 
     
    374466        group->addChild(transform.get()); 
    375467    } 
     468 
     469 
    376470 
    377471    std::string filename;