Changeset 11194
- Timestamp:
- 03/10/10 17:05:52 (3 years ago)
- Location:
- OpenSceneGraph/trunk/src/osgPlugins/3ds
- Files:
-
- 4 modified
-
ReaderWriter3DS.cpp (modified) (2 diffs)
-
WriterCompareTriangle.cpp (modified) (1 diff)
-
WriterNodeVisitor.cpp (modified) (12 diffs)
-
WriterNodeVisitor.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgPlugins/3ds/ReaderWriter3DS.cpp
r11180 r11194 903 903 if (texture && *(texture->name)) 904 904 { 905 osg::notify(osg:: NOTICE)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl;905 osg::notify(osg::INFO)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl; 906 906 907 907 std::string fileName = osgDB::findFileInDirectory(texture->name,_directory,osgDB::CASE_INSENSITIVE); … … 910 910 // file not found in .3ds file's directory, so we'll look in the datafile path list. 911 911 fileName = osgDB::findDataFile(texture->name,options, osgDB::CASE_INSENSITIVE); 912 osg::notify(osg:: NOTICE)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl;912 osg::notify(osg::INFO)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl; 913 913 } 914 914 -
OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.cpp
r11056 r11194 49 49 unsigned int nbVerticesZ = static_cast<unsigned int>( (nbVertices * k) / (length.x() * length.y()) ); 50 50 51 setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cut scene in too many blocs51 setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cutting the scene in too many blocs 52 52 53 osg::notify(osg::ALWAYS) << "Cutting x by " << nbVerticesX << std::endl 53 osg::notify(osg::INFO) 54 << "Cutting x by " << nbVerticesX << std::endl 54 55 << "Cutting y by " << nbVerticesY << std::endl 55 56 << "Cutting z by " << nbVerticesZ << std::endl; 56 57 57 osg::BoundingBox::value_type blocX = length.x() / nbVerticesX; //This3 lines set the size of a bloc in x, y and z58 osg::BoundingBox::value_type blocX = length.x() / nbVerticesX; // These 3 lines set the size of a bloc in x, y and z 58 59 osg::BoundingBox::value_type blocY = length.y() / nbVerticesY; 59 60 osg::BoundingBox::value_type blocZ = length.z() / nbVerticesZ; -
OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.cpp
r11123 r11194 16 16 #include <osg/io_utils> 17 17 #include <osg/CullFace> 18 #include <osg/Billboard> 18 19 #include <osgDB/WriteFile> 19 20 … … 659 660 660 661 /** 661 * Add a vertice to the index and link himwith the Triangle index and the drawable.662 * Add a vertice to the index and link it with the Triangle index and the drawable. 662 663 * \param index_vert is the map where the vertice are stored. 663 664 * \param index is the indice of the vertice's position in the vec3. … … 681 682 682 683 void 683 WriterNodeVisitor::buildMesh(osg::Geode & geo, 684 MapIndices & index_vert, 685 bool texcoords, 686 Lib3dsMesh * mesh) 684 WriterNodeVisitor::buildMesh(osg::Geode & geo, 685 const osg::Matrix & mat, 686 MapIndices & index_vert, 687 bool texcoords, 688 Lib3dsMesh * mesh) 687 689 { 688 690 osg::notify(osg::DEBUG_INFO) << "Building Mesh" << std::endl; … … 690 692 if (!mesh) throw "Allocation error"; // TODO 691 693 694 // Write points 695 assert(index_vert.size() <= MAX_VERTICES); 692 696 lib3ds_mesh_resize_vertices(mesh, index_vert.size(), texcoords ? 1 : 0, 0); 693 // Write points694 697 695 698 for(MapIndices::iterator it = index_vert.begin(); it != index_vert.end();++it) … … 700 703 throw "Vertex array is not Vec3. Not implemented"; // TODO 701 704 const osg::Vec3Array & vecs= *static_cast<osg::Vec3Array *>(g->getVertexArray()); 702 copyOsgVectorToLib3dsVector(mesh->vertices[it->second], vecs[it->first.first] );705 copyOsgVectorToLib3dsVector(mesh->vertices[it->second], vecs[it->first.first]*mat); 703 706 } 704 707 … … 745 748 746 749 void 747 WriterNodeVisitor::buildFaces(osg::Geode & geo, 748 ListTriangle & listTriangles, 750 WriterNodeVisitor::buildFaces(osg::Geode & geo, 751 const osg::Matrix & mat, 752 ListTriangle & listTriangles, 749 753 bool texcoords) 750 754 { 751 755 MapIndices index_vert; 752 unsigned int nbFace = 0;753 756 Lib3dsMesh *mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), "geo").c_str() ); 754 unsigned int nbTriangles = listTriangles.size(); 755 756 lib3ds_mesh_resize_faces(mesh, nbTriangles); 757 758 unsigned int nbVertices = calcVertices(geo); 759 if (listTriangles.size() >= MAX_FACES-2 || 760 ((nbVertices) >= MAX_VERTICES-2)) 757 if (!mesh) throw "Allocation error"; 758 759 unsigned int nbTrianglesRemaining = listTriangles.size(); 760 unsigned int nbVerticesRemaining = calcVertices(geo); 761 762 lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); 763 lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block 764 765 // Test if the mesh will be split and needs sorting 766 if (nbVerticesRemaining >= MAX_VERTICES || nbTrianglesRemaining >= MAX_FACES) 761 767 { 762 768 osg::notify(osg::INFO) << "Sorting elements..." << std::endl; 763 WriterCompareTriangle cmp(geo, nbVertices );769 WriterCompareTriangle cmp(geo, nbVerticesRemaining); 764 770 std::sort(listTriangles.begin(), listTriangles.end(), cmp); 765 771 } 766 772 773 unsigned int numFace = 0; // Current face index 767 774 for (ListTriangle::iterator it = listTriangles.begin(); it != listTriangles.end(); ++it) //Go through the triangle list to define meshs 768 775 { 769 // Using -2 due to the fact that we treat 3 faces in one time (=the algorithm may overrun the limit by 2).770 if ( (index_vert.size() >= MAX_VERTICES-2 || // If mesh is full771 nbFace >= MAX_FACES-2))772 {773 // Finnishing mesh774 lib3ds_mesh_resize_faces(mesh, nbFace);775 buildMesh(geo, index_vert, texcoords, mesh);776 777 // Creatinga new mesh776 // Test if the mesh will be full after adding a face 777 if (index_vert.size()+3 >= MAX_VERTICES || numFace+1 >= MAX_FACES) 778 { 779 // Finnish mesh 780 lib3ds_mesh_resize_faces (mesh, numFace); 781 //lib3ds_mesh_resize_vertices() will be called in buildMesh() 782 buildMesh(geo, mat, index_vert, texcoords, mesh); 783 784 // "Reset" values and start over a new mesh 778 785 index_vert.clear(); 786 nbTrianglesRemaining -= numFace; 787 numFace = 0; 788 // We can't call a thing like "nbVerticesRemaining -= ...;" because points may be used multiple times. 789 // [Sukender: An optimisation here would take too much time I think.] 790 779 791 mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), "geo").c_str()); 780 nbTriangles -= nbFace;781 nbFace = 0;782 lib3ds_mesh_resize_ faces(mesh, nbTriangles);783 } 784 Lib3dsFace & face = mesh->faces[n bFace++];792 if (!mesh) throw "Allocation error"; 793 lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); 794 lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block 795 } 796 Lib3dsFace & face = mesh->faces[numFace++]; 785 797 face.index[0] = getMeshIndexForGeometryIndex(index_vert, it->first.t1, it->second); 786 798 face.index[1] = getMeshIndexForGeometryIndex(index_vert, it->first.t2, it->second); … … 788 800 face.material = it->first.material; 789 801 } 790 buildMesh(geo, index_vert, texcoords, mesh); //When a Mesh is completed without restriction of vertices number802 buildMesh(geo, mat, index_vert, texcoords, mesh); //When a Mesh is completed without restriction of vertices number 791 803 } 792 804 … … 841 853 } 842 854 843 void WriterNodeVisitor::apply( osg::Geode &node ) 844 { 855 void WriterNodeVisitor::apply( osg::Geode &node ) { 845 856 pushStateSet(node.getStateSet()); 846 857 //_nameStack.push_back(node.getName()); 847 //osg::Matrix m = osg::computeLocalToWorld(getNodePath());848 858 unsigned int count = node.getNumDrawables(); 849 859 ListTriangle listTriangles; … … 861 871 if (count > 0) 862 872 { 863 buildFaces(node, listTriangles, texcoords); 873 osg::Matrix mat( osg::computeLocalToWorld(getNodePath()) ); 874 buildFaces(node, mat, listTriangles, texcoords); 864 875 } 865 876 popStateSet(node.getStateSet()); … … 869 880 } 870 881 871 void WriterNodeVisitor::apply(osg::Group &node) 872 { 882 void WriterNodeVisitor::apply( osg::Billboard &node ) { 883 // TODO Does not handle Billboards' points yet 884 885 pushStateSet(node.getStateSet()); 873 886 Lib3dsMeshInstanceNode * parent = _cur3dsNode; 874 Lib3dsMeshInstanceNode * node3ds = lib3ds_node_new_mesh_instance(NULL, getUniqueName(node.getName().empty() ? node.className() : getFileName(node.getName()), "grp").c_str(), NULL, NULL, NULL); 875 lib3ds_file_append_node(file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(parent)); 876 _cur3dsNode = node3ds; 887 888 unsigned int count = node.getNumDrawables(); 889 ListTriangle listTriangles; 890 bool texcoords = false; 891 osg::notify(osg::NOTICE) << "Warning: 3DS writer is incomplete for Billboards (rotation not implemented)." << std::endl; 892 osg::Matrix m( osg::computeLocalToWorld(getNodePath()) ); 893 for ( unsigned int i = 0; i < count; i++ ) 894 { 895 osg::Geometry *g = node.getDrawable( i )->asGeometry(); 896 if ( g != NULL ) 897 { 898 listTriangles.clear(); 899 _cur3dsNode = parent; 900 901 pushStateSet(g->getStateSet()); 902 createListTriangle(g, listTriangles, texcoords, i); 903 popStateSet(g->getStateSet()); 904 905 osg::Matrix currentBillBoardMat(osg::Matrix::translate(node.getPosition(i)) * m); // TODO handle rotation 906 apply3DSMatrixNode(node, currentBillBoardMat, "bil"); // Add a 3DS matrix node 907 buildFaces(node, currentBillBoardMat, listTriangles, texcoords); 908 } 909 } 910 877 911 if (suceedLastApply()) 878 912 traverse(node); 879 913 _cur3dsNode = parent; 914 popStateSet(node.getStateSet()); 915 } 916 917 918 919 void WriterNodeVisitor::apply(osg::Group &node) 920 { 921 pushStateSet(node.getStateSet()); 922 Lib3dsMeshInstanceNode * parent = _cur3dsNode; 923 apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "grp"); 924 if (suceedLastApply()) 925 traverse(node); 926 _cur3dsNode = parent; 927 popStateSet(node.getStateSet()); 880 928 } 881 929 882 930 void WriterNodeVisitor::apply(osg::MatrixTransform &node) 883 931 { 932 pushStateSet(node.getStateSet()); 884 933 Lib3dsMeshInstanceNode * parent = _cur3dsNode; 885 886 const osg::Matrix & m = node.getMatrix(); 887 //const osg::Matrix m( osg::computeWorldToLocal(getNodePath()) ); // [NEEDS TESTING!] 3DS matrices always contain world to local transformation (not local transform; ie. from parent) 934 apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "mtx"); 935 if (suceedLastApply()) 936 traverse(node); 937 _cur3dsNode = parent; 938 popStateSet(node.getStateSet()); 939 } 940 941 void WriterNodeVisitor::apply3DSMatrixNode(osg::Node &node, const osg::Matrix & m, const char * const prefix) 942 { 943 Lib3dsMeshInstanceNode * parent = _cur3dsNode; 944 945 //const osg::Matrix & m = node.getMatrix(); 946 //const osg::Matrix m( osg::computeLocalToWorld(nodePath) ); // [NEEDS TESTING!] 3DS matrices always contain world to local transformation (not local transform; ie. from parent) 888 947 889 948 // Transform data used to be given to lib3ds_node_new_mesh_instance(), but it seems buggy (pivot problem? bug in conversion?). … … 898 957 copyOsgQuatToLib3dsQuat(rot, osgRot); 899 958 Lib3dsMeshInstanceNode * node3ds = lib3ds_node_new_mesh_instance 900 (NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), "mtx").c_str(), pos, scl, rot);959 (NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), prefix).c_str(), pos, scl, rot); 901 960 902 961 //// Create a mesh instance with no transform and then copy the matrix (doesn't work) … … 907 966 lib3ds_file_append_node(file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(parent)); 908 967 _cur3dsNode = node3ds; 909 if (suceedLastApply()) 910 traverse(node); 911 _cur3dsNode = parent; 912 } 968 } -
OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.h
r11056 r11194 62 62 void failedApply(); 63 63 virtual void apply(osg::Geode &node); 64 virtual void apply(osg::Billboard &node); 64 65 65 66 virtual void apply(osg::Group &node); … … 135 136 * Fill the faces field of the mesh and call buildMesh(). 136 137 * \param geo is the geode who contain vertice and faces. 138 * \param mat Local to world matrix applied to the geode 137 139 * \param listTriangles contain all the meshs faces. 138 140 * \param texcoords tell us if we have to treat texture coord. 139 141 */ 140 void buildFaces(osg::Geode & geo, ListTriangle & listTriangles, bool texcoords);142 void buildFaces(osg::Geode & geo, const osg::Matrix & mat, ListTriangle & listTriangles, bool texcoords); 141 143 142 144 /** … … 150 152 * Build a mesh 151 153 * \param geo is the geode who contain vertice and faces 154 * \param mat Local to world matrix applied to the geode 152 155 * \param index_vert is the index used to build the new mesh 153 156 * \param texcoords tell us if we have to treat texture coord 154 157 * \param mesh is the mesh with faces filled 155 * \return the place of the box in the vector.156 158 * \sa See cutScene() about the definition of the boxes for faces sorting. 157 159 */ 158 160 void 159 buildMesh(osg::Geode & geo, 160 MapIndices & index_vert, 161 bool texcoords, 161 buildMesh(osg::Geode & geo, 162 const osg::Matrix & mat, 163 MapIndices & index_vert, 164 bool texcoords, 162 165 Lib3dsMesh *mesh); 163 166 … … 193 196 typedef std::map< osg::ref_ptr<osg::StateSet>, Material, CompareStateSet> MaterialMap; 194 197 198 void apply3DSMatrixNode(osg::Node &node, const osg::Matrix & m, const char * const prefix); 195 199 196 200 bool _suceedLastApply;
