# HG changeset patch # User John Tsiombikas # Date 1377053548 -10800 # Node ID cd71f0b92f442a8b16097adbdd627de0a8847c5c # Parent 97139303348c77618009b81d1da215278a90761a a bit more... diff -r 97139303348c -r cd71f0b92f44 src/camera.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/camera.cc Wed Aug 21 05:52:28 2013 +0300 @@ -0,0 +1,13 @@ +#include "camera.h" + +Camera::Camera() +{ + near_clip = 0.5; + far_clip = 500.0; +} + +TargetCamera::TargetCamera() + : target(0, 0, 0), up(0, 1, 0) +{ + pos = Vector3(0, 0, 10); +} diff -r 97139303348c -r cd71f0b92f44 src/camera.h --- a/src/camera.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/camera.h Wed Aug 21 05:52:28 2013 +0300 @@ -1,8 +1,20 @@ #ifndef CAMERA_H_ #define CAMERA_H_ -class Camera { - // TODO +#include "object.h" + +class Camera : public Object { +public: + float near_clip, far_clip; + + Camera(); +}; + +class TargetCamera : public Camera { +public: + Vector3 target, up; + + TargetCamera(); }; #endif // CAMERA_H_ diff -r 97139303348c -r cd71f0b92f44 src/chunk.h --- a/src/chunk.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/chunk.h Wed Aug 21 05:52:28 2013 +0300 @@ -57,6 +57,10 @@ CNK_MESH_SKINMATRIX_LIST, // has a series of CNK_INT4 chunks (4 matrix indices) CNK_MESH_COLOR_LIST, // has a series of CNK_FLOAT4 chunks CNK_MESH_BONES_LIST, // has a series of CNK_INT or CNK_STRING chunks identifying the bone nodes + CNK_MESH_FACE_LIST, // has a series of CNK_FACE chunks + + // child of CNK_MESH_FACE_LIST + CNK_MESH_FACE, // has three CNK_INT chunks // children of CNK_LIGHT CNK_LIGHT_NAME, // has a single CNK_STRING diff -r 97139303348c -r cd71f0b92f44 src/goat3d.cc --- a/src/goat3d.cc Wed Aug 21 04:00:22 2013 +0300 +++ b/src/goat3d.cc Wed Aug 21 05:52:28 2013 +0300 @@ -1,8 +1,6 @@ #include "goat3d.h" #include "goat3d_impl.h" -static void delete_node_tree(Node *n); - Scene::Scene() : name("unnamed"), ambient(0.05, 0.05, 0.05) { @@ -43,14 +41,6 @@ name = "unnamed"; } -static void delete_node_tree(Node *n) -{ - for(int i=0; iget_num_children(); i++) { - delete_node_tree(n->get_child(i)); - } - delete n; -} - void Scene::set_name(const char *name) { this->name = name; @@ -60,3 +50,123 @@ { return name.c_str(); } + +void Scene::set_ambient(const Vector3 &amb) +{ + ambient = amb; +} + +const Vector3 &Scene::get_ambient() const +{ + return ambient; +} + +void Scene::add_material(Material *mat) +{ + materials.push_back(mat); +} + +Material *Scene::get_material(int idx) const +{ + return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0; +} + +Material *Scene::get_material(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return materials[i]; + } + } + return 0; +} + +void Scene::add_mesh(Mesh *mesh) +{ + meshes.push_back(mesh); +} + +Mesh *Scene::get_mesh(int idx) const +{ + return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0; +} + +Mesh *Scene::get_mesh(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return meshes[i]; + } + } + return 0; +} + +void Scene::add_light(Light *light) +{ + lights.push_back(light); +} + +Light *Scene::get_light(int idx) const +{ + return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0; +} + +Light *Scene::get_light(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return lights[i]; + } + } + return 0; +} + +void Scene::add_camera(Camera *cam) +{ + cameras.push_back(cam); +} + +Camera *Scene::get_camera(int idx) const +{ + return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0; +} + +Camera *Scene::get_camera(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return cameras[i]; + } + } + return 0; +} + +void Scene::add_node(Node *node) +{ + nodes.push_back(node); +} + +Node *Scene::get_node(int idx) const +{ + return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0; +} + +Node *Scene::get_node(const char *name) const +{ + for(size_t i=0; iget_name(), name) == 0) { + return nodes[i]; + } + } + return 0; +} + +bool Scene::load(goat3d_io *io) +{ + return false; +} + +bool Scene::save(goat3d_io *io) const +{ + return false; +} diff -r 97139303348c -r cd71f0b92f44 src/light.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/light.cc Wed Aug 21 05:52:28 2013 +0300 @@ -0,0 +1,18 @@ +#include "light.h" + +Light::Light() + : color(1, 1, 1), attenuation(1, 0, 0) +{ + max_dist = 0.0; +} + +DirLight::DirLight() + : dir(0, 0, 1) +{ +} + +SpotLight::SpotLight() +{ + inner_cone = DEG_TO_RAD(30); + outer_cone = DEG_TO_RAD(45); +} diff -r 97139303348c -r cd71f0b92f44 src/light.h --- a/src/light.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/light.h Wed Aug 21 05:52:28 2013 +0300 @@ -1,8 +1,30 @@ #ifndef LIGHT_H_ #define LIGHT_H_ -class Light { - // TODO +#include +#include "object.h" + +class Light : public Object { +public: + Vector3 color; + Vector3 attenuation; + float max_dist; + + Light(); +}; + +class DirLight : public Light { +public: + Vector3 dir; + + DirLight(); +}; + +class SpotLight : public DirLight { +public: + float inner_cone, outer_cone; + + SpotLight(); }; #endif // LIGHT_H_ diff -r 97139303348c -r cd71f0b92f44 src/material.h --- a/src/material.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/material.h Wed Aug 21 05:52:28 2013 +0300 @@ -26,6 +26,8 @@ std::map attrib; public: + std::string name; + MaterialAttrib &operator [](const std::string &name) { return attrib[name]; diff -r 97139303348c -r cd71f0b92f44 src/mesh.cc --- a/src/mesh.cc Wed Aug 21 04:00:22 2013 +0300 +++ b/src/mesh.cc Wed Aug 21 05:52:28 2013 +0300 @@ -1,973 +1,23 @@ -#include -#include -#include -#include -#include "opengl.h" #include "mesh.h" -#include "xform_node.h" -//#include "logger.h" - -int Mesh::global_sdr_loc[NUM_MESH_ATTR] = { 0, 1, 2, 3, 4, 5 }; -unsigned int Mesh::intersect_mode = ISECT_DEFAULT; -float Mesh::vertex_sel_dist = 0.01; -float Mesh::vis_vecsize = 1.0; Mesh::Mesh() { - clear(); - - glGenBuffers(NUM_MESH_ATTR + 1, buffer_objects); - - for(int i=0; iname = name; + return material; } -const char *Mesh::get_name() const +const Material *Mesh::get_material() const { - return name.c_str(); + return material; } - -bool Mesh::has_attrib(int attr) const -{ - if(attr < 0 || attr >= NUM_MESH_ATTR) { - return false; - } - - // if neither of these is valid, then nobody has set this attribute - return vattr[attr].vbo_valid || vattr[attr].data_valid; -} - -void Mesh::clear() -{ - bones.clear(); - - for(int i=0; i= NUM_MESH_ATTR) { - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); - return 0; - } - - if(nverts && num != nverts) { - fprintf(stderr, "%s: attribute count missmatch (%d instead of %d)\n", __FUNCTION__, num, nverts); - return 0; - } - nverts = num; - - vattr[attrib].data.clear(); - vattr[attrib].nelem = nelem; - vattr[attrib].data.resize(num * nelem); - - if(data) { - memcpy(&vattr[attrib].data[0], data, num * nelem * sizeof *data); - } - - vattr[attrib].data_valid = true; - vattr[attrib].vbo_valid = false; - return &vattr[attrib].data[0]; -} - -float *Mesh::get_attrib_data(int attrib) -{ - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); - return 0; - } - - vattr[attrib].vbo_valid = false; - return (float*)((const Mesh*)this)->get_attrib_data(attrib); -} - -const float *Mesh::get_attrib_data(int attrib) const -{ - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); - return 0; - } - - if(!vattr[attrib].data_valid) { -#if GL_ES_VERSION_2_0 - fprintf(stderr, "%s: can't read back attrib data on CrippledGL ES\n", __FUNCTION__); - return 0; -#else - if(!vattr[attrib].vbo_valid) { - fprintf(stderr, "%s: unavailable attrib: %d\n", __FUNCTION__, attrib); - return 0; - } - - // local data copy is unavailable, grab the data from the vbo - Mesh *m = (Mesh*)this; - m->vattr[attrib].data.resize(nverts * vattr[attrib].nelem); - - glBindBuffer(GL_ARRAY_BUFFER, vattr[attrib].vbo); - void *data = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); - memcpy(&m->vattr[attrib].data[0], data, nverts * vattr[attrib].nelem * sizeof(float)); - glUnmapBuffer(GL_ARRAY_BUFFER); - - vattr[attrib].data_valid = true; -#endif - } - - return &vattr[attrib].data[0]; -} - -void Mesh::set_attrib(int attrib, int idx, const Vector4 &v) -{ - float *data = get_attrib_data(attrib); - if(data) { - data += idx * vattr[attrib].nelem; - for(int i=0; iget_index_data(); -} - -const unsigned int *Mesh::get_index_data() const -{ - if(!idata_valid) { -#if GL_ES_VERSION_2_0 - fprintf(stderr, "%s: can't read back index data in CrippledGL ES\n", __FUNCTION__); - return 0; -#else - if(!ibo_valid) { - fprintf(stderr, "%s: indices unavailable\n", __FUNCTION__); - return 0; - } - - // local data copy is unavailable, gram the data from the ibo - Mesh *m = (Mesh*)this; - int nidx = nfaces * 3; - m->idata.resize(nidx); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - void *data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); - memcpy(&m->idata[0], data, nidx * sizeof(unsigned int)); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - idata_valid = true; -#endif - } - - return &idata[0]; -} - -void Mesh::append(const Mesh &mesh) -{ - unsigned int idxoffs = nverts; - - nverts += mesh.nverts; - nfaces += mesh.nfaces; - - for(int i=0; i= NUM_MESH_ATTR) { - return; - } - Mesh::global_sdr_loc[attr] = loc; -} - -/// static function -int Mesh::get_attrib_location(int attr) -{ - if(attr < 0 || attr >= NUM_MESH_ATTR) { - return -1; - } - return Mesh::global_sdr_loc[attr]; -} - -/// static function -void Mesh::clear_attrib_locations() -{ - for(int i=0; i= (int)bones.size()) { - return 0; - } - return bones[idx]; -} - -int Mesh::get_bones_count() const -{ - return (int)bones.size(); -} - -void Mesh::draw() const -{ - ((Mesh*)this)->update_buffers(); - - if(!vattr[MESH_ATTR_VERTEX].vbo_valid) { - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); - return; - } - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); - return; - } - - for(int i=0; i= 0 && vattr[i].vbo_valid) { - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(loc); - } - } - glBindBuffer(GL_ARRAY_BUFFER, 0); - - if(ibo_valid) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } else { - glDrawArrays(GL_TRIANGLES, 0, nverts); - } - - for(int i=0; i= 0 && vattr[i].vbo_valid) { - glDisableVertexAttribArray(loc); - } - } -} - -void Mesh::draw_wire() const -{ - ((Mesh*)this)->update_wire_ibo(); - - if(!vattr[MESH_ATTR_VERTEX].vbo_valid || !wire_ibo_valid) { - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); - return; - } - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); - return; - } - - for(int i=0; i= 0 && vattr[i].vbo_valid) { - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(loc); - } - } - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wire_ibo); - glDrawElements(GL_LINES, nfaces * 6, GL_UNSIGNED_INT, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - for(int i=0; i= 0 && vattr[i].vbo_valid) { - glDisableVertexAttribArray(loc); - } - } -} - -void Mesh::draw_vertices() const -{ - ((Mesh*)this)->update_buffers(); - - if(!vattr[MESH_ATTR_VERTEX].vbo_valid) { - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); - return; - } - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); - return; - } - - for(int i=0; i= 0 && vattr[i].vbo_valid) { - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(loc); - } - } - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glDrawArrays(GL_POINTS, 0, nverts); - - for(int i=0; i= 0 && vattr[i].vbo_valid) { - glDisableVertexAttribArray(loc); - } - } -} - -void Mesh::draw_normals() const -{ -#ifdef USE_OLDGL - int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX]; - Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); - Vector3 *norm = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL); - - if(!varr || !norm || vert_loc < 0) { - return; - } - - glBegin(GL_LINES); - for(size_t i=0; icalc_aabb(); - } - *vmin = aabb.min; - *vmax = aabb.max; -} - -const AABox &Mesh::get_aabbox() const -{ - if(!aabb_valid) { - ((Mesh*)this)->calc_aabb(); - } - return aabb; -} - -float Mesh::get_bsphere(Vector3 *center, float *rad) const -{ - if(!bsph_valid) { - ((Mesh*)this)->calc_bsph(); - } - *center = bsph.center; - *rad = bsph.radius; - return bsph.radius; -} - -const Sphere &Mesh::get_bsphere() const -{ - if(!bsph_valid) { - ((Mesh*)this)->calc_bsph(); - } - return bsph; -} - -/// static function -void Mesh::set_intersect_mode(unsigned int mode) -{ - Mesh::intersect_mode = mode; -} - -/// static function -unsigned int Mesh::get_intersect_mode() -{ - return Mesh::intersect_mode; -} - -/// static function -void Mesh::set_vertex_select_distance(float dist) -{ - Mesh::vertex_sel_dist = dist; -} - -/// static function -float Mesh::get_vertex_select_distance() -{ - return Mesh::vertex_sel_dist; -} - -/*bool Mesh::intersect(const Ray &ray, HitPoint *hit) const -{ - assert((Mesh::intersect_mode & (ISECT_VERTICES | ISECT_FACE)) != (ISECT_VERTICES | ISECT_FACE)); - - const Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); - const Vector3 *narr = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL); - if(!varr) { - return false; - } - const unsigned int *idxarr = get_index_data(); - - // first test with the bounding box - AABox box; - get_aabbox(&box.min, &box.max); - if(!box.intersect(ray)) { - return false; - } - - HitPoint nearest_hit; - nearest_hit.dist = FLT_MAX; - nearest_hit.obj = 0; - - if(Mesh::intersect_mode & ISECT_VERTICES) { - // we asked for "intersections" with the vertices of the mesh - long nearest_vidx = -1; - float thres_sq = Mesh::vertex_sel_dist * Mesh::vertex_sel_dist; - - for(unsigned int i=0; i 0) { - continue; - } - - // project the vertex onto the ray line - float t = dot_product(varr[i] - ray.origin, ray.dir); - Vector3 vproj = ray.origin + ray.dir * t; - - float dist_sq = (vproj - varr[i]).length_sq(); - if(dist_sq < thres_sq) { - if(!hit) { - return true; - } - if(t < nearest_hit.dist) { - nearest_hit.dist = t; - nearest_vidx = i; - } - } - } - - if(nearest_vidx != -1) { - hitvert = varr[nearest_vidx]; - nearest_hit.obj = &hitvert; - } - - } else { - // regular intersection test with polygons - - for(unsigned int i=0; i 0) { - continue; - } - - HitPoint fhit; - if(face.intersect(ray, hit ? &fhit : 0)) { - if(!hit) { - return true; - } - if(fhit.dist < nearest_hit.dist) { - nearest_hit = fhit; - hitface = face; - } - } - } - } - - if(nearest_hit.obj) { - if(hit) { - *hit = nearest_hit; - - // if we are interested in the mesh and not the faces set obj to this - if(Mesh::intersect_mode & ISECT_FACE) { - hit->obj = &hitface; - } else if(Mesh::intersect_mode & ISECT_VERTICES) { - hit->obj = &hitvert; - } else { - hit->obj = this; - } - } - return true; - } - return false; -}*/ - - -// ------ private member functions ------ - -void Mesh::calc_aabb() -{ - // the cast is to force calling the const version which doesn't invalidate - if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) { - return; - } - - aabb.min = Vector3(FLT_MAX, FLT_MAX, FLT_MAX); - aabb.max = -aabb.min; - - for(unsigned int i=0; i aabb.max[j]) { - aabb.max[j] = v[j]; - } - } - } - aabb_valid = true; -} - -void Mesh::calc_bsph() -{ - // the cast is to force calling the const version which doesn't invalidate - if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) { - return; - } - - Vector3 v; - bsph.center = Vector3(0, 0, 0); - - // first find the center - for(unsigned int i=0; i bsph.radius) { - bsph.radius = dist_sq; - } - } - bsph.radius = sqrt(bsph.radius); - - bsph_valid = true; -} -#endif - -void Mesh::update_buffers() -{ - for(int i=0; iget_index_data(); - - for(unsigned int i=0; icalc_normal(); - } - return normal; -} - -void Triangle::transform(const Matrix4x4 &xform) -{ - v[0].transform(xform); - v[1].transform(xform); - v[2].transform(xform); - normal_valid = false; -} - -void Triangle::draw() const -{ - Vector3 n[3]; - n[0] = get_normal(); - n[1] = get_normal(); - n[2] = get_normal(); - - int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX); - int nloc = Mesh::get_attrib_location(MESH_ATTR_NORMAL); - - glEnableVertexAttribArray(vloc); - glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x); - glVertexAttribPointer(nloc, 3, GL_FLOAT, GL_FALSE, 0, &n[0].x); - - glDrawArrays(GL_TRIANGLES, 0, 3); - - glDisableVertexAttribArray(vloc); - glDisableVertexAttribArray(nloc); - CHECKGLERR; -} - -void Triangle::draw_wire() const -{ - static const int idxarr[] = {0, 1, 1, 2, 2, 0}; - int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX); - - glEnableVertexAttribArray(vloc); - glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x); - - glDrawElements(GL_LINES, 6, GL_UNSIGNED_INT, idxarr); - - glDisableVertexAttribArray(vloc); - CHECKGLERR; -} - -Vector3 Triangle::calc_barycentric(const Vector3 &pos) const -{ - Vector3 norm = get_normal(); - - float area_sq = fabs(dot_product(cross_product(v[1] - v[0], v[2] - v[0]), norm)); - if(area_sq < 1e-5) { - return Vector3(0, 0, 0); - } - - float asq0 = fabs(dot_product(cross_product(v[1] - pos, v[2] - pos), norm)); - float asq1 = fabs(dot_product(cross_product(v[2] - pos, v[0] - pos), norm)); - float asq2 = fabs(dot_product(cross_product(v[0] - pos, v[1] - pos), norm)); - - return Vector3(asq0 / area_sq, asq1 / area_sq, asq2 / area_sq); -} - -/*bool Triangle::intersect(const Ray &ray, HitPoint *hit) const -{ - Vector3 normal = get_normal(); - - float ndotdir = dot_product(ray.dir, normal); - if(fabs(ndotdir) < 1e-4) { - return false; - } - - Vector3 vertdir = v[0] - ray.origin; - float t = dot_product(normal, vertdir) / ndotdir; - - Vector3 pos = ray.origin + ray.dir * t; - Vector3 bary = calc_barycentric(pos); - - if(bary.x + bary.y + bary.z > 1.00001) { - return false; - } - - if(hit) { - hit->dist = t; - hit->pos = ray.origin + ray.dir * t; - hit->normal = normal; - hit->obj = this; - } - return true; -}*/ diff -r 97139303348c -r cd71f0b92f44 src/mesh.h --- a/src/mesh.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/mesh.h Wed Aug 21 05:52:28 2013 +0300 @@ -1,213 +1,40 @@ #ifndef MESH_H_ #define MESH_H_ -#include #include -#include -//#include "geom.h" +#include "object.h" +#include "material.h" -enum { - MESH_ATTR_VERTEX, - MESH_ATTR_NORMAL, - MESH_ATTR_TANGENT, - MESH_ATTR_TEXCOORD, - MESH_ATTR_COLOR, - MESH_ATTR_BONEWEIGHTS, - MESH_ATTR_BONEIDX, +class Node; - NUM_MESH_ATTR +struct Face { + int v[3]; }; -// intersection mode flags -enum { - ISECT_DEFAULT = 0, // default (whole mesh, all intersections) - ISECT_FRONT = 1, // front-faces only - ISECT_FACE = 2, // return intersected face pointer instead of mesh - ISECT_VERTICES = 4 // return (?) TODO +struct Int4 { + int x, y, z, w; }; -class XFormNode; +class Mesh : public Object { +public: + Material *material; + std::vector vertices; + std::vector normals; + std::vector tangents; + std::vector texcoords; + std::vector skin_weights; + std::vector skin_matrices; + std::vector colors; + std::vector bones; + std::vector faces; -class Triangle { -public: - Vector3 v[3]; - Vector3 normal; - bool normal_valid; - int id; + Mesh(); + virtual ~Mesh(); - Triangle(); - Triangle(const Vector3 &v0, const Vector3 &v1, const Vector3 &v2); - Triangle(int n, const Vector3 *varr, const unsigned int *idxarr = 0); - - /// calculate normal (quite expensive) - void calc_normal(); - const Vector3 &get_normal() const; - - void transform(const Matrix4x4 &xform); - - void draw() const; - void draw_wire() const; - - /// calculate barycentric coordinates of a point - Vector3 calc_barycentric(const Vector3 &pos) const; - - //bool intersect(const Ray &ray, HitPoint *hit = 0) const; + virtual void set_material(Material *mat); + virtual Material *get_material(); + virtual const Material *get_material() const; }; - -class Mesh { -private: - std::string name; - unsigned int nverts, nfaces; - - // current value for each attribute for the immedate mode - // interface. - Vector4 cur_val[NUM_MESH_ATTR]; - - unsigned int buffer_objects[NUM_MESH_ATTR + 1]; - - // vertex attribute data and buffer objects - struct { - int nelem; // number of elements per attribute range: [1, 4] - std::vector data; - unsigned int vbo; - mutable bool vbo_valid; // if this is false, the vbo needs updating from the data - mutable bool data_valid; // if this is false, the data needs to be pulled from the vbo - //int sdr_loc; - } vattr[NUM_MESH_ATTR]; - - static int global_sdr_loc[NUM_MESH_ATTR]; - - std::vector bones; // bones affecting this mesh - - // index data and buffer object - std::vector idata; - unsigned int ibo; - mutable bool ibo_valid; - mutable bool idata_valid; - - // index buffer object for wireframe rendering (constructed on demand) - unsigned int wire_ibo; - mutable bool wire_ibo_valid; - - // axis-aligned bounding box - /*mutable AABox aabb; - mutable bool aabb_valid; - - // bounding sphere - mutable Sphere bsph; - mutable bool bsph_valid;*/ - - // keeps the last intersected face - mutable Triangle hitface; - // keeps the last intersected vertex position - mutable Vector3 hitvert; - - void calc_aabb(); - void calc_bsph(); - - static unsigned int intersect_mode; - static float vertex_sel_dist; - - static float vis_vecsize; - - /// update the VBOs after data has changed (invalid vbo/ibo) - void update_buffers(); - /// construct/update the wireframe index buffer (called from draw_wire). - void update_wire_ibo(); - - -public: - Mesh(); - ~Mesh(); - - void set_name(const char *name); - const char *get_name() const; - - bool has_attrib(int attr) const; - - // clears everything about this mesh, and returns to the newly constructed state - void clear(); - - // access the vertex attribute data - // if vdata == 0, space is just allocated - float *set_attrib_data(int attrib, int nelem, unsigned int num, const float *vdata = 0); // invalidates vbo - float *get_attrib_data(int attrib); // invalidates vbo - const float *get_attrib_data(int attrib) const; - - // simple access to any particular attribute - void set_attrib(int attrib, int idx, const Vector4 &v); // invalidates vbo - Vector4 get_attrib(int attrib, int idx) const; - - // ... same for index data - unsigned int *set_index_data(int num, const unsigned int *indices = 0); // invalidates ibo - unsigned int *get_index_data(); // invalidates ibo - const unsigned int *get_index_data() const; - - void append(const Mesh &mesh); - - // immediate-mode style mesh construction interface - void vertex(float x, float y, float z); - void normal(float nx, float ny, float nz); - void tangent(float tx, float ty, float tz); - void texcoord(float u, float v, float w); - void boneweights(float w1, float w2, float w3, float w4); - void boneidx(int idx1, int idx2, int idx3, int idx4); - - /* apply a transformation to the vertices and its inverse-transpose - * to the normals and tangents. - */ - void apply_xform(const Matrix4x4 &xform); - void apply_xform(const Matrix4x4 &xform, const Matrix4x4 &dir_xform); - - // adds a bone and returns its index - int add_bone(XFormNode *bone); - const XFormNode *get_bone(int idx) const; - int get_bones_count() const; - - // access the shader attribute locations - static void set_attrib_location(int attr, int loc); - static int get_attrib_location(int attr); - static void clear_attrib_locations(); - - static void set_vis_vecsize(float sz); - static float get_vis_vecsize(); - - void draw() const; - void draw_wire() const; - void draw_vertices() const; - void draw_normals() const; - void draw_tangents() const; - -#if 0 - /** get the bounding box in local space. The result will be cached, and subsequent - * calls will return the same box. The cache gets invalidated by any functions that can affect - * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included). - * @{ */ - void get_aabbox(Vector3 *vmin, Vector3 *vmax) const; - const AABox &get_aabbox() const; - /// @} - - /** get the bounding sphere in local space. The result will be cached, and subsequent - * calls will return the same box. The cache gets invalidated by any functions that can affect - * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included). - * @{ */ - float get_bsphere(Vector3 *center, float *rad) const; - const Sphere &get_bsphere() const; - - static void set_intersect_mode(unsigned int mode); - static unsigned int get_intersect_mode(); - static void set_vertex_select_distance(float dist); - static float get_vertex_select_distance(); - - /** Find the intersection between the mesh and a ray. - * XXX Brute force at the moment, not intended to be used for anything other than picking in tools. - * If you intend to use it in a speed-critical part of the code, you'll *have* to optimize it! - */ - bool intersect(const Ray &ray, HitPoint *hit = 0) const; -#endif -}; - - #endif // MESH_H_ diff -r 97139303348c -r cd71f0b92f44 src/node.cc --- a/src/node.cc Wed Aug 21 04:00:22 2013 +0300 +++ b/src/node.cc Wed Aug 21 05:52:28 2013 +0300 @@ -4,92 +4,28 @@ Node::Node() { - parent = 0; + obj = 0; } -Node::~Node() +void Node::set_object(Object *obj) { + this->obj = obj; } -void Node::set_name(const char *name) +Object *Node::get_object() { - this->name = name; + return obj; } -const char *Node::get_name() const +const Object *Node::get_object() const { - return name.c_str(); + return obj; } -void Node::add_child(Node *c) +void delete_node_tree(Node *n) { - // make sure we don't add it twice - if(std::find(children.begin(), children.end(), c) != children.end()) { - return; + for(int i=0; iget_children_count(); i++) { + delete_node_tree((Node*)n->get_child(i)); } - children.push_back(c); - c->parent = this; + delete n; } - -int Node::get_num_children() const -{ - return (int)children.size(); -} - -Node *Node::get_child(int idx) const -{ - if(idx < 0 || idx >= get_num_children()) { - return 0; - } - return children[idx]; -} - -Node *Node::get_child(const char *name) const -{ - for(size_t i=0; iget_name(), name) == 0) { - return children[i]; - } - } - return 0; -} - -Node *Node::get_descendant(const char *name) const -{ - Node *c = get_child(name); - if(c) { - return c; - } - - // depth first search might not be ideal in this case, but it's the simplest - for(size_t i=0; iget_descendant(name))) { - return c; - } - } - return 0; -} - -Node *Node::get_parent() const -{ - return parent; -} - -Node *Node::get_ancestor(const char *name) const -{ - Node *n = (Node*)this; - - if(!name) { - // just return the root - while(n->parent) { - n = n->parent; - } - return n; - } - - // otherwise we're looking for a specific ancestor - while(n && strcmp(n->get_name(), name) != 0) { - n = n->parent; - } - return n; -} diff -r 97139303348c -r cd71f0b92f44 src/node.h --- a/src/node.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/node.h Wed Aug 21 05:52:28 2013 +0300 @@ -1,9 +1,8 @@ #ifndef NODE_H_ #define NODE_H_ -#include -#include #include "xform_node.h" +#include "object.h" class Node : public XFormNode { private: @@ -11,11 +10,12 @@ public: Node(); - virtual ~Node(); void set_object(Object *obj); Object *get_object(); const Object *get_object() const; }; +void delete_node_tree(Node *n); + #endif // NODE_H_ diff -r 97139303348c -r cd71f0b92f44 src/object.cc --- a/src/object.cc Wed Aug 21 04:00:22 2013 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#include "object.h" - -Object::Object() -{ - material = 0; - mesh = 0; -} - -void Object::set_mesh(Mesh *mesh) -{ - this->mesh = mesh; -} - -Mesh *Object::get_mesh() const -{ - return mesh; -} - -void Object::set_material(Material *mtl) -{ - material = mtl; -} - -Material *Object::get_material() const -{ - return material; -} diff -r 97139303348c -r cd71f0b92f44 src/object.h --- a/src/object.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/object.h Wed Aug 21 05:52:28 2013 +0300 @@ -1,23 +1,15 @@ #ifndef OBJECT_H_ #define OBJECT_H_ -#include "node.h" -#include "mesh.h" -#include "material.h" +#include +#include -class Object : public Node { -private: - Material *material; - Mesh *mesh; +class Object { +public: + std::string name; -public: - Object(); - - void set_mesh(Mesh *mesh); - Mesh *get_mesh() const; - - void set_material(Material *mtl); - Material *get_material() const; + Vector3 pos; + Quaternion rot; }; #endif // OBJECT_H_ diff -r 97139303348c -r cd71f0b92f44 src/opengl.cc --- a/src/opengl.cc Wed Aug 21 04:00:22 2013 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#include "opengl.h" - -void init_opengl() -{ -#ifdef __GLEW_H__ - glewInit(); -#endif -} - -const char *strglerr(int err) -{ - static const char *errnames[] = { - "GL_INVALID_ENUM", - "GL_INVALID_VALUE", - "GL_INVALID_OPERATION", - "GL_STACK_OVERFLOW", - "GL_STACK_UNDERFLOW", - "GL_OUT_OF_MEMORY", - "GL_INVALID_FRAMEBUFFER_OPERATION" - }; - - if(!err) { - return "GL_NO_ERROR"; - } - if(err < GL_INVALID_ENUM || err > GL_OUT_OF_MEMORY) { - return ""; - } - return errnames[err - GL_INVALID_ENUM]; -} diff -r 97139303348c -r cd71f0b92f44 src/opengl.h --- a/src/opengl.h Wed Aug 21 04:00:22 2013 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -#ifndef OPENGL_H_ -#define OPENGL_H_ - -#include - -#ifdef __APPLE__ -#include "TargetConditionals.h" - -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -/* iOS */ -#include -#include - -#define GL_CLAMP GL_CLAMP_TO_EDGE -#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES - -#undef USE_OLDGL - -#define GL_WRITE_ONLY GL_WRITE_ONLY_OES -#define glMapBuffer glMapBufferOES -#define glUnmapBuffer glUnmapBufferOES - -#else -/* MacOS X */ -#include -#include - -#define USE_OLDGL -#endif - -#else -/* UNIX or Windows */ -#include -#include - -#define USE_OLDGL -#endif - -#ifndef GL_RGB16F -#define GL_RGB16F 0x881b -#endif -#ifndef GL_RGBA16F -#define GL_RGBA16F 0x881a -#endif -#ifndef GL_RGB32F -#define GL_RGB32F 0x8815 -#endif -#ifndef GL_RGBA32F -#define GL_RGBA32F 0x8814 -#endif -#ifndef GL_LUMINANCE16F -#define GL_LUMINANCE16F 0x881e -#endif -#ifndef GL_LUMINANCE32F -#define GL_LUMINANCE32F 0x8818 -#endif - -#define CHECKGLERR \ - do { \ - int err = glGetError(); \ - if(err) { \ - fprintf(stderr, "%s:%d: OpenGL error 0x%x: %s\n", __FILE__, __LINE__, err, strglerr(err)); \ - abort(); \ - } \ - } while(0) - -void init_opengl(); - -const char *strglerr(int err); - -#endif // OPENGL_H_ diff -r 97139303348c -r cd71f0b92f44 src/xform_node.h --- a/src/xform_node.h Wed Aug 21 04:00:22 2013 +0300 +++ b/src/xform_node.h Wed Aug 21 05:52:28 2013 +0300 @@ -35,53 +35,53 @@ XFormNode(); virtual ~XFormNode(); - void set_name(const char *name); - const char *get_name() const; + virtual void set_name(const char *name); + virtual const char *get_name() const; - void set_interpolator(Interp in); - Interp get_interpolator() const; - void set_extrapolator(Extrap ex); - Extrap get_extrapolator() const; + virtual void set_interpolator(Interp in); + virtual Interp get_interpolator() const; + virtual void set_extrapolator(Extrap ex); + virtual Extrap get_extrapolator() const; // children management - void add_child(XFormNode *child); - void remove_child(XFormNode *child); + virtual void add_child(XFormNode *child); + virtual void remove_child(XFormNode *child); - int get_children_count() const; - XFormNode *get_child(int idx); - const XFormNode *get_child(int idx) const; + virtual int get_children_count() const; + virtual XFormNode *get_child(int idx); + virtual const XFormNode *get_child(int idx) const; - void set_position(const Vector3 &pos, long tmsec = 0); - Vector3 get_node_position(long tmsec = 0) const; + virtual void set_position(const Vector3 &pos, long tmsec = 0); + virtual Vector3 get_node_position(long tmsec = 0) const; - void set_rotation(const Quaternion &quat, long tmsec = 0); - Quaternion get_node_rotation(long tmsec = 0) const; + virtual void set_rotation(const Quaternion &quat, long tmsec = 0); + virtual Quaternion get_node_rotation(long tmsec = 0) const; - void set_scaling(const Vector3 &pos, long tmsec = 0); - Vector3 get_node_scaling(long tmsec = 0) const; + virtual void set_scaling(const Vector3 &pos, long tmsec = 0); + virtual Vector3 get_node_scaling(long tmsec = 0) const; // these take hierarchy into account - Vector3 get_position(long tmsec = 0) const; - Quaternion get_rotation(long tmsec = 0) const; - Vector3 get_scaling(long tmsec = 0) const; + virtual Vector3 get_position(long tmsec = 0) const; + virtual Quaternion get_rotation(long tmsec = 0) const; + virtual Vector3 get_scaling(long tmsec = 0) const; - void set_pivot(const Vector3 &pivot); - Vector3 get_pivot() const; + virtual void set_pivot(const Vector3 &pivot); + virtual Vector3 get_pivot() const; // the local matrix is concatenated with the regular node/anim matrix - void set_local_matrix(const Matrix4x4 &mat); - const Matrix4x4 &get_local_matrix() const; + virtual void set_local_matrix(const Matrix4x4 &mat); + virtual const Matrix4x4 &get_local_matrix() const; // for bone nodes, the transformation of the bone in bind position - void set_bone_matrix(const Matrix4x4 &bmat); - const Matrix4x4 &get_bone_matrix() const; + virtual void set_bone_matrix(const Matrix4x4 &bmat); + virtual const Matrix4x4 &get_bone_matrix() const; // node transformation alone - void get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; + virtual void get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; // node transformation taking hierarchy into account - void get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; + virtual void get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; };