|
@@ -0,0 +1,149 @@
|
|
|
+#include "ObjFile.h"
|
|
|
+#include "Vec2.h"
|
|
|
+#include "Model3D.h"
|
|
|
+
|
|
|
+using namespace Framework;
|
|
|
+
|
|
|
+
|
|
|
+ObjFile::ObjFile(const char* path)
|
|
|
+ : ReferenceCounter()
|
|
|
+{
|
|
|
+ file.setDatei(path);
|
|
|
+ file.open(Datei::Style::lesen);
|
|
|
+ Text* line = file.leseZeile();
|
|
|
+ while (line)
|
|
|
+ {
|
|
|
+ if (line->positionVon("o ") == 0)
|
|
|
+ objectNames.add(line->getTeilText(2));
|
|
|
+ line->release();
|
|
|
+ line = file.leseZeile();
|
|
|
+ }
|
|
|
+ file.close();
|
|
|
+}
|
|
|
+
|
|
|
+Vec3<int> ObjFile::parseIndex(Text* s)
|
|
|
+{
|
|
|
+ Text* x = s->getTeilText(0, s->positionVon("/"));
|
|
|
+ Text* y = s->getTeilText(s->positionVon("/") + 1, s->positionVon("/", 1));
|
|
|
+ Text* z = s->getTeilText(s->positionVon("/", 1) + 1);
|
|
|
+ Vec3<int> result((int)*x, (int)*y, (int)*z);
|
|
|
+ x->release();
|
|
|
+ y->release();
|
|
|
+ z->release();
|
|
|
+ s->release();
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+void ObjFile::readModel(Model3DData* zTarget)
|
|
|
+{
|
|
|
+ Array<Vec3<float>> vertices;
|
|
|
+ Array<Vec2<float>> textureCoordinates;
|
|
|
+ Array<Vec3<float>> normals;
|
|
|
+ Array<Vec3<int>> indices;
|
|
|
+ // read model info
|
|
|
+ Text* line = file.leseZeile();
|
|
|
+ while (line)
|
|
|
+ {
|
|
|
+ if (line->positionVon("o "))
|
|
|
+ {
|
|
|
+ line->release();
|
|
|
+ break;;
|
|
|
+ }
|
|
|
+ if (line->positionVon("v ") == 0)
|
|
|
+ {
|
|
|
+ Text* x = line->getTeilText(2, line->positionVon(" ", 1));
|
|
|
+ Text* y = line->getTeilText(line->positionVon(" ", 1) + 1, line->positionVon(" ", 2));
|
|
|
+ Text* z = line->getTeilText(line->positionVon(" ", 2) + 1);
|
|
|
+ vertices.add(Vec3<float>((float)*x, (float)*y, (float)*z));
|
|
|
+ x->release();
|
|
|
+ y->release();
|
|
|
+ z->release();
|
|
|
+ }
|
|
|
+ if (line->positionVon("vt ") == 0)
|
|
|
+ {
|
|
|
+ Text* x = line->getTeilText(3, line->positionVon(" ", 1));
|
|
|
+ Text* y = line->getTeilText(line->positionVon(" ", 1) + 1);
|
|
|
+ textureCoordinates.add(Vec2<float>((float)*x, (float)*y));
|
|
|
+ x->release();
|
|
|
+ y->release();
|
|
|
+ }
|
|
|
+ if (line->positionVon("vn ") == 0)
|
|
|
+ {
|
|
|
+ Text* x = line->getTeilText(3, line->positionVon(" ", 1));
|
|
|
+ Text* y = line->getTeilText(line->positionVon(" ", 1) + 1, line->positionVon(" ", 2));
|
|
|
+ Text* z = line->getTeilText(line->positionVon(" ", 2) + 1);
|
|
|
+ normals.add(Vec3<float>((float)*x, (float)*y, (float)*z));
|
|
|
+ x->release();
|
|
|
+ y->release();
|
|
|
+ z->release();
|
|
|
+ }
|
|
|
+ if (line->positionVon("f ") == 0)
|
|
|
+ {
|
|
|
+ // only triangulated meshes ares supported
|
|
|
+ Text* p1 = line->getTeilText(3, line->positionVon(" ", 1));
|
|
|
+ Text* p2 = line->getTeilText(line->positionVon(" ", 1) + 1, line->positionVon(" ", 2));
|
|
|
+ Text* p3 = line->getTeilText(line->positionVon(" ", 2) + 1);
|
|
|
+ indices.add(parseIndex(p1));
|
|
|
+ indices.add(parseIndex(p2));
|
|
|
+ indices.add(parseIndex(p3));
|
|
|
+ }
|
|
|
+ line->release();
|
|
|
+ line = file.leseZeile();
|
|
|
+ }
|
|
|
+ // compute vertex data and index buffer
|
|
|
+ Array<Vertex3D> modelData;
|
|
|
+ int* indexList = new int[indices.getEintragAnzahl()];
|
|
|
+ int rInd = 0;
|
|
|
+ for (Vec3<int> index : indices)
|
|
|
+ {
|
|
|
+ Vertex3D current;
|
|
|
+ current.pos = vertices.get(index.x - 1);
|
|
|
+ current.tPos = textureCoordinates.get(index.y - 1);
|
|
|
+ current.normal = normals.get(index.z - 1);
|
|
|
+ current.knochenId = 0;
|
|
|
+ int ind = 0;
|
|
|
+ for (Vertex3D& other : modelData)
|
|
|
+ {
|
|
|
+ if (other.pos == current.pos && other.tPos == current.tPos && other.normal == current.normal)
|
|
|
+ break;
|
|
|
+ ind++;
|
|
|
+ }
|
|
|
+ if (modelData.getEintragAnzahl() == ind)
|
|
|
+ modelData.add(current);
|
|
|
+ indexList[rInd++] = ind;
|
|
|
+ }
|
|
|
+ Vertex3D* vertexData = new Vertex3D[modelData.getEintragAnzahl()];
|
|
|
+ int ind = 0;
|
|
|
+ for (Vertex3D& vertex : modelData)
|
|
|
+ vertexData[ind++] = vertex;
|
|
|
+ zTarget->setVertecies(vertexData, modelData.getEintragAnzahl());
|
|
|
+ Polygon3D* polygon = new Polygon3D();
|
|
|
+ polygon->indexAnz = indices.getEintragAnzahl();
|
|
|
+ polygon->indexList = indexList;
|
|
|
+ zTarget->addPolygon(polygon);
|
|
|
+}
|
|
|
+
|
|
|
+bool ObjFile::loadModel(const char* name, Model3DData* zTarget)
|
|
|
+{
|
|
|
+ file.open(Datei::Style::lesen);
|
|
|
+ Text* line = file.leseZeile();
|
|
|
+ while (line)
|
|
|
+ {
|
|
|
+ if (line->positionVon("o ") == 0 && line->positionVon(name) == 2 && line->getLength() == textLength(name) + 2)
|
|
|
+ {
|
|
|
+ readModel(zTarget);
|
|
|
+ line->release();
|
|
|
+ file.close();
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ line->release();
|
|
|
+ line = file.leseZeile();
|
|
|
+ }
|
|
|
+ file.close();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+const RCArray<Text>& ObjFile::getContainedModelNames() const
|
|
|
+{
|
|
|
+ return objectNames;
|
|
|
+}
|