#include<Windows.h>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include <osg/Geometry>
#include<osgUtil/Optimizer>
#include <cmath>
#include<iostream>
#include<osgViewer/Viewer>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
std::set<osg::Vec3> pointSet;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
void subdivide(float v1x, float v1y, float v1z,
float v2x, float v2y, float v2z,
float v3x, float v3y, float v3z,
int level) {
if (level == 0) {
// Reached desired tessellation level, emit triangle.
osg::Vec3 v1Temp = osg::Vec3(v1x, v1y, v1z);
osg::Vec3 v2Temp = osg::Vec3(v2x, v2y, v2z);
osg::Vec3 v3Temp = osg::Vec3(v3x, v3y, v3z);
v1Temp.normalize();
v2Temp.normalize();
v3Temp.normalize();
pointSet.insert(v1Temp);
pointSet.insert(v2Temp);
pointSet.insert(v3Temp);
osg::ref_ptr<osg::Vec3Array> vertex = new osg::Vec3Array;
vertex->push_back(v1Temp);
vertex->push_back(v2Temp);
vertex->push_back(v3Temp);
osg::ref_ptr < osg::Geometry>geometry = new osg::Geometry;
geometry->setVertexArray(vertex.get());
geometry->setNormalArray(vertex.get());
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertex->size()));
geode->addDrawable(geometry);
/*drawTriangle(v1x, v1y, v1z,
v2x, v2y, v2z,
v3x, v3y, v3z);
*/
}
else {
// Calculate middle of first edge...
float v12x = 0.5f * (v1x + v2x);
float v12y = 0.5f * (v1y + v2y);
float v12z = 0.5f * (v1z + v2z);
// ... and renormalize it to get a point on the sphere.
float s = 1.0f / sqrt(v12x * v12x + v12y * v12y + v12z * v12z);
v12x *= s;
v12y *= s;
v12z *= s;
// Same thing for the middle of the other two edges.
float v13x = 0.5f * (v1x + v3x);
float v13y = 0.5f * (v1y + v3y);
float v13z = 0.5f * (v1z + v3z);
s = 1.0f / sqrt(v13x * v13x + v13y * v13y + v13z * v13z);
v13x *= s;
v13y *= s;
v13z *= s;
float v23x = 0.5f * (v2x + v3x);
float v23y = 0.5f * (v2y + v3y);
float v23z = 0.5f * (v2z + v3z);
s = 1.0f / sqrt(v23x * v23x + v23y * v23y + v23z * v23z);
v23x *= s;
v23y *= s;
v23z *= s;
// Make the recursive calls.
subdivide(v1x, v1y, v1z,
v12x, v12y, v12z,
v13x, v13y, v13z,
level - 1);
subdivide(v12x, v12y, v12z,
v2x, v2y, v2z,
v23x, v23y, v23z,
level - 1);
subdivide(v13x, v13y, v13z,
v23x, v23y, v23z,
v3x, v3y, v3z,
level - 1);
subdivide(v12x, v12y, v12z,
v23x, v23y, v23z,
v13x, v13y, v13z,
level - 1);
}
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
int level = 3;
subdivide(0.000000, 0.000000, 1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, level);
subdivide(0.000000, 0.000000, 1.000000, -1.000000,0.000000, 0.000000, 0.000000, 1.000000, 0.000000, level);
subdivide(0.000000, 0.000000, 1.000000, -1.000000, 0.000000, 0.000000, -0.000000 ,- 1.000000,0.000000, level);
subdivide(0.000000, 0.000000, 1.000000, 1.000000, 0.000000, 0.000000, -0.000000, -1.000000, 0.000000, level);
subdivide(0.000000, 0.000000, -1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, level);
subdivide(0.000000, 0.000000, -1.000000, -1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, level);
subdivide(0.000000, 0.000000, -1.000000, -1.000000, 0.000000, 0.000000, 0.000000, -1.000000, 0.000000, level);
subdivide(0.000000, 0.000000, -1.000000, 1.000000, 0.000000, 0.000000, 0.000000, -1.000000, 0.000000, level);
osg::ref_ptr<osg::Group> node = new osg::Group;
node->addChild(geode);
osgUtil::Optimizer optimizer;
optimizer.optimize(node.get());
viewer->setSceneData(node.get());
viewer->realize();
viewer->run();
return 0;
}