⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readerwriter3ds.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    sitr!=smoothingFaceMap.end();                    ++sitr)                {                    // each smoothing group to have its own geom                     // to ensure the vertices on adjacent groups                    // don't get shared.                    FaceList& smoothFaceMap = sitr->second;                    osg::Drawable* drawable = createDrawable(mesh,smoothFaceMap,matrix);                    if (drawable)                    {                        drawable->setStateSet(drawStateMap[itr->first]);                        geode->addDrawable(drawable);                    }                }            }            else // ignore smoothing groups.            {                osg::Drawable* drawable = createDrawable(mesh,faceList,matrix);                if (drawable)                {                    drawable->setStateSet(drawStateMap[itr->first]);                    geode->addDrawable(drawable);                }            }        }        if (parent) parent->addChild(geode);        return geode;    }}/**How to cope with pivot points in 3ds (short version)  All object coordinates in 3ds are stored in world space, this is why you can just rip out the meshes and use/draw them without meddeling further  Unfortunately, this gets a bit wonky with objects with pivot points (conjecture: PP support is retro fitted into the .3ds format and so doesn't fit perfectly?)  Objects with pivot points have a position relative to their PP, so they have to undergo this transform:    invert the mesh matrix, apply this matrix to the object. This puts the object back at the origin    Transform the object by the nodes (negative) pivot point coords, this puts the PP at the origin    Transform the node by the node matrix, which does the orientation about the pivot point, (and currently) transforms the object back by a translation to the PP.  */osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,Lib3dsFile *f,Lib3dsNode *node) {        osg::Group* group=NULL;// created on demand if we find we have children to group together        // Handle all children of this node for hierarchical assemblies    Lib3dsNode *p;    for (p=node->childs; p!=0; p=p->next) {        if (!group) {            group =new osg::Group;            if (strcmp(node->name, "$$$DUMMY") == 0) {                group->setName(node->data.object.instance);            } else {                group->setName(node->name);            }        }        group->addChild(processNode(drawStateMap,f,p));    }        // MIKEC: possible BUG - 3ds files APPEAR to enforce unqiue names, so this is OK, but I am not 100% sure    // failed to find any alternative way to do it in lib3ds though, and lib3ds player.c application uses this method    Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(f,node->name);    if (mesh) {        Lib3dsObjectData* object=&node->data.object;        Lib3dsMatrix mesh_inverse;        osg::Matrix osgmatrix;                lib3ds_matrix_copy(mesh_inverse,mesh->matrix);         lib3ds_matrix_inv(mesh_inverse);                Lib3dsMatrix M,N;        lib3ds_matrix_identity(M);        lib3ds_matrix_identity(N);        lib3ds_matrix_copy(M,node->matrix);        N[3][0]=-object->pivot[0];        N[3][1]=-object->pivot[1];        N[3][2]=-object->pivot[2];        bool pivoted=false;        if ( (object->pivot[0]!=0.0) || (object->pivot[1]!=0.0) || (object->pivot[2]!=0.0) ) {            pivoted=true; // there is a pivot point, so we must use it        }        /*cout<<"M"<<node->name<<endl;        print(M,0);        cout<<"N"<<endl;        print(N,0);*/        if (pivoted) {            // Transform object's pivot point to the world origin            osg::MatrixTransform* T=new osg::MatrixTransform;            copyLib3dsMatrixToOsgMatrix(osgmatrix, N);            T->setMatrix(osgmatrix);            T->setName("3DSPIVOTPOINT: Translate pivotpoint to (world) origin");            //cout<<"Translation for "<<node->name<<" is "<<osgmatrix<<endl;            // rotate about "origin" (after the transform this is the world origin)            // BUG this matrix also contains the translation to the pivot point - we should plit that out (maybe)            osg::MatrixTransform* R=new osg::MatrixTransform;            copyLib3dsMatrixToOsgMatrix(osgmatrix, M);            R->setMatrix(osgmatrix);            R->setName("3DSPIVOTPOINT: Rotate");                            /*            cout<<"Rotation for "<<node->name<<" is "<<osgmatrix<<endl;            osg::Quat quat;            quat.set(osgmatrix);            osg::Vec3 axis;            float angle;            quat.getRotate(angle,axis);            cout<<"which is "<<osg::RadiansToDegrees(angle)<<" degrees around "<<axis<<endl;            */            /*            printf("%s---------------\n",node->name);            printf("mesh matrix :\n");         print(mesh->matrix,1);            printf("mesh inverse:\n");         print(mesh_inverse,1);            printf("node matrix :\n");         print(matrix,1);            printf("pivot=%f,%f,%f pos=%f,%f,%f\n",object->pivot[0],object->pivot[1],object->pivot[2],object->pos[0],object->pos[1],object->pos[2]);            */            if (group) {                // Always in reverse order...                group->addChild(R);                 R->addChild(T);                processMesh(drawStateMap,T,mesh,&mesh_inverse); // creates geometry under modifier node                return group;            } else {                // We are a pivoted node with no children                R->addChild(T);                processMesh(drawStateMap,T,mesh,&mesh_inverse); // creates geometry under modifier node                return R;            }        } else {            if(group) {                // add our geometry to group (where our children already are)                processMesh(drawStateMap,group,mesh,NULL); // creates geometry under modifier node                return group;            } else {                // didnt use group for children                // return a ptr directly to the Geode for this mesh                return processMesh(drawStateMap,NULL,mesh,NULL);             }            }    } else {        // no mesh for this node - probably a camera or something of that persuasion        //cout << "no mesh for object " << node->name << endl;        return group; // we have no mesh, but we might have children    }}osgDB::ReaderWriter::ReadResult ReaderWriter3DS::readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const{    std::string ext = osgDB::getLowerCaseFileExtension(file);    if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;    std::string fileName = osgDB::findDataFile( file, options );    if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;    Lib3dsFile *f = lib3ds_file_load(fileName.c_str());    if (f==NULL) return ReadResult::FILE_NOT_HANDLED;    // MIKEC    // This appears to build the matrix structures for the 3ds structure    // It wasn't previously necessary because all the meshes are stored in world coordinates    // but is VERY necessary if you want to use pivot points...    lib3ds_file_eval(f,0.0f); // second param is time 't' for animated files    ReaderObject reader;    reader._directory = osgDB::getFilePath(fileName);    osg::Group* group = new osg::Group;    group->setName(fileName);    ReaderObject::StateSetMap drawStateMap;    for (Lib3dsMaterial *mat=f->materials; mat; mat=mat->next)    {        drawStateMap[mat->name] = reader.createStateSet(mat, options);    }        if (osg::getNotifyLevel()>=osg::INFO)    {        int level=0;        std::cout << "NODE TRAVERSAL of 3ds file "<<f->name<<std::endl;        for(Lib3dsNode *node=f->nodes; node; node=node->next) {            print(node,level+1);        }        std::cout << "MESH TRAVERSAL of 3ds file "<<f->name<<std::endl;        for(Lib3dsMesh *mesh=f->meshes; mesh; mesh=mesh->next) {            print(mesh,level+1);        }    }    // We can traverse by meshes (old method, broken for pivot points, but otherwise works), or by nodes (new method, not so well tested yet)    // if your model is broken, especially wrt object positions try setting this flag. If that fixes it,    // send me the model    bool traverse_nodes=false;        // MIKEC: have found 3ds files with NO node structure - only meshes, for this case we fall back to the old traverse-by-meshes code    // Loading and re-exporting these files from 3DS produces a file with correct node structure, so perhaps these are not 100% conformant?    if (f->nodes == NULL) {        osg::notify(osg::WARN)<<"Warning: in 3ds loader: file has no nodes, traversing by meshes instead"<< std::endl;        traverse_nodes=true;    }    if (traverse_nodes) { // old method        for (Lib3dsMesh *mesh=f->meshes; mesh; mesh=mesh->next) {            reader.processMesh(drawStateMap,group,mesh,NULL);        }    } else { // new method        for(Lib3dsNode *node=f->nodes; node; node=node->next) {            group->addChild(reader.processNode(drawStateMap,f,node));        }    }     if (osg::getNotifyLevel()>=osg::INFO)    {        osg::notify(osg::NOTICE) << "Final OSG node structure looks like this:"<< endl;        PrintVisitor pv(osg::notify(osg::NOTICE));        group->accept(pv);    }            lib3ds_file_free(f);    return group;}/**use matrix to pretransform geometry, or NULL to do nothing*/osg::Drawable*   ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceList& faceList,Lib3dsMatrix *matrix){    osg::Geometry* geom = new osg::Geometry;    unsigned int i;        std::vector<int> orig2NewMapping;    for(i=0;i<m->points;++i) orig2NewMapping.push_back(-1);    unsigned int noVertex=0;    FaceList::iterator fitr;    for (fitr=faceList.begin();        fitr!=faceList.end();        ++fitr)    {        Lib3dsFace& face = m->faceL[*fitr];        if (orig2NewMapping[face.points[0]]<0)            orig2NewMapping[face.points[0]] = noVertex++;        if (orig2NewMapping[face.points[1]]<0)            orig2NewMapping[face.points[1]] = noVertex++;        if (orig2NewMapping[face.points[2]]<0)            orig2NewMapping[face.points[2]] = noVertex++;    }    // create vertices.        osg::Vec3Array* osg_coords = new osg::Vec3Array(noVertex);    geom->setVertexArray(osg_coords);    Lib3dsVector c;           for (i=0; i<m->points; ++i)    {        if (orig2NewMapping[i]>=0)        {            if (matrix)            {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -