hi lucie,
here is something with geometry shaders ... might get you inspired
-Nick
On Wed, Dec 22, 2010 at 6:42 PM, lucie lemonnier
<[email protected]>wrote:
> Hi,
>
> I want to draw a 3D curved pipe from a list of points.
> I looked at osgModeling but I don't know how to do this.
> Would you have an idea using osgModeling or something else?
>
> Thank you!
>
> Cheers,
> lucie
>
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=35083#35083
>
>
>
>
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
#include <osg/Notify>
#include <osg/ref_ptr>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Program>
#include <osg/Shader>
#include <osg/Uniform>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/StateSetManipulator>
///////////////////////////////////////////////////////////////////////////
static const char* vertSource = {
"void main(void) \n"
"{ \n"
" gl_Position = gl_Vertex; \n"
" gl_FrontColor = gl_Color; \n"
"} \n"
};
static const char* geomSource = {
"#version 120 \n"
"#extension GL_EXT_geometry_shader4 : enable \n"
"uniform int numCylinderSegments; \n"
"uniform float cylinderRadius; \n"
"vec3 rotateVec3(vec4 q,vec3 v) \n"
"{ \n"
" vec3 uv, uuv; \n"
" vec3 qvec = vec3(q.x, q.y, q.z); \n"
" uv = cross(qvec,v); \n"
" uuv = cross(qvec,uv); \n"
" uv *= ( 2.0 * q.w ); \n"
" uuv *= 2.0; \n"
" return v + uv + uuv; \n"
"} \n"
"void main(void) \n"
"{ \n"
" { \n"
" vec4 q1 = gl_FrontColorIn[0]; \n"
" vec4 p1 = gl_PositionIn[0]; \n"
" vec4 p2 = gl_PositionIn[1]; \n"
" vec4 q2 = gl_FrontColorIn[1]; \n"
" { \n"
" for (int i=0; i<=numCylinderSegments; ++i) \n"
" { \n"
" float a = 3.14159265358979323846*2.0 / float(numCylinderSegments); \n"
" \n"
" float x = cos(a*float(i))*cylinderRadius; \n"
" float y = sin(a*float(i))*cylinderRadius; \n"
" float z = 0.0; \n"
" \n"
" float clr = cos(a*float(i)+1.57079632679489661923); \n"
" vec3 vx = vec3(x,y,z); \n"
" \n"
" gl_Position = gl_ModelViewProjectionMatrix * vec4(rotateVec3(q2,vx)+p2.xyz,1.0);\n"
" gl_FrontColor = vec4(clr,clr,clr,1.0); \n"
" EmitVertex(); \n"
" \n"
" gl_Position = gl_ModelViewProjectionMatrix * vec4(rotateVec3(q1,vx)+p1.xyz,1.0);\n"
" gl_FrontColor = vec4(clr,clr,clr,1.0); \n"
" EmitVertex(); \n"
" } \n"
" EndPrimitive(); \n"
" } \n"
" } \n"
"} \n"
};
static const char* fragSource = {
"void main(void) \n"
"{ \n"
" gl_FragColor = gl_Color; \n"
"} \n"
};
///////////////////////////////////////////////////////////////////////////
osg::Program* createShader(int numVxs)
{
osg::Program* pgm = new osg::Program;
pgm->setName( "osgshader2 demo" );
pgm->addShader( new osg::Shader( osg::Shader::VERTEX, vertSource ) );
pgm->addShader( new osg::Shader( osg::Shader::FRAGMENT, fragSource ) );
pgm->addShader( new osg::Shader( osg::Shader::GEOMETRY, geomSource ) );
pgm->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, numVxs );
pgm->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, GL_LINES );
pgm->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP );
return pgm;
}
///////////////////////////////////////////////////////////////////////////
class CatMullRomCurve : public osg::Geometry
{
public:
CatMullRomCurve(int numCurveSegments = 100, int numCylinderSegments = 35,float cylinderRadius = 0.035f)
{
std::vector<osg::Vec3> vxs;
vxs.push_back( osg::Vec3(0,0,0) );
vxs.push_back( osg::Vec3(1,1,0) );
vxs.push_back( osg::Vec3(0.5,0.5,0.5) );
vxs.push_back( osg::Vec3(1.0,1.0,1.0) );
vxs.push_back( osg::Vec3(1.5,1.5,0.5) );
osg::Vec3Array* vAry = new osg::Vec3Array;
setVertexArray( vAry );
osg::Vec4Array* quatsIncolorArray = new osg::Vec4Array;
setColorArray(quatsIncolorArray);
setColorBinding(BIND_PER_VERTEX);
for (unsigned int i=0; i<vxs.size()-1; ++i)
{
int idx0 = i>0?i-1:0;
int idx1 = i;
int idx2 = i+1;
int idx3 = idx2<(int)vxs.size()-1?idx2+1:idx2;
osg::Vec3 p0 = vxs.at(idx0);
osg::Vec3 p1 = vxs.at(idx1);
osg::Vec3 p2 = vxs.at(idx2);
osg::Vec3 p3 = vxs.at(idx3);
for (int j=0; j<numCurveSegments; ++j)
{
float t = float(j)/numCurveSegments;
osg::Vec3 v =((p1*2.0)+(-p0+p2)*t+((p0*2.0)-(p1*5.0)+(p2*4.0)-p3)*t*t+(-p0+(p1*3.0)-(p2*3.0)+p3)*t*t*t) * 0.5;
vAry->push_back(v);
if (vAry->size() % 2 == 0)
{
osg::Vec3 p0 = vAry->at(vAry->size()-2);
osg::Vec3 p1 = vAry->at(vAry->size()-1);
osg::Vec3 n = p1-p0;
n.normalize();
osg::Quat q;
q.makeRotate(osg::Vec3(0,0,1),n);
quatsIncolorArray->push_back(osg::Vec4(q.x(),q.y(),q.z(),q.w()));
if (quatsIncolorArray->size() > 1)
{
quatsIncolorArray->push_back(osg::Vec4(q.x(),q.y(),q.z(),q.w()));
}
}
if (vAry->size()>1)
{
vAry->push_back(v);
}
}
}
vAry->push_back(vxs.back());
osg::Vec3 p0 = vAry->at(vAry->size()-2);
osg::Vec3 p1 = vAry->at(vAry->size()-1);
osg::Vec3 n = p1-p0;
n.normalize();
osg::Quat q;
q.makeRotate(osg::Vec3(0,0,1),n);
quatsIncolorArray->push_back(osg::Vec4(q.x(),q.y(),q.z(),q.w()));
quatsIncolorArray->push_back(osg::Vec4(q.x(),q.y(),q.z(),q.w()));
quatsIncolorArray->push_back(osg::Vec4(q.x(),q.y(),q.z(),q.w()));
addPrimitiveSet( new osg::DrawArrays( GL_LINES, 0, vAry->size() ) );
osg::StateSet* sset = getOrCreateStateSet();
sset->setAttribute( createShader((numCylinderSegments+1)*2 ) );
osg::Uniform* u2( new osg::Uniform( "numCylinderSegments", numCylinderSegments ) );
sset->addUniform( u2 );
osg::Uniform* u3( new osg::Uniform( "cylinderRadius", cylinderRadius ) );
sset->addUniform( u3 );
}
};
///////////////////////////////////////////////////////////////////////////
int main( int argc , char** argv )
{
osg::Geode* root( new osg::Geode );
root->addDrawable( new CatMullRomCurve() );
osgViewer::Viewer viewer;
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
viewer.addEventHandler(new osgViewer::ThreadingHandler);
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
viewer.addEventHandler(new osgViewer::StatsHandler);
viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);
viewer.addEventHandler(new osgViewer::LODScaleHandler);
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
viewer.setSceneData( root );
return viewer.run();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org