vrheights

diff src/scenefile.cc @ 8:3f221bdc9bab

mesh loading walk polys
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 03 Oct 2014 04:16:16 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/scenefile.cc	Fri Oct 03 04:16:16 2014 +0300
     1.3 @@ -0,0 +1,165 @@
     1.4 +#include <float.h>
     1.5 +#include <assert.h>
     1.6 +#include <string>
     1.7 +#include <map>
     1.8 +#include "scenefile.h"
     1.9 +#include "goat3d.h"
    1.10 +#include "texman.h"
    1.11 +
    1.12 +SceneFile::SceneFile()
    1.13 +{
    1.14 +}
    1.15 +
    1.16 +SceneFile::~SceneFile()
    1.17 +{
    1.18 +}
    1.19 +
    1.20 +bool SceneFile::load(const char *fname)
    1.21 +{
    1.22 +	std::map<struct goat3d_mesh*, Mesh*> meshmap;
    1.23 +
    1.24 +	struct goat3d *g3d = goat3d_create();
    1.25 +	if(!g3d) return false;
    1.26 +
    1.27 +	if(goat3d_load(g3d, fname) == -1) {
    1.28 +		return false;
    1.29 +	}
    1.30 +
    1.31 +	int nmeshes = goat3d_get_mesh_count(g3d);
    1.32 +	for(int i=0; i<nmeshes; i++) {
    1.33 +		struct goat3d_mesh *gm = goat3d_get_mesh(g3d, i);
    1.34 +		int nverts = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_VERTEX);
    1.35 +
    1.36 +		Mesh *m = new Mesh;
    1.37 +		m->set_vertex_data(MESH_VERTEX, 3, nverts, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_VERTEX));
    1.38 +
    1.39 +		int nnorm = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_NORMAL);
    1.40 +		if(nnorm) {
    1.41 +			assert(nnorm == nverts);
    1.42 +			m->set_vertex_data(MESH_NORMAL, 3, nnorm, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_NORMAL));
    1.43 +		}
    1.44 +
    1.45 +		int ntex = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TEXCOORD);
    1.46 +		if(ntex) {
    1.47 +			assert(ntex == nverts);
    1.48 +			m->set_vertex_data(MESH_TEXCOORD, 2, ntex, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TEXCOORD));
    1.49 +		}
    1.50 +
    1.51 +		int ntang = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TANGENT);
    1.52 +		if(ntang) {
    1.53 +			assert(ntang == nverts);
    1.54 +			m->set_vertex_data(MESH_TANGENT, 3, ntang, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TANGENT));
    1.55 +		}
    1.56 +
    1.57 +		int nfaces = goat3d_get_mesh_face_count(gm);
    1.58 +		if(nfaces) {
    1.59 +			m->set_index_data(nfaces * 3, (unsigned int*)goat3d_get_mesh_faces(gm));
    1.60 +		}
    1.61 +
    1.62 +		mesh.push_back(m);
    1.63 +		meshmap[gm] = m;
    1.64 +		// TODO: do this after nodes are loaded per object to pre-transform if applicable
    1.65 +		colmesh.push_back(m);
    1.66 +	}
    1.67 +
    1.68 +	/* iterate the nodes and create objects */
    1.69 +	int nnodes = goat3d_get_node_count(g3d);
    1.70 +	for(int i=0; i<nnodes; i++) {
    1.71 +		struct goat3d_node *gn = goat3d_get_node(g3d, i);
    1.72 +		if(goat3d_get_node_type(gn) != GOAT3D_NODE_MESH) {
    1.73 +			continue;
    1.74 +		}
    1.75 +		struct goat3d_mesh *gm = (struct goat3d_mesh*)goat3d_get_node_object(gn);
    1.76 +		if(!gm) continue;
    1.77 +		Mesh *m = meshmap[gm];
    1.78 +		if(!m) continue;
    1.79 +
    1.80 +		Object *obj = new Object;
    1.81 +		obj->set_mesh(m);
    1.82 +
    1.83 +		float mat[16];
    1.84 +		goat3d_get_node_matrix(gn, mat, 0);
    1.85 +		for(int i=0; i<4; i++) {
    1.86 +			for(int j=0; j<4; j++) {
    1.87 +				obj->xform[i][j] = mat[i * 4 + j];
    1.88 +			}
    1.89 +		}
    1.90 +
    1.91 +		struct goat3d_material *gmtl = goat3d_get_mesh_mtl(gm);
    1.92 +		const float *col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_DIFFUSE);
    1.93 +		if(col) {
    1.94 +			obj->mtl.diffuse = Vector3(col[0], col[1], col[2]);
    1.95 +		}
    1.96 +		if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SPECULAR))) {
    1.97 +			obj->mtl.specular = Vector3(col[0], col[1], col[2]);
    1.98 +		}
    1.99 +		if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_ALPHA))) {
   1.100 +			obj->mtl.alpha = col[0];
   1.101 +		}
   1.102 +		if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SHININESS))) {
   1.103 +			obj->mtl.shininess = col[0];
   1.104 +		}
   1.105 +		const char *fname = goat3d_get_mtl_attrib_map(gmtl, GOAT3D_MAT_ATTR_DIFFUSE);
   1.106 +		if(fname) {
   1.107 +			obj->mtl.tex = get_texture(fname);
   1.108 +		}
   1.109 +
   1.110 +		this->obj.push_back(obj);
   1.111 +	}
   1.112 +
   1.113 +	goat3d_free(g3d);
   1.114 +	return true;
   1.115 +}
   1.116 +
   1.117 +static Vector3 bary(const Vector3 &a, const Vector3 &b, const Vector3 &c,
   1.118 +		const Vector3 &p)
   1.119 +{
   1.120 +	float ctri = cross_product(b - a, c - a).length();
   1.121 +	if(ctri == 0.0f) {
   1.122 +		return Vector3(2, 0, 0);
   1.123 +	}
   1.124 +
   1.125 +	float ca = cross_product(b - p, c - p).length() / ctri;
   1.126 +	float cb = cross_product(a - p, c - p).length() / ctri;
   1.127 +	float cc = cross_product(a - p, b - p).length() / ctri;
   1.128 +
   1.129 +	return Vector3(ca, cb, cc);
   1.130 +}
   1.131 +
   1.132 +extern MeshFace dbg_walk_face;
   1.133 +
   1.134 +Vector3 SceneFile::find_walk_pos(const Vector3 &pos) const
   1.135 +{
   1.136 +	float max_y = -FLT_MAX;
   1.137 +	Vector3 pos_xz = Vector3(pos.x, 0, pos.z);
   1.138 +
   1.139 +	for(size_t i=0; i<colmesh.size(); i++) {
   1.140 +		const Mesh *m = colmesh[i];
   1.141 +
   1.142 +		int num_faces = m->get_face_count();
   1.143 +		for(int j=0; j<num_faces; j++) {
   1.144 +			MeshFace face = m->get_face(j);
   1.145 +
   1.146 +			Vector3 v0_xz = Vector3(face.v[0].x, 0, face.v[0].z);
   1.147 +			Vector3 v1_xz = Vector3(face.v[1].x, 0, face.v[1].z);
   1.148 +			Vector3 v2_xz = Vector3(face.v[2].x, 0, face.v[2].z);
   1.149 +
   1.150 +			Vector3 bc = bary(v0_xz, v1_xz, v2_xz, pos_xz);
   1.151 +			float bsum = bc.x + bc.y + bc.z;
   1.152 +			if(bsum > 1.000001) {
   1.153 +				continue;
   1.154 +			}
   1.155 +
   1.156 +			float y = face.v[0].y * bc.x + face.v[1].y * bc.y + face.v[2].y * bc.z;
   1.157 +			if(y > max_y && y <= pos.y) {
   1.158 +				dbg_walk_face = face;
   1.159 +				max_y = y;
   1.160 +			}
   1.161 +		}
   1.162 +	}
   1.163 +
   1.164 +	if(max_y == -FLT_MAX) {
   1.165 +		return pos;
   1.166 +	}
   1.167 +	return Vector3(pos.x, max_y, pos.z);
   1.168 +}