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

Reply via email to