| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | #ifndef _FBX_WRITER_NODE_VISITOR_HEADER__ |
|---|
| 16 | #define _FBX_WRITER_NODE_VISITOR_HEADER__ |
|---|
| 17 | |
|---|
| 18 | #include <map> |
|---|
| 19 | #include <set> |
|---|
| 20 | #include <stack> |
|---|
| 21 | #include <osg/Geometry> |
|---|
| 22 | #include <osg/Material> |
|---|
| 23 | #include <osg/NodeVisitor> |
|---|
| 24 | #include <osg/PrimitiveSet> |
|---|
| 25 | #include <osgDB/FileNameUtils> |
|---|
| 26 | #include <osgDB/ReaderWriter> |
|---|
| 27 | #include <osgDB/ExternalFileWriter> |
|---|
| 28 | |
|---|
| 29 | #if defined(_MSC_VER) |
|---|
| 30 | #pragma warning( disable : 4505 ) |
|---|
| 31 | #pragma warning( default : 4996 ) |
|---|
| 32 | #endif |
|---|
| 33 | #include <fbxsdk.h> |
|---|
| 34 | |
|---|
| 35 | struct Triangle |
|---|
| 36 | { |
|---|
| 37 | unsigned int t1; |
|---|
| 38 | unsigned int t2; |
|---|
| 39 | unsigned int t3; |
|---|
| 40 | unsigned int normalIndex1; |
|---|
| 41 | unsigned int normalIndex2; |
|---|
| 42 | unsigned int normalIndex3; |
|---|
| 43 | int material; |
|---|
| 44 | }; |
|---|
| 45 | |
|---|
| 46 | struct VertexIndex |
|---|
| 47 | { |
|---|
| 48 | VertexIndex(unsigned int vertexIndex, unsigned int drawableIndex, unsigned int normalIndex) |
|---|
| 49 | : vertexIndex(vertexIndex), drawableIndex(drawableIndex), normalIndex(normalIndex) |
|---|
| 50 | {} |
|---|
| 51 | VertexIndex(const VertexIndex & v) : vertexIndex(v.vertexIndex), drawableIndex(v.drawableIndex), normalIndex(v.normalIndex) {} |
|---|
| 52 | |
|---|
| 53 | unsigned int vertexIndex; |
|---|
| 54 | unsigned int drawableIndex; |
|---|
| 55 | unsigned int normalIndex; |
|---|
| 56 | |
|---|
| 57 | bool operator<(const VertexIndex & v) const { |
|---|
| 58 | if (drawableIndex!=v.drawableIndex) return drawableIndex<v.drawableIndex; |
|---|
| 59 | return vertexIndex<v.vertexIndex; |
|---|
| 60 | } |
|---|
| 61 | }; |
|---|
| 62 | |
|---|
| 63 | typedef std::vector<std::pair<Triangle, int> > ListTriangle; |
|---|
| 64 | typedef std::map<VertexIndex, unsigned int> MapIndices; |
|---|
| 65 | |
|---|
| 66 | namespace pluginfbx |
|---|
| 67 | { |
|---|
| 68 | |
|---|
| 69 | |
|---|
| 70 | class WriterNodeVisitor: public osg::NodeVisitor |
|---|
| 71 | { |
|---|
| 72 | public: |
|---|
| 73 | WriterNodeVisitor(KFbxScene* pScene, |
|---|
| 74 | KFbxSdkManager* pSdkManager, |
|---|
| 75 | const std::string& fileName, |
|---|
| 76 | const osgDB::ReaderWriter::Options* options, |
|---|
| 77 | const std::string& srcDirectory) : |
|---|
| 78 | osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), |
|---|
| 79 | _pSdkManager(pSdkManager), |
|---|
| 80 | _succeedLastApply(true), |
|---|
| 81 | _pScene(pScene), |
|---|
| 82 | _curFbxNode(pScene->GetRootNode()), |
|---|
| 83 | _currentStateSet(new osg::StateSet()), |
|---|
| 84 | _lastMaterialIndex(0), |
|---|
| 85 | _lastMeshIndex(0), |
|---|
| 86 | _options(options), |
|---|
| 87 | _externalWriter(srcDirectory, osgDB::getFilePath(fileName), true, 0) |
|---|
| 88 | {} |
|---|
| 89 | |
|---|
| 90 | |
|---|
| 91 | bool succeedLastApply() const { return _succeedLastApply; } |
|---|
| 92 | |
|---|
| 93 | |
|---|
| 94 | void failedApply() { _succeedLastApply = false; } |
|---|
| 95 | |
|---|
| 96 | virtual void apply(osg::Geode& node); |
|---|
| 97 | virtual void apply(osg::Group& node); |
|---|
| 98 | virtual void apply(osg::MatrixTransform& node); |
|---|
| 99 | |
|---|
| 100 | void traverse (osg::Node& node) |
|---|
| 101 | { |
|---|
| 102 | pushStateSet(node.getStateSet()); |
|---|
| 103 | osg::NodeVisitor::traverse(node); |
|---|
| 104 | popStateSet(node.getStateSet()); |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | void pushStateSet(const osg::StateSet* ss) |
|---|
| 108 | { |
|---|
| 109 | if (ss) |
|---|
| 110 | { |
|---|
| 111 | |
|---|
| 112 | _stateSetStack.push(_currentStateSet.get()); |
|---|
| 113 | |
|---|
| 114 | |
|---|
| 115 | _currentStateSet = static_cast<osg::StateSet*>( |
|---|
| 116 | _currentStateSet->clone(osg::CopyOp::SHALLOW_COPY)); |
|---|
| 117 | _currentStateSet->merge(*ss); |
|---|
| 118 | } |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | |
|---|
| 122 | void popStateSet(const osg::StateSet* ss) |
|---|
| 123 | { |
|---|
| 124 | if (ss) |
|---|
| 125 | { |
|---|
| 126 | |
|---|
| 127 | _currentStateSet = _stateSetStack.top(); |
|---|
| 128 | _stateSetStack.pop(); |
|---|
| 129 | } |
|---|
| 130 | } |
|---|
| 131 | |
|---|
| 132 | |
|---|
| 133 | void copyTexture(); |
|---|
| 134 | typedef std::map<const osg::Image*, std::string> ImageSet; |
|---|
| 135 | typedef std::set<std::string> ImageFilenameSet; |
|---|
| 136 | |
|---|
| 137 | |
|---|
| 138 | class Material |
|---|
| 139 | { |
|---|
| 140 | public: |
|---|
| 141 | |
|---|
| 142 | Material(WriterNodeVisitor& writerNodeVisitor, |
|---|
| 143 | osgDB::ExternalFileWriter & externalWriter, |
|---|
| 144 | const osg::StateSet* stateset, |
|---|
| 145 | const osg::Material* mat, |
|---|
| 146 | const osg::Texture* tex, |
|---|
| 147 | KFbxSdkManager* pSdkManager, |
|---|
| 148 | const osgDB::ReaderWriter::Options * options, |
|---|
| 149 | int index = -1); |
|---|
| 150 | |
|---|
| 151 | KFbxFileTexture* getFbxTexture() const |
|---|
| 152 | { |
|---|
| 153 | return _fbxTexture; |
|---|
| 154 | } |
|---|
| 155 | |
|---|
| 156 | KFbxSurfaceMaterial* getFbxMaterial() const |
|---|
| 157 | { |
|---|
| 158 | return _fbxMaterial; |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | const osg::Image* getOsgImage() const |
|---|
| 162 | { |
|---|
| 163 | return _osgImage; |
|---|
| 164 | } |
|---|
| 165 | |
|---|
| 166 | const int getIndex() const |
|---|
| 167 | { |
|---|
| 168 | return _index; |
|---|
| 169 | } |
|---|
| 170 | |
|---|
| 171 | void setIndex(int index) |
|---|
| 172 | { |
|---|
| 173 | _index = index; |
|---|
| 174 | } |
|---|
| 175 | |
|---|
| 176 | private: |
|---|
| 177 | KFbxSurfacePhong* _fbxMaterial; |
|---|
| 178 | KFbxFileTexture* _fbxTexture; |
|---|
| 179 | int _index; |
|---|
| 180 | const osg::Image* _osgImage; |
|---|
| 181 | }; |
|---|
| 182 | |
|---|
| 183 | protected: |
|---|
| 184 | |
|---|
| 185 | |
|---|
| 186 | struct CompareStateSet |
|---|
| 187 | { |
|---|
| 188 | bool operator () (const osg::ref_ptr<const osg::StateSet>& ss1, const osg::ref_ptr<const osg::StateSet>& ss2) const |
|---|
| 189 | { |
|---|
| 190 | return *ss1 < *ss2; |
|---|
| 191 | } |
|---|
| 192 | }; |
|---|
| 193 | |
|---|
| 194 | private: |
|---|
| 195 | |
|---|
| 196 | |
|---|
| 197 | |
|---|
| 198 | |
|---|
| 199 | |
|---|
| 200 | |
|---|
| 201 | void buildFaces(const osg::Geode& geo, |
|---|
| 202 | ListTriangle& listTriangles, |
|---|
| 203 | bool texcoords); |
|---|
| 204 | |
|---|
| 205 | |
|---|
| 206 | void setLayerTextureAndMaterial(KFbxMesh* mesh); |
|---|
| 207 | |
|---|
| 208 | |
|---|
| 209 | void setControlPointAndNormalsAndUV(const osg::Geode& geo, |
|---|
| 210 | MapIndices& index_vert, |
|---|
| 211 | bool texcoords, |
|---|
| 212 | KFbxMesh* fbxMesh); |
|---|
| 213 | |
|---|
| 214 | |
|---|
| 215 | |
|---|
| 216 | |
|---|
| 217 | |
|---|
| 218 | |
|---|
| 219 | |
|---|
| 220 | |
|---|
| 221 | void createListTriangle(const osg::Geometry* geo, |
|---|
| 222 | ListTriangle& listTriangles, |
|---|
| 223 | bool& texcoords, |
|---|
| 224 | unsigned int& drawable_n); |
|---|
| 225 | |
|---|
| 226 | |
|---|
| 227 | int processStateSet(const osg::StateSet* stateset); |
|---|
| 228 | |
|---|
| 229 | typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack; |
|---|
| 230 | typedef std::map<osg::ref_ptr<const osg::StateSet>, Material, CompareStateSet> MaterialMap; |
|---|
| 231 | |
|---|
| 232 | |
|---|
| 233 | KFbxSdkManager* _pSdkManager; |
|---|
| 234 | |
|---|
| 235 | |
|---|
| 236 | bool _succeedLastApply; |
|---|
| 237 | |
|---|
| 238 | |
|---|
| 239 | std::string _directory; |
|---|
| 240 | |
|---|
| 241 | |
|---|
| 242 | KFbxScene* _pScene; |
|---|
| 243 | |
|---|
| 244 | |
|---|
| 245 | KFbxNode* _curFbxNode; |
|---|
| 246 | |
|---|
| 247 | |
|---|
| 248 | StateSetStack _stateSetStack; |
|---|
| 249 | |
|---|
| 250 | |
|---|
| 251 | osg::ref_ptr<osg::StateSet> _currentStateSet; |
|---|
| 252 | |
|---|
| 253 | |
|---|
| 254 | MaterialMap _materialMap; |
|---|
| 255 | unsigned int _lastMaterialIndex; |
|---|
| 256 | unsigned int _lastMeshIndex; |
|---|
| 257 | const osgDB::ReaderWriter::Options* _options; |
|---|
| 258 | osgDB::ExternalFileWriter _externalWriter; |
|---|
| 259 | }; |
|---|
| 260 | |
|---|
| 261 | |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | #endif // _FBX_WRITER_NODE_VISITOR_HEADER__ |
|---|