Restructure file structure

This commit is contained in:
2014-05-09 15:24:46 +02:00
parent 66e88179e3
commit 5bfce60f7e
17 changed files with 69 additions and 53 deletions

54
src/Makefile Normal file
View File

@@ -0,0 +1,54 @@
# compiler, tools
CC = clang
PKG_CONFIG ?= pkg-config
# flags
CFLAGS ?= -march=native -O2 -pipe
CFLAGS += -std=c99 -pedantic -Wall -Wextra -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function
ifeq ($(shell $(CC) -v 2>&1 | grep 'gcc version' &>/dev/null && echo 1),1)
CFLAGS += -Wno-unused-but-set-variable
endif
LDFLAGS ?= -Wl,-O1 -Wl,--as-needed -Wl,--hash-style=gnu
ifndef NODEBUG
CFLAGS += -O0 -g3
endif
TARGET = drow-engine
HEADERS = err.h parser.h types.h print.h filereader.h gl_draw.h
OBJECTS = main.o parser.o print.o filereader.o gl_draw.c
INCS = -I.
CFLAGS += $(shell $(PKG_CONFIG) --cflags gl glu glib-2.0)
LIBS = $(shell $(PKG_CONFIG) --libs gl glu glib-2.0) -lglut -lm
CPPFLAGS += -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_GNU_SOURCE
# install variables
INSTALL = install
INSTALL_BIN = install -m755
INSTALL_DIR = install -d
PREFIX = /usr/local
LIBDIR = lib64
INSTALL_BINDIR = $(PREFIX)/bin
INSTALL_LIBDIR = $(PREFIX)/$(LIBDIR)
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(INCS) -c $*.c
all: $(TARGET)
$(TARGET): $(HEADERS) $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(INCS) -o ../$(TARGET) $(OBJECTS) $(LDFLAGS) $(LIBS)
install: $(TARGET)
$(INSTALL_DIR) "$(DESTDIR)$(INSTALL_BINDIR)"
$(INSTALL_BIN) $(TARGET) "$(DESTDIR)$(INSTALL_BINDIR)"
uninstall:
rm "$(DESTDIR)$(INSTALL_BINDIR)/$(TARGET)"
clean:
rm -f *.o $(TARGET) core vgcore*
.PHONY: all clean install uninstall

52
src/err.h Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DROW_ENGINE_ERR_H
#define _DROW_ENGINE_ERR_H
#include <stdio.h>
/**
* @file err.h
* Holds error handling macros.
* @brief error handling
*/
/**
* Abort the program with a given error message.
*/
#define ABORT(...) \
{ \
fprintf(stderr, __VA_ARGS__); \
abort(); \
}
/**
* Used for checking if a pointer is non-NULL
* after allocation.
*/
#define CHECK_PTR_VAL(ptr) \
{ \
if (ptr == NULL) { \
fprintf(stderr,"NULL Pointer in %s [%d]",__FILE__,__LINE__); \
abort(); \
} \
}
#endif /* _DROW_ENGINE_ERR_H */

96
src/filereader.c Normal file
View File

@@ -0,0 +1,96 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "err.h"
#include "filereader.h"
#include "parser.h"
#include "types.h"
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/**
* Read an obj file and return a HE_obj
* if parsing worked.
*
* @param filename file to open
* @return the HE_obj or NULL for failure
*/
HE_obj *read_obj_file(char const * const filename)
{
char *string = NULL; /* file content */
HE_obj *obj = NULL;
/* read the whole file into string */
string = read_file(filename);
if (!filename || !*filename || !string || !*string)
return NULL;
obj = parse_obj(string);
free(string);
return obj;
}
/**
* Reads a file and returns a newly allocated string.
*
* @param filename file to open
* @return newly allocated string, must be freed by the caller
*/
char *read_file(char const * const filename)
{
char buf[STD_FILE_BUF],
*string = NULL;
int objfile = 0;
size_t str_size = 0;
ssize_t n;
objfile = open(filename, O_RDONLY);
if (objfile != -1) {
/* read and copy chunks */
while ((n = read(objfile, buf, STD_FILE_BUF)) > 0) {
char *tmp_ptr = NULL;
str_size += n; /* count total bytes read */
tmp_ptr = (char*) realloc( /* allocate correct size */
string, /* pointer to realloc */
str_size /* total bytes read */
+ 1); /* space for trailing NULL byte */
CHECK_PTR_VAL(tmp_ptr);
string = tmp_ptr;
/* append buffer to string */
memcpy(string + (str_size - n), buf, n);
}
/* add trailing NULL byte */
string[str_size] = '\0';
close(objfile);
return string;
} else {
return NULL;
}
}

30
src/filereader.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DROW_ENGINE_FILEREADER_H
#define _DROW_ENGINE_FILEREADER_H
#include "types.h"
HE_obj *read_obj_file(char const * const filename);
char *read_file(char const * const filename);
#endif /* _DROW_ENGINE_FILEREADER_H */

417
src/gl_draw.c Normal file
View File

@@ -0,0 +1,417 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "err.h"
#include "filereader.h"
#include "types.h"
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <limits.h>
#include <unistd.h>
#include <stdio.h>
#define XY_WIRE_COUNT 10.0f
#define ROT_FACTOR_PLANET_SUN (360.0 / yearabs)
#define ROT_FACTOR_PLANET (360.0 / 1.0)
#define ROT_FACTOR_MOON (360.0 / dayabs)
#define SYSTEM_POS_Z -15.0f
#define SYSTEM_POS_Z_BACK 15.0f
int year;
int yearabs = 365;
int day;
int dayabs = 30;
HE_obj *obj;
/*
* static function declaration
*/
static void draw_obj(uint32_t xrot, uint32_t yrot, uint32_t zrot);
static void draw_Planet_1(void);
static void draw_Planet_2(void);
static void gl_destroy(void);
/**
* Call glVertex3f on all of the vertices of the object,
* in appropriate order.
*
* @param obj the object of which we will draw the vertices
*/
static void draw_vertices(HE_obj *obj)
{
for (uint32_t i = 0; i < obj->fc; i++) { /* for all faces */
HE_edge *tmp_edge = obj->faces[i].edge;
do { /* for all edges of the face */
glVertex3f(tmp_edge->vert->x,
tmp_edge->vert->y,
tmp_edge->vert->z);
} while ((tmp_edge = tmp_edge->next) != obj->faces[i].edge);
}
}
/**
* Draws an object.
*
* @param myxrot rotation increment around x-axis
* @param myyrot rotation increment around x-axis
* @param myzrot rotation increment around x-axis
*/
static void draw_obj(uint32_t myxrot, uint32_t myyrot, uint32_t myzrot)
{
static uint32_t xrot = 0,
yrot = 0,
zrot = 0;
xrot += myxrot;
yrot += myyrot;
zrot += myzrot;
glPushMatrix();
/* rotate according to static members */
glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z);
glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK);
/* pull into middle of universe */
glTranslatef(-obj->faces->edge->vert->x,
-obj->faces->edge->vert->y,
-obj->faces->edge->vert->z + SYSTEM_POS_Z);
glBegin(GL_POLYGON);
glColor3f(0.0f, 1.0f, 0.0f);
draw_vertices(obj);
glEnd();
glPopMatrix();
}
/**
* Draws a planet with some Saturn like rings, two moons and an axis.
* Rotates the planet around the sun, the moons around the planet
* and the planet around its axis.
*/
static void draw_Planet_1(void)
{
GLUquadric* quadric = NULL;
quadric = gluNewQuadric();
const int rot_fac_day = 15;
glPushMatrix();
/* Rotate around the sun */
glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z);
glRotatef(90, 1.0f, 0.0f, 0.0f);
glRotatef((ROT_FACTOR_PLANET_SUN * day), 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, 4.0f, 0.0f);
glRotatef((ROT_FACTOR_PLANET_SUN * day), 0.0f, 0.0f, -1.0f);
glRotatef(315, 0.0f, 1.0f, 0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
/* A rotation (full 360°) once a day is much
* too fast you woulden'd see a thing */
glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, 1.0f);
glutWireSphere(1.0f, XY_WIRE_COUNT, XY_WIRE_COUNT);
glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, -1.0f);
/* Center axis */
glPushMatrix();
glLineWidth(3);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex3f(0, 0, -5);
glVertex3f(0, 0, 5);
glEnd();
glPopMatrix();
/* circle1 */
glPushMatrix();
glColor3f(0.8f, 0.0f, 0.2f);
/* glRotatef(90, 0.0f, 1.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
gluDisk(quadric, 1.2f, 1.3f, 32, 1);
glPopMatrix();
/* circle2 */
glPushMatrix();
glColor3f(0.0f, 1.0f, 0.0f);
/* glRotatef(90, 0.0f, 1.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
gluDisk(quadric, 1.4f, 1.7f, 32, 1);
glPopMatrix();
/* Moon1 */
glPushMatrix();
glColor3f(0.0f, 0.0f, 1.0f);
/* glRotatef((ROT_FACTOR_MOON * day), 1.0f, 0.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, 2.0f, 0.0f);
glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT);
glPopMatrix();
/* Moon2 */
glPushMatrix();
glColor3f(0.0f, 1.0f, 1.0f);
/* glRotatef((ROT_FACTOR_MOON * day), 1.0f, 0.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, -2.0f, 0.0f);
glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT);
glPopMatrix();
glPopMatrix();
}
/**
* Draws a Planet with three moons.
* The planet rotates around the sun and the moons around the planet
* and the planet around its axis.
*/
static void draw_Planet_2(void)
{
glPushMatrix();
const float moon_pos_fac = 2.5;
/* Rotate around the sun */
glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z);
glRotatef(90, 1.0f, 0.0f, 0.0f);
glRotatef((ROT_FACTOR_PLANET_SUN * day), 0.0f, 0.0f, 1.0f);
glTranslatef(-2.0f, -8.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
/* A rotation (full 360°) once a day is much
* too fast you woulden'd see a thing */
const int rot_fac_day = 15;
glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, 1.0f);
glutWireSphere(1.3f, XY_WIRE_COUNT, XY_WIRE_COUNT);
glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, -1.0f);
/* Moon3 */
glPushMatrix();
glColor3f(1.0f, 1.0f, 1.0f);
glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f);
glTranslatef(cos(0 * (M_PI / 180)) * moon_pos_fac,
sin(0 * (M_PI / 180)) * moon_pos_fac, 0.0f);
glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT);
glPopMatrix();
/* Moon4 */
glPushMatrix();
glColor3f(1.0f, 0.0f, 1.0f);
glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f);
glTranslatef(cos(120 * (M_PI / 180)) * moon_pos_fac,
sin(120 * (M_PI / 180)) * moon_pos_fac, 0.0f);
glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT);
glPopMatrix();
/* Moon5 */
glPushMatrix();
glColor3f(1.0f, 0.0f, 0.0f);
glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f);
glTranslatef(cos(240 * (M_PI / 180)) * moon_pos_fac,
sin(240 * (M_PI / 180)) * moon_pos_fac, 0.0f);
glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT);
glPopMatrix();
glPopMatrix();
}
/**
* Displays the whole setup with the sun, planet one, planet two and the frame rate
*/
void display(void)
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
draw_obj(0, 0, 0);
draw_Planet_1();
draw_Planet_2();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, 500, 0.0, 500);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3f(1.0f, 1.0f, 1.0f);
glRasterPos2i(5, 10);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glEnable(GL_TEXTURE_2D);
glutSwapBuffers();
}
/**
* Sets the initial values to start the program.
*/
void init(char const * const filename)
{
obj = read_obj_file(filename);
if (!obj)
ABORT("Failed to read object file \"%s\"!", filename);
day = 0;
year = 0;
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
}
/**
* Is called when the window size changes.
* Fits the viewport to the new dimension.
*
* @param w the new width of the window
* @param h the new height of the window
*/
void reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w / (GLfloat) h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
}
/**
* Is called over and over again.
* Counts the years and days.
*/
void animate()
{
day++;
if (day >= yearabs) {
day = 0;
year++;
}
if (year >= (INT_MAX - 1000) || year < 0) {
year = 0;
}
if (day < 0) {
day = 0;
}
/* cout << day << endl; */
usleep(30000); // some very basic VScny to see the movement better
glutPostRedisplay();
}
/**
* Keyboard callback function,
*
* press t to increase the day
* press T to decrease the day
* press j to increase the year
* press J to decrease the year
* press x to rotate the middle object in x direction
* press y to rotate the middle object in y direction
* press c to rotate the middle object in z direction
* press w to translate the whole scene in y direction
* press s to translate the whole scene in -y direction
* press a to translate the whole scene in -x direction
* press d to translate the whole scene in x direction
* press q to translate the whole scene in z direction
* press e to translate the whole scene in -z direction
*
* @param key which was pressed
* @param x coordinate
* @param y coordinate
*/
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 't':
dayabs += 15;
glutPostRedisplay();
break;
case 'j':
yearabs += 50;
glutPostRedisplay();
break;
case 'T':
dayabs -= 15;
glutPostRedisplay();
break;
case 'J':
yearabs -= 50;
glutPostRedisplay();
break;
case 'x':
draw_obj(1, 0, 0);
glutPostRedisplay();
break;
case 'y':
draw_obj(0, 1, 0);
glutPostRedisplay();
break;
case 'c':
draw_obj(0, 0, 1);
glutPostRedisplay();
break;
case 'w':
glTranslatef(0.0f, 1.0f, 0.0f);
break;
case 'a':
glTranslatef(-1.0f, 0.0f, 0.0f);
break;
case 's':
glTranslatef(0.0f, -1.0f, 0.0f);
break;
case 'd':
glTranslatef(1.0f, 0.0f, 0.0f);
break;
case '+':
glTranslatef(0.0f, 0.0f, 1.0f);
break;
case '-':
glTranslatef(0.0f, 0.0f, -1.0f);
break;
case 'q':
gl_destroy();
break;
}
}
/**
* Destroy the gl session/window.
*/
static void gl_destroy(void)
{
free(obj->edges);
free(obj->vertices);
free(obj->faces);
free(obj);
glutDestroyWindow(glutGetWindow());
}

37
src/gl_draw.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DROW_ENGINE_DRAW_H
#define _DROW_ENGINE_DRAW_H
#include "types.h"
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
void init(char const * const filename);
void display(void);
void reshape(GLsizei w, GLsizei h);
void animate();
void keyboard(unsigned char key, int x, int y);
#endif /* _DROW_ENGINE_DRAW_H */

70
src/main.c Normal file
View File

@@ -0,0 +1,70 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gl_draw.h"
#include "print.h"
#include "types.h"
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#define filename __FILE__
/**
* Program help text.
*/
char const * const helptext = "Usage: drow-engine <file.obj>\n";
int main(int argc, char *argv[])
{
int windowX;
int windowY;
int screenX;
int screenY;
float factor = 0.80; /* percent of screen */
if (argc == 1) {
printf("%s", helptext);
return 1;
}
glutInit(&argc, argv);
screenX = glutGet(GLUT_SCREEN_WIDTH);
windowX = (screenX * factor);
screenY = glutGet(GLUT_SCREEN_HEIGHT);
windowY = (screenY * factor);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(((screenX / 2) - (windowX / 2)),
((screenY / 2) - (windowY / 2)));
glutInitWindowSize(windowX, windowY);
glutCreateWindow(filename);
init(argv[1]);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(animate);
glutMainLoop();
return 0;
}

178
src/parser.c Normal file
View File

@@ -0,0 +1,178 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "err.h"
#include "filereader.h"
#include "types.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* Parse an .obj string and return a HE_obj
* that represents the whole object.
*
* @param obj_string the whole string from the .obj file
* @return the HE_face array that represents the object
*/
HE_obj *parse_obj(char const * const obj_string)
{
uint32_t vc = 0, /* vertices count */
fc = 0, /* face count */
ec = 0; /* edge count */
char *string = malloc(sizeof(char) * strlen(obj_string) + 1),
*str_ptr_space = NULL, /* for strtok */
*str_ptr_newline = NULL, /* for strtok */
*str_tmp_ptr = NULL; /* for strtok */
HE_vert *vertices = NULL;
HE_edge *edges = NULL;
HE_face *faces = NULL;
HE_obj *obj = NULL;
FACE face_v = NULL;
strcpy(string, obj_string);
str_tmp_ptr = strtok_r(string, "\n", &str_ptr_newline);
while (str_tmp_ptr && *str_tmp_ptr) {
str_tmp_ptr = strtok_r(str_tmp_ptr, " ", &str_ptr_space);
/* parse vertices */
if (!strcmp(str_tmp_ptr, "v")) {
char *myfloat = NULL;
HE_vert *tmp_ptr;
tmp_ptr = (HE_vert*) realloc(vertices,
sizeof(HE_vert) * (vc + 1));
CHECK_PTR_VAL(tmp_ptr);
vertices = tmp_ptr;
/* fill x */
myfloat = strtok_r(NULL, " ", &str_ptr_space);
CHECK_PTR_VAL(myfloat);
vertices[vc].x = atof(myfloat);
/* fill y */
myfloat = strtok_r(NULL, " ", &str_ptr_space);
CHECK_PTR_VAL(myfloat);
vertices[vc].y = atof(myfloat);
/* fill z */
myfloat = strtok_r(NULL, " ", &str_ptr_space);
CHECK_PTR_VAL(myfloat);
vertices[vc].z = atof(myfloat);
/* set edge NULL */
vertices[vc].edge = NULL;
vc++;
/* exceeds 3 dimensions, malformed vertice */
if (strtok_r(NULL, " ", &str_ptr_space))
return NULL;
/* parse faces */
} else if (!strcmp(str_tmp_ptr, "f")) {
char *myint = NULL;
uint8_t i = 0;
FACE tmp_ptr = NULL;
/* fill FACE */
tmp_ptr = (FACE) realloc(face_v, sizeof(FACE*) * (fc + 1));
CHECK_PTR_VAL(tmp_ptr);
face_v = tmp_ptr;
face_v[fc] = NULL;
while ((myint = strtok_r(NULL, " ", &str_ptr_space))) {
uint32_t *tmp_ptr = NULL;
i++;
ec++;
tmp_ptr = (uint32_t*) realloc(face_v[fc],
sizeof(FACE**) * (i + 1));
CHECK_PTR_VAL(tmp_ptr);
tmp_ptr[i - 1] = (uint32_t) atoi(myint);
tmp_ptr[i] = 0; /* so we can iterate over it */
face_v[fc] = tmp_ptr;
}
fc++;
}
str_tmp_ptr = strtok_r(NULL, "\n", &str_ptr_newline);
}
faces = (HE_face*) malloc(sizeof(HE_face) * fc);
CHECK_PTR_VAL(faces);
edges = (HE_edge*) malloc(sizeof(HE_edge) * ec);
CHECK_PTR_VAL(edges);
ec = 0;
/* create HE_edges and real HE_faces */
for (uint32_t i = 0; i < fc; i++) {
uint32_t j = 0;
/* for all vertices of the face */
while (face_v[i][j]) {
edges[ec].vert = &(vertices[face_v[i][j] - 1]);
edges[ec].face = &(faces[j]);
edges[ec].pair = NULL; /* preliminary */
vertices[face_v[i][j] - 1].edge = &(edges[ec]); /* last one wins */
if (face_v[i][j + 1]) /* connect to next vertice */
edges[ec].next = &(edges[ec + 1]);
else /* no vertices left, connect to first vertice */
edges[ec].next = &(edges[ec - j]);
ec++;
j++;
}
faces[i].edge = &(edges[ec - 1]); /* "last" edge */
}
/* find pairs */
/* TODO: acceleration */
for (uint32_t i = 0; i < ec; i++) {
HE_vert *next_vert = edges[i].next->vert;
for (uint32_t j = 0; j < ec; j++)
if (next_vert == edges[j].vert)
edges[i].pair = &(edges[j]);
}
obj = (HE_obj*) malloc(sizeof(HE_obj));
CHECK_PTR_VAL(obj);
obj->vertices = vertices;
obj->vc = vc;
obj->edges = edges;
obj->ec = ec;
obj->faces = faces;
obj->fc = fc;
free(string);
for (uint32_t i = 0; i < fc; i++)
free(face_v[i]);
free(face_v);
return obj;
}

29
src/parser.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DROW_ENGINE_PARSER_H
#define _DROW_ENGINE_PARSER_H
#include "types.h"
HE_obj *parse_obj(char const * const filename);
#endif /* _DROW_ENGINE_PARSER_H */

94
src/print.c Normal file
View File

@@ -0,0 +1,94 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "types.h"
#include <stdio.h>
/**
* Print the coordinates of the starting vertices
* of all edges.
*
* @param obj the 3d object
*/
void print_edges(HE_obj *obj)
{
for (uint32_t i = 0; i < obj->ec; i++) {
printf("edge vertices %i:\n", i);
printf(" x: %f\n", obj->edges[i].vert->x);
printf(" y: %f\n", obj->edges[i].vert->y);
printf(" z: %f\n", obj->edges[i].vert->z);
printf("\n");
}
}
/**
* Print the coordinates of all vertices.
*
* @param obj the 3d object
*/
void print_vertices(HE_obj *obj)
{
printf("vertices: %d\n", obj->vc);
for (uint32_t i = 0; i < obj->vc; i++) {
printf("x[%d]: %f\n", i, obj->vertices[i].x);
printf("y[%d]: %f\n", i, obj->vertices[i].y);
printf("z[%d]: %f\n", i, obj->vertices[i].z);
printf("\n");
}
}
/**
* Print the coordinates of all edges
* that are saved in the HE_face structs.
*
* @param obj the 3d object
*/
void print_faces(HE_obj *obj)
{
for (uint32_t i = 0; i < obj->fc; i++) {
printf("face edge vertice %i:\n", i);
printf(" x: %f\n", obj->faces[i].edge->vert->x);
printf(" y: %f\n", obj->faces[i].edge->vert->y);
printf(" z: %f\n", obj->faces[i].edge->vert->z);
printf("\n");
}
}
/**
* Print all plain unconverted faces
* as they are saved in the .obj file.
*
* @param face the plain face struct
* @param fc the count of faces
*/
void print_plain_faces(FACE face, uint32_t fc)
{
printf("plain faces:\n");
for (uint32_t i = 0; i < fc - 1; i++) {
uint32_t j = 0;
printf("f:");
while (face[i][j]) {
printf(" %d", face[i][j]);
j++;
}
printf("\n");
}
printf("\n");
}

32
src/print.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DROW_ENGINE_PRINT_H
#define _DROW_ENGINE_PRINT_H
#include "types.h"
void print_edges(HE_obj *obj);
void print_vertices(HE_obj *obj);
void print_faces(HE_obj *obj);
void print_plain_faces(FACE face, uint32_t fc);
#endif /* _DROW_ENGINE_PRINT_H */

118
src/types.h Normal file
View File

@@ -0,0 +1,118 @@
/*
* Copyright 2011-2014 hasufell
*
* This file is part of a hasufell project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DROW_ENGINE_TYPES_H
#define _DROW_ENGINE_TYPES_H
#include <stdint.h>
/**
* Standard file buffer
*/
#define STD_FILE_BUF 4096
typedef uint32_t** FACE;
typedef struct HE_edge HE_edge;
typedef struct HE_vert HE_vert;
typedef struct HE_face HE_face;
typedef struct HE_obj HE_obj;
/**
* Represents a half-edge.
*/
struct HE_edge {
/**
* Start-vertex of the halfe-edge.
*/
HE_vert *vert;
/**
* Oppositely oriented adjacent half-edge.
*/
HE_edge *pair;
/**
* Face the half-edge borders.
*/
HE_face *face;
/**
* Next half-edge around the face.
*/
HE_edge *next;
};
/**
* Represents a vertex with a random attached
* hald-edge.
*/
struct HE_vert {
float x;
float y;
float z;
/**
* One of the half-edges emanating from the vertex.
*/
HE_edge *edge;
};
/**
* Represents a face
*/
struct HE_face {
/**
* One of the half-edges bordering the face.
*/
HE_edge *edge;
};
/**
* Represents a collection of HE_edge, HE_vert and HE_face
* which are all attached to one object. This is useful
* for algorithms that need to iterate over one or another.
*/
struct HE_obj {
/**
* Array of edges.
*/
HE_edge *edges;
/**
* Array of vertices.
*/
HE_vert *vertices;
/**
* Array of faces.
*/
HE_face *faces;
/**
* Count of edges.
*/
uint32_t ec;
/**
* Count of vertices.
*/
uint32_t vc;
/**
* Count of faces.
*/
uint32_t fc;
};
#endif /* _DROW_ENGINE_TYPES_H */