1#include "OpenFlightLoader.h"
7Cogs::Core::Extensions::OpenFlightLoader::OpenFlightLoader()
13bool Cogs::Core::Extensions::OpenFlightLoader::canLoadModel(Context * context,
const std::string & fileName)
15 auto ext = fileName.substr(fileName.rfind(
"."), fileName.size() - 1);
20#include <unordered_map>
28 const size_t reserve = 100000;
30 positions.reserve(reserve);
31 normals.reserve(reserve);
32 texCoords.reserve(reserve);
37 std::vector<glm::vec3> positions;
38 std::vector<glm::vec3> normals;
39 std::vector<glm::vec2> texCoords;
43 std::vector<std::vector<uint32_t>> subMeshes;
44 std::unordered_map<int, int> subMeshMapping;
48static void ParsePolygon(mgrec * rec,
void * userData)
50 auto & parseContext = *(
reinterpret_cast<ParseContext *
>(userData));
52 mgrec * vertex = mgGetChild(rec);
55 bool useTexture =
false;
57 glm::vec3 positions[4];
59 glm::vec2 texCoords[4];
63 if (mgGetVtxCoord(vertex, &pos.x, &pos.y, &pos.z) == MG_TRUE) {
64 positions[count] = glm::vec3(pos.x, pos.y, pos.z);
67 if (mgGetVtxNormal(vertex, &normals[count].x, &normals[count].y, &normals[count].z) == MG_TRUE) {
72 if (mgGetAttList(vertex, fltVU, &u, fltVV, &v, MG_NULL) == 2) {
73 texCoords[count] = glm::vec2(u, 1.0 - v);
78 vertex = mgGetNext(vertex);
82 if (count == 3 || count == 4) {
83 short textureIndex = -1;
84 short textureMappingIndex = -1;
87 fltPolyTexture, &textureIndex,
90 if (textureIndex > -1) {
91 if (textureIndex != parseContext.currentIndex) {
92 parseContext.currentIndex = parseContext.subMeshMapping[textureIndex];
95 parseContext.currentIndex = 0;
98 auto & subMeshIndexes = parseContext.subMeshes[parseContext.currentIndex];
99 const auto start = parseContext.positions.size();
102 subMeshIndexes.push_back(start);
103 subMeshIndexes.push_back(start + 1);
104 subMeshIndexes.push_back(start + 2);
106 parseContext.positions.push_back(positions[0]);
107 parseContext.positions.push_back(positions[1]);
108 parseContext.positions.push_back(positions[2]);
110 parseContext.normals.push_back(normals[0]);
111 parseContext.normals.push_back(normals[1]);
112 parseContext.normals.push_back(normals[2]);
115 parseContext.texCoords.push_back(texCoords[0]);
116 parseContext.texCoords.push_back(texCoords[1]);
117 parseContext.texCoords.push_back(texCoords[2]);
120 subMeshIndexes.push_back(start);
121 subMeshIndexes.push_back(start + 1);
122 subMeshIndexes.push_back(start + 2);
124 subMeshIndexes.push_back(start);
125 subMeshIndexes.push_back(start + 2);
126 subMeshIndexes.push_back(start + 3);
128 parseContext.positions.push_back(positions[0]);
129 parseContext.positions.push_back(positions[1]);
130 parseContext.positions.push_back(positions[2]);
131 parseContext.positions.push_back(positions[3]);
133 parseContext.normals.push_back(normals[0]);
134 parseContext.normals.push_back(normals[1]);
135 parseContext.normals.push_back(normals[2]);
136 parseContext.normals.push_back(normals[3]);
139 parseContext.texCoords.push_back(texCoords[0]);
140 parseContext.texCoords.push_back(texCoords[1]);
141 parseContext.texCoords.push_back(texCoords[2]);
142 parseContext.texCoords.push_back(texCoords[3]);
150static mgbool Parse(mgrec * db, mgrec * parent, mgrec * rec,
void * userData)
152 if (mgGetCode(rec) == fltPolygon) {
153 ParsePolygon(rec, userData);
154 }
else if (mgGetCode(rec) == fltMesh) {
161Cogs::Core::ModelHandle Cogs::Core::Extensions::OpenFlightLoader::loadModel(Context * context,
const std::string & fileName)
163 auto & modelManager = context->modelManager;
165 ParseContext parseContext;
167 mgrec * db = mgOpenDb(fileName.c_str());
169 auto modelHandle = modelManager.createModel();
170 auto modelData = modelManager.getModel(modelHandle);
173 subModel.transform = glm::mat4(1.0f);
174 subModel.mesh = modelManager.createMesh();
176 int texCount = mgGetTextureCount(db);
178 auto defmaterialHandle = context->materialManager.createMaterialInstance(context->materialManager.getDefaultMaterial());
179 auto defmaterial = context->materialManager.getMaterialInstance(defmaterialHandle);
181 defmaterial->vectorProperties[
"diffuseColor"] = glm::vec4(1, 1, 1, 1);
183 subModel.materials.push_back(defmaterialHandle);
185 parseContext.subMeshMapping[-1] = parseContext.subMeshes.size();
186 parseContext.subMeshes.push_back(std::vector<uint32_t>());
188 int textureIndex = 0;
189 char * textureName =
nullptr;
191 mgbool hasTexture = mgGetFirstTexture(db, &textureIndex, textureName);
194 auto name = mgGetTextureName(db, textureIndex);
197 auto materialHandle = context->materialManager.createMaterialInstance(context->materialManager.getDefaultMaterial());
198 auto material = context->materialManager.getMaterialInstance(materialHandle);
200 material->vectorProperties[
"diffuseColor"] = glm::vec4(1, 1, 1, 1);
202 auto tName = std::string(name);
203 auto ext = tName.substr(tName.rfind(
"."), tName.size() - 1);
205 if (ext ==
".inta" || ext ==
".rgba") {
208 auto texture = context->textureManager.loadTexture(std::string(name));
211 material->textureProperties[
"diffuseMap"] = texture;
213 if (!defmaterial->textureProperties.size()) {
214 defmaterial->textureProperties[
"diffuseMap"] = material->textureProperties[
"diffuseMap"];
219 subModel.materials.push_back(materialHandle);
221 parseContext.subMeshMapping[textureIndex] = parseContext.subMeshes.size();
222 parseContext.subMeshes.push_back(std::vector<uint32_t>());
225 hasTexture = mgGetNextTexture(db, &textureIndex, textureName);
228 mgWalk(db, Parse, MG_NULL, &parseContext, MWALK_NOREADONLY);
230 auto mesh = modelManager.getMesh(subModel.mesh);
232 mesh->count = parseContext.positions.size();
233 mesh->setPositions(std::move(parseContext.positions));
234 mesh->setNormals(std::move(parseContext.normals));
235 mesh->setTexCoords(std::move(parseContext.texCoords));
237 for (
auto & p : parseContext.subMeshes) {
238 mesh->addSubMesh(std::move(p),
false);
241 modelData->subModels.push_back(std::move(subModel));
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.