/src/ogre/OgreMain/src/OgreMeshSerializer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #include "OgreStableHeaders.h" |
29 | | #include "OgreMeshSerializerImpl.h" |
30 | | |
31 | | namespace Ogre { |
32 | | |
33 | | class _OgrePrivate MeshVersionData : public SerializerAlloc |
34 | | { |
35 | | public: |
36 | | MeshVersion version; |
37 | | String versionString; |
38 | | MeshSerializerImpl* impl; |
39 | | |
40 | | MeshVersionData(MeshVersion _ver, const String& _string, MeshSerializerImpl* _impl) |
41 | 0 | : version(_ver), versionString(_string), impl(_impl) {} |
42 | | |
43 | 0 | ~MeshVersionData() { OGRE_DELETE impl; } |
44 | | |
45 | | }; |
46 | | |
47 | | const unsigned short HEADER_CHUNK_ID = 0x1000; |
48 | | //--------------------------------------------------------------------- |
49 | | MeshSerializer::MeshSerializer() |
50 | 0 | :mListener(0) |
51 | 0 | { |
52 | | // Init implementations |
53 | | // String identifiers have not always been 100% unified with OGRE version |
54 | | |
55 | | // Note MUST be added in reverse order so latest is first in the list |
56 | | |
57 | | // This one is a little ugly, 1.10 is used for version 1.1 legacy meshes. |
58 | | // So bump up to 1.100 |
59 | 0 | mVersionData.push_back(OGRE_NEW MeshVersionData( |
60 | 0 | MESH_VERSION_1_10, "[MeshSerializer_v1.100]", |
61 | 0 | OGRE_NEW MeshSerializerImpl())); |
62 | |
|
63 | 0 | mVersionData.push_back(OGRE_NEW MeshVersionData( |
64 | 0 | MESH_VERSION_1_8, "[MeshSerializer_v1.8]", |
65 | 0 | OGRE_NEW MeshSerializerImpl_v1_8())); |
66 | |
|
67 | 0 | mVersionData.push_back(OGRE_NEW MeshVersionData( |
68 | 0 | MESH_VERSION_1_7, "[MeshSerializer_v1.41]", |
69 | 0 | OGRE_NEW MeshSerializerImpl_v1_41())); |
70 | |
|
71 | 0 | mVersionData.push_back(OGRE_NEW MeshVersionData( |
72 | 0 | MESH_VERSION_1_4, "[MeshSerializer_v1.40]", |
73 | 0 | OGRE_NEW MeshSerializerImpl_v1_4())); |
74 | |
|
75 | 0 | mVersionData.push_back(OGRE_NEW MeshVersionData( |
76 | 0 | MESH_VERSION_1_0, "[MeshSerializer_v1.30]", |
77 | 0 | OGRE_NEW MeshSerializerImpl_v1_3())); |
78 | 0 | mVersionData.push_back(OGRE_NEW MeshVersionData( |
79 | 0 | MESH_VERSION_LEGACY, "[MeshSerializer_v1.20]", |
80 | 0 | OGRE_NEW MeshSerializerImpl_v1_2())); |
81 | |
|
82 | 0 | mVersionData.push_back(OGRE_NEW MeshVersionData( |
83 | 0 | MESH_VERSION_LEGACY, "[MeshSerializer_v1.10]", |
84 | 0 | OGRE_NEW MeshSerializerImpl_v1_1())); |
85 | | |
86 | 0 | } |
87 | | //--------------------------------------------------------------------- |
88 | | MeshSerializer::~MeshSerializer() |
89 | 0 | { |
90 | | // delete map |
91 | 0 | for (auto & i : mVersionData) |
92 | 0 | { |
93 | 0 | OGRE_DELETE i; |
94 | 0 | } |
95 | 0 | mVersionData.clear(); |
96 | |
|
97 | 0 | } |
98 | | //--------------------------------------------------------------------- |
99 | | void MeshSerializer::exportMesh(const Mesh* pMesh, const String& filename, |
100 | | MeshVersion version, Endian endianMode) |
101 | 0 | { |
102 | 0 | DataStreamPtr stream = _openFileStream(filename, std::ios::binary | std::ios::out); |
103 | | |
104 | 0 | exportMesh(pMesh, stream, version, endianMode); |
105 | | |
106 | 0 | stream->close(); |
107 | 0 | } |
108 | | //--------------------------------------------------------------------- |
109 | | void MeshSerializer::exportMesh(const Mesh* pMesh, DataStreamPtr stream, |
110 | | MeshVersion version, Endian endianMode) |
111 | 0 | { |
112 | 0 | if (version == MESH_VERSION_LEGACY) |
113 | 0 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, |
114 | 0 | "You may not supply a legacy version number (pre v1.0) for writing meshes.", |
115 | 0 | "MeshSerializer::exportMesh"); |
116 | | |
117 | 0 | MeshSerializerImpl* impl = 0; |
118 | 0 | if (version == MESH_VERSION_LATEST) |
119 | 0 | impl = mVersionData[0]->impl; |
120 | 0 | else |
121 | 0 | { |
122 | 0 | for (auto & i : mVersionData) |
123 | 0 | { |
124 | 0 | if (version == i->version) |
125 | 0 | { |
126 | 0 | impl = i->impl; |
127 | 0 | break; |
128 | 0 | } |
129 | 0 | } |
130 | 0 | } |
131 | | |
132 | 0 | if (!impl) |
133 | 0 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Cannot find serializer implementation for " |
134 | 0 | "specified version", "MeshSerializer::exportMesh"); |
135 | | |
136 | | |
137 | 0 | impl->exportMesh(pMesh, stream, endianMode); |
138 | 0 | } |
139 | | //--------------------------------------------------------------------- |
140 | | void MeshSerializer::importMesh(const DataStreamPtr& stream, Mesh* pDest) |
141 | 0 | { |
142 | 0 | determineEndianness(stream); |
143 | | |
144 | | // Read header and determine the version |
145 | 0 | unsigned short headerID; |
146 | | |
147 | | // Read header ID |
148 | 0 | readShorts(stream, &headerID, 1); |
149 | | |
150 | 0 | if (headerID != HEADER_CHUNK_ID) |
151 | 0 | { |
152 | 0 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "File header not found", |
153 | 0 | "MeshSerializer::importMesh"); |
154 | 0 | } |
155 | | // Read version |
156 | 0 | String ver = readString(stream); |
157 | | // Jump back to start |
158 | 0 | stream->seek(0); |
159 | | |
160 | | // Find the implementation to use |
161 | 0 | MeshSerializerImpl* impl = 0; |
162 | 0 | for (auto & i : mVersionData) |
163 | 0 | { |
164 | 0 | if (i->versionString == ver) |
165 | 0 | { |
166 | 0 | impl = i->impl; |
167 | 0 | break; |
168 | 0 | } |
169 | 0 | } |
170 | 0 | if (!impl) |
171 | 0 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Cannot find serializer implementation for " |
172 | 0 | "mesh version " + ver, "MeshSerializer::importMesh"); |
173 | | |
174 | | // Call implementation |
175 | 0 | impl->importMesh(stream, pDest, mListener); |
176 | | // Warn on old version of mesh |
177 | 0 | if (ver != mVersionData[0]->versionString) |
178 | 0 | { |
179 | 0 | LogManager::getSingleton().logWarning(pDest->getName() + " uses an old format " + ver + |
180 | 0 | "; upgrade with the OgreMeshUpgrader tool"); |
181 | 0 | } |
182 | |
|
183 | 0 | if(mListener) |
184 | 0 | mListener->processMeshCompleted(pDest); |
185 | |
|
186 | 0 | auto rs = Root::getSingletonPtr() ? Root::getSingleton().getRenderSystem() : NULL; |
187 | 0 | if (!rs || !rs->getCapabilities()->hasCapability(RSC_VERTEX_FORMAT_INT_10_10_10_2)) |
188 | 0 | { |
189 | | // unpacks to floats, if packed |
190 | 0 | pDest->_convertVertexElement(VES_NORMAL, VET_FLOAT3); |
191 | 0 | pDest->_convertVertexElement(VES_TANGENT, VET_FLOAT4); |
192 | 0 | } |
193 | 0 | } |
194 | | //--------------------------------------------------------------------- |
195 | | void MeshSerializer::setListener(Ogre::MeshSerializerListener *listener) |
196 | 0 | { |
197 | 0 | mListener = listener; |
198 | 0 | } |
199 | | //------------------------------------------------------------------------- |
200 | | MeshSerializerListener *MeshSerializer::getListener() |
201 | 0 | { |
202 | 0 | return mListener; |
203 | 0 | } |
204 | | } |
205 | | |