zoukankan      html  css  js  c++  java
  • OSG实现正八面体剖分成球

    #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;
    }
    

      

  • 相关阅读:
    LINQ大全。
    李开复回复:为什么很多人进不了Google
    判断输入的是否是数字?
    SQL Server 2005安装详解
    学习asp.net比较完整的流程
    .NET常用网站
    软件设计经典书籍推荐
    Linux 下zip包的压缩与解压
    centos的用户、组权限、添加删除用户等操作的详细操作命令
    CentOS5.5 默认基本服务详解
  • 原文地址:https://www.cnblogs.com/tangmiao/p/7691322.html
Copyright © 2011-2022 走看看