Skip to content

Instantly share code, notes, and snippets.

@Erkaman
Created December 25, 2016 14:22
Show Gist options
  • Save Erkaman/e0017c0aac5969c357d7f1cde0dc31cb to your computer and use it in GitHub Desktop.
Save Erkaman/e0017c0aac5969c357d7f1cde0dc31cb to your computer and use it in GitHub Desktop.
/*
GLM
*/
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <sstream>
#include <fstream>
#include <stdio.h>
#include <vector>
using std::string;
using std::vector;
using glm::vec3;
/*
Global variables below.
*/
const int WINDOW_WIDTH = 960;
const int WINDOW_HEIGHT = 650;
float cameraYaw = 3.97f;
float cameraPitch = 0.2f;
float cameraZoom = 6.3f;
glm::vec3 cameraPos;
glm::mat4 viewMatrix;
glm::mat4 projectionMatrix;
glm::vec2 trans(glm::mat4 MVP, glm::vec3 p0, int width, int height) {
glm::vec4 v0 = MVP * glm::vec4(p0, 1.0);
glm::vec3 a0 = glm::vec3( v0.x / v0.w, v0.y / v0.w, v0.z / v0.w );
glm::vec2 b0 = glm::vec2(
(a0.x + 1.0) * (width * 0.5),
(a0.y + 1.0) * (height * 0.5)
);
return b0;
}
/*
Update view matrix according pitch and yaw. Is called every frame.
*/
void UpdateViewMatrix() {
glm::mat4 cameraTransform;
cameraTransform = glm::rotate(cameraTransform, cameraYaw, glm::vec3(0.f, 1.f, 0.f)); // add yaw
cameraTransform = glm::rotate(cameraTransform, cameraPitch, glm::vec3(0.f, 0.f, 1.f)); // add pitch
glm::vec3 up(0.0f, 1.0f, 0.0f);
glm::vec3 center(0.0f, 0.0f, 0.0f);
cameraPos = glm::vec3(cameraTransform * glm::vec4(cameraZoom, 0.0, 0.0, 1.0));
viewMatrix = glm::lookAt(
cameraPos,
center,
up
);
}
void LoadMesh(void) {
using namespace std;
ifstream file("../mask.obj");
vector<float> vertices;
vector<int> faces;
// parse the obj file:
string token;
while(!file.eof()) {
token = "";
file >> token;
if(token == "v") { // vertex.
float x, y, z;
file >> x >> y >> z;
vertices.push_back(x);
vertices.push_back(y);
vertices.push_back(z);
}
else if(token=="f")
{
string line;
getline(file, line);
istringstream stream(line);
vector<string> vertices;
copy(istream_iterator<string>(stream),
istream_iterator<string>(),
back_inserter(vertices));
if(vertices.size() != 3) {
printf("ERROR: Found primitive with %ld vertices. But only meshes with only triangles are accepted!", vertices.size());
exit(1);
}
for(size_t i=0 ; i< 3 ; ++i) {
string::size_type _pos = vertices[i].find('/', 0);
string _indexStr = vertices[i].substr(0, _pos);
faces.push_back(stoi(_indexStr)-1);
}
}
}
glm::vec3* vVertices = (glm::vec3*)vertices.data();
vector<glm::vec3> lines;
for(int i = 0; i < faces.size(); i+=3) {
int i0 = faces[i+0];
int i1 = faces[i+1];
int i2 = faces[i+2];
lines.push_back(vVertices[i0]);
lines.push_back(vVertices[i1]);
lines.push_back(vVertices[i1]);
lines.push_back(vVertices[i2]);
lines.push_back(vVertices[i2]);
lines.push_back(vVertices[i0]);
}
glm::mat4 MVP = projectionMatrix * viewMatrix;
int width = 960;
int height = 650;
FILE* fp = fopen ("out.svg","w");
fprintf(fp, "<svg width=\"%f\" height=\"%f\" version=\"1.1\" baseProfile=\"full\" xmlns=\"http://www.w3.org/2000/svg\">", (float)width, (float)height);
fprintf(fp, "<g transform=\"translate(0,%f) scale(1,-1)\">", (float)height);
for(int i = 0; i < lines.size(); i+=2) {
glm::vec3 p0 = lines[i+0];
glm::vec3 p1 = lines[i+1];
glm::vec2 t0 = trans(MVP, p0, width, height);
glm::vec2 t1 = trans(MVP, p1, width, height);
fprintf(fp, "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" file=\"none\" stroke=\"black\"/>", t0.x, t0.y, t1.x, t1.y);
}
fprintf(fp, "</g></svg>");
fclose(fp);
}
int main(int argc, char** argv) {
// setup projection matrix.
projectionMatrix = glm::perspective(0.9f, (float)(WINDOW_WIDTH) / WINDOW_HEIGHT, 0.1f, 200.0f);
UpdateViewMatrix();
LoadMesh();
exit(EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment