📄 primitives.cpp
字号:
// -*-c++-*-#include "ReaderWriterVRML2.h"#include <complex>#if defined(_MSC_VER)# pragma warning(disable: 4250) # pragma warning(disable: 4290) # pragma warning(disable: 4800) #endif #include <openvrml/vrml97node.h>#include <openvrml/common.h>#include <openvrml/node.h>#include <openvrml/node_ptr.h>#include <openvrml/field.h>#include <osg/CullFace>osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Box(openvrml::vrml97_node::box_node* vrml_box) const{ const openvrml::vec3f& size = static_cast<const openvrml::sfvec3f&>(vrml_box->field("size")).value; osg::Vec3 halfSize(size[0] * 0.5f, size[1] * 0.5f, size[2] * 0.5f); BoxLibrary::const_iterator it = m_boxLibrary.find(halfSize); if (it != m_boxLibrary.end()) { return (*it).second.get(); } osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array(); osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array(); osg::ref_ptr<osg::DrawArrays> box = new osg::DrawArrays(osg::PrimitiveSet::QUADS); osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); for (int i = 0; i != 6; ++i) { osg_texcoords->push_back(osg::Vec2(0.0f, 1.0f)); osg_texcoords->push_back(osg::Vec2(0.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(1.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(1.0f, 1.0f)); } osg_normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); osg_normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); osg_normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); osg_normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f)); osg_normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); box->setCount(osg_vertices->size()); osg_geom->addPrimitiveSet(box.get()); osg_geom->setVertexArray(osg_vertices.get()); osg_geom->setTexCoordArray(0, osg_texcoords.get()); osg_geom->setNormalArray(osg_normals.get()); osg_geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE); osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK)); m_boxLibrary[halfSize] = osg_geom; return osg_geom.get();}osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrml97_node::sphere_node* vrml_sphere) const{ float radius = static_cast<const openvrml::sffloat&>(vrml_sphere->field("radius")).value; SphereLibrary::const_iterator it = m_sphereLibrary.find(radius); if (it != m_sphereLibrary.end()) { return (*it).second.get(); } osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array(); osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array(); unsigned int numSegments = 40; unsigned int numRows = 20; const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments); const float texCoordSDelta = 1.0f / float(numSegments); const float phiDelta = float(osg::PI) / float(numRows); const float texCoordTDelta = 1.0f / float(numRows); float phi = -0.5f * float(osg::PI); float texCoordT = 0.0f; osg::ref_ptr<osg::DrawArrayLengths> sphere = new osg::DrawArrayLengths(osg::PrimitiveSet::QUAD_STRIP); for (unsigned int i = 0; i < numRows; ++i, phi += phiDelta, texCoordT += texCoordTDelta) { std::complex<float> latBottom = std::polar(1.0f, phi); std::complex<float> latTop = std::polar(1.0f, phi + phiDelta); std::complex<float> eBottom = latBottom * radius; std::complex<float> eTop = latTop * radius; float theta = 0.0f; float texCoordS = 0.0f; for (unsigned int j = 0; j < numSegments; ++j, theta += thetaDelta, texCoordS += texCoordSDelta) { std::complex<float> n = -std::polar(1.0f, theta); osg_normals->push_back(osg::Vec3(latTop.real() * n.imag(), latTop.imag(), latTop.real() * n.real())); osg_normals->push_back(osg::Vec3(latBottom.real() * n.imag(), latBottom.imag(), latBottom.real() * n.real())); osg_texcoords->push_back(osg::Vec2(texCoordS, texCoordT + texCoordTDelta)); osg_texcoords->push_back(osg::Vec2(texCoordS, texCoordT)); osg_vertices->push_back(osg::Vec3(eTop.real() * n.imag(), eTop.imag(), eTop.real() * n.real())); osg_vertices->push_back(osg::Vec3(eBottom.real() * n.imag(), eBottom.imag(), eBottom.real() * n.real())); } osg_normals->push_back(osg::Vec3(0.0f, latTop.imag(), -latTop.real())); osg_normals->push_back(osg::Vec3(0.0f, latBottom.imag(), -latBottom.real())); osg_texcoords->push_back(osg::Vec2(1.0f, texCoordT + texCoordTDelta)); osg_texcoords->push_back(osg::Vec2(1.0f, texCoordT)); osg_vertices->push_back(osg::Vec3(0.0f, eTop.imag(), -eTop.real())); osg_vertices->push_back(osg::Vec3(0.0f, eBottom.imag(), -eBottom.real())); sphere->push_back(numSegments * 2 + 2); } osg_geom->addPrimitiveSet(sphere.get()); osg_geom->setVertexArray(osg_vertices.get()); osg_geom->setTexCoordArray(0, osg_texcoords.get()); osg_geom->setNormalArray(osg_normals.get()); osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK)); m_sphereLibrary[radius] = osg_geom; return osg_geom.get();}osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cone(openvrml::vrml97_node::cone_node* vrml_cone) const{ float height = static_cast<const openvrml::sffloat&>(vrml_cone->field("height")).value; float radius = static_cast<const openvrml::sffloat&>(vrml_cone->field("bottomRadius")).value; bool bottom = static_cast<const openvrml::sfbool&>(vrml_cone->field("bottom")).value; bool side = static_cast<const openvrml::sfbool&>(vrml_cone->field("side")).value; QuadricKey key(height, radius, bottom, side, false); ConeLibrary::const_iterator it = m_coneLibrary.find(key); if (it != m_coneLibrary.end()) { return (*it).second.get(); } osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array(); osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array(); unsigned int numSegments = 40; const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments); float topY = height * 0.5f; float bottomY = height * -0.5f; if (side) { osg::ref_ptr<osg::DrawArrays> side = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP); const float texCoordDelta = 1.0f / float(numSegments); float theta = 0.0f; float texCoord = 0.0f; for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta, texCoord += texCoordDelta) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -