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

Clean up boudnary code

Files:
1 modified

Legend:

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

    r11681 r11684  
    3333 
    3434 
    35 osg::Vec3 computeRayIntersectionPoint(const osg::Vec3& a, const osg::Vec3& an, const osg::Vec3& c, const osg::Vec3& cn) 
    36 { 
    37     float denominator = ( cn.x() * an.y() - cn.y() * an.x()); 
    38     if (denominator==0.0) 
    39     { 
    40         //OSG_NOTICE<<"computeRayIntersectionPoint()<<denominator==0.0"<<std::endl; 
    41         // line segments must be parallel. 
    42         return (a+c)*0.5; 
    43     } 
    44  
    45     float t = ((a.x()-c.x())*an.y() - (a.y()-c.y())*an.x()) / denominator; 
    46     return c + cn*t; 
    47 } 
    48  
    49 osg::Vec3 computeIntersectionPoint(const osg::Vec3& a, const osg::Vec3& b, const osg::Vec3& c, const osg::Vec3& d) 
    50 { 
    51 #if 0 
    52     float ba_x = b.x()-a.x(); 
    53     float ba_y = b.y()-a.y(); 
    54  
    55     float dc_x = d.x()-c.x(); 
    56     float dc_y = d.y()-c.y(); 
    57  
    58     float denominator = (dc_x * ba_y - dc_y * ba_x); 
    59     if (denominator==0.0) 
    60     { 
    61         // line segments must be parallel. 
    62         return (b+c)*0.5; 
    63     } 
    64  
    65     float t = ((a.x()-c.x())*ba_y + (a.y()-c.y())*ba_x) / denominator; 
    66  
    67     return c + (d-c)*t; 
    68 #endif 
    69     return computeRayIntersectionPoint(a, b-a, c, d-c); 
    70  
    71 } 
    72  
    73 osg::Vec3 computeBisectorNormal(const osg::Vec3& a, const osg::Vec3& b, const osg::Vec3& c, const osg::Vec3& d) 
    74 { 
    75     osg::Vec2 ab(a.x()-b.x(), a.y()-b.y()); 
    76     osg::Vec2 dc(d.x()-c.x(), d.y()-c.y()); 
    77     /*float length_ab =*/ ab.normalize(); 
    78     /*float length_dc =*/ dc.normalize(); 
    79  
    80     float e = dc.y() - ab.y(); 
    81     float f = ab.x() - dc.x(); 
    82     float denominator = sqrtf(e*e + f*f); 
    83     float nx = e / denominator; 
    84     float ny = f / denominator; 
    85     if (( ab.x()*ny - ab.y()*nx) > 0.0f) 
    86     { 
    87         // OSG_NOTICE<<"   computeBisectorNormal(a=["<<a<<"], b=["<<b<<"], c=["<<c<<"], d=["<<d<<"]), nx="<<nx<<", ny="<<ny<<", denominator="<<denominator<<" no need to swap"<<std::endl; 
    88         return osg::Vec3(nx,ny,0.0f); 
    89     } 
    90     else 
    91     { 
    92         OSG_NOTICE<<"   computeBisectorNormal(a=["<<a<<"], b=["<<b<<"], c=["<<c<<"], d=["<<d<<"]), nx="<<nx<<", ny="<<ny<<", denominator="<<denominator<<" need to swap!!!"<<std::endl; 
    93         return osg::Vec3(-nx,-ny,0.0f); 
    94     } 
    95 } 
    96  
    97 float computeBisectorIntersectorThickness(const osg::Vec3& a, const osg::Vec3& b, const osg::Vec3& c, const osg::Vec3& d, const osg::Vec3& e, const osg::Vec3& f) 
    98 { 
    99     osg::Vec3 intersection_abcd = computeIntersectionPoint(a,b,c,d); 
    100     osg::Vec3 bisector_abcd = computeBisectorNormal(a,b,c,d); 
    101     osg::Vec3 intersection_cdef = computeIntersectionPoint(c,d,e,f); 
    102     osg::Vec3 bisector_cdef = computeBisectorNormal(c,d,e,f); 
    103     if (bisector_abcd==bisector_cdef) 
    104     { 
    105         //OSG_NOTICE<<"computeBisectorIntersector(["<<a<<"], ["<<b<<"], ["<<c<<"], ["<<d<<"], ["<<e<<"], ["<<f<<"[)"<<std::endl; 
    106         //OSG_NOTICE<<"   bisectors parallel, thickness = "<<FLT_MAX<<std::endl; 
    107         return FLT_MAX; 
    108     } 
    109  
    110     osg::Vec3 bisector_intersection = computeRayIntersectionPoint(intersection_abcd,bisector_abcd, intersection_cdef, bisector_cdef); 
    111     osg::Vec3 normal(d.y()-c.y(), c.x()-d.x(), 0.0); 
    112     float cd_length = normal.normalize(); 
    113     if (cd_length==0) 
    114     { 
    115         //OSG_NOTICE<<"computeBisectorIntersector(["<<a<<"], ["<<b<<"], ["<<c<<"], ["<<d<<"], ["<<e<<"], ["<<f<<"[)"<<std::endl; 
    116         //OSG_NOTICE<<"   segment length==0, thickness = "<<FLT_MAX<<std::endl; 
    117         return FLT_MAX; 
    118     } 
    119  
    120     float thickness = (bisector_intersection - c) * normal; 
    121 #if 0 
    122     OSG_NOTICE<<"computeBisectorIntersector(["<<a<<"], ["<<b<<"], ["<<c<<"], ["<<d<<"], ["<<e<<"], ["<<f<<"[)"<<std::endl; 
    123     OSG_NOTICE<<"   bisector_abcd = "<<bisector_abcd<<", bisector_cdef="<<bisector_cdef<<std::endl; 
    124     OSG_NOTICE<<"   bisector_intersection = "<<bisector_intersection<<", thickness = "<<thickness<<std::endl; 
    125 #endif 
    126     return thickness; 
    127 } 
    12835 
    12936class Boundary 
     
    15562        } 
    15663 
     64    } 
     65 
     66    osg::Vec3 computeRayIntersectionPoint(const osg::Vec3& a, const osg::Vec3& an, const osg::Vec3& c, const osg::Vec3& cn) 
     67    { 
     68        float denominator = ( cn.x() * an.y() - cn.y() * an.x()); 
     69        if (denominator==0.0) 
     70        { 
     71            //OSG_NOTICE<<"computeRayIntersectionPoint()<<denominator==0.0"<<std::endl; 
     72            // line segments must be parallel. 
     73            return (a+c)*0.5; 
     74        } 
     75 
     76        float t = ((a.x()-c.x())*an.y() - (a.y()-c.y())*an.x()) / denominator; 
     77        return c + cn*t; 
     78    } 
     79 
     80    osg::Vec3 computeIntersectionPoint(const osg::Vec3& a, const osg::Vec3& b, const osg::Vec3& c, const osg::Vec3& d) 
     81    { 
     82        return computeRayIntersectionPoint(a, b-a, c, d-c); 
     83    } 
     84 
     85    osg::Vec3 computeBisectorNormal(const osg::Vec3& a, const osg::Vec3& b, const osg::Vec3& c, const osg::Vec3& d) 
     86    { 
     87        osg::Vec2 ab(a.x()-b.x(), a.y()-b.y()); 
     88        osg::Vec2 dc(d.x()-c.x(), d.y()-c.y()); 
     89        /*float length_ab =*/ ab.normalize(); 
     90        /*float length_dc =*/ dc.normalize(); 
     91 
     92        float e = dc.y() - ab.y(); 
     93        float f = ab.x() - dc.x(); 
     94        float denominator = sqrtf(e*e + f*f); 
     95        float nx = e / denominator; 
     96        float ny = f / denominator; 
     97        if (( ab.x()*ny - ab.y()*nx) > 0.0f) 
     98        { 
     99            // OSG_NOTICE<<"   computeBisectorNormal(a=["<<a<<"], b=["<<b<<"], c=["<<c<<"], d=["<<d<<"]), nx="<<nx<<", ny="<<ny<<", denominator="<<denominator<<" no need to swap"<<std::endl; 
     100            return osg::Vec3(nx,ny,0.0f); 
     101        } 
     102        else 
     103        { 
     104            OSG_NOTICE<<"   computeBisectorNormal(a=["<<a<<"], b=["<<b<<"], c=["<<c<<"], d=["<<d<<"]), nx="<<nx<<", ny="<<ny<<", denominator="<<denominator<<" need to swap!!!"<<std::endl; 
     105            return osg::Vec3(-nx,-ny,0.0f); 
     106        } 
     107    } 
     108 
     109    float computeBisectorIntersectorThickness(const osg::Vec3& a, const osg::Vec3& b, const osg::Vec3& c, const osg::Vec3& d, const osg::Vec3& e, const osg::Vec3& f) 
     110    { 
     111        osg::Vec3 intersection_abcd = computeIntersectionPoint(a,b,c,d); 
     112        osg::Vec3 bisector_abcd = computeBisectorNormal(a,b,c,d); 
     113        osg::Vec3 intersection_cdef = computeIntersectionPoint(c,d,e,f); 
     114        osg::Vec3 bisector_cdef = computeBisectorNormal(c,d,e,f); 
     115        if (bisector_abcd==bisector_cdef) 
     116        { 
     117            //OSG_NOTICE<<"computeBisectorIntersector(["<<a<<"], ["<<b<<"], ["<<c<<"], ["<<d<<"], ["<<e<<"], ["<<f<<"[)"<<std::endl; 
     118            //OSG_NOTICE<<"   bisectors parallel, thickness = "<<FLT_MAX<<std::endl; 
     119            return FLT_MAX; 
     120        } 
     121 
     122        osg::Vec3 bisector_intersection = computeRayIntersectionPoint(intersection_abcd,bisector_abcd, intersection_cdef, bisector_cdef); 
     123        osg::Vec3 normal(d.y()-c.y(), c.x()-d.x(), 0.0); 
     124        float cd_length = normal.normalize(); 
     125        if (cd_length==0) 
     126        { 
     127            //OSG_NOTICE<<"computeBisectorIntersector(["<<a<<"], ["<<b<<"], ["<<c<<"], ["<<d<<"], ["<<e<<"], ["<<f<<"[)"<<std::endl; 
     128            //OSG_NOTICE<<"   segment length==0, thickness = "<<FLT_MAX<<std::endl; 
     129            return FLT_MAX; 
     130        } 
     131 
     132        float thickness = (bisector_intersection - c) * normal; 
     133    #if 0 
     134        OSG_NOTICE<<"computeBisectorIntersector(["<<a<<"], ["<<b<<"], ["<<c<<"], ["<<d<<"], ["<<e<<"], ["<<f<<"[)"<<std::endl; 
     135        OSG_NOTICE<<"   bisector_abcd = "<<bisector_abcd<<", bisector_cdef="<<bisector_cdef<<std::endl; 
     136        OSG_NOTICE<<"   bisector_intersection = "<<bisector_intersection<<", thickness = "<<thickness<<std::endl; 
     137    #endif 
     138        return thickness; 
    157139    } 
    158140 
     
    266248 
    267249 
    268 float computeAngle(osg::Vec3& v1, osg::Vec3& v2, osg::Vec3& v3) 
    269 { 
    270     osg::Vec3 v12(v1-v2); 
    271     osg::Vec3 v32(v3-v2); 
    272     v12.normalize(); 
    273     v32.normalize(); 
    274     float dot = v12*v32; 
    275     float angle = acosf(dot); 
    276     return angle; 
    277 } 
    278  
    279 void computeBoundaryAngles(osg::Vec3Array& vertices, unsigned int start, unsigned int count) 
    280 { 
    281     //OSG_NOTICE<<"computeBoundaryAngles("<<vertices.size()<<", "<<start<<", "<<count<<")"<<std::endl; 
    282     if (vertices[start+count-1]==vertices[start]) 
    283     { 
    284         // OSG_NOTICE<<"is a line loop"<<std::endl; 
    285     } 
    286     else 
    287     { 
    288         OSG_NOTICE<<"is not line loop, ("<<vertices[start+count-1]<<"), ("<<vertices[start]<<")"<<std::endl; 
    289         return; 
    290     } 
    291  
    292     computeAngle(vertices[start+count-2],vertices[start],vertices[start+1]); 
    293     for(unsigned int i=start+1; i<start+count-1; ++i) 
    294     { 
    295         computeAngle(vertices[i-1],vertices[i],vertices[i+1]); 
    296     } 
    297     computeAngle(vertices[start+count-2],vertices[start],vertices[start+1]); 
    298 } 
    299  
    300 void computeBoundaryAngles(osg::Geometry* geometry) 
    301 { 
    302     OSG_NOTICE<<"computeBoundaryAngles("<<geometry<<")"<<std::endl; 
    303     osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); 
    304     osg::Geometry::PrimitiveSetList& primitives = geometry->getPrimitiveSetList(); 
    305     for(osg::Geometry::PrimitiveSetList::iterator itr = primitives.begin(); 
    306         itr != primitives.end(); 
    307         ++itr) 
    308     { 
    309         osg::DrawArrays* drawArray = dynamic_cast<osg::DrawArrays*>(itr->get()); 
    310         if (drawArray && drawArray->getMode()==GL_POLYGON) 
    311         { 
    312             computeBoundaryAngles(*vertices, drawArray->getFirst(), drawArray->getCount()); 
    313         } 
    314     } 
    315 } 
    316  
    317 osg::Vec3 computeNewVertexPosition(osg::Vec3& v1, osg::Vec3& v2, osg::Vec3& v3) 
    318 { 
    319     double angle = computeAngle(v1,v2,v3); 
    320     osg::Vec3 v21(v2-v1); 
    321     osg::Vec3 v32(v3-v2); 
    322     float length_21 = v21.normalize(); 
    323     float length_32 = v32.normalize(); 
    324  
    325     float t = 5.0; 
    326     if (length_21==0.0) 
    327     { 
    328         OSG_NOTICE<<"length_21=="<<length_21<<", length_32="<<length_32<<std::endl; 
    329         osg::Vec3 bisector = v32 ^ osg::Vec3(0.0f,0.0f,1.0f); 
    330         bisector.normalize(); 
    331         osg::Vec3 new_vertex = v2 + bisector * t; 
    332         return new_vertex; 
    333     } 
    334     else if (length_32==0.0) 
    335     { 
    336         OSG_NOTICE<<"length_21=="<<length_21<<", length_32="<<length_32<<std::endl; 
    337         osg::Vec3 bisector = v21 ^ osg::Vec3(0.0f,0.0f,1.0f); 
    338         bisector.normalize(); 
    339         osg::Vec3 new_vertex = v2 + bisector * t; 
    340         return new_vertex; 
    341     } 
    342  
    343     osg::Vec3 cross = v21^v32; 
    344     osg::Vec3 bisector(v32-v21); 
    345  
    346 #if 0 
    347     OSG_NOTICE<<"v1=["<<v1<<"], v2=["<<v2<<"], v3=["<<v3<<"], dot_angle="<<osg::RadiansToDegrees(angle)<<std::endl; 
    348     OSG_NOTICE<<"     computeIntersectionPoint() point "<<computeIntersectionPoint(v1,v2,v2,v3)<<std::endl; 
    349 #endif 
    350     // OSG_NOTICE<<"     computeBisectorNormal() normal "<<computeBisectorNormal(v1,v2,v2,v3)<<std::endl; 
    351      
    352     if (bisector.length()<0.5) 
    353     { 
    354         // angle wider than 90 degrees so use side vectors as guide for angle to project along. 
    355         osg::Vec3 s21 = v21 ^ osg::Vec3(0.0f,0.0f,1.0f); 
    356         s21.normalize(); 
    357  
    358         osg::Vec3 s32 = v32 ^ osg::Vec3(0.0f,0.0f,1.0f); 
    359         s32.normalize(); 
    360  
    361         osg::Vec3 bisector(s21+s32); 
    362         bisector.normalize(); 
    363  
    364          
    365         if ((computeBisectorNormal(v1,v2,v2,v3)-bisector).length2()>0.001) 
    366         { 
    367             OSG_NOTICE<<"     WARNING 1 bisector disagree "<<bisector<<", s21=["<<s21<<"], s32=["<<s32<<"]"<<std::endl; 
    368         } 
    369         else 
    370         { 
    371 #if 0 
    372             OSG_NOTICE<<"     bisector normal "<<bisector<<std::endl; 
    373 #endif 
    374         } 
    375  
    376         float l = t / sin(angle*0.5); 
    377  
    378         osg::Vec3 new_vertex = v2 + bisector * l; 
    379         new_vertex.z() += 0.5f; 
    380  
    381         return new_vertex; 
    382     } 
    383     else 
    384     { 
    385         float l = t / sin(angle*0.5); 
    386  
    387         bisector.normalize(); 
    388         if (cross.z()>0.0) bisector = -bisector; 
    389  
    390         if ((computeBisectorNormal(v1,v2,v2,v3)-bisector).length2()>0.001) 
    391         { 
    392             OSG_NOTICE<<"     WARNING 2 bisector disagree "<<bisector<<std::endl; 
    393         } 
    394         else 
    395         { 
    396 #if 0 
    397             OSG_NOTICE<<"     bisector normal "<<bisector<<std::endl; 
    398 #endif 
    399         } 
    400  
    401         osg::Vec3 new_vertex = v2 + bisector * l; 
    402         new_vertex.z() += 0.5f; 
    403         return new_vertex; 
    404     } 
    405 } 
    406  
    407 osg::DrawArrays* computeBevelEdge(osg::Vec3Array& orig_vertices, unsigned int start, unsigned int count, osg::Vec3Array& new_vertices) 
    408 { 
    409  
    410     // OSG_NOTICE<<"computeBevelEdge("<<orig_vertices.size()<<", "<<start<<", "<<count<<")"<<std::endl; 
    411     if (orig_vertices[start+count-1]==orig_vertices[start]) 
    412     { 
    413         // OSG_NOTICE<<"is a line loop"<<std::endl; 
    414     } 
    415     else 
    416     { 
    417         OSG_NOTICE<<"is not line loop, ("<<orig_vertices[start+count-1]<<"), ("<<orig_vertices[start]<<")"<<std::endl; 
    418         return new osg::DrawArrays(GL_POLYGON, start, count); 
    419     } 
    420  
    421     new_vertices[start] = computeNewVertexPosition(orig_vertices[start+count-2],orig_vertices[start],orig_vertices[start+1]); 
    422     for(unsigned int i=start+1; i<start+count-1; ++i) 
    423     { 
    424         new_vertices[i] = computeNewVertexPosition(orig_vertices[i-1],orig_vertices[i],orig_vertices[i+1]); 
    425     } 
    426     new_vertices[start+count-1] = computeNewVertexPosition(orig_vertices[start+count-2],orig_vertices[start],orig_vertices[start+1]); 
    427  
    428     return new osg::DrawArrays(GL_POLYGON, start, count); 
    429 } 
    430  
    431 void removeLoops(osg::Vec3Array& orig_vertices, unsigned int start, unsigned int count) 
    432 { 
    433 } 
    434  
    435 osg::Geometry* computeBevelEdge(osg::Geometry* orig_geometry) 
    436 { 
    437     // OSG_NOTICE<<"computeBoundaryAngles("<<orig_geometry<<")"<<std::endl; 
    438     osg::Vec3Array* orig_vertices = dynamic_cast<osg::Vec3Array*>(orig_geometry->getVertexArray()); 
    439     osg::Geometry::PrimitiveSetList& orig_primitives = orig_geometry->getPrimitiveSetList(); 
    440  
    441     osg::Geometry* new_geometry = new osg::Geometry; 
    442     osg::Vec3Array* new_vertices = new osg::Vec3Array(*orig_vertices); 
    443     osg::Geometry::PrimitiveSetList& new_primitives = new_geometry->getPrimitiveSetList(); 
    444     new_geometry->setVertexArray(new_vertices); 
    445     osg::Vec4Array* new_colours = new osg::Vec4Array; 
    446     new_colours->push_back(osg::Vec4(1.0,0.0,0.0,1.0)); 
    447     new_geometry->setColorArray(new_colours); 
    448     new_geometry->setColorBinding(osg::Geometry::BIND_OVERALL); 
    449  
    450     for(osg::Geometry::PrimitiveSetList::iterator itr = orig_primitives.begin(); 
    451         itr != orig_primitives.end(); 
    452         ++itr) 
    453     { 
    454         osg::DrawArrays* drawArray = dynamic_cast<osg::DrawArrays*>(itr->get()); 
    455         if (drawArray && drawArray->getMode()==GL_POLYGON) 
    456         { 
    457             osg::DrawArrays* new_drawArray = computeBevelEdge(*orig_vertices, drawArray->getFirst(), drawArray->getCount(), *new_vertices); 
    458             removeLoops(*new_vertices, new_drawArray->getFirst(), new_drawArray->getCount()); 
    459             new_primitives.push_back(new_drawArray); 
    460         } 
    461     } 
    462     return new_geometry; 
    463 } 
    464  
    465250osg::Geometry* computeThickness(osg::Geometry* orig_geometry, float thickness) 
    466251{ 
     
    525310    if (!font) return 1; 
    526311    OSG_NOTICE<<"Read font "<<fontFile<<" font="<<font.get()<<std::endl; 
    527  
    528     bool useOldBoundaryCalc = false; 
    529     while(arguments.read("--old")) useOldBoundaryCalc = true; 
    530312 
    531313    bool useTessellator = false; 
     
    562344        geometry->setColorBinding(osg::Geometry::BIND_OVERALL); 
    563345 
    564         osg::Geometry* bevel = 0; 
    565         if (useOldBoundaryCalc) 
    566         { 
    567             bevel = computeBevelEdge(geometry); 
    568        } 
    569         else 
    570         { 
    571             bevel = computeThickness(geometry, thickness); 
    572         } 
     346        osg::Geometry* bevel = computeThickness(geometry, thickness); 
    573347 
    574348        if (bevel) geode->addDrawable(bevel);