OpenSceneGraph: рдкреНрд▓рдЧрдЗрди рд╕рд┐рд╕реНрдЯрдо

рдЫрд╡рд┐

рдкрд░рд┐рдЪрдп


рдкрд┐рдЫрд▓реЗ рдкрд╛рдареЛрдВ рдореЗрдВ, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдУрдПрд╕рдЬреА рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдмрд┐рдЯрдореИрдк рдЫрд╡рд┐рдпрд╛рдВ, рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХреЗ 3 рдбреА рдореЙрдбрд▓, рдпрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд▓рдЧ-рдЗрди рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдлреЛрдВрдЯред рдУрдПрд╕рдЬреА рдкреНрд▓рдЧрдЗрди рдПрдХ рдЕрд▓рдЧ рдШрдЯрдХ рд╣реИ рдЬреЛ рдЗрдВрдЬрди рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдУрдПрд╕рдЬреА рдХреЗ рднреАрддрд░ рдорд╛рдирдХреАрдХреГрдд рд╣реИред рдкреНрд▓рдЧрдЗрди рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд╕рд╛рдЭрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп (рд╡рд┐рдВрдбреЛрдЬ рдкрд░ рд▓рд┐рдирдХреНрд╕, рдЗрддреНрдпрд╛рджрд┐ рдкрд░) рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдкреНрд▓рдЧрдЗрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рдирд╛рдо рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдореНрдореЗрд▓рди рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВ

osgdb_< >.dll 

рд╡рд╣ рд╣реИ, рдкреНрд▓рдЧрдЗрди рдирд╛рдо рдореЗрдВ рд╣рдореЗрд╢рд╛ osgdb_ рдЙрдкрд╕рд░реНрдЧ рд╣реЛрддрд╛ рд╣реИред рдПрдХ рдлрд╝рд╛рдЗрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЗрдВрдЬрди рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕ рдкреНрд▓рдЧ-рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рд╣рдо рдХреЛрдб рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрддреЗ рд╣реИрдВ

 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cessna.osg"); 

рдЗрдВрдЬрди osg рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рджреЗрдЦрддрд╛ рд╣реИ рдФрд░ Linux рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ osgdb_osg.dll (рдпрд╛ osgdb_osg.so) рдирд╛рдордХ рдПрдХ рдкреНрд▓рдЧрдЗрди рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИред рдкреНрд▓рдЧрдЗрди рдХреЛрдб рд╣рдореЗрдВ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдПрдХ рдиреЛрдб рдХреЛ рдкреЙрдЗрдВрдЯрд░ рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╕реЗрд╕рдирд╛ рдореЙрдбрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕реА рддрд░рд╣, рдПрдХ рдкреАрдПрдирдЬреА рдЫрд╡рд┐ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ

 osg::ref_ptr<osg:Image> image = osgDB::readImageFile("picture.png"); 

рдХрд╛рд░рдг osgdb_png.dll рдкреНрд▓рдЧрдЗрди рдХреЛ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ PNG рдЫрд╡рд┐ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдФрд░ рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рдкреНрд░рдХрд╛рд░ osg :: рдЫрд╡рд┐ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред

рдмрд╛рд╣рд░реА рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдкрд░ рд╕рднреА рдСрдкрд░реЗрд╢рди рдСрд╕реНрдмреАрдбреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд▓рд╛рдЗрдмреНрд░реЗрд░реА OSG рдкреНрд▓рдЧрдЗрди рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред рдЖрдЬ рддрдХ, рдУрдПрд╕рдЬреА рдкреИрдХреЗрдЬ рдореЗрдВ рдХрдИ рдкреНрд▓рдЧ-рдЗрди рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬреЛ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЫрд╡рд┐ рдкреНрд░рд╛рд░реВрдкреЛрдВ, 3 рдбреА рдореЙрдбрд▓ рдФрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдлреЛрдВрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдкреНрд▓рдЧрдЗрдиреНрд╕ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рд╛рд░реВрдк рдХреЗ рджреЛрдиреЛрдВ рд░реАрдбрд┐рдВрдЧ рдбреЗрдЯрд╛ (рдЖрдпрд╛рдд) рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рд╛рд░реВрдк (рдирд┐рд░реНрдпрд╛рдд) рдХреА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдбреЗрдЯрд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВред Osgconv рдЙрдкрдпреЛрдЧрд┐рддрд╛, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЖрдкрдХреЛ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдкреНрд░рд╛рд░реВрдк рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд▓рдЧ-рдЗрди рд╕рд┐рд╕реНрдЯрдоред

 $ osgconv cessna.osg cessna.3ds 

рдпрд╣ рдЖрд╕рд╛рдиреА рд╕реЗ рдФрд░ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╕реЗрд╕рдирд╛ рдУрдПрд╕рдЬреА рдореЙрдбрд▓ рдХреЛ 3 рдбреАрдПрд╕ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдмрд╛рдж рдореЗрдВ 3 рдбреА рд╕рдВрдкрд╛рджрдХ рдореЗрдВ рдЖрдпрд╛рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмреНрд▓реЗрдВрдбрд░ рдореЗрдВ (рд╡реИрд╕реЗ, рд╕реАрдзреЗ рдмреНрд▓реЗрдВрдбрд░ рдХреЗ рд▓рд┐рдП рдУрдПрд╕рдЬреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИ )



рдЙрдирдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдорд╛рдирдХ рдУрдПрд╕рдЬреА рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреА рдПрдХ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕реВрдЪреА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд▓рдВрдмрд╛ рд╣реИ рдФрд░ рдореИрдВ рдЗрд╕реЗ рдпрд╣рд╛рдВ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд▓рд╕реА рд╣реВрдВред рдмрд┐рди / ospPlugins-xyz рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рд╕реНрдерд╛рдкрдирд╛ рдкрде рдХреЛ рджреЗрдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдЬрд╣рд╛рдВ x, y, z OSG рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрдЦреНрдпрд╛ рд╣реИред рдкреНрд▓рдЧрдЗрди рдлрд╝рд╛рдЗрд▓ рдХреЗ рдирд╛рдо рд╕реЗ рдпрд╣ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИред

рдпрджрд┐ OSG рдХреЛ MinGW рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкреНрд▓рдЧрдЗрди рдХреЗ рдорд╛рдирдХ рдирд╛рдо рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЙрдкрд╕рд░реНрдЧ mingw_ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдирд╛рдо рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛

 mingw_osgdb_< >.dll 

DEBUG рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдкреНрд▓рдЧрдЗрди рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рдЕрддрд┐рд░рд┐рдХреНрдд рд░реВрдк рд╕реЗ рдирд╛рдо рдХреЗ рдЕрдВрдд рдореЗрдВ рдкреНрд░рддреНрдпрдп d рд╕реЗ рд╕реБрд╕рдЬреНрдЬрд┐рдд рд╣реИ, рдЕрд░реНрдерд╛рддреН рдкреНрд░рд╛рд░реВрдк рд╣реЛрдЧрд╛

 osgdb_< >d.dll 

рдпрд╛

 mingw_osgdb_< >d.dll 

рдЬрдм MinGW рдХреЛрдбрд╛рдВрддрд░рдгред

1. рдкреНрд▓рдЧрдЗрдиреНрд╕ рдЫрджреНрдо рд▓реЛрдбрд░


рдХреБрдЫ OSG рдкреНрд▓рдЧрдЗрдиреНрд╕ рддрдерд╛рдХрдерд┐рдд рдЫрджреНрдо рд▓реЛрдбрд░ рдХреЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВ - рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд╝рд╛рдЗрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реЗ рдмрдВрдзреЗ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдХреЗ рдЕрдВрдд рдореЗрдВ рдПрдХ рдкреНрд░рддреНрдпрдп рдЬреЛрдбрд╝рдХрд░, рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕ рдкреНрд▓рдЧ-рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП

 $ osgviewer worldmap.shp.ogr 

рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдбрд┐рд╕реНрдХ рдкрд░ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдирд╛рдо worldmap.shp рд╣реИ - рдпрд╣ рдлрд╝рд╛рдЗрд▓ ESRI рдЖрдХрд╛рд░ рд╕реНрд╡рд░реВрдк рдореЗрдВ рдПрдХ рд╡рд┐рд╢реНрд╡ рдорд╛рдирдЪрд┐рддреНрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреА рд╣реИред рдкреНрд░рддреНрдпрдп .ogr рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП osgdb_ogr рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП osgDB рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ; рдЕрдиреНрдпрдерд╛, osgdb_shp рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдПрдХ рдФрд░ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг osgdb_ffmpeg рдкреНрд▓рдЧрдЗрди рд╣реИред FFmpeg рд▓рд╛рдЗрдмреНрд░реЗрд░реА 100 рд╕реЗ рдЕрдзрд┐рдХ рд╡рд┐рднрд┐рдиреНрди рдХреЛрдбреЗрдХреНрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреА рд╣реИред рдЙрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреЛ рднреА рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдореАрдбрд┐рдпрд╛ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдирд╛рдо рдХреЗ рдмрд╛рдж рдХреЗрд╡рд▓ рдкреНрд░рддреНрдпрдп .ffmpeg рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреБрдЫ рдЫрджреНрдо рд▓реЛрдбрд░ рд╣рдореЗрдВ рдХрдИ рдкреНрд░рддреНрдпрдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧреБрдЬрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ рдЬреЛ рд▓реЛрдб рдХреА рдЧрдИ рд╡рд╕реНрддреБ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рдкрд╣рд▓реЗ рд╣реА рдПрдиреАрдореЗрд╢рди рдХреЗ рд╕рд╛рде рдПрдХ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЗрд╕рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ

 node = osgDB::readNodeFile("cessna.osg.0,0,90.rot"); 

рд▓рд╛рдЗрди 0.90 рд▓реЛрдб рдХрд┐рдП рдЧрдП рдореЙрдбрд▓ рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдСрд╕рдЧреНрдбрдмреЛрд╕ рдкреНрд▓рдЧ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдХреБрдЫ рдЫрджреНрдо рд▓реЛрдбрд░реЛрдВ рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

2. рддреГрддреАрдп-рдкрдХреНрд╖ рдкреНрд▓рдЧрдЗрдиреНрд╕ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдкреАрдЖрдИ


рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рддрд╛рд░реНрдХрд┐рдХ рд╣реИ, рдЕрдЧрд░ рд╕рднреА рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдерд╛ рдХрд┐ рдУрдПрд╕рдЬреА рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдкреНрд▓рдЧ-рдЗрди рд▓рд┐рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЬреЛ рдЖрдкрдХреЛ 3 рдбреА рдореЙрдбрд▓ рдпрд╛ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рдЧреИрд░-рдорд╛рдирдХ рдкреНрд░рд╛рд░реВрдк рдХреЛ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдФрд░ рдпрд╣ рдПрдХ рд╕рдЪреНрдЪреА рд╕реЛрдЪ рд╣реИ! рдкреНрд▓рдЧрдЗрди рддрдВрддреНрд░ рд╕рд┐рд░реНрдл OSG рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдЗрдВрдЬрди рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрдиреЗ рдХреЗ рдореВрд▓ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рдкреНрд▓рдЧрдЗрди рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдУрдПрд╕рдЬреА рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рд╡рд░реНрдЪреБрдЕрд▓ рд░реАрдб / рд░рд╛рдЗрдЯ рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ osgDB :: ReaderWriter рд╡рд░реНрдЪреБрдЕрд▓ рдХреНрд▓рд╛рд╕ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╣реИред рдпрд╣ рд╡рд░реНрдЧ рдкреНрд▓рдЧрдЗрди рдбреЗрд╡рд▓рдкрд░ рджреНрд╡рд╛рд░рд╛ рдкреБрди: рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрдИ рдЖрднрд╛рд╕реА рддрд░реАрдХреЗ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
рд╡рд┐рдзрд┐рд╡рд┐рд╡рд░рдг
рд╕рдорд░реНрдерди ()рдпрд╣ рджреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ: рдлрд╝рд╛рдЗрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдФрд░ рд╡рд┐рд╡рд░рдгред рд╡рд┐рдзрд┐ рдХреЛ рд╣рдореЗрд╢рд╛ рдЙрдкрд╡рд░реНрдЧ рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╕реНрд╡реАрдХрд╛рд░реНрдпрддрд╛ ()рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкреНрд▓рдЧрдЗрди рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╣реИ
fileExists ()рдЖрдкрдХреЛ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдбрд┐рд╕реНрдХ рдкрд░ рдХреЛрдИ рдлрд╝рд╛рдЗрд▓ рдореМрдЬреВрдж рд╣реИ (рдкрде рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)
readNode ()рдПрдХ рдСрд╕реНрдмреАрдбреА :: рд╡рд┐рдХрд▓реНрдк рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдФрд░ рд╡рд┐рдХрд▓реНрдк рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдбреЗрд╡рд▓рдкрд░ рджреНрд╡рд╛рд░рд╛ рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ
рд░рд╛рдЗрдЯрдСрдирдиреЛрдб рдирд╛рдо, рд╡рд╛рдВрдЫрд┐рдд рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдФрд░ рд╡рд┐рдХрд▓реНрдк рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдбрд┐рд╕реНрдХ рджреНрд╡рд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
readImage ()рдбрд┐рд╕реНрдХ рдмрд┐рдЯрдореИрдк рдбреЗрдЯрд╛ рдкрдврд╝рдирд╛
рд▓рд┐рдЦрдирд╛рдЗрдореЗрдЬ ()рдбрд┐рд╕реНрдХ рдкрд░ рдПрдХ рдмрд┐рдЯрдореИрдк рд▓рд┐рдЦрдирд╛

рд░реАрдбрдСрдиреЛрдб () рдкрджреНрдзрддрд┐ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

 osgDB::ReaderWriter::ReadResult readNode( const std::string &file, const osgDB::Options *options) const { //         bool recognizableExtension = ...; bool fileExists = ...; if (!recognizableExtension) return ReadResult::FILE_NOT_HANDLED; if (!fileExists) return ReadResult::FILE_NOT_FOUND; //          osg::Node *root = ...; //       -     . //    -      bool errorInParsing = ...; if (errorInParsing) return ReadResult::ERROR_IN_READING_FILE; return root; } 

рдпрд╣ рдереЛрдбрд╝рд╛ рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рд╣реИ рдХрд┐ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреЗ рдмрдЬрд╛рдп рджреГрд╢реНрдп рдЧреНрд░рд╛рдл рдХреЗ рдиреЛрдб рдХреЗ рд▓рд┐рдП, рд╡рд┐рдзрд┐ osgDB рдЯрд╛рдЗрдк рдХрд░рддреА рд╣реИ :: ReaderWriter :: ReadResultред рдпрд╣ рдкреНрд░рдХрд╛рд░ рдПрдХ рд░реАрдб рд░рд┐рдЬрд▓реНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдиреЛрдб рдХрдВрдЯреЗрдирд░, рдЗрдореЗрдЬ, рд╕реНрдЯреЗрдЯ рдПрдиреНрдпреВрдорд░реЗрдЯрд░ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, FILE_NOT_FOUND), рдПрдХ рдЕрдиреНрдп рд╡рд┐рд╢реЗрд╖ рдСрдмреНрдЬреЗрдХреНрдЯ, рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдирд┐рд╣рд┐рдд рдирд┐рд░реНрдорд╛рддрд╛ рд╣реИрдВред

рдПрдХ рдЕрдиреНрдп рдЙрдкрдпреЛрдЧреА рд╡рд░реНрдЧ osgDB :: рд╡рд┐рдХрд▓реНрдк рд╣реИред рдпрд╣ рдЖрдкрдХреЛ SetOptionString () рдФрд░ getOptionString () рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЛрдбрд┐рдВрдЧ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗрдЯ рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рднреА рдЕрдиреБрдорддрд┐ рд╣реИред

рдбреЗрд╡рд▓рдкрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рдкрд╛рд░рд┐рдд рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╕реЗрдЯ рдХрд░рдХреЗ рдкреНрд▓рдЧрдЗрди рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рд╕реЗ

 //    osg::Node* node1 = osgDB::readNodeFile("cow.osg"); //     string osg::Node* node2 = osgDB::readNodeFile("cow.osg", new osgDB::Options(string)); 

3. рдУрдПрд╕рдЬреА рдкреНрд▓рдЧрдЗрди рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг


рдмреЗрд╕ рдХреНрд▓рд╛рд╕ osgDB :: ReaderWriter рдореЗрдВ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ рдорд╛рдирдХ + ++ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрди рдкрдврд╝рдиреЗ / рд▓рд┐рдЦрдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдФрд░ рдКрдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдХреЗ рдмрдЬрд╛рдп, рд╡реЗ std :: istream рдФрд░ input st рд╕реНрдЯреНрд░реАрдо рдпрд╛ std :: ostream рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдлрд╝рд╛рдЗрд▓ I / O рд╕реНрдЯреНрд░реАрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрд╢рд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИред рдлрд╝рд╛рдЗрд▓ рд░реАрдб рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 osgDB::ReaderWriter::ReadResult readNode( const std::string &file, const osgDB::Options *options) const { ... osgDB::ifstream stream(file.c_str(), std::ios::binary); if (!stream) return ReadResult::ERROR_IN_READING_FILE; return readNode(stream, options); } ... osgDB::ReaderWriter::ReadResult readNode( std::istream &stream, const osgDB::Options *options) const { //         osg::Node *root = ...; return root; } 

рдкреНрд▓рдЧрдЗрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдорд╛рдирдХ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ osgDB :: readNodeFile () рдФрд░ osgDB :: readImageFile () рдореЙрдбрд▓ рдФрд░ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдлрд╝рд╛рдЗрд▓ рдкрде рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗред OSG рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рдкреНрд▓рдЧрдЗрди рдХреЛ рдЦреЛрдЬреЗрдЧрд╛ рдФрд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдЧрд╛ред

4. рд╣рдо рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрддреЗ рд╣реИрдВ



рдЗрд╕рд▓рд┐рдП, рдХреЛрдИ рднреА рд╣рдореЗрдВ рддреНрд░рд┐-рдЖрдпрд╛рдореА рдЬреНрдпрд╛рдорд┐рддрд┐ рдкрд░ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рд╛рд░реВрдк рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдЖрдПрдВрдЧреЗ

piramide.pmd

 vertex: 1.0 1.0 0.0 vertex: 1.0 -1.0 0.0 vertex: -1.0 -1.0 0.0 vertex: -1.0 1.0 0.0 vertex: 0.0 0.0 2.0 face: 0 1 2 3 face: 0 3 4 face: 1 0 4 face: 2 1 4 face: 3 2 4 

рдпрд╣рд╛рдБ рдлрд╝рд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЙрдирдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд╕рд╛рде рдХреЛрдиреЗ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред рд╡рд░реНрдЯреЗрдХреНрд╕ рдЗрдВрдбреЗрдХреНрд╕ рд╢реВрдиреНрдп рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░ рдХреНрд░рдо рдореЗрдВ рдЪрд▓рддреЗ рд╣реИрдВред рд╢реАрд░реНрд╖ рдХреА рд╕реВрдЪреА рдХреЗ рдмрд╛рдж рдЪреЗрд╣рд░реЗ рдХреА рд╕реВрдЪреА рдЖрддреА рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдЪреЗрд╣рд░реЗ рдХреЛ рд╡рд░реНрдЯреЗрдХреНрд╕ рдЗрдВрдбреЗрдХреНрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдпрд╣ рдмрдирддрд╛ рд╣реИред рдЬрд╛рд╣рд┐рд░ рд╣реИ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдХрд╛рд░реНрдп рдЗрд╕ рдлрд╛рдЗрд▓ рдХреЛ рдбрд┐рд╕реНрдХ рд╕реЗ рдкрдврд╝рдирд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рддреНрд░рд┐-рдЖрдпрд╛рдореА рдЬреНрдпрд╛рдорд┐рддрд┐ рдмрдирд╛рдирд╛ рд╣реИред

5. рдкреНрд▓рдЧрдЗрди рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗрдЯрдЕрдк: рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг


рдпрджрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рдЖрд╡реЗрджрди рдмрдирд╛рдП рдереЗ, рддреЛ рдЕрдм рд╣рдореЗрдВ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓рд┐рдЦрдирд╛ рд╣реИ, рдФрд░ рди рдХреЗрд╡рд▓ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп, рдмрд▓реНрдХрд┐ рдПрдХ OSG рдкреНрд▓рдЧ-рдЗрди рд╣реИ рдЬреЛ рдХреБрдЫ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред рд╣рдо рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрд┐рд▓реНрдб рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдЗрди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛

plugin.pro

 TEMPLATE = lib CONFIG += plugin CONFIG += no_plugin_name_prefix TARGET = osgdb_pmd win32-g++: TARGET = $$join(TARGET,,mingw_,) win32 { OSG_LIB_DIRECTORY = $$(OSG_BIN_PATH) OSG_INCLUDE_DIRECTORY = $$(OSG_INCLUDE_PATH) DESTDIR = $$(OSG_PLUGINS_PATH) CONFIG(debug, debug|release) { TARGET = $$join(TARGET,,,d) LIBS += -L$$OSG_LIB_DIRECTORY -losgd LIBS += -L$$OSG_LIB_DIRECTORY -losgViewerd LIBS += -L$$OSG_LIB_DIRECTORY -losgDBd LIBS += -L$$OSG_LIB_DIRECTORY -lOpenThreadsd LIBS += -L$$OSG_LIB_DIRECTORY -losgUtild } else { LIBS += -L$$OSG_LIB_DIRECTORY -losg LIBS += -L$$OSG_LIB_DIRECTORY -losgViewer LIBS += -L$$OSG_LIB_DIRECTORY -losgDB LIBS += -L$$OSG_LIB_DIRECTORY -lOpenThreads LIBS += -L$$OSG_LIB_DIRECTORY -losgUtil } INCLUDEPATH += $$OSG_INCLUDE_DIRECTORY } unix { DESTDIR = /usr/lib/osgPlugins-3.7.0 CONFIG(debug, debug|release) { TARGET = $$join(TARGET,,,d) LIBS += -losgd LIBS += -losgViewerd LIBS += -losgDBd LIBS += -lOpenThreadsd LIBS += -losgUtild } else { LIBS += -losg LIBS += -losgViewer LIBS += -losgDB LIBS += -lOpenThreads LIBS += -losgUtil } } INCLUDEPATH += ./include HEADERS += $$files(./include/*.h) SOURCES += $$files(./src/*.cpp) 

рд╣рдо рд╡реНрдпрдХреНрддрд┐рдЧрдд рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХрд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ

 TEMPLATE = lib 

рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗред * Nix рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╡рд░реНрдЬрди рдХреЗ рд╕рдВрдШрд░реНрд╖ рдХреЗ рдореБрджреНрджреЛрдВ рдХреА рдорджрдж рд╕реЗ рдкреНрд░рддреАрдХрд╛рддреНрдордХ рд▓рд┐рдВрдХ рдХреА рдкреАрдврд╝реА рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирд┐рд░реНрдорд╛рдг рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкреНрд▓рдЧ-рдЗрди рд╣реЛрдЧреА, рдпрд╛рдиреА рдпрд╣ "рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рд╣реЛ рдЬрд╛рдПрдЧреА" рдлреНрд▓рд╛рдИ рдкрд░ред

 CONFIG += plugin 

рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдЙрд╕ рдЙрдкрд╕рд░реНрдЧ рдХреА рдкреАрдврд╝реА рдХреЛ рдмрд╛рд╣рд░ рдХрд░ рджреЗрддреЗ рд╣реИрдВ, рдЬреЛ gcc рдкрд░рд┐рд╡рд╛рд░ рдХреЗ рд╕рдВрдХрд▓рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдЬреЛрдбрд╝реА рдЬрд╛рддреА рд╣реИ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рд░рдирдЯрд╛рдЗрдо рд╡рд╛рддрд╛рд╡рд░рдг рджреНрд╡рд╛рд░рд╛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред

 CONFIG += no_plugin_name_prefix 

рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рд╕реЗрдЯ рдХрд░реЗрдВ

 TARGET = osgdb_pmd 

рдЬрд╣рд╛рдБ pmd 3 рдбреА рдореЙрдбрд▓ рдкреНрд░рд╛рд░реВрдк рдХрд╛ рдлрд╝рд╛рдЗрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд╣рдордиреЗ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ рдерд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд╕рдВрдХреЗрдд рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдорд┐рдЧрд╡ рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЙрдкрд╕рд░реНрдЧ mingw_

 win32-g++: TARGET = $$join(TARGET,,mingw_,) 

рд▓рд╛рдпрдмреНрд░реЗрд░реА рдмрд┐рд▓реНрдб рдкрде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ: Windows рдХреЗ рд▓рд┐рдП

 DESTDIR = $$(OSG_PLUGINS_PATH) 

linux рдХреЗ рд▓рд┐рдП

 DESTDIR = /usr/lib/osgPlugins-3.7.0 

рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП, рдкрде рдХреЗ рдРрд╕реЗ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде (рдЬреЛ рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рдПрдХ рдмреИрд╕рд╛рдЦреА рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЕрднреА рддрдХ рдПрдХ рдФрд░ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ) рд╣рдо рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдУрдПрд╕рдЬреА рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рджреЗрддреЗ рд╣реИрдВ

 # chmod 666 /usr/lib/osgPlugins-3.7.0 

рдЕрдиреНрдп рд╕рднреА рдмрд┐рд▓реНрдб рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдкрд╣рд▓реЗ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдирдореВрдирд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рд╕рдорд╛рди рд╣реИрдВред

6. рдкреНрд▓рдЧрдЗрди рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗрдЯрдЕрдк: рдбрд┐рдмрдЧ рдореЛрдб рд╕реБрд╡рд┐рдзрд╛рдПрдБ


рдЪреВрдВрдХрд┐ рдпрд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдРрд╕рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЗрд╕рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХреЛрдИ рднреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдУрдПрд╕рдЬреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЬрд┐рд╕рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛

 node = osdDB::readNodeFile("piramide.pmd"); 

рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдорд╛рд░рд╛ рдкреНрд▓рдЧрдЗрди рд▓реЛрдб рд╣реЛрдЧрд╛ред рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рд╕реНрд╡рдпрдВ рдирд╣реАрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ - рдорд╛рдирдХ рдСрдЧреНрдЧреАрд╡рд┐рдЕрд░ рджрд░реНрд╢рдХ, рдЬреЛ рдЗрдВрдЬрди рдХреЗ рд╡рд┐рддрд░рдг рдкреИрдХреЗрдЬ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИред рдпрджрд┐ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд

 $ osgviewer piramide.pmd 

рддрдм рдпрд╣ рдкреНрд▓рдЧрдЗрди рдХреЛ рднреА рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ред рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд▓реЙрдиреНрдЪ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ, рдХрд╛рд░реНрдп рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдСрд╕рдЧреНрд╡рд┐рдПрд░рдб рдХреЗ рд▓рд┐рдП рдкрде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ, рдЙрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ рдкреАрд░рдбрд╛рдорд╛рдЗрдбредрдкреАрдПрдордбреА рдлрд╝рд╛рдЗрд▓ рд╕реНрдерд┐рдд рд╣реИ, рдФрд░ рдСрд╕реНрдЧреНрд╡рд┐рд╢рд░ рдХрдорд╛рдВрдб-рд▓рд╛рдЗрди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рдЙрд╕реА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ



рдЕрдм рд╣рдо рдкреНрд▓рдЧрдЗрди рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕реАрдзреЗ QtCreator IDE рд╕реЗ рдбрд┐рдмрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

6. рд╣рдо рдкреНрд▓рдЧрдЗрди рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ


рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдХреБрдЫ рд╣рдж рддрдХ рдЙрд╕ рдЬреНрдЮрд╛рди рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╣рдордиреЗ рдкрд┐рдЫрд▓реЗ рдкрд╛рдареЛрдВ рд╕реЗ рдУрдПрд╕рдЬреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рд╣реИред рдПрдХ рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрддреЗ рд╕рдордп, рд╣рдореЗрдВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛

  1. рдореЙрдбрд▓ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдкрдврд╝реА рдЧрдИ рдореЙрдбрд▓ рдЬреНрдпрд╛рдорд┐рддрд┐ рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ
  2. рдореЙрдбрд▓ рдбреЗрдЯрд╛ рдлрд╝рд╛рдЗрд▓ рдкрдврд╝реЗрдВ рдФрд░ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВ
  3. рд╕рд╣реА рдврдВрдЧ рд╕реЗ osg :: рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдкрдврд╝реЗ рдЧрдП рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдбреНрд░рд╛ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдЬреНрдпрд╛рдорд┐рддреАрдп рд╡рд╕реНрддреБ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
  4. рд▓реЛрдбреЗрдб рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рджреГрд╢реНрдп рд╕рдмрдЧреНрд░рд╛рдл рдмрдирд╛рдПрдБ

рдЗрд╕рд▓рд┐рдП, рдкрд░рдВрдкрд░рд╛ рд╕реЗ, рдореИрдВ рдкреНрд▓рдЧрдЗрди рдХрд╛ рд╕рдВрдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рджреВрдВрдЧрд╛

Osgdb_pmd рдкреНрд▓рдЧрдЗрди
main.h

 #ifndef MAIN_H #define MAIN_H #include <osg/Geometry> #include <osg/Geode> #include <osgDB/FileNameUtils> #include <osgDB/FileUtils> #include <osgDB/Registry> #include <osgUtil/SmoothingVisitor> //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ struct face_t { std::vector<unsigned int> indices; }; //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ struct pmd_mesh_t { osg::ref_ptr<osg::Vec3Array> vertices; osg::ref_ptr<osg::Vec3Array> normals; std::vector<face_t> faces; pmd_mesh_t() : vertices(new osg::Vec3Array) , normals(new osg::Vec3Array) { } osg::Vec3 calcFaceNormal(const face_t &face) const { osg::Vec3 v0 = (*vertices)[face.indices[0]]; osg::Vec3 v1 = (*vertices)[face.indices[1]]; osg::Vec3 v2 = (*vertices)[face.indices[2]]; osg::Vec3 n = (v1 - v0) ^ (v2 - v0); return n * (1 / n.length()); } }; //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ class ReaderWriterPMD : public osgDB::ReaderWriter { public: ReaderWriterPMD(); virtual ReadResult readNode(const std::string &filename, const osgDB::Options *options) const; virtual ReadResult readNode(std::istream &stream, const osgDB::Options *options) const; private: pmd_mesh_t parsePMD(std::istream &stream) const; std::vector<std::string> parseLine(const std::string &line) const; }; #endif 

main.cpp

 #include "main.h" //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ ReaderWriterPMD::ReaderWriterPMD() { supportsExtension("pmd", "PMD model file"); } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ osgDB::ReaderWriter::ReadResult ReaderWriterPMD::readNode( const std::string &filename, const osgDB::Options *options) const { std::string ext = osgDB::getLowerCaseFileExtension(filename); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile(filename, options); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; std::ifstream stream(fileName.c_str(), std::ios::in); if (!stream) return ReadResult::ERROR_IN_READING_FILE; return readNode(stream, options); } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ osgDB::ReaderWriter::ReadResult ReaderWriterPMD::readNode( std::istream &stream, const osgDB::Options *options) const { (void) options; pmd_mesh_t mesh = parsePMD(stream); osg::ref_ptr<osg::Geometry> geom = new osg::Geometry; geom->setVertexArray(mesh.vertices.get()); for (size_t i = 0; i < mesh.faces.size(); ++i) { osg::ref_ptr<osg::DrawElementsUInt> polygon = new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0); for (size_t j = 0; j < mesh.faces[i].indices.size(); ++j) polygon->push_back(mesh.faces[i].indices[j]); geom->addPrimitiveSet(polygon.get()); } geom->setNormalArray(mesh.normals.get()); geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET); osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable(geom.get()); return geode.release(); } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ pmd_mesh_t ReaderWriterPMD::parsePMD(std::istream &stream) const { pmd_mesh_t mesh; while (!stream.eof()) { std::string line; std::getline(stream, line); std::vector<std::string> tokens = parseLine(line); if (tokens[0] == "vertex") { osg::Vec3 point; std::istringstream iss(tokens[1]); iss >> point.x() >> point.y() >> point.z(); mesh.vertices->push_back(point); } if (tokens[0] == "face") { unsigned int idx = 0; std::istringstream iss(tokens[1]); face_t face; while (!iss.eof()) { iss >> idx; face.indices.push_back(idx); } mesh.faces.push_back(face); mesh.normals->push_back(mesh.calcFaceNormal(face)); } } return mesh; } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ std::string delete_symbol(const std::string &str, char symbol) { std::string tmp = str; tmp.erase(std::remove(tmp.begin(), tmp.end(), symbol), tmp.end()); return tmp; } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ std::vector<std::string> ReaderWriterPMD::parseLine(const std::string &line) const { std::vector<std::string> tokens; std::string tmp = delete_symbol(line, '\r'); size_t pos = 0; std::string token; while ( (pos = tmp.find(':')) != std::string::npos ) { token = tmp.substr(0, pos); tmp.erase(0, pos + 1); if (!token.empty()) tokens.push_back(token); } tokens.push_back(tmp); return tokens; } REGISTER_OSGPLUGIN( pmd, ReaderWriterPMD ) 


рдкрд╣рд▓реЗ, рдЪрд▓реЛ рдЬреНрдпрд╛рдорд┐рддрд┐ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдзреНрдпрд╛рди рд░рдЦреЗрдВред

 struct face_t { std::vector<unsigned int> indices; }; 

- рдЗрд╕ рдЪреЗрд╣рд░реЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдиреЗ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреА рд╕реВрдЪреА рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЪреЗрд╣рд░реЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдПрдХ рдкреВрд░реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдореЙрдбрд▓ рдХреЛ рдРрд╕реА рд╕рдВрд░рдЪрдирд╛ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛

 struct pmd_mesh_t { osg::ref_ptr<osg::Vec3Array> vertices; osg::ref_ptr<osg::Vec3Array> normals; std::vector<face_t> faces; pmd_mesh_t() : vertices(new osg::Vec3Array) , normals(new osg::Vec3Array) { } osg::Vec3 calcFaceNormal(const face_t &face) const { osg::Vec3 v0 = (*vertices)[face.indices[0]]; osg::Vec3 v1 = (*vertices)[face.indices[1]]; osg::Vec3 v2 = (*vertices)[face.indices[2]]; osg::Vec3 n = (v1 - v0) ^ (v2 - v0); return n * (1 / n.length()); } }; 

рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдп рдЪрд░ рд╣реЛрддреЗ рд╣реИрдВ: рд░реЗрдЦрд╛рдВрдХрди - рдПрдХ рдЬреНрдпрд╛рдорд┐рддреАрдп рд╡рд╕реНрддреБ рдХреЗ рдХреЛрдиреЗ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЗ рднрдВрдбрд╛рд░рдг рдХреЗ рд▓рд┐рдП; рдорд╛рдирджрдВрдб - рд╡рд╕реНрддреБ рдХреЗ рдЪреЗрд╣рд░реЛрдВ рдХреЛ рдорд╛рдирджрдВрдбреЛрдВ рдХрд╛ рдПрдХ рд╕рд░рдгреА; рдЪреЗрд╣рд░реЗ - рд╡рд╕реНрддреБ рдХреЗ рдЪреЗрд╣рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреАред рд╕рдВрд░рдЪрдирд╛ рдирд┐рд░реНрдорд╛рддрд╛ рддреБрд░рдВрдд рд╕реНрдорд╛рд░реНрдЯ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддрд╛ рд╣реИ

 pmd_mesh_t() : vertices(new osg::Vec3Array) , normals(new osg::Vec3Array) { } 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд╡реЗрдХреНрдЯрд░ рдХреА рдЧрдгрдирд╛ рдЪреЗрд╣рд░реЗ рдХреЗ рдХреИрд▓реНрд╕реЗрдлреЗрдиреЙрд░реНрдорд▓ () рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░рддреА рд╣реИ рдЬреЛ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЪреЗрд╣рд░реЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рд╣рдо рдЕрднреА рддрдХ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдПрдВрдЧреЗ, рд╣рдо рдереЛрдбрд╝рд╛ рдмрд╛рдж рдореЗрдВ рдЙрдирдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рдЙрди рд╕рдВрд░рдЪрдирд╛рдУрдВ рдкрд░ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЬреНрдпрд╛рдорд┐рддрд┐ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗред рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдкреНрд▓рдЧрдЗрди рдХреЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рд╣реИ, рд╣рдо рдСрд╕реНрдмреАрдбреА :: рд░реАрдбрд░рд╡рд░реНрдЯрд░ рдЗрдирд╣реЗрд░рд┐рдЯрд░ рдХреНрд▓рд╛рд╕ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ

 class ReaderWriterPMD : public osgDB::ReaderWriter { public: ReaderWriterPMD(); virtual ReadResult readNode(const std::string &filename, const osgDB::Options *options) const; virtual ReadResult readNode(std::istream &stream, const osgDB::Options *options) const; private: pmd_mesh_t parsePMD(std::istream &stream) const; std::vector<std::string> parseLine(const std::string &line) const; }; 

рдЬреИрд╕рд╛ рдХрд┐ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдПрдкреАрдЖрдИ рдХреЗ рд╡рд░реНрдгрди рдореЗрдВ рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЧрдИ рд╣реИ, рдЗрд╕ рд╡рд░реНрдЧ рдореЗрдВ рд╣рдо рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдФрд░ рдЗрд╕реЗ рджреГрд╢реНрдп рдХреЗ рд╕рдмрдЧреНрд░рд╛рдл рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд░реАрдбрдСрдиреЛрдб () рд╡рд┐рдзрд┐ рджреЛ рдЕрдзрд┐рднрд╛рд░ рдХрд░рддрд╛ рд╣реИ - рдПрдХ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдХреЛ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рджреВрд╕рд░рд╛ рдорд╛рдирдХ рдЗрдирдкреБрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдХреНрд▓рд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдкреНрд▓рдЧрдЗрди рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдлрд╝рд╛рдЗрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ

 ReaderWriterPMD::ReaderWriterPMD() { supportsExtension("pmd", "PMD model file"); } 

рд░реАрдбрдСрди рдХрд╛ рдкрд╣рд▓рд╛ рдЕрдзрд┐рднрд╛рд░ () рд╡рд┐рдзрд┐ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдФрд░ рдЙрд╕рдХреЗ рд▓рд┐рдП рдкрде рдХреА рд╢реБрджреНрдзрддрд╛ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреА рд╣реИ, рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдорд╛рдирдХ рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЛ рдЬреЛрдбрд╝рддреА рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдЕрдзрд┐рднрд╛рд░ рдХрд╣рддрд╛ рд╣реИ, рдЬреЛ рдореБрдЦреНрдп рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

 osgDB::ReaderWriter::ReadResult ReaderWriterPMD::readNode( const std::string &filename, const osgDB::Options *options) const { //       std::string ext = osgDB::getLowerCaseFileExtension(filename); // ,      if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; // ,       std::string fileName = osgDB::findDataFile(filename, options); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; //      std::ifstream stream(fileName.c_str(), std::ios::in); if (!stream) return ReadResult::ERROR_IN_READING_FILE; //      readNode() return readNode(stream, options); } 

рджреВрд╕рд░реЗ рдЕрдзрд┐рднрд╛рд░ рдореЗрдВ, рд╣рдо OSG рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдЬреЗрдирд░реЗрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рдердо рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ

 osgDB::ReaderWriter::ReadResult ReaderWriterPMD::readNode( std::istream &stream, const osgDB::Options *options) const { (void) options; //   *.pmd       pmd_mesh_t mesh = parsePMD(stream); //    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry; //    geom->setVertexArray(mesh.vertices.get()); //    for (size_t i = 0; i < mesh.faces.size(); ++i) { //    GL_POLYGON      (  - 0) osg::ref_ptr<osg::DrawElementsUInt> polygon = new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0); //       for (size_t j = 0; j < mesh.faces[i].indices.size(); ++j) polygon->push_back(mesh.faces[i].indices[j]); //     geom->addPrimitiveSet(polygon.get()); } //    geom->setNormalArray(mesh.normals.get()); //  OpenGL,       geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET); //             osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable(geom.get()); //     return geode.release(); } 

Main.cpp рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ, REGISTER_OSGPLUGIN () рдореИрдХреНрд░реЛ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред

 REGISTER_OSGPLUGIN( pmd, ReaderWriterPMD ) 

рдпрд╣ рдореИрдХреНрд░реЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдУрдПрд╕рдЬреА рдХреЛ рдСрд╕реНрдмреАрдбреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд░реВрдк рдореЗрдВ, рд░реАрдбрд╡рд░реНрдЯрд░рдкреАрдПрдордбреА рдкреНрд░рдХрд╛рд░ рдХреА рдПрдХ рд╡рд╕реНрддреБ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЯрд╛рдЗрдк рдкреАрдПрдордбреА рдХреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреНрд▓рдЧрдЗрди рд░реВрдкрд░реЗрдЦрд╛ рддреИрдпрд╛рд░ рд╣реИ, рдмрд╛рдд рдЫреЛрдЯреА рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ - рд▓реЛрдбрд┐рдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдФрд░ рдкреАрдбреАрдПрдлрд╝ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

7. рдкрд╛рд░рд╕рд┐рдо 3 рдбреА рдореЙрдбрд▓ рдлрд╝рд╛рдЗрд▓


рдЕрдм рдкреНрд▓рдЧрдЗрди рдХреА рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ parsePMD () рд╡рд┐рдзрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдЯрд┐рдХреА рд╣реБрдИ рд╣реИ

 pmd_mesh_t ReaderWriterPMD::parsePMD(std::istream &stream) const { pmd_mesh_t mesh; //    while (!stream.eof()) { //      std::string line; std::getline(stream, line); //     -     std::vector<std::string> tokens = parseLine(line); //    -  if (tokens[0] == "vertex") { //       osg::Vec3 point; std::istringstream iss(tokens[1]); iss >> point.x() >> point.y() >> point.z(); //      mesh.vertices->push_back(point); } //    -  if (tokens[0] == "face") { //         unsigned int idx = 0; std::istringstream iss(tokens[1]); face_t face; while (!iss.eof()) { iss >> idx; face.indices.push_back(idx); } //      mesh.faces.push_back(face); //     mesh.normals->push_back(mesh.calcFaceNormal(face)); } } return mesh; } 

ParseLine () рдореЗрдердб рдлрд╝рд╛рдЗрд▓ рдХреА рдкрд╛рд░реНрд╕ рд▓рд╛рдЗрди

 std::vector<std::string> ReaderWriterPMD::parseLine(const std::string &line) const { std::vector<std::string> tokens; //   ,        ( Windows) std::string tmp = delete_symbol(line, '\r'); size_t pos = 0; std::string token; //      ,     : //      while ( (pos = tmp.find(':')) != std::string::npos ) { //     (vertex  face   ) token = tmp.substr(0, pos); //         tmp.erase(0, pos + 1); if (!token.empty()) tokens.push_back(token); } //        tokens.push_back(tmp); return tokens; } 

рдпрд╣ рд╡рд┐рдзрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ "рд╡рд░реНрдЯреЗрдХреНрд╕: 1.0 -1.0 0.0" рдХреЛ рджреЛ рд▓рд╛рдЗрдиреЛрдВ "рд╡рд░реНрдЯреЗрдХреНрд╕" рдФрд░ "1.0 -1.0 0.0" рдХреА рд╕реВрдЪреА рдореЗрдВ рдмрджрд▓ рджреЗрдЧреАред рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдкрд░ рд╣рдо рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рддреЗ рд╣реИрдВ - рд╢реАрд░реНрд╖ рдпрд╛ рдЪреЗрд╣рд░рд╛, рджреВрд╕рд░реА рд╕реЗ рд╣рдо рдбреЗрдЯрд╛ рдХреЛ рд╡рд░реНрдЯреЗрдХреНрд╕ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдкрд░ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВред рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди delete_symbol () рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рджрд┐рдП рдЧрдП рд╡рд░реНрдг рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рд╡рд░реНрдг рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ

 std::string delete_symbol(const std::string &str, char symbol) { std::string tmp = str; tmp.erase(std::remove(tmp.begin(), tmp.end(), symbol), tmp.end()); return tmp; } 

рдпрд╣реА рд╣реИ, рдЕрдм рд╣рдордиреЗ рдЕрдкрдиреЗ рдкреНрд▓рдЧрдЗрди рдХреА рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

8. рдкреНрд▓рдЧрдЗрди рдХрд╛ рдкрд░реАрдХреНрд╖рдг


рд╣рдо рдкреНрд▓рдЧрдЗрди рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдбреАрдмрдЧрд┐рдВрдЧ (F5) рдЪрд▓рд╛рддреЗ рд╣реИрдВред рдорд╛рдирдХ osgviewerd рджрд░реНрд╢рдХ рдХрд╛ рдПрдХ рдбреАрдмрдЧ рд╕рдВрд╕реНрдХрд░рдг рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдЗрд╕рдХреЗ рдкрд╛рд╕ рджрд┐рдП рдЧрдП рдкрд╛рдЗрд░рд╛рдорд╛рдЗрдб.рдкреАрдПрдордбреА рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдЧрд╛, рд╣рдорд╛рд░реЗ рдкреНрд▓рдЧрдЗрди рдХреЛ рд▓реЛрдб рдХрд░реЗрдЧрд╛ рдФрд░ рдЗрд╕рдХреЗ рд░реАрдбрдСрди () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рд╣рдордиреЗ рд╕рдм рдХреБрдЫ рдареАрдХ рдХрд┐рдпрд╛, рддреЛ рд╣рдореЗрдВ рдРрд╕рд╛ рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓реЗрдЧрд╛ред



рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ 3 рдбреА рдореЙрдбрд▓ рдХреА рд╣рдорд╛рд░реА рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХреА рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдиреЗ рдФрд░ рдЪреЗрд╣рд░реЗ рдХреА рд╕реВрдЪреА рдиреЗ рдПрдХ рдЪрддреБрд╖реНрдХреЛрдгреАрдп рдкрд┐рд░рд╛рдорд┐рдб рдЫрд┐рдкрд╛рдпрд╛ рд╣реИред

рд╣рдордиреЗ рдЦреБрдж рдорд╛рдирджрдВрдбреЛрдВ рдХреА рдЧрдгрдирд╛ рдХреНрдпреЛрдВ рдХреА? рдкрд╛рдареЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ, рд╣рдореЗрдВ рд╕реНрдореВрде рдорд╛рдирджрдВрдбреЛрдВ рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЧрдгрдирд╛ рдХреА рдирд┐рдореНрди рд╡рд┐рдзрд┐ рдХреА рдкреЗрд╢рдХрд╢ рдХреА рдЧрдИ рдереА

 osgUtil::SmoothingVisitor::smooth(*geom); 

рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдорд╛рдирджрдВрдбреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ

 //geom->setNormalArray(mesh.normals.get()); //geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET); osgUtil::SmoothingVisitor::smooth(*geom); 

рдФрд░ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рддреЗ рд╣реИрдВред



рдорд╛рдирджрдВрдб рдореЙрдбрд▓ рдХреА рдкреНрд░рдХрд╛рд╢ рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреА рдЧрдгрдирд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЪрд┐рдХрдиреЗ рдорд╛рдирджрдВрдб рдкрд┐рд░рд╛рдорд┐рдб рдХреА рдкреНрд░рдХрд╛рд╢ рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреА рдЧрдгрдирд╛ рдХреЗ рдЧрд▓рдд рдкрд░рд┐рдгрд╛рдо рджреЗрддреЗ рд╣реИрдВред рдпрд╣ рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ рд╣реИ рдХрд┐ рд╣рдордиреЗ рдЕрдкрдиреА рдмрд╛рдЗрдХ рдХреЛ рдорд╛рдирджрдВрдбреЛрдВ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЛ рд╕рдордЭрд╛рдирд╛ рдЗрд╕ рдкрд╛рда рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИред

Source: https://habr.com/ru/post/hi438296/


All Articles