Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None
diff --git a/source/game/render/bmf_loader.cpp b/source/game/render/bmf_loader.cpp
index 91ddf6d..b64b171 100644
--- a/source/game/render/bmf_loader.cpp
+++ b/source/game/render/bmf_loader.cpp
@@ -1,261 +1,265 @@
#include "bmf_loader.h"
#include <fstream>
#include <map>
#include <string.h>
//BMF Specification (version 0):
//uint32 == "BMF "
//uint32: version number (0 for current version)
//
//uint32: vertex count
//Repeat <vertex count>:
// float x,y,z: vertex[n] coordinates
//
//uint32: normal count
//Repeat <normal count>:
// float x,y,z: normal[n] values
//
//uint32: uv count
//Repeat <uv count>:
// float u,v: uv[n] coordinates
//
//uint32: face count
//Repeat <face count>:
// If <vertex count> <= 0xffff
// uint16 v1,v2,v3: face[n] vertex indices
// Else
// uint32 v1,v2,v3: face[n] vertex indices
//
// If <normal count> > 0
// If <normal count> <= 0xffff
// uint16 n1,n2,n3: face[n] normal indices
// Else
// uint32 n1,n2,n3: face[n] normal indices
//
// If <uv count> > 0
// If <uv count> <= 0xffff
// uint16 u1,u2,u3: face[n] uv indices
// Else
// uint32 u1,u2,u3: face[n] uv indices
//First 4 characters of any Binary Mesh File
const char* bmfHead = "BMF ";
namespace render {
-struct UV {
- float u, v;
-};
-
+namespace bmf {
struct VertexIndex {
unsigned a, b, c;
VertexIndex() : a(0), b(0), c(0) {}
VertexIndex(unsigned A, unsigned B, unsigned C) : a(A), b(B), c(C) {}
bool operator<(const VertexIndex& other) const {
return memcmp(this, &other, sizeof(unsigned) * 3) < 0;
}
};
+}
+using namespace bmf;
+
+
+struct UV {
+ float u, v;
+};
void loadBinaryMesh(const char* filename, Mesh& mesh) {
static_assert(sizeof(vec3f) == 12, "vec3f must be the size of 3 floats");
static_assert(sizeof(UV) == 8, "UV must be the size of 2 floats");
std::vector<vec3f> vertices;
std::vector<vec3f> normals;
std::vector<UV> uvs;
std::ifstream file(filename, std::ios_base::binary | std::ios_base::in);
if(!file.is_open())
return;
char buff[4];
file.read(buff, 4);
if(file.fail() || strncmp(bmfHead, buff, 4) != 0)
return;
unsigned version;
file.read((char*)&version, sizeof(version));
if(file.fail() || version != 0)
return;
//Vertices
unsigned count;
file.read((char*)&count, sizeof(count));
if(file.fail() || count == 0)
return;
vertices.resize(count);
file.read((char*)&vertices.front(), sizeof(vec3f) * count);
//Normals
file.read((char*)&count, sizeof(count));
if(file.fail())
return;
normals.resize(count);
file.read((char*)&normals.front(), sizeof(vec3f) * count);
//UVs
file.read((char*)&count, sizeof(count));
if(file.fail())
return;
uvs.resize(count);
file.read((char*)&uvs.front(), sizeof(UV) * count);
//Faces
file.read((char*)&count, sizeof(count));
if(file.fail())
return;
std::map<VertexIndex,unsigned> vertexMap;
mesh.faces.reserve(count);
mesh.vertices.reserve(count);
for(unsigned i = 0; i < count; ++i) {
Mesh::Face face;
Vertex vertex[3];
VertexIndex vertIndices[3];
//Load vertex position indices
for(unsigned j = 0; j < 3; ++j) {
unsigned index;
if(vertices.size() <= 0xffff) {
unsigned short v;
file.read((char*)&v, sizeof(v));
index = v;
}
else {
file.read((char*)&index, sizeof(index));
}
if(index >= vertices.size())
index = 0;
vertex[j].position = vertices[index];
vertIndices[j].a = index;
}
//Load vertex normal indices
if(!normals.empty()) {
for(unsigned j = 0; j < 3; ++j) {
unsigned index;
if(normals.size() <= 0xffff) {
unsigned short v;
file.read((char*)&v, sizeof(v));
index = v;
}
else {
file.read((char*)&index, sizeof(index));
}
if(index >= normals.size())
index = 0;
vertex[j].normal = normals[index];
vertIndices[j].b = index;
}
}
//Load vertex uv indices
if(!uvs.empty()) {
for(unsigned j = 0; j < 3; ++j) {
unsigned index;
if(uvs.size() <= 0xffff) {
unsigned short v;
file.read((char*)&v, sizeof(v));
index = v;
}
else {
file.read((char*)&index, sizeof(index));
}
if(index >= uvs.size())
index = 0;
vertex[j].u = uvs[index].u;
vertex[j].v = uvs[index].v;
vertIndices[j].c = index;
}
}
if(file.fail())
return;
//Automatically fuse identical vertices and store results in mesh
unsigned indices[3];
for(unsigned j = 0; j < 3; ++j) {
auto previous = vertexMap.find(vertIndices[j]);
if(previous != vertexMap.end()) {
indices[j] = previous->second;
}
else {
indices[j] = (unsigned)mesh.vertices.size();
mesh.vertices.push_back(vertex[j]);
vertexMap[vertIndices[j]] = indices[j];
}
}
face.a = indices[0];
face.b = indices[1];
face.c = indices[2];
mesh.faces.push_back(face);
}
}
bool saveBinaryMesh(const char* filename, Mesh& mesh) {
std::ofstream file(filename, std::ios_base::binary | std::ios_base::out);
if(!file.is_open())
return false;
file.write(bmfHead, 4);
unsigned version = 0;
file.write((char*)&version, sizeof(version));
//TODO: Writes duplicate data unnecessarily
unsigned count;
count = (unsigned)mesh.vertices.size();
file.write((char*)&count, sizeof(count));
for(unsigned i = 0; i < count; ++i)
file.write((char*)&mesh.vertices[i].position, sizeof(vec3f));
count = (unsigned)mesh.vertices.size();
file.write((char*)&count, sizeof(count));
for(unsigned i = 0; i < count; ++i)
file.write((char*)&mesh.vertices[i].normal, sizeof(vec3f));
count = (unsigned)mesh.vertices.size();
file.write((char*)&count, sizeof(count));
for(unsigned i = 0; i < count; ++i) {
file.write((char*)&mesh.vertices[i].u, sizeof(float));
file.write((char*)&mesh.vertices[i].v, sizeof(float));
}
bool shortIndices = mesh.vertices.size() <= 0xffff;
count = (unsigned)mesh.faces.size();
file.write((char*)&count, sizeof(count));
for(unsigned i = 0; i < count; ++i) {
Mesh::Face face = mesh.faces[i];
if(shortIndices) {
unsigned short data[] = {face.a, face.b, face.c, face.a, face.b, face.c, face.a, face.b, face.c};
file.write((char*)data, sizeof(data));
}
else {
unsigned data[] = {face.a, face.b, face.c, face.a, face.b, face.c, face.a, face.b, face.c};
file.write((char*)data, sizeof(data));
}
}
return true;
}
};
diff --git a/source/game/render/obj_loader.cpp b/source/game/render/obj_loader.cpp
index 8d981aa..6c2129f 100644
--- a/source/game/render/obj_loader.cpp
+++ b/source/game/render/obj_loader.cpp
@@ -1,149 +1,153 @@
#include "render/obj_loader.h"
#include "compat/misc.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
namespace render {
+namespace obj {
struct VertexIndex {
int a, b, c;
VertexIndex(int A, int B, int C) : a(A), b(B), c(C) {}
bool operator<(const VertexIndex& other) const {
return memcmp(this, &other, sizeof(int) * 3) < 0;
}
};
+}
+
+using namespace obj;
void loadMeshOBJ(const char* filename, Mesh& mesh) {
// Read all the appropriate separate data arrays
std::vector<vec3f> vertices;
std::vector<vec3f> normals;
std::vector<float> ucoord;
std::vector<float> vcoord;
float scale = 1.f;
std::string line;
std::ifstream file(filename);
vec3f vec;
std::map<VertexIndex, unsigned> vertex_map;
if(file.is_open()) {
while(file.good()) {
std::getline(file, line);
if(line.size() == 0)
continue;
switch(line[0]) {
case 's':
if(line[1] == 'c') { //Non-standard extension 'scaling factor'
sscanf(line.c_str(), "sc %f", &scale);
}
break;
case 'v':
switch(line[1]) {
case ' ':
// Vertex
sscanf(line.c_str(), "v %f %f %f", &vec.x, &vec.y, &vec.z);
vec *= scale;
vertices.push_back(vec);
break;
case 'n':
// Normal
sscanf(line.c_str(), "vn %f %f %f", &vec.x, &vec.y, &vec.z);
normals.push_back(vec);
break;
case 't':
// Texture
float u, v;
sscanf(line.c_str(), "vt %f %f", &u, &v);
ucoord.push_back(u);
vcoord.push_back(v);
break;
}
break;
case 'f':
// Face
int vertsThisLine = 3;
int vertexIndex[4];
int uvIndex[4];
int normalIndex[4];
int elemIndex[4];
int items = sscanf(line.c_str(), "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d",
&vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2],
&vertexIndex[3], &uvIndex[3], &normalIndex[3]);
vertsThisLine = items / 3;
int vertCount = (int)vertices.size();
int normCount = (int)normals.size();
int uvCount = (int)ucoord.size();
for(int i = 0; i < vertsThisLine; ++i) {
if(vertexIndex[i] > 0)
vertexIndex[i] -= 1;
if(normalIndex[i] > 0)
normalIndex[i] -= 1;
if(uvIndex[i] > 0)
uvIndex[i] -= 1;
if(vertexIndex[i] >= vertCount || vertexIndex[i] < -vertCount)
goto ignoreFace;
if(normalIndex[i] >= normCount || normalIndex[i] < -normCount)
goto ignoreFace;
if(uvIndex[i] >= uvCount || uvIndex[i] < -uvCount)
goto ignoreFace;
if(vertexIndex[i] < 0)
vertexIndex[i] = vertCount + vertexIndex[i];
if(normalIndex[i] < 0)
normalIndex[i] = normCount + normalIndex[i];
if(uvIndex[i] < 0)
uvIndex[i] = uvCount + uvIndex[i];
VertexIndex ind(vertexIndex[i], normalIndex[i], uvIndex[i]);
auto it = vertex_map.find(ind);
if(it == vertex_map.end()) {
Vertex v;
v.position = vertices[vertexIndex[i]];
v.normal = normals[normalIndex[i]];
v.u = ucoord[uvIndex[i]];
v.v = 1.f - vcoord[uvIndex[i]];
elemIndex[i] = mesh.vertices.size();
mesh.vertices.push_back(v);
vertex_map[ind] = elemIndex[i];
}
else {
elemIndex[i] = it->second;
}
}
if(vertsThisLine >= 3)
mesh.faces.push_back(Mesh::Face(elemIndex[0], elemIndex[1], elemIndex[2]));
if(vertsThisLine >= 4)
mesh.faces.push_back(Mesh::Face(elemIndex[0], elemIndex[2], elemIndex[3]));
ignoreFace:
break;
}
}
file.close();
}
}
};

File Metadata

Mime Type
text/x-diff
Expires
Thu, May 14, 11:41 PM (1 d, 6 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63691
Default Alt Text
(10 KB)

Event Timeline