Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F117867
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Thu, May 14, 11:41 PM (1 d, 7 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63691
Default Alt Text
(10 KB)
Attached To
Mode
R80 StarRuler2-Source
Attached
Detach File
Event Timeline