📄 readerwriter3ds.cpp
字号:
#include <osg/Notify>#include <osg/Group>#include <osg/Geode>#include <osg/Geometry>#include <osg/Texture2D>#include <osg/Material>#include <osg/TexEnv>#include <osg/ref_ptr>#include <osg/MatrixTransform>#include <osgDB/Registry>#include <osgDB/FileUtils>#include <osgDB/FileNameUtils>#include <osgDB/ReadFile>#include <osgUtil/TriStripVisitor>//MIKEC debug only for PrintVisitor#include <osg/NodeVisitor>#include "file.h"#include "mesh.h"#include "material.h"#include "vector.h"#include "matrix.h"#include "node.h"#include "quat.h"#include "readwrite.h"#include <stdlib.h>#include <string.h>#include <set>#include <map>#include <iostream>using namespace std;using namespace osg;class PrintVisitor : public NodeVisitor{ public: PrintVisitor(std::ostream& out): NodeVisitor(NodeVisitor::TRAVERSE_ALL_CHILDREN), _out(out) { _indent = 0; _step = 4; } inline void moveIn() { _indent += _step; } inline void moveOut() { _indent -= _step; } inline void writeIndent() { for(int i=0;i<_indent;++i) _out << " "; } virtual void apply(Node& node) { moveIn(); writeIndent(); _out << node.className() <<std::endl; traverse(node); moveOut(); } virtual void apply(Geode& node) { apply((Node&)node); } virtual void apply(Billboard& node) { apply((Geode&)node); } virtual void apply(LightSource& node) { apply((Group&)node); } virtual void apply(ClipNode& node) { apply((Group&)node); } virtual void apply(Group& node) { apply((Node&)node); } virtual void apply(Transform& node) { apply((Group&)node); } virtual void apply(Projection& node) { apply((Group&)node); } virtual void apply(Switch& node) { apply((Group&)node); } virtual void apply(LOD& node) { apply((Group&)node); } protected: std::ostream& _out; int _indent; int _step;};class ReaderWriter3DS : public osgDB::ReaderWriter{ public: ReaderWriter3DS(); virtual const char* className() const { return "3DS Auto Studio Reader"; } virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const; protected: class ReaderObject { public: ReaderObject(); typedef std::map<std::string,osg::StateSet*> StateSetMap; typedef std::vector<int> FaceList; typedef std::map<std::string,osg::StateSet*> GeoStateMap; osg::Texture2D* createTexture(Lib3dsTextureMap *texture,const char* label,bool& transparancy, const osgDB::ReaderWriter::Options* options); osg::StateSet* createStateSet(Lib3dsMaterial *materials, const osgDB::ReaderWriter::Options* options); osg::Drawable* createDrawable(Lib3dsMesh *meshes,FaceList& faceList, Lib3dsMatrix* matrix); std::string _directory; bool _useSmoothingGroups; bool _usePerVertexNormals; // MIKEC osg::Node* processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, Lib3dsMatrix* matrix); osg::Node* processNode(StateSetMap drawStateMap,Lib3dsFile *f,Lib3dsNode *node); };};// now register with Registry to instantiate the above// reader/writer.REGISTER_OSGPLUGIN(3ds, ReaderWriter3DS)ReaderWriter3DS::ReaderWriter3DS(){ supportsExtension("3ds","3D Studio model format"); setByteOrder();#if 0 osg::notify(osg::NOTICE)<<"3DS reader sizes:"<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsBool)="<<sizeof(Lib3dsBool)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsByte)="<<sizeof(Lib3dsByte)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsWord)="<<sizeof(Lib3dsWord)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsDword)="<<sizeof(Lib3dsDword)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsIntb)="<<sizeof(Lib3dsIntb)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsIntw)="<<sizeof(Lib3dsIntw)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsIntd)="<<sizeof(Lib3dsIntd)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsFloat)="<<sizeof(Lib3dsFloat)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsDouble)="<<sizeof(Lib3dsDouble)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsVector)="<<sizeof(Lib3dsVector)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsTexel)="<<sizeof(Lib3dsTexel)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsQuat)="<<sizeof(Lib3dsQuat)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsMatrix)="<<sizeof(Lib3dsMatrix)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsRgb)="<<sizeof(Lib3dsRgb)<<std::endl; osg::notify(osg::NOTICE)<<" sizeof(Lib3dsRgba)="<<sizeof(Lib3dsRgba)<<std::endl;#endif}ReaderWriter3DS::ReaderObject::ReaderObject(){ _useSmoothingGroups = true; _usePerVertexNormals = true;}/** These print methods for 3ds hacking*/void pad(int level) { for(int i=0;i<level;i++) std::cout<<" ";}void print(Lib3dsMesh *mesh,int level);void print(Lib3dsUserData *user,int level);void print(Lib3dsNodeData *user,int level);void print(Lib3dsObjectData *object,int level);void print(Lib3dsNode *node, int level);void print(Lib3dsMatrix matrix,int level) { pad(level); cout << matrix[0][0] <<" "<< matrix[0][1] <<" "<< matrix[0][2] <<" "<< matrix[0][3] << endl; pad(level); cout << matrix[1][0] <<" "<< matrix[1][1] <<" "<< matrix[1][2] <<" "<< matrix[1][3] << endl; pad(level); cout << matrix[2][0] <<" "<< matrix[2][1] <<" "<< matrix[2][2] <<" "<< matrix[2][3] << endl; pad(level); cout << matrix[3][0] <<" "<< matrix[3][1] <<" "<< matrix[3][2] <<" "<< matrix[3][3] << endl;}void print(Lib3dsMesh *mesh,int level) { if (mesh) { pad(level); cout << "mesh name " << mesh->name << endl; print(mesh->matrix,level); } else { pad(level); cout << "no mesh " << endl; }}void print(Lib3dsUserData *user,int level) { if (user) { pad(level); cout << "user data" << endl; //print(user->mesh,level+1); } else { pad(level); cout << "no user data" << endl; }}void print(Lib3dsNodeData *node,int level) { if (node) { pad(level); cout << "node data:" << endl; // nodedata->object is a union of many types print((Lib3dsObjectData *)&node->object,level+1); } else { pad(level); cout << "no user data" << endl; }}void print(Lib3dsObjectData *object,int level) { if (object) { pad(level); cout << "objectdata instance [" << object->instance << "]" << endl; pad(level); cout << "pivot " << object->pivot[0] <<" "<< object->pivot[1] <<" "<< object->pivot[2] << endl; pad(level); cout << "pos " << object->pos[0] <<" "<< object->pos[1] <<" "<< object->pos[2] << endl; pad(level); cout << "scl " << object->scl[0] <<" "<< object->scl[1] <<" "<< object->scl[2] << endl; pad(level); cout << "rot " << object->rot[0] <<" "<< object->rot[1] <<" "<< object->rot[2] <<" "<< object->rot[3] << endl; } else { pad(level); cout << "no object data" << endl; }}void print(Lib3dsNode *node, int level) { pad(level); cout << "node name [" << node->name << "]" << endl; pad(level); cout << "node id " << node->node_id << endl; pad(level); cout << "node parent id " << node->parent_id << endl; pad(level); cout << "node matrix:" << endl; print(node->matrix,level+1); print(&node->data,level); print(&node->user,level); for(Lib3dsNode *child=node->childs; child; child=child->next) { print(child,level+1); }}void copyLib3dsMatrixToOsgMatrix(osg::Matrix& osg_matrix, const Lib3dsMatrix lib3ds_matrix){ osg_matrix.set( lib3ds_matrix[0][0],lib3ds_matrix[0][1],lib3ds_matrix[0][2],lib3ds_matrix[0][3], lib3ds_matrix[1][0],lib3ds_matrix[1][1],lib3ds_matrix[1][2],lib3ds_matrix[1][3], lib3ds_matrix[2][0],lib3ds_matrix[2][1],lib3ds_matrix[2][2],lib3ds_matrix[2][3], lib3ds_matrix[3][0],lib3ds_matrix[3][1],lib3ds_matrix[3][2],lib3ds_matrix[3][3]); }// Transforms points by matrix if 'matrix' is not NULL// Creates a Geode and Geometry (as parent,child) and adds the Geode to 'parent' parameter iff 'parent' is non-NULL// Returns ptr to the Geodeosg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, Lib3dsMatrix* matrix) { typedef std::vector<int> FaceList; typedef std::map<std::string,FaceList> MaterialFaceMap; MaterialFaceMap materialFaceMap; for (unsigned int i=0; i<mesh->faces; ++i) { materialFaceMap[mesh->faceL[i].material].push_back(i); } if (materialFaceMap.empty()) { osg::notify(osg::NOTICE)<<"Warning : no triangles assigned to mesh '"<<mesh->name<<"'"<< std::endl; return NULL; } else { osg::Geode* geode = new osg::Geode; geode->setName(mesh->name); for(MaterialFaceMap::iterator itr=materialFaceMap.begin(); itr!=materialFaceMap.end(); ++itr) { FaceList& faceList = itr->second; if (_useSmoothingGroups) { typedef std::map<int,FaceList> SmoothingFaceMap; SmoothingFaceMap smoothingFaceMap; for (FaceList::iterator flitr=faceList.begin(); flitr!=faceList.end(); ++flitr) { smoothingFaceMap[mesh->faceL[*flitr].smoothing].push_back(*flitr); } for(SmoothingFaceMap::iterator sitr=smoothingFaceMap.begin();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -