nuclear@8: #include nuclear@8: #include nuclear@8: #include nuclear@8: #include nuclear@8: #include "scenefile.h" nuclear@8: #include "goat3d.h" nuclear@8: #include "texman.h" nuclear@8: nuclear@8: SceneFile::SceneFile() nuclear@8: { nuclear@8: } nuclear@8: nuclear@8: SceneFile::~SceneFile() nuclear@8: { nuclear@8: } nuclear@8: nuclear@8: bool SceneFile::load(const char *fname) nuclear@8: { nuclear@8: std::map meshmap; nuclear@8: nuclear@8: struct goat3d *g3d = goat3d_create(); nuclear@8: if(!g3d) return false; nuclear@8: nuclear@8: if(goat3d_load(g3d, fname) == -1) { nuclear@8: return false; nuclear@8: } nuclear@8: nuclear@8: int nmeshes = goat3d_get_mesh_count(g3d); nuclear@8: for(int i=0; iset_vertex_data(MESH_VERTEX, 3, nverts, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_VERTEX)); nuclear@8: nuclear@8: int nnorm = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_NORMAL); nuclear@8: if(nnorm) { nuclear@8: assert(nnorm == nverts); nuclear@8: m->set_vertex_data(MESH_NORMAL, 3, nnorm, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_NORMAL)); nuclear@8: } nuclear@8: nuclear@8: int ntex = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TEXCOORD); nuclear@8: if(ntex) { nuclear@8: assert(ntex == nverts); nuclear@8: m->set_vertex_data(MESH_TEXCOORD, 2, ntex, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TEXCOORD)); nuclear@8: } nuclear@8: nuclear@8: int ntang = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TANGENT); nuclear@8: if(ntang) { nuclear@8: assert(ntang == nverts); nuclear@8: m->set_vertex_data(MESH_TANGENT, 3, ntang, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TANGENT)); nuclear@8: } nuclear@8: nuclear@8: int nfaces = goat3d_get_mesh_face_count(gm); nuclear@8: if(nfaces) { nuclear@8: m->set_index_data(nfaces * 3, (unsigned int*)goat3d_get_mesh_faces(gm)); nuclear@8: } nuclear@8: nuclear@8: mesh.push_back(m); nuclear@8: meshmap[gm] = m; nuclear@8: // TODO: do this after nodes are loaded per object to pre-transform if applicable nuclear@8: colmesh.push_back(m); nuclear@8: } nuclear@8: nuclear@8: /* iterate the nodes and create objects */ nuclear@8: int nnodes = goat3d_get_node_count(g3d); nuclear@8: for(int i=0; iset_mesh(m); nuclear@8: nuclear@8: float mat[16]; nuclear@8: goat3d_get_node_matrix(gn, mat, 0); nuclear@8: for(int i=0; i<4; i++) { nuclear@8: for(int j=0; j<4; j++) { nuclear@8: obj->xform[i][j] = mat[i * 4 + j]; nuclear@8: } nuclear@8: } nuclear@8: nuclear@8: struct goat3d_material *gmtl = goat3d_get_mesh_mtl(gm); nuclear@8: const float *col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_DIFFUSE); nuclear@8: if(col) { nuclear@8: obj->mtl.diffuse = Vector3(col[0], col[1], col[2]); nuclear@8: } nuclear@8: if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SPECULAR))) { nuclear@8: obj->mtl.specular = Vector3(col[0], col[1], col[2]); nuclear@8: } nuclear@8: if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_ALPHA))) { nuclear@8: obj->mtl.alpha = col[0]; nuclear@8: } nuclear@8: if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SHININESS))) { nuclear@8: obj->mtl.shininess = col[0]; nuclear@8: } nuclear@8: const char *fname = goat3d_get_mtl_attrib_map(gmtl, GOAT3D_MAT_ATTR_DIFFUSE); nuclear@8: if(fname) { nuclear@8: obj->mtl.tex = get_texture(fname); nuclear@8: } nuclear@8: nuclear@8: this->obj.push_back(obj); nuclear@8: } nuclear@8: nuclear@8: goat3d_free(g3d); nuclear@8: return true; nuclear@8: } nuclear@8: nuclear@8: static Vector3 bary(const Vector3 &a, const Vector3 &b, const Vector3 &c, nuclear@8: const Vector3 &p) nuclear@8: { nuclear@8: float ctri = cross_product(b - a, c - a).length(); nuclear@8: if(ctri == 0.0f) { nuclear@8: return Vector3(2, 0, 0); nuclear@8: } nuclear@8: nuclear@8: float ca = cross_product(b - p, c - p).length() / ctri; nuclear@8: float cb = cross_product(a - p, c - p).length() / ctri; nuclear@8: float cc = cross_product(a - p, b - p).length() / ctri; nuclear@8: nuclear@8: return Vector3(ca, cb, cc); nuclear@8: } nuclear@8: nuclear@8: extern MeshFace dbg_walk_face; nuclear@8: nuclear@8: Vector3 SceneFile::find_walk_pos(const Vector3 &pos) const nuclear@8: { nuclear@8: float max_y = -FLT_MAX; nuclear@8: Vector3 pos_xz = Vector3(pos.x, 0, pos.z); nuclear@8: nuclear@8: for(size_t i=0; iget_face_count(); nuclear@8: for(int j=0; jget_face(j); nuclear@8: nuclear@8: Vector3 v0_xz = Vector3(face.v[0].x, 0, face.v[0].z); nuclear@8: Vector3 v1_xz = Vector3(face.v[1].x, 0, face.v[1].z); nuclear@8: Vector3 v2_xz = Vector3(face.v[2].x, 0, face.v[2].z); nuclear@8: nuclear@8: Vector3 bc = bary(v0_xz, v1_xz, v2_xz, pos_xz); nuclear@8: float bsum = bc.x + bc.y + bc.z; nuclear@8: if(bsum > 1.000001) { nuclear@8: continue; nuclear@8: } nuclear@8: nuclear@8: float y = face.v[0].y * bc.x + face.v[1].y * bc.y + face.v[2].y * bc.z; nuclear@8: if(y > max_y && y <= pos.y) { nuclear@8: dbg_walk_face = face; nuclear@8: max_y = y; nuclear@8: } nuclear@8: } nuclear@8: } nuclear@8: nuclear@8: if(max_y == -FLT_MAX) { nuclear@8: return pos; nuclear@8: } nuclear@8: return Vector3(pos.x, max_y, pos.z); nuclear@8: }