Ult3D
Implementation of "Ultimate 3D Game Engine Design & Architecture" by Allan Sherrod
Loading...
Searching...
No Matches
OBJLoader.h
Go to the documentation of this file.
1#ifndef ULT_OBJ_LOADER_H_INCLUDED
2#define ULT_OBJ_LOADER_H_INCLUDED
3
4#include <cstring>
5#include <fstream>
6#include <sstream>
7#include <string>
8
9#include "ModelData.h"
10
11namespace Ult
12{
13
15{
16 float x, y, z;
17 float tu1, tv1;
18 float nx, ny, nz;
19};
21{
22 float* vertices;
23 float* normals;
24 float* texCoords;
26};
27
32inline stObjModel* LoadOBJ(const char* fileName)
33{
34 std::ifstream fileInput(fileName);
35 if (!fileInput || !fileInput.is_open()) {
36 return nullptr;
37 }
38
39 std::string tmpLine, token;
40 int totalVertices = 0, totalNormals = 0,
41 totalTexC = 0, totalFaces = 0;
42
43 while (std::getline(fileInput, tmpLine))
44 {
45 if (tmpLine.empty()) {
46 continue;
47 }
48
49 std::stringstream ss(tmpLine);
50 ss >> token;
51 if (token == "v") { totalVertices++; }
52 else if (token == "vn") { totalNormals++; }
53 else if (token == "vt") { totalTexC++; }
54 else if (token == "f") { totalFaces++; }
55 }
56 fileInput.clear();
57 fileInput.seekg(0, fileInput.beg);
58
59 float* verts = new float[totalVertices*3];
60 float* norms = new float[totalNormals*3];
61 float* texC = new float[totalTexC*2];
62 int* faces = new int[totalFaces*9];
63 int vIndex = 0, nIndex = 0, tIndex = 0, fIndex = 0, index = 0;
64
65 while (std::getline(fileInput, tmpLine))
66 {
67 if (tmpLine.empty()) {
68 continue;
69 }
70
71 std::stringstream ss(tmpLine);
72 ss >> token;
73 if (token == "v") {
74 ss >> token;
75 verts[vIndex++] = (float)std::atof(token.c_str());
76
77 ss >> token;
78 verts[vIndex++] = (float)std::atof(token.c_str());
79
80 ss >> token;
81 verts[vIndex++] = (float)std::atof(token.c_str());
82 }
83
84 else if (token == "vn") {
85 ss >> token;
86 norms[nIndex++] = (float)std::atof(token.c_str());
87
88 ss >> token;
89 norms[nIndex++] = (float)std::atof(token.c_str());
90
91 ss >> token;
92 norms[nIndex++] = (float)std::atof(token.c_str());
93 }
94
95 else if (token == "vt") {
96 ss >> token;
97 texC[tIndex++] = (float)std::atof(token.c_str());
98
99 ss >> token;
100 texC[tIndex++] = (float)std::atof(token.c_str());
101 }
102
103 else if (token == "f") {
104 for (int i=0; i<3; i++) {
105 ss >> token;
106 int len = (int)token.size();
107 for (int s=0; s<len+1; s++) {
108 char buff[64];
109 if (token[s] != '/' && s < len) {
110 buff[index++] = token[s];
111 } else {
112 buff[index] = '\0';
113 faces[fIndex++] = (int)atoi(buff);
114 index = 0;
115 }
116 }
117 }
118 }
119 }
120
121 stObjModel* model = new stObjModel;
122 if (!model) {
123 return nullptr;
124 }
125 memset(model, 0, sizeof(stObjModel));
126
127 model->numFaces = totalFaces;
128 vIndex = 0, nIndex = 0, tIndex = 0, fIndex = 0, index = 0;
129
130 model->vertices = new float[totalFaces * 3 * 3];
131 if (totalNormals) { model->normals = new float[totalFaces * 3 * 3]; }
132 if (totalTexC) { model->texCoords = new float[totalFaces * 3 * 2]; }
133
134 for (int f=0; f<totalFaces*9; f+=3) {
135 model->vertices[vIndex+0] = verts[(faces[f+0]-1)*3 + 0];
136 model->vertices[vIndex+1] = verts[(faces[f+0]-1)*3 + 1];
137 model->vertices[vIndex+2] = verts[(faces[f+0]-1)*3 + 2];
138 vIndex += 3;
139
140 if (model->texCoords) {
141 model->texCoords[tIndex+0] = texC[(faces[f+1]-1)*2 + 0];
142 model->texCoords[tIndex+1] = texC[(faces[f+1]-1)*2 + 1];
143 tIndex += 2;
144 }
145
146 if (model->normals) {
147 model->normals[nIndex + 0] = norms[(faces[f+2]-1)*3 + 0];
148 model->normals[nIndex + 1] = norms[(faces[f+2]-1)*3 + 1];
149 model->normals[nIndex + 2] = norms[(faces[f+2]-1)*3 + 2];
150 nIndex += 3;
151 }
152 }
153
154 delete[] verts;
155 delete[] norms;
156 delete[] texC;
157 delete[] faces;
158
159 return model;
160}
161
165inline bool CreateOBJMesh(const char* fileName, ModelData* model)
166{
167 if (!model) {
168 return false;
169 }
170
171 stObjModel* loadedModel = LoadOBJ(fileName);
172 if (!loadedModel) {
173 return false;
174 }
175
176 int totalVertices = loadedModel->numFaces * 3;
177 stOBJMeshVertex* objMesh = new stOBJMeshVertex[totalVertices];
178 if (!objMesh) {
179 return false;
180 }
181
182 int i = 0, v = 0, n = 0, t = 0;
183 for (i=0; i<totalVertices; i++) {
184 objMesh[i].x = loadedModel->vertices[v++];
185 objMesh[i].y = loadedModel->vertices[v++];
186 objMesh[i].z = loadedModel->vertices[v++];
187
188 objMesh[i].nx = loadedModel->normals[n++];
189 objMesh[i].ny = loadedModel->normals[n++];
190 objMesh[i].nz = loadedModel->normals[n++];
191
192 objMesh[i].tu1 = loadedModel->texCoords[t++];
193 objMesh[i].tv1 = loadedModel->texCoords[t++];
194 }
195
196 model->Clear();
200 if (!model->SetVertices(
202 totalVertices,
203 sizeof(stOBJMeshVertex),
204 (char*)objMesh)) {
205 return false;
206 }
207 model->SetIndices(0, nullptr);
208
209 delete[] loadedModel;
210 delete[] objMesh;
211
212 return true;
213}
214
215} // namespace Ult
216
217#endif // ULT_OBJ_LOADER_H_INCLUDED
218
Definition ModelData.h:26
void Clear()
Definition ModelData.cpp:21
bool SetIndices(int totalIndices, unsigned int *indices)
Definition ModelData.cpp:36
bool AddDescriptorElement(ElementType type)
Definition ModelData.h:49
bool SetVertices(PrimitiveType type, int totalVertices, int stride, char *vertices)
Definition ModelData.cpp:53
@ ULT_TRI_LIST
Definition PrimitiveType.h:12
@ ULT_VERTEX_3F
Definition ElementType.h:13
@ ULT_TEX1_2F
Definition ElementType.h:16
@ ULT_NORMAL_3F
Definition ElementType.h:14
Definition Archive.h:13
stObjModel * LoadOBJ(const char *fileName)
Definition OBJLoader.h:32
bool CreateOBJMesh(const char *fileName, ModelData *model)
Definition OBJLoader.h:165
Definition OBJLoader.h:15
float y
Definition OBJLoader.h:16
float tv1
Definition OBJLoader.h:17
float nz
Definition OBJLoader.h:18
float ny
Definition OBJLoader.h:18
float nx
Definition OBJLoader.h:18
float x
Definition OBJLoader.h:16
float tu1
Definition OBJLoader.h:17
float z
Definition OBJLoader.h:16
Definition OBJLoader.h:21
int numFaces
Definition OBJLoader.h:25
float * vertices
Definition OBJLoader.h:22
float * normals
Definition OBJLoader.h:23
float * texCoords
Definition OBJLoader.h:24