Skip to content

Instantly share code, notes, and snippets.

@vicrucann
Last active April 10, 2017 17:58
Show Gist options
  • Save vicrucann/8b35bcb190ab9531170e5502e7209b90 to your computer and use it in GitHub Desktop.
Save vicrucann/8b35bcb190ab9531170e5502e7209b90 to your computer and use it in GitHub Desktop.
Tube tester file
#include "Tube.h"
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/StateSet>
#include <osg/LineWidth>
#include <osg/BlendFunc>
#include <osg/Material>
#include <osg/LightSource>
Tube::Tube(const std::vector<osg::Vec3f> &path, float radius, int numProfPts)
: m_Ps(path)
, m_scaleMin(1)
, m_scaleMax(1)
{
this->extractTangents();
makeCircleProfile(m_prof, radius, numProfPts);
}
void Tube::buildPTF()
{
m_frames.clear();
int n = m_Ps.size();
if (n>=3){
m_frames.resize(n);
m_frames[0] = firstFrame(m_Ps[0], m_Ps[1], m_Ps[2]);
for (int i=1; i<n; ++i){
osg::Vec3f prevT = m_Ts[i-1];
osg::Vec3f currT = m_Ts[i];
m_frames[i] = nextFrame(m_frames[i-1], m_Ps[i-1], m_Ps[i], prevT, currT);
}
m_frames[n-1] = lastFrame(m_frames[n-2], m_Ps[n-2], m_Ps[n-1]);
}
}
osg::Node *Tube::buildWireframe()
{
if (m_Ps.size() != m_frames.size() || m_frames.size()<3 || m_prof.empty())
return nullptr;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::Geometry* geom = new osg::Geometry;
geode->addDrawable(geom);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4f(0.7f,0,0.7f,1.f));
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
osg::Vec3Array* vertices = new osg::Vec3Array;
for (unsigned int i=0; i<m_Ps.size()-1; ++i){
osg::Matrix M0 = m_frames[i];
osg::Matrix M1 = m_frames[i+1];
float r0 = std::sin( (float)(i + 0)/(float)(m_Ps.size() - 1)*3.141592f );
float r1 = std::sin( (float)(i + 1)/(float)(m_Ps.size() - 1)*3.141592f );
float rs0 = (m_scaleMax - m_scaleMin)*r0 + m_scaleMin;
float rs1 = (m_scaleMax - m_scaleMin)*r1 + m_scaleMin;
if (i==0){
// profile line if it's the first point
for (unsigned int ci=0; ci<m_prof.size(); ++ci){
int idx0 = ci;
osg::Vec3f P0 = (m_prof[idx0]*rs0) * M0;
vertices->push_back(P0);
}
}
for (unsigned int ci=0; ci<m_prof.size(); ++ci){
int idx0 = ci;
int idx1 = (ci == (m_prof.size() - 1)) ? 0 : ci + 1;
osg::Vec3f P0 = (m_prof[idx0]*rs0) * M0;
osg::Vec3f P1 = (m_prof[idx1]*rs0) * M0;
osg::Vec3f P2 = (m_prof[idx1]*rs1) * M1;
osg::Vec3f P3 = (m_prof[idx0]*rs1) * M1;
// first triangle
vertices->push_back(P0);
vertices->push_back(P3);
vertices->push_back(P1);
// second triangle
vertices->push_back(P1);
vertices->push_back(P3);
vertices->push_back(P2);
}
}
geom->setVertexArray(vertices);
geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, vertices->size()));
geom->getOrCreateStateSet()->setAttribute(new osg::LineWidth(3.f), osg::StateAttribute::ON);
return geode.release();
}
osg::Node *Tube::buildFrameSlices(float scale)
{
if (m_Ps.empty() || m_frames.empty())
return nullptr;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::Geometry* geomLines = new osg::Geometry;
osg::Geometry* geomQuads = new osg::Geometry;
geode->addDrawable(geomLines);
geode->addDrawable(geomQuads);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
geode->getOrCreateStateSet()->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
osg::Vec4Array* colorsLines = new osg::Vec4Array;
colorsLines->push_back(osg::Vec4f(1,1,1,0.75f));
geomLines->setColorArray(colorsLines, osg::Array::BIND_OVERALL);
osg::Vec4Array* colorsQuads = new osg::Vec4Array;
colorsQuads->push_back(osg::Vec4f(1,1,1,0.25f));
geomQuads->setColorArray(colorsQuads, osg::Array::BIND_OVERALL);
osg::Vec3Array* vertLines = new osg::Vec3Array;
for (unsigned int i=0; i<m_Ps.size(); ++i){
osg::Matrix Mi = m_frames[i];
vertLines->push_back(osg::Vec3f(-1,1,0)*scale*Mi);
vertLines->push_back(osg::Vec3f(1,1,0)*scale*Mi);
vertLines->push_back(osg::Vec3f(1,1,0)*scale*Mi);
vertLines->push_back(osg::Vec3f(1,-1,0)*scale*Mi);
vertLines->push_back(osg::Vec3f(1,-1,0)*scale*Mi);
vertLines->push_back(osg::Vec3f(-1,-1,0)*scale*Mi);
vertLines->push_back(osg::Vec3f(-1,-1,0)*scale*Mi);
vertLines->push_back(osg::Vec3f(-1,1,0)*scale*Mi);
}
geomLines->setVertexArray(vertLines);
geomLines->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, vertLines->size()));
osg::Vec3Array* vertQuads = new osg::Vec3Array;
for (unsigned int i=0; i<m_Ps.size(); ++i){
vertQuads->push_back(osg::Vec3f(-1,1,0)*scale*m_frames[i]);
vertQuads->push_back(osg::Vec3f(1,1,0)*scale*m_frames[i]);
vertQuads->push_back(osg::Vec3f(1,-1,0)*scale*m_frames[i]);
vertQuads->push_back(osg::Vec3f(-1,-1,0)*scale*m_frames[i]);
}
geomQuads->setVertexArray(vertQuads);
geomQuads->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, vertQuads->size()));
return geode.release();
}
osg::Node *Tube::buildTriMesh()
{
if (m_Ps.size() != m_frames.size() || m_frames.size()<3 || m_prof.empty())
return nullptr;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::Geometry* geom = new osg::Geometry;
geode->addDrawable(geom);
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4f(0.5f,0.5,0.7f,1.f));
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
osg::Vec3Array* vertices = new osg::Vec3Array;
osg::Vec3Array* normals = new osg::Vec3Array;
// first frame cover
for (unsigned int ci=1; ci<m_prof.size()-1; ++ci){
osg::Vec3f P0 = m_prof[0] * m_frames.front();
osg::Vec3f P1 = m_prof[ci] * m_frames.front();
osg::Vec3f P2 = m_prof[ci+1] * m_frames.front();
// normals
osg::Vec3f a = P1-P0;
osg::Vec3f b = P2-P0;
osg::Vec3f n = a^b;
n.normalize();
vertices->push_back(P2);
vertices->push_back(P0);
vertices->push_back(P1);
normals->push_back(n);
normals->push_back(n);
normals->push_back(n);
}
// frame structure
for (unsigned int i=0; i<m_Ps.size()-1; ++i){
osg::Matrix M0 = m_frames[i];
osg::Matrix M1 = m_frames[i+1];
float r0 = std::sin( (float)(i + 0)/(float)(m_Ps.size() - 1)*3.141592f );
float r1 = std::sin( (float)(i + 1)/(float)(m_Ps.size() - 1)*3.141592f );
float rs0 = (m_scaleMax - m_scaleMin)*r0 + m_scaleMin;
float rs1 = (m_scaleMax - m_scaleMin)*r1 + m_scaleMin;
for (unsigned int ci=0; ci<m_prof.size(); ++ci){
int idx0 = ci;
int idx1 = (ci == (m_prof.size() - 1)) ? 0 : ci + 1;
osg::Vec3f P0 = (m_prof[idx0]*rs0) * M0;
osg::Vec3f P1 = (m_prof[idx1]*rs0) * M0;
osg::Vec3f P2 = (m_prof[idx1]*rs1) * M1;
osg::Vec3f P3 = (m_prof[idx0]*rs1) * M1;
// normal for the given face
osg::Vec3f a = P3-P0;
a.normalize();
osg::Vec3f b = P1-P0;
b.normalize();
osg::Vec3f n = a^b;
n.normalize();
// first triangle
vertices->push_back(P0);
vertices->push_back(P3);
vertices->push_back(P1);
normals->push_back(n);
normals->push_back(n);
normals->push_back(n);
// second triangle
vertices->push_back(P1);
vertices->push_back(P3);
vertices->push_back(P2);
normals->push_back(n);
normals->push_back(n);
normals->push_back(n);
}
}
//last frame cover
for (unsigned int ci=1; ci<m_prof.size()-1; ++ci){
osg::Vec3f P0 = m_prof[0] * m_frames.back();
osg::Vec3f P1 = m_prof[ci] * m_frames.back();
osg::Vec3f P2 = m_prof[ci+1] * m_frames.back();
// normals
osg::Vec3f a = P1-P0;
osg::Vec3f b = P2-P0;
osg::Vec3f n = a^b;
n.normalize();
vertices->push_back(P1);
vertices->push_back(P0);
vertices->push_back(P2);
normals->push_back(n);
normals->push_back(n);
normals->push_back(n);
}
geom->setVertexArray(vertices);
geom->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
geom->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, vertices->size()));
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_LIGHT0, osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
return geode.release();
}
osg::Node *Tube::buildQuadMesh()
{
if (m_Ps.size() != m_frames.size() || m_frames.size()<3 || m_prof.empty() || m_prof.size() != 4)
return nullptr;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::Geometry* geom = new osg::Geometry;
geode->addDrawable(geom);
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4f(0.5f,0.5,0.7f,1.f));
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
osg::Vec3Array* vertices = new osg::Vec3Array;
// first frame cover
vertices->push_back(m_prof[0] * m_frames.front());
vertices->push_back(m_prof[1] * m_frames.front());
vertices->push_back(m_prof[2] * m_frames.front());
vertices->push_back(m_prof[3] * m_frames.front());
// frame structure
for (unsigned int i=0; i<m_Ps.size()-1; ++i){
for (unsigned int ci=0; ci<m_prof.size(); ++ci){
int idx0 = ci;
int idx1 = (ci == (m_prof.size() - 1)) ? 0 : ci + 1;
osg::Vec3f P0 = m_prof[idx0] * m_frames[i];
osg::Vec3f P1 = m_prof[idx1] * m_frames[i];
osg::Vec3f P2 = m_prof[idx1] * m_frames[i+1];
osg::Vec3f P3 = m_prof[idx0] * m_frames[i+1];
vertices->push_back(P0);
vertices->push_back(P3);
vertices->push_back(P2);
vertices->push_back(P1);
}
}
//last frame cover
vertices->push_back(m_prof[0] * m_frames.back());
vertices->push_back(m_prof[3] * m_frames.back());
vertices->push_back(m_prof[2] * m_frames.back());
vertices->push_back(m_prof[1] * m_frames.back());
// GL settings
geom->setVertexArray(vertices);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, vertices->size()));
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
return geode.release();
}
void Tube::extractTangents()
{
for (unsigned int i=0; i<m_Ps.size(); ++i){
osg::Vec3f t;
if (i==0)
t = m_Ps[i+1]-m_Ps[i];
else if (i<m_Ps.size()-1){
osg::Vec3f t1 = m_Ps[i]-m_Ps[i-1];
osg::Vec3f t2 = m_Ps[i+1]-m_Ps[i];
t = (t1+t2)*0.5f;
}
else{
t = m_Ps[i]-m_Ps[i-1];
}
t.normalize();
m_Ts.push_back(t);
}
}
osg::Matrix Tube::firstFrame(const osg::Vec3f &firstPoint, const osg::Vec3f &secondPoint, const osg::Vec3f &thirdPoint)
{
osg::Vec3f t = secondPoint - firstPoint;
t.normalize();
osg::Vec3f n = t ^ (thirdPoint - firstPoint);
n.normalize();
// if two vectors are collinear, an arbitrary twist value is chosen
if (n.length() == 0.f){
int i = std::fabs(t[0]) < std::fabs(t[1]) ? 0 : 1;
if (std::fabs(t[2])<std::fabs(t[i])) i=2;
osg::Vec3f v;
v[i] = 1.f;
n = t^v;
n.normalize();
}
osg::Vec3f b = t^n;
osg::Matrix M(
b[0], b[1], b[2], 0.f,
n[0], n[1], n[2], 0.f,
t[0], t[1], t[2], 0.f,
firstPoint[0], firstPoint[1], firstPoint[2], 1.f);
return M;
}
osg::Matrix Tube::nextFrame(const osg::Matrix &prevMatrix, const osg::Vec3f &prevPoint, const osg::Vec3f &currPoint, osg::Vec3f prevTangent, osg::Vec3f currTangent)
{
osg::Vec3f axis;
float r = 0.f;
if (prevTangent.length() != 0 && currTangent.length() != 0){
prevTangent.normalize();
currTangent.normalize();
float dot = prevTangent * currTangent;
if (dot>1) {
dot=1;
}
else if (dot<-1) {
dot=-1;
}
r = std::acos(dot);
axis = prevTangent ^ currTangent;
}
if (axis.length() != 0 && r!=0){
osg::Matrix R = osg::Matrix::rotate(r, axis);
osg::Matrix Tj = osg::Matrix::translate(currPoint);
osg::Matrix Ti = osg::Matrix::translate(-prevPoint);
return prevMatrix*Ti*R*Tj /*Tj*R*Ti*prevMatrix*/ ;
}
else{
osg::Matrix Tr = osg::Matrix::translate(currPoint - prevPoint);
return prevMatrix*Tr /*Tr*prevMatrix*/;
}
}
osg::Matrix Tube::lastFrame(const osg::Matrix &prevMatrix, const osg::Vec3f &prevPoint, const osg::Vec3f &lastPoint)
{
return prevMatrix * osg::Matrix::translate(lastPoint - prevPoint) /*osg::Matrix::translate(lastPoint - prevPoint)*prevMatrix*/;
}
void makeCircleProfile(std::vector<osg::Vec3f> &prof, float rad, int segments)
{
prof.clear();
float dt = 6.28318531f/(float)segments;
for (int i=0; i<segments; ++i){
float t= i*dt;
prof.push_back(osg::Vec3f(std::cos(t)*rad, std::sin(t)*rad, 0.f));
}
}
#ifndef TUBE_H
#define TUBE_H
#include <vector>
#include <osg/Array>
#include <osg/Matrix>
#include <osg/Node>
class Tube
{
public:
Tube(const std::vector<osg::Vec3f>& path, float radius, int numProfPts = 4);
/*! Computer consequtive reference frames along the path. */
void buildPTF();
/*! The frame geometry is built using line_strip as follows:
* 1. Define two consequitive points along profile.
* 2. Find same-index profile points along the next frame.
* 3. Connect: P0-P3-P1 and P1-P3-P2.
* 4. Make sure the first frame's profile is drawn (we always assume the path is not closed).
*
* P0 P1 - frame[i]
* | /
* | /
* P3-----P2 - frame[i+1]
*/
osg::Node* buildWireframe();
/*! \return geometry containing each frame's location as rectangles. */
osg::Node* buildFrameSlices(float scale = 1.f);
/*! The mesh geometry is build using triangules.
* \sa buildWireFrame() */
osg::Node* buildTriMesh();
/*! The mesh geometry is built using quads. Can only be used if the profile path is rectangular.
* \sa buildTriMesh(), buildWireMesh(). */
osg::Node* buildQuadMesh();
protected:
/*! Compute first derivatives for the path. */
void extractTangents();
/*! Compute the first reference frame along a path.
* \return transformation matrix to the reference frame defined by the three points. */
osg::Matrix firstFrame(const osg::Vec3f& firstPoint, const osg::Vec3f& secondPoint, const osg::Vec3f& thirdPoint);
/*! Compute the next reference frame along a path.
* \return transformation matrix to the next reference frame defined by the previously computed transformation matrix,
* and the new point and tangent vector along the curve. */
osg::Matrix nextFrame(const osg::Matrix& prevMatrix, const osg::Vec3f& prevPoint, const osg::Vec3f& currPoint,
osg::Vec3f prevTangent, osg::Vec3f currTangent);
/*! Compute the last reference frame along a path.
* \return the transformation matrix to the last reference frame defined by the previously computed transformation matrix
* and the last point along the path. */
osg::Matrix lastFrame(const osg::Matrix& prevMatrix, const osg::Vec3f& prevPoint, const osg::Vec3f& lastPoint);
private:
std::vector<osg::Vec3f> m_Ps; //< points
std::vector<osg::Vec3f> m_prof; //< profile shape
float m_scaleMin; //< min scale to profile along the curves
float m_scaleMax; //< max scale to profile along the curves
std::vector<osg::Vec3f> m_Ts; //< tangents
std::vector<osg::Matrix> m_frames; //< frames
};
void makeCircleProfile(std::vector<osg::Vec3f>& prof, float rad = 0.25f, int segments = 16);
#endif // TUBE_H
#include <iostream>
#include <stdio.h>
#ifdef _WIN32
#include <Windows.h>
#endif
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/ref_ptr>
#include <osg/ShapeDrawable>
#include <osgDB/WriteFile>
#include <osg/Camera>
#include <osg/BlendFunc>
#include <osg/AlphaFunc>
#include <osgUtil/CullVisitor>
#include <osg/TexMat>
#include <osg/Material>
//#include "testat.h"
#include "testmesh.h"
#include "Tube.h"
const int OSG_WIDTH = 700;
const int OSG_HEIGHT = 700;
osg::Node* createReferenceShape()
{
osg::Cylinder* cylinder = new osg::Cylinder(osg::Vec3( 0.f, 0.f, 0.f ), 0.5f, 2.f);
osg::ShapeDrawable* sd = new osg::ShapeDrawable( cylinder );
sd->setColor( osg::Vec4( 0.8f, 0.5f, 0.2f, 1.f ) );
osg::Geode* geode = new osg::Geode;
geode->addDrawable(sd);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
return geode;
}
osg::Node* createLightSource()
{
// light source
osg::LightSource* light = new osg::LightSource;
light->getLight()->setPosition(osg::Vec4(1,-1, 1, 0));
light->getLight()->setAmbient(osg::Vec4(0.5, 0.2, 0.2, 1.0));
light->getLight()->setDiffuse(osg::Vec4(0.7, 0.4, 0.6, 1.0));
light->getLight()->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
return light;
}
osg::Node* createReferenceGeometry()
{
float sz = 0.5;
float ht = 0.8;
osg::Geode* geode = new osg::Geode;
osg::Geometry* geom = new osg::Geometry;
geode->addDrawable(geom);
osg::Vec3Array* verts = new osg::Vec3Array;
verts->push_back(osg::Vec3f(-sz,-sz,0));
verts->push_back(osg::Vec3f(sz,-sz,0));
verts->push_back(osg::Vec3f(sz,sz,0));
verts->push_back(osg::Vec3f(-sz,sz,0));
verts->push_back(osg::Vec3f(0,0,ht));
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3f(-1,-1,0));
normals->push_back(osg::Vec3f(1,-1,0));
normals->push_back(osg::Vec3f(1,1,0));
normals->push_back(osg::Vec3f(-1,1,0));
normals->push_back(osg::Vec3f(-1,1,0));
normals->push_back(osg::Vec3f(0,0,1));
geom->setVertexArray(verts);
geom->setNormalArray(normals);
geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
// counter-clockwise order
osg::DrawElementsUInt* base = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
base->push_back(3);
base->push_back(2);
base->push_back(1);
base->push_back(0);
geom->addPrimitiveSet(base);
osg::DrawElementsUInt* face1 = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
face1->push_back(0);
face1->push_back(1);
face1->push_back(4);
geom->addPrimitiveSet(face1);
osg::DrawElementsUInt* face2 = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
face2->push_back(1);
face2->push_back(2);
face2->push_back(4);
geom->addPrimitiveSet(face2);
osg::DrawElementsUInt* face3 =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
face3->push_back(2);
face3->push_back(3);
face3->push_back(4);
geom->addPrimitiveSet(face3);
osg::DrawElementsUInt* face4 =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
face4->push_back(3);
face4->push_back(0);
face4->push_back(4);
geom->addPrimitiveSet(face4);
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 0.0f, 1.0f, 0.5f) ); //index 0 red
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 0.5f) ); //index 1 green
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 0.5f) ); //index 2 blue
colors->push_back(osg::Vec4(0.0f, 1.0f, 1.0f, 0.5f) ); //index 3 white
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 0.5f) ); //index 4 red
geom->setColorArray(colors);
geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setAttributeAndModes(new osg::BlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA));
// geode->getOrCreateStateSet()->setRenderBinDetails(10, "TraversalOrderBin", osg::StateSet::INHERIT_RENDERBIN_DETAILS );
geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON);
return geode;
}
int main(int, char**)
{
#ifdef _WIN32
::SetProcessDPIAware();
#endif
osgViewer::Viewer viewer;
viewer.setUpViewInWindow(100,100,OSG_WIDTH, OSG_HEIGHT);
osg::ref_ptr<osg::Group> root = new osg::Group();
root->addChild(createReferenceShape());
root->addChild(createLightSource());
// root->addChild(createPolyLine(getLinePoints3d()));
Tube ptf(getLinePoints3d(), 0.5, 5);
ptf.buildPTF();
// root->addChild(ptf.buildFrameSlices(0.25f));
// root->addChild(ptf.buildWireframe());
root->addChild(ptf.buildTriMesh());
// root->addChild(ptf.buildQuadMesh());
// root->addChild(createATLabel());
viewer.setSceneData(root.get());
// save scene to obj file
osgDB::writeNodeFile(*root, "test.obj");
return viewer.run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment