vrheights

changeset 8:3f221bdc9bab

mesh loading walk polys
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 03 Oct 2014 04:16:16 +0300
parents 0eca023ed909
children df3a70664a7d
files src/game.cc src/game_var.cc src/material.cc src/material.h src/mesh.cc src/mesh.h src/object.cc src/object.h src/scenefile.cc src/scenefile.h src/texman.cc src/texman.h
diffstat 12 files changed, 806 insertions(+), 15 deletions(-) [+]
line diff
     1.1 --- a/src/game.cc	Wed Oct 01 01:06:55 2014 +0300
     1.2 +++ b/src/game.cc	Fri Oct 03 04:16:16 2014 +0300
     1.3 @@ -10,6 +10,7 @@
     1.4  #include "console.h"
     1.5  #include "drawtext.h"
     1.6  #include "game_var.h"
     1.7 +#include "scenefile.h"
     1.8  
     1.9  static void draw_scene();
    1.10  static void material(float r, float g, float b, float roughness);
    1.11 @@ -26,19 +27,33 @@
    1.12  
    1.13  static unsigned int chess_tex;
    1.14  
    1.15 -static float cam_theta, cam_phi;
    1.16 -static Vector3 cam_pos;
    1.17 +static float cam_theta = -90, cam_phi;
    1.18 +static Vector3 cam_pos = {15.4, 0, 0};
    1.19  static bool keystate[256];
    1.20  
    1.21  static Console con;
    1.22  static dtx_font *con_font;
    1.23  
    1.24 -#define OPT_LOOK_WALK	"look-walk"
    1.25 +static SceneFile scn;
    1.26 +
    1.27 +#define GVAR_LOOK_WALK	"look-walk"
    1.28 +#define GVAR_MAX_STEP	"max-step"
    1.29  
    1.30  bool game_init()
    1.31  {
    1.32  	init_opengl();
    1.33  
    1.34 +	if(!(con_font = dtx_open_font_glyphmap("data/mono14.glyphmap"))) {
    1.35 +		fprintf(stderr, "failed to open console font\n");
    1.36 +		return false;
    1.37 +	}
    1.38 +	con.set_font(con_font, 14);
    1.39 +	con.set_size(7, 52);
    1.40 +	con.set_position(0, 0, Console::CENTER);
    1.41 +	con.set_command_func(con_handle);
    1.42 +	con.set_echo(false);
    1.43 +
    1.44 +
    1.45  	if(vr_init() == -1) {
    1.46  		return false;
    1.47  	}
    1.48 @@ -57,18 +72,14 @@
    1.49  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    1.50  	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, chess_pixels);
    1.51  
    1.52 -	if(!(con_font = dtx_open_font_glyphmap("data/mono14.glyphmap"))) {
    1.53 -		fprintf(stderr, "failed to open console font\n");
    1.54 +	if(!scn.load("data/sibenik.goatsce")) {
    1.55 +		fprintf(stderr, "failed to load scene file\n");
    1.56  		return false;
    1.57  	}
    1.58 -	con.set_font(con_font, 14);
    1.59 -	con.set_size(7, 52);
    1.60 -	con.set_position(0, 0, Console::CENTER);
    1.61 -	con.set_command_func(con_handle);
    1.62 -	con.set_echo(false);
    1.63  
    1.64  	/* initialize all option variables */
    1.65 -	set_gvar_bool(OPT_LOOK_WALK, true);
    1.66 +	set_gvar_bool(GVAR_LOOK_WALK, true);
    1.67 +	set_gvar_num(GVAR_MAX_STEP, 0.5);
    1.68  
    1.69  	return true;
    1.70  }
    1.71 @@ -105,7 +116,7 @@
    1.72  		dir += Vector3(0, 0, offs);
    1.73  	}
    1.74  
    1.75 -	if(get_gvar_bool(OPT_LOOK_WALK)) {
    1.76 +	if(get_gvar_bool(GVAR_LOOK_WALK)) {
    1.77  		float rot[4];
    1.78  		vr_view_rotation(0, rot);
    1.79  		Quaternion q(rot[3], rot[0], rot[1], rot[2]);
    1.80 @@ -118,6 +129,8 @@
    1.81  	cam_pos.x += dir.x * cos_theta - dir.z * sin_theta;
    1.82  	cam_pos.z += dir.x * sin_theta + dir.z * cos_theta;
    1.83  
    1.84 +	float max_step = get_gvar_num(GVAR_MAX_STEP);
    1.85 +	cam_pos = scn.find_walk_pos(cam_pos + Vector3(0, max_step, 0));
    1.86  }
    1.87  
    1.88  void game_display()
    1.89 @@ -242,6 +255,8 @@
    1.90  	}
    1.91  }
    1.92  
    1.93 +MeshFace dbg_walk_face;
    1.94 +
    1.95  static void draw_scene()
    1.96  {
    1.97  	float lpos[][4] = {
    1.98 @@ -261,6 +276,7 @@
    1.99  
   1.100  	glMatrixMode(GL_MODELVIEW);
   1.101  
   1.102 +	/*
   1.103  	glBindTexture(GL_TEXTURE_2D, chess_tex);
   1.104  	glEnable(GL_TEXTURE_2D);
   1.105  	material(1, 1, 1, 1);
   1.106 @@ -272,14 +288,33 @@
   1.107  	glTexCoord2f(0, 1); glVertex3f(-10, 0, -10);
   1.108  	glEnd();
   1.109  	glDisable(GL_TEXTURE_2D);
   1.110 +	*/
   1.111  
   1.112 -	material(1, 1, 1, 0.4);
   1.113 +	/*material(1, 1, 1, 0.4);
   1.114  	glPushMatrix();
   1.115  	glTranslatef(0, 1.3, -10);
   1.116  	glFrontFace(GL_CW);
   1.117  	bezier_teapot(2.0);
   1.118  	glFrontFace(GL_CCW);
   1.119 -	glPopMatrix();
   1.120 +	glPopMatrix();*/
   1.121 +
   1.122 +	for(size_t i=0; i<scn.obj.size(); i++) {
   1.123 +		scn.obj[i]->draw();
   1.124 +	}
   1.125 +
   1.126 +	glPushAttrib(GL_ENABLE_BIT);
   1.127 +	glDisable(GL_DEPTH_TEST);
   1.128 +	glDisable(GL_LIGHTING);
   1.129 +
   1.130 +	glBegin(GL_TRIANGLES);
   1.131 +	glColor3f(0, 1, 0);
   1.132 +	glVertex3fv(&dbg_walk_face.v[0].x);
   1.133 +	glVertex3fv(&dbg_walk_face.v[1].x);
   1.134 +	glVertex3fv(&dbg_walk_face.v[2].x);
   1.135 +	glColor3f(1, 1, 1);
   1.136 +	glEnd();
   1.137 +
   1.138 +	glPopAttrib();
   1.139  }
   1.140  
   1.141  static void material(float r, float g, float b, float roughness)
   1.142 @@ -392,6 +427,11 @@
   1.143  
   1.144  static void con_handle(const char *cmd)
   1.145  {
   1.146 +	/* set debug values */
   1.147 +	set_gvar_num("cam-pos-x", cam_pos[0]);
   1.148 +	set_gvar_num("cam-pos-y", cam_pos[1]);
   1.149 +	set_gvar_num("cam-pos-z", cam_pos[2]);
   1.150 +
   1.151  	std::vector<char*> argv;
   1.152  	cmd = strip_spaces(cmd);
   1.153  
     2.1 --- a/src/game_var.cc	Wed Oct 01 01:06:55 2014 +0300
     2.2 +++ b/src/game_var.cc	Fri Oct 03 04:16:16 2014 +0300
     2.3 @@ -1,3 +1,4 @@
     2.4 +#include <string.h>
     2.5  #include <map>
     2.6  #include "game_var.h"
     2.7  
     2.8 @@ -138,4 +139,4 @@
     2.9  		res.push_back((it++)->first);
    2.10  	}
    2.11  	return res;
    2.12 -}
    2.13 \ No newline at end of file
    2.14 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/material.cc	Fri Oct 03 04:16:16 2014 +0300
     3.3 @@ -0,0 +1,27 @@
     3.4 +#include "material.h"
     3.5 +#include "opengl.h"
     3.6 +
     3.7 +Material::Material()
     3.8 +	: diffuse(1, 1, 1)
     3.9 +{
    3.10 +	alpha = 1.0;
    3.11 +	shininess = 60.0;
    3.12 +	tex = 0;
    3.13 +}
    3.14 +
    3.15 +void Material::setup() const
    3.16 +{
    3.17 +	float diff[] = {diffuse.x, diffuse.y, diffuse.z, alpha};
    3.18 +	float spec[] = {specular.x, specular.y, specular.z, 1.0};
    3.19 +
    3.20 +	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diff);
    3.21 +	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
    3.22 +	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess > 128.0f ? 128.0f : shininess);
    3.23 +
    3.24 +	if(tex) {
    3.25 +		glEnable(GL_TEXTURE_2D);
    3.26 +		glBindTexture(GL_TEXTURE_2D, tex);
    3.27 +	} else {
    3.28 +		glDisable(GL_TEXTURE_2D);
    3.29 +	}
    3.30 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/material.h	Fri Oct 03 04:16:16 2014 +0300
     4.3 @@ -0,0 +1,19 @@
     4.4 +#ifndef MATERIAL_H_
     4.5 +#define MATERIAL_H_
     4.6 +
     4.7 +#include <vmath/vmath.h>
     4.8 +
     4.9 +class Material {
    4.10 +public:
    4.11 +	Vector3 diffuse, specular;
    4.12 +	float shininess;
    4.13 +	float alpha;
    4.14 +
    4.15 +	unsigned int tex;
    4.16 +
    4.17 +	Material();
    4.18 +
    4.19 +	void setup() const;
    4.20 +};
    4.21 +
    4.22 +#endif	// MATERIAL_H_
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/mesh.cc	Fri Oct 03 04:16:16 2014 +0300
     5.3 @@ -0,0 +1,328 @@
     5.4 +#include <string.h>
     5.5 +#include "mesh.h"
     5.6 +#include "opengl.h"
     5.7 +
     5.8 +Mesh::Mesh()
     5.9 +{
    5.10 +	set_primitive(GL_TRIANGLES);
    5.11 +
    5.12 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    5.13 +		attrib[i].nelems = 3;
    5.14 +		attrib[i].sdrloc = -1;
    5.15 +		attrib[i].vbo = 0;
    5.16 +		attrib[i].vbo_valid = false;
    5.17 +	}
    5.18 +	num_verts = 0;
    5.19 +
    5.20 +	num_idx = 0;
    5.21 +	ibo = 0;
    5.22 +	ibo_size = 0;
    5.23 +	ibo_valid = false;
    5.24 +
    5.25 +	vbo_usage = ibo_usage = GL_STATIC_DRAW;
    5.26 +}
    5.27 +
    5.28 +Mesh::~Mesh()
    5.29 +{
    5.30 +	clear();
    5.31 +
    5.32 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    5.33 +		if(attrib[i].vbo) {
    5.34 +			glDeleteBuffers(1, &attrib[i].vbo);
    5.35 +		}
    5.36 +	}
    5.37 +	if(ibo) {
    5.38 +		glDeleteBuffers(1, &ibo);
    5.39 +	}
    5.40 +}
    5.41 +
    5.42 +void Mesh::clear()
    5.43 +{
    5.44 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    5.45 +		attrib[i].vbo_valid = false;
    5.46 +		attrib[i].data.clear();
    5.47 +
    5.48 +	}
    5.49 +	ibo_valid = false;
    5.50 +	index.clear();
    5.51 +}
    5.52 +
    5.53 +void Mesh::set_primitive(int prim)
    5.54 +{
    5.55 +	if(prim == -1) {
    5.56 +		this->prim = GL_TRIANGLES;
    5.57 +	} else {
    5.58 +		this->prim = prim;
    5.59 +	}
    5.60 +
    5.61 +	switch(this->prim) {
    5.62 +	case GL_TRIANGLES:
    5.63 +		prim_verts = 3;
    5.64 +		break;
    5.65 +
    5.66 +	case GL_QUADS:
    5.67 +		prim_verts = 4;
    5.68 +		break;
    5.69 +
    5.70 +	case GL_LINES:
    5.71 +		prim_verts = 2;
    5.72 +		break;
    5.73 +
    5.74 +	case GL_POINTS:
    5.75 +		prim_verts = 1;
    5.76 +		break;
    5.77 +
    5.78 +	default:
    5.79 +		break;
    5.80 +	}
    5.81 +}
    5.82 +
    5.83 +void Mesh::set_attrib_location(int attr, int loc)
    5.84 +{
    5.85 +	attrib[attr].sdrloc = loc;
    5.86 +}
    5.87 +
    5.88 +float *Mesh::set_vertex_data(int attr, int nelem, int count, float *data)
    5.89 +{
    5.90 +	attrib[attr].data.resize(count * nelem);
    5.91 +	if(data) {
    5.92 +		memcpy(&attrib[attr].data[0], data, nelem * count * sizeof(float));
    5.93 +	}
    5.94 +
    5.95 +	attrib[attr].nelems = nelem;
    5.96 +	attrib[attr].vbo_valid = false;
    5.97 +
    5.98 +	num_verts = count;
    5.99 +
   5.100 +	return &attrib[attr].data[0];
   5.101 +}
   5.102 +
   5.103 +unsigned int *Mesh::set_index_data(int count, unsigned int *data)
   5.104 +{
   5.105 +	index.resize(count);
   5.106 +	if(data) {
   5.107 +		memcpy(&index[0], data, count * sizeof(unsigned int));
   5.108 +	}
   5.109 +
   5.110 +	num_idx = count;
   5.111 +	ibo_valid = false;
   5.112 +
   5.113 +	return &index[0];
   5.114 +}
   5.115 +
   5.116 +int Mesh::get_vertex_count() const
   5.117 +{
   5.118 +	return num_verts;
   5.119 +}
   5.120 +
   5.121 +float *Mesh::get_vertex_data(int attr)
   5.122 +{
   5.123 +	if(attrib[attr].data.empty()) {
   5.124 +		return 0;
   5.125 +	}
   5.126 +	return &attrib[attr].data[0];
   5.127 +}
   5.128 +
   5.129 +const float *Mesh::get_vertex_data(int attr) const
   5.130 +{
   5.131 +	if(attrib[attr].data.empty()) {
   5.132 +		return 0;
   5.133 +	}
   5.134 +	return &attrib[attr].data[0];
   5.135 +}
   5.136 +
   5.137 +int Mesh::get_index_count() const
   5.138 +{
   5.139 +	return num_idx;
   5.140 +}
   5.141 +
   5.142 +unsigned int *Mesh::get_index_data()
   5.143 +{
   5.144 +	if(index.empty()) {
   5.145 +		return 0;
   5.146 +	}
   5.147 +	return &index[0];
   5.148 +}
   5.149 +
   5.150 +const unsigned int *Mesh::get_index_data() const
   5.151 +{
   5.152 +	if(index.empty()) {
   5.153 +		return 0;
   5.154 +	}
   5.155 +	return &index[0];
   5.156 +}
   5.157 +
   5.158 +int Mesh::get_face_count() const
   5.159 +{
   5.160 +	if(index.empty()) {
   5.161 +		return get_vertex_count() / prim_verts;
   5.162 +	}
   5.163 +	return get_index_count() / prim_verts;
   5.164 +}
   5.165 +
   5.166 +MeshFace Mesh::get_face(int idx) const
   5.167 +{
   5.168 +	MeshFace face;
   5.169 +	face.vcount = prim_verts;
   5.170 +
   5.171 +	int nfaces = get_face_count();
   5.172 +	if(idx < 0 || idx >= nfaces) {
   5.173 +		return face;
   5.174 +	}
   5.175 +
   5.176 +	const Vector3 *verts = (const Vector3*)&attrib[MESH_VERTEX].data[0];
   5.177 +
   5.178 +	if(index.empty()) {
   5.179 +		for(int i=0; i<3; i++) {
   5.180 +			face.v[i] = verts[idx * 3 + i];
   5.181 +		}
   5.182 +
   5.183 +	} else {
   5.184 +		for(int i=0; i<3; i++) {
   5.185 +			int vidx = index[idx * 3 + i];
   5.186 +			face.v[i] = verts[vidx];
   5.187 +		}
   5.188 +	}
   5.189 +
   5.190 +	return face;
   5.191 +}
   5.192 +
   5.193 +
   5.194 +void Mesh::begin(int prim)
   5.195 +{
   5.196 +	if(prim == -1) {
   5.197 +		this->prim = GL_TRIANGLES;
   5.198 +	} else {
   5.199 +		this->prim = prim;
   5.200 +	}
   5.201 +
   5.202 +	clear();
   5.203 +
   5.204 +	cur_norm_valid = false;
   5.205 +	cur_tc_valid = false;
   5.206 +	cur_tang_valid = false;
   5.207 +}
   5.208 +
   5.209 +void Mesh::end()
   5.210 +{
   5.211 +}
   5.212 +
   5.213 +void Mesh::vertex(float x, float y, float z)
   5.214 +{
   5.215 +	if(cur_norm_valid) {
   5.216 +		attrib[MESH_NORMAL].data.push_back(cur_norm.x);
   5.217 +		attrib[MESH_NORMAL].data.push_back(cur_norm.y);
   5.218 +		attrib[MESH_NORMAL].data.push_back(cur_norm.z);
   5.219 +	}
   5.220 +	if(cur_tc_valid) {
   5.221 +		attrib[MESH_TEXCOORD].data.push_back(cur_tc.x);
   5.222 +		attrib[MESH_TEXCOORD].data.push_back(cur_tc.y);
   5.223 +	}
   5.224 +	if(cur_tang_valid) {
   5.225 +		attrib[MESH_TANGENT].data.push_back(cur_tang.x);
   5.226 +		attrib[MESH_TANGENT].data.push_back(cur_tang.y);
   5.227 +		attrib[MESH_TANGENT].data.push_back(cur_tang.z);
   5.228 +	}
   5.229 +	attrib[MESH_VERTEX].data.push_back(x);
   5.230 +	attrib[MESH_VERTEX].data.push_back(y);
   5.231 +	attrib[MESH_VERTEX].data.push_back(z);
   5.232 +}
   5.233 +
   5.234 +void Mesh::normal(float x, float y, float z)
   5.235 +{
   5.236 +	cur_norm = Vector3(x, y, z);
   5.237 +	cur_norm_valid = true;
   5.238 +}
   5.239 +
   5.240 +void Mesh::texcoord(float x, float y)
   5.241 +{
   5.242 +	cur_tc = Vector2(x, y);
   5.243 +	cur_tc_valid = true;
   5.244 +}
   5.245 +
   5.246 +void Mesh::tangent(float x, float y, float z)
   5.247 +{
   5.248 +	cur_tang = Vector3(x, y, z);
   5.249 +	cur_tang_valid = true;
   5.250 +}
   5.251 +
   5.252 +void Mesh::draw() const
   5.253 +{
   5.254 +	if(attrib[MESH_VERTEX].data.empty()) {
   5.255 +		return;
   5.256 +	}
   5.257 +
   5.258 +	bool use_norm = !attrib[MESH_NORMAL].data.empty();
   5.259 +	bool use_tc = !attrib[MESH_TEXCOORD].data.empty();
   5.260 +	bool use_tang = !attrib[MESH_TANGENT].data.empty();
   5.261 +	int norm_loc, tc_loc, tang_loc;
   5.262 +
   5.263 +	const float *ptr = &attrib[MESH_VERTEX].data[0];
   5.264 +	int loc = attrib[MESH_VERTEX].sdrloc;
   5.265 +	if(loc == -1) {
   5.266 +		glEnableClientState(GL_VERTEX_ARRAY);
   5.267 +		glVertexPointer(attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, ptr);
   5.268 +	} else {
   5.269 +		glEnableVertexAttribArray(loc);
   5.270 +		glVertexAttribPointer(loc, attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, 0, ptr);
   5.271 +	}
   5.272 +
   5.273 +	if(use_norm) {
   5.274 +		const float *ptr = &attrib[MESH_NORMAL].data[0];
   5.275 +		norm_loc = attrib[MESH_NORMAL].sdrloc;
   5.276 +		if(norm_loc == -1) {
   5.277 +			glEnableClientState(GL_NORMAL_ARRAY);
   5.278 +			glNormalPointer(GL_FLOAT, 0, ptr);
   5.279 +		} else {
   5.280 +			glEnableVertexAttribArray(norm_loc);
   5.281 +			glVertexAttribPointer(norm_loc, attrib[MESH_NORMAL].nelems, GL_FLOAT, 0, 0, ptr);
   5.282 +		}
   5.283 +	}
   5.284 +
   5.285 +	if(use_tc) {
   5.286 +		const float *ptr = &attrib[MESH_TEXCOORD].data[0];
   5.287 +		tc_loc = attrib[MESH_TEXCOORD].sdrloc;
   5.288 +		if(tc_loc == -1) {
   5.289 +			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   5.290 +			glTexCoordPointer(attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, ptr);
   5.291 +		} else {
   5.292 +			glEnableVertexAttribArray(tc_loc);
   5.293 +			glVertexAttribPointer(tc_loc, attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, 0, ptr);
   5.294 +		}
   5.295 +	}
   5.296 +
   5.297 +	if(!attrib[MESH_TANGENT].data.empty()) {
   5.298 +		const float *ptr = &attrib[MESH_TANGENT].data[0];
   5.299 +		tang_loc = attrib[MESH_TANGENT].sdrloc;
   5.300 +		if(tang_loc != -1) {
   5.301 +			glEnableVertexAttribArray(tang_loc);
   5.302 +			glVertexAttribPointer(tang_loc, attrib[MESH_TANGENT].nelems, GL_FLOAT, 0, 0, ptr);
   5.303 +		}
   5.304 +	}
   5.305 +
   5.306 +	if(!index.empty()) {
   5.307 +		glDrawElements(prim, num_idx, GL_UNSIGNED_INT, &index[0]);
   5.308 +	} else {
   5.309 +		glDrawArrays(prim, 0, num_verts * 3);
   5.310 +	}
   5.311 +
   5.312 +	if(use_norm) {
   5.313 +		if(norm_loc == -1) {
   5.314 +			glDisableClientState(GL_NORMAL_ARRAY);
   5.315 +		} else {
   5.316 +			glDisableVertexAttribArray(norm_loc);
   5.317 +		}
   5.318 +	}
   5.319 +	if(use_tc) {
   5.320 +		if(tc_loc == -1) {
   5.321 +			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   5.322 +		} else {
   5.323 +			glDisableVertexAttribArray(tc_loc);
   5.324 +		}
   5.325 +	}
   5.326 +	if(use_tang) {
   5.327 +		if(tang_loc != -1) {
   5.328 +			glDisableVertexAttribArray(tang_loc);
   5.329 +		}
   5.330 +	}
   5.331 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/mesh.h	Fri Oct 03 04:16:16 2014 +0300
     6.3 @@ -0,0 +1,83 @@
     6.4 +#ifndef MESH_H_
     6.5 +#define MESH_H_
     6.6 +
     6.7 +#include <vector>
     6.8 +#include <vmath/vmath.h>
     6.9 +
    6.10 +enum MeshAttrib {
    6.11 +	MESH_VERTEX,
    6.12 +	MESH_NORMAL,
    6.13 +	MESH_TEXCOORD,
    6.14 +	MESH_TANGENT,
    6.15 +
    6.16 +	NUM_MESH_ATTRIBS
    6.17 +};
    6.18 +
    6.19 +struct MeshAttribData {
    6.20 +	std::vector<float> data;
    6.21 +	int nelems;
    6.22 +	int sdrloc;
    6.23 +
    6.24 +	int vbo_size;
    6.25 +	unsigned int vbo;
    6.26 +	bool vbo_valid;
    6.27 +};
    6.28 +
    6.29 +struct MeshFace {
    6.30 +	int vcount;
    6.31 +	Vector3 v[4];
    6.32 +};
    6.33 +
    6.34 +class Mesh {
    6.35 +private:
    6.36 +	int prim, prim_verts;
    6.37 +	MeshAttribData attrib[NUM_MESH_ATTRIBS];
    6.38 +	int num_verts;
    6.39 +
    6.40 +	std::vector<unsigned int> index;
    6.41 +	int num_idx;
    6.42 +	unsigned int ibo;
    6.43 +	int ibo_size;
    6.44 +	bool ibo_valid;
    6.45 +
    6.46 +	unsigned int vbo_usage, ibo_usage;
    6.47 +
    6.48 +	Vector3 cur_norm, cur_tang;
    6.49 +	Vector2 cur_tc;
    6.50 +	bool cur_norm_valid, cur_tc_valid, cur_tang_valid;
    6.51 +
    6.52 +public:
    6.53 +	Mesh();
    6.54 +	~Mesh();
    6.55 +
    6.56 +	void clear();
    6.57 +
    6.58 +	void set_primitive(int prim = -1);
    6.59 +	void set_attrib_location(int attr, int loc);
    6.60 +
    6.61 +	float *set_vertex_data(int attr, int nelem, int count, float *data = 0);
    6.62 +	unsigned int *set_index_data(int count, unsigned int *data = 0);
    6.63 +
    6.64 +	int get_vertex_count() const;
    6.65 +	float *get_vertex_data(int attr);
    6.66 +	const float *get_vertex_data(int attr) const;
    6.67 +
    6.68 +	int get_index_count() const;
    6.69 +	unsigned int *get_index_data();
    6.70 +	const unsigned int *get_index_data() const;
    6.71 +
    6.72 +	int get_face_count() const;
    6.73 +	MeshFace get_face(int idx) const;
    6.74 +
    6.75 +	void begin(int prim = -1);
    6.76 +	void end();
    6.77 +
    6.78 +	void vertex(float x, float y, float z);
    6.79 +	void normal(float x, float y, float z);
    6.80 +	void texcoord(float x, float y);
    6.81 +	void tangent(float x, float y, float z);
    6.82 +
    6.83 +	void draw() const;
    6.84 +};
    6.85 +
    6.86 +#endif	// MESH_H_
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/object.cc	Fri Oct 03 04:16:16 2014 +0300
     7.3 @@ -0,0 +1,26 @@
     7.4 +#include "object.h"
     7.5 +#include "opengl.h"
     7.6 +
     7.7 +Object::Object()
     7.8 +{
     7.9 +	mesh = 0;
    7.10 +}
    7.11 +
    7.12 +void Object::set_mesh(Mesh *m)
    7.13 +{
    7.14 +	mesh = m;
    7.15 +}
    7.16 +
    7.17 +void Object::draw() const
    7.18 +{
    7.19 +	if(!mesh) return;
    7.20 +
    7.21 +	glMatrixMode(GL_MODELVIEW);
    7.22 +	glPushMatrix();
    7.23 +	glMultTransposeMatrixf(xform[0]);
    7.24 +
    7.25 +	mtl.setup();
    7.26 +	mesh->draw();
    7.27 +
    7.28 +	glPopMatrix();
    7.29 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/object.h	Fri Oct 03 04:16:16 2014 +0300
     8.3 @@ -0,0 +1,23 @@
     8.4 +#ifndef OBJECT_H_
     8.5 +#define OBJECT_H_
     8.6 +
     8.7 +#include <vmath/vmath.h>
     8.8 +#include "mesh.h"
     8.9 +#include "material.h"
    8.10 +
    8.11 +class Object {
    8.12 +private:
    8.13 +	Mesh *mesh;
    8.14 +
    8.15 +public:
    8.16 +	Material mtl;
    8.17 +	Matrix4x4 xform;
    8.18 +
    8.19 +	Object();
    8.20 +
    8.21 +	void set_mesh(Mesh *m);
    8.22 +
    8.23 +	void draw() const;
    8.24 +};
    8.25 +
    8.26 +#endif	/* OBJECT_H_ */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/scenefile.cc	Fri Oct 03 04:16:16 2014 +0300
     9.3 @@ -0,0 +1,165 @@
     9.4 +#include <float.h>
     9.5 +#include <assert.h>
     9.6 +#include <string>
     9.7 +#include <map>
     9.8 +#include "scenefile.h"
     9.9 +#include "goat3d.h"
    9.10 +#include "texman.h"
    9.11 +
    9.12 +SceneFile::SceneFile()
    9.13 +{
    9.14 +}
    9.15 +
    9.16 +SceneFile::~SceneFile()
    9.17 +{
    9.18 +}
    9.19 +
    9.20 +bool SceneFile::load(const char *fname)
    9.21 +{
    9.22 +	std::map<struct goat3d_mesh*, Mesh*> meshmap;
    9.23 +
    9.24 +	struct goat3d *g3d = goat3d_create();
    9.25 +	if(!g3d) return false;
    9.26 +
    9.27 +	if(goat3d_load(g3d, fname) == -1) {
    9.28 +		return false;
    9.29 +	}
    9.30 +
    9.31 +	int nmeshes = goat3d_get_mesh_count(g3d);
    9.32 +	for(int i=0; i<nmeshes; i++) {
    9.33 +		struct goat3d_mesh *gm = goat3d_get_mesh(g3d, i);
    9.34 +		int nverts = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_VERTEX);
    9.35 +
    9.36 +		Mesh *m = new Mesh;
    9.37 +		m->set_vertex_data(MESH_VERTEX, 3, nverts, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_VERTEX));
    9.38 +
    9.39 +		int nnorm = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_NORMAL);
    9.40 +		if(nnorm) {
    9.41 +			assert(nnorm == nverts);
    9.42 +			m->set_vertex_data(MESH_NORMAL, 3, nnorm, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_NORMAL));
    9.43 +		}
    9.44 +
    9.45 +		int ntex = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TEXCOORD);
    9.46 +		if(ntex) {
    9.47 +			assert(ntex == nverts);
    9.48 +			m->set_vertex_data(MESH_TEXCOORD, 2, ntex, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TEXCOORD));
    9.49 +		}
    9.50 +
    9.51 +		int ntang = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TANGENT);
    9.52 +		if(ntang) {
    9.53 +			assert(ntang == nverts);
    9.54 +			m->set_vertex_data(MESH_TANGENT, 3, ntang, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TANGENT));
    9.55 +		}
    9.56 +
    9.57 +		int nfaces = goat3d_get_mesh_face_count(gm);
    9.58 +		if(nfaces) {
    9.59 +			m->set_index_data(nfaces * 3, (unsigned int*)goat3d_get_mesh_faces(gm));
    9.60 +		}
    9.61 +
    9.62 +		mesh.push_back(m);
    9.63 +		meshmap[gm] = m;
    9.64 +		// TODO: do this after nodes are loaded per object to pre-transform if applicable
    9.65 +		colmesh.push_back(m);
    9.66 +	}
    9.67 +
    9.68 +	/* iterate the nodes and create objects */
    9.69 +	int nnodes = goat3d_get_node_count(g3d);
    9.70 +	for(int i=0; i<nnodes; i++) {
    9.71 +		struct goat3d_node *gn = goat3d_get_node(g3d, i);
    9.72 +		if(goat3d_get_node_type(gn) != GOAT3D_NODE_MESH) {
    9.73 +			continue;
    9.74 +		}
    9.75 +		struct goat3d_mesh *gm = (struct goat3d_mesh*)goat3d_get_node_object(gn);
    9.76 +		if(!gm) continue;
    9.77 +		Mesh *m = meshmap[gm];
    9.78 +		if(!m) continue;
    9.79 +
    9.80 +		Object *obj = new Object;
    9.81 +		obj->set_mesh(m);
    9.82 +
    9.83 +		float mat[16];
    9.84 +		goat3d_get_node_matrix(gn, mat, 0);
    9.85 +		for(int i=0; i<4; i++) {
    9.86 +			for(int j=0; j<4; j++) {
    9.87 +				obj->xform[i][j] = mat[i * 4 + j];
    9.88 +			}
    9.89 +		}
    9.90 +
    9.91 +		struct goat3d_material *gmtl = goat3d_get_mesh_mtl(gm);
    9.92 +		const float *col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_DIFFUSE);
    9.93 +		if(col) {
    9.94 +			obj->mtl.diffuse = Vector3(col[0], col[1], col[2]);
    9.95 +		}
    9.96 +		if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SPECULAR))) {
    9.97 +			obj->mtl.specular = Vector3(col[0], col[1], col[2]);
    9.98 +		}
    9.99 +		if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_ALPHA))) {
   9.100 +			obj->mtl.alpha = col[0];
   9.101 +		}
   9.102 +		if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SHININESS))) {
   9.103 +			obj->mtl.shininess = col[0];
   9.104 +		}
   9.105 +		const char *fname = goat3d_get_mtl_attrib_map(gmtl, GOAT3D_MAT_ATTR_DIFFUSE);
   9.106 +		if(fname) {
   9.107 +			obj->mtl.tex = get_texture(fname);
   9.108 +		}
   9.109 +
   9.110 +		this->obj.push_back(obj);
   9.111 +	}
   9.112 +
   9.113 +	goat3d_free(g3d);
   9.114 +	return true;
   9.115 +}
   9.116 +
   9.117 +static Vector3 bary(const Vector3 &a, const Vector3 &b, const Vector3 &c,
   9.118 +		const Vector3 &p)
   9.119 +{
   9.120 +	float ctri = cross_product(b - a, c - a).length();
   9.121 +	if(ctri == 0.0f) {
   9.122 +		return Vector3(2, 0, 0);
   9.123 +	}
   9.124 +
   9.125 +	float ca = cross_product(b - p, c - p).length() / ctri;
   9.126 +	float cb = cross_product(a - p, c - p).length() / ctri;
   9.127 +	float cc = cross_product(a - p, b - p).length() / ctri;
   9.128 +
   9.129 +	return Vector3(ca, cb, cc);
   9.130 +}
   9.131 +
   9.132 +extern MeshFace dbg_walk_face;
   9.133 +
   9.134 +Vector3 SceneFile::find_walk_pos(const Vector3 &pos) const
   9.135 +{
   9.136 +	float max_y = -FLT_MAX;
   9.137 +	Vector3 pos_xz = Vector3(pos.x, 0, pos.z);
   9.138 +
   9.139 +	for(size_t i=0; i<colmesh.size(); i++) {
   9.140 +		const Mesh *m = colmesh[i];
   9.141 +
   9.142 +		int num_faces = m->get_face_count();
   9.143 +		for(int j=0; j<num_faces; j++) {
   9.144 +			MeshFace face = m->get_face(j);
   9.145 +
   9.146 +			Vector3 v0_xz = Vector3(face.v[0].x, 0, face.v[0].z);
   9.147 +			Vector3 v1_xz = Vector3(face.v[1].x, 0, face.v[1].z);
   9.148 +			Vector3 v2_xz = Vector3(face.v[2].x, 0, face.v[2].z);
   9.149 +
   9.150 +			Vector3 bc = bary(v0_xz, v1_xz, v2_xz, pos_xz);
   9.151 +			float bsum = bc.x + bc.y + bc.z;
   9.152 +			if(bsum > 1.000001) {
   9.153 +				continue;
   9.154 +			}
   9.155 +
   9.156 +			float y = face.v[0].y * bc.x + face.v[1].y * bc.y + face.v[2].y * bc.z;
   9.157 +			if(y > max_y && y <= pos.y) {
   9.158 +				dbg_walk_face = face;
   9.159 +				max_y = y;
   9.160 +			}
   9.161 +		}
   9.162 +	}
   9.163 +
   9.164 +	if(max_y == -FLT_MAX) {
   9.165 +		return pos;
   9.166 +	}
   9.167 +	return Vector3(pos.x, max_y, pos.z);
   9.168 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/scenefile.h	Fri Oct 03 04:16:16 2014 +0300
    10.3 @@ -0,0 +1,22 @@
    10.4 +#ifndef SCENEFILE_H_
    10.5 +#define SCENEFILE_H_
    10.6 +
    10.7 +#include <vector>
    10.8 +#include "mesh.h"
    10.9 +#include "object.h"
   10.10 +
   10.11 +class SceneFile {
   10.12 +public:
   10.13 +	std::vector<Mesh*> mesh;
   10.14 +	std::vector<Mesh*> colmesh;
   10.15 +	std::vector<Object*> obj;
   10.16 +
   10.17 +	SceneFile();
   10.18 +	~SceneFile();
   10.19 +
   10.20 +	bool load(const char *fname);
   10.21 +
   10.22 +	Vector3 find_walk_pos(const Vector3 &pos) const;
   10.23 +};
   10.24 +
   10.25 +#endif	// SCENEFILE_H_
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/texman.cc	Fri Oct 03 04:16:16 2014 +0300
    11.3 @@ -0,0 +1,51 @@
    11.4 +#include <stdio.h>
    11.5 +#include <string>
    11.6 +#include <map>
    11.7 +#include <imago2.h>
    11.8 +#include "opengl.h"
    11.9 +#include "texman.h"
   11.10 +
   11.11 +static std::string find_datafile(const std::string &fname);
   11.12 +
   11.13 +static std::map<std::string, unsigned int> textures;
   11.14 +static const char *paths[] = {
   11.15 +	"data",
   11.16 +	0
   11.17 +};
   11.18 +
   11.19 +unsigned int get_texture(const char *fname)
   11.20 +{
   11.21 +	unsigned int tex;
   11.22 +
   11.23 +	if(!fname || !*fname) {
   11.24 +		return 0;
   11.25 +	}
   11.26 +
   11.27 +	std::map<std::string, unsigned int>::const_iterator it = textures.find(fname);
   11.28 +	if(it != textures.end()) {
   11.29 +		tex = it->second;
   11.30 +	} else {
   11.31 +		if(!(tex = img_gltexture_load(find_datafile(fname).c_str()))) {
   11.32 +			fprintf(stderr, "failed to load image: %s\n", fname);
   11.33 +		} else {
   11.34 +			textures[fname] = tex;
   11.35 +		}
   11.36 +	}
   11.37 +
   11.38 +	return tex;
   11.39 +}
   11.40 +
   11.41 +static std::string find_datafile(const std::string &fname)
   11.42 +{
   11.43 +	FILE *fp;
   11.44 +
   11.45 +	for(int i=0; paths[i]; i++) {
   11.46 +		std::string path = paths[i] + std::string("/") + fname;
   11.47 +		if((fp = fopen(path.c_str(), "rb"))) {
   11.48 +			fclose(fp);
   11.49 +			return path;
   11.50 +		}
   11.51 +	}
   11.52 +
   11.53 +	return fname;
   11.54 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/texman.h	Fri Oct 03 04:16:16 2014 +0300
    12.3 @@ -0,0 +1,6 @@
    12.4 +#ifndef TEXMAN_H_
    12.5 +#define TEXMAN_H_
    12.6 +
    12.7 +unsigned int get_texture(const char *fname);
    12.8 +
    12.9 +#endif