From: Mikko Rasa Date: Wed, 11 Sep 2013 07:53:41 +0000 (+0300) Subject: Add an interface for obtaining bounding spheres from renderables X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=46921b54c8252bb535a3b2cb7be97eb38e66eaed;p=libs%2Fgl.git Add an interface for obtaining bounding spheres from renderables This can be used for various forms of culling. --- diff --git a/source/object.cpp b/source/object.cpp index ae38af6b..d35517bf 100644 --- a/source/object.cpp +++ b/source/object.cpp @@ -41,6 +41,32 @@ void Object::set_mesh(unsigned i, const Mesh *m) meshes[i].keep(); } +void Object::update_bounding_sphere() +{ + vector points; + for(vector >::const_iterator i=meshes.begin(); i!=meshes.end(); ++i) + { + const VertexArray &vertices = (*i)->get_vertices(); + int offset = vertices.get_format().offset(VERTEX3); + if(offset<0) + { + // TODO Handle two-dimensional meshes + bounding_sphere = Geometry::BoundingSphere(); + return; + } + + unsigned n_vertices = vertices.size(); + points.reserve(points.size()+n_vertices); + for(unsigned j=0; j::from_point_cloud(points.begin(), points.end()); +} + const Mesh *Object::get_mesh(unsigned i) const { if(i>=meshes.size()) @@ -136,6 +162,11 @@ void Object::Loader::init() add("lod_mesh", &Loader::mesh_lod); } +void Object::Loader::finish() +{ + obj.update_bounding_sphere(); +} + void Object::Loader::mesh_inline() { RefPtr msh = new Mesh; diff --git a/source/object.h b/source/object.h index 7820d29c..82e12f14 100644 --- a/source/object.h +++ b/source/object.h @@ -33,8 +33,8 @@ public: Loader(Object &, Collection &); private: void init(); + virtual void finish(); - private: void mesh_inline(); void mesh_inline_lod(unsigned); void mesh(const std::string &); @@ -46,6 +46,7 @@ public: private: std::vector > meshes; RefPtr technique; + Geometry::BoundingSphere bounding_sphere; public: Object(); @@ -54,10 +55,15 @@ public: void set_mesh(const Mesh *m) { set_mesh(0, m); } void set_mesh(unsigned, const Mesh *); +private: + void update_bounding_sphere(); +public: const Mesh *get_mesh(unsigned = 0) const; void set_technique(const Technique *); const Technique *get_technique() const { return technique.get(); } + virtual const Geometry::BoundingSphere *get_bounding_sphere() const { return &bounding_sphere; } + virtual void render(const Tag &tag = Tag()) const; virtual void render(Renderer &, const Tag & = Tag()) const; diff --git a/source/objectinstance.cpp b/source/objectinstance.cpp index e3bb8f80..b3fc133d 100644 --- a/source/objectinstance.cpp +++ b/source/objectinstance.cpp @@ -1,4 +1,3 @@ -#include "object.h" #include "objectinstance.h" #include "renderer.h" diff --git a/source/objectinstance.h b/source/objectinstance.h index 6094517b..6a874976 100644 --- a/source/objectinstance.h +++ b/source/objectinstance.h @@ -2,12 +2,12 @@ #define MSP_GL_OBJETCINSTANCE_H_ #include +#include "object.h" #include "renderable.h" namespace Msp { namespace GL { -class Object; class ProgramData; /** @@ -29,6 +29,8 @@ public: const Object &get_object() const { return object; } virtual long get_instance_key() const { return reinterpret_cast(&object); } + virtual const Geometry::BoundingSphere *get_bounding_sphere() const { return object.get_bounding_sphere(); } + virtual void render(const Tag &tag = Tag()) const; virtual void render(Renderer &, const Tag & = Tag()) const; diff --git a/source/renderable.h b/source/renderable.h index b53fa9ac..eae75cce 100644 --- a/source/renderable.h +++ b/source/renderable.h @@ -2,6 +2,7 @@ #define MSP_GL_RENDERABLE_H_ #include +#include #include "tag.h" namespace Msp { @@ -38,6 +39,11 @@ public: matrix exists. */ virtual const Matrix *get_matrix() const { return 0; } + /** Returns a bounding sphere that completely encloses the Renderable. The + bounding sphere is expressed in the renderable's coordinates. Null is + returned if the bounding sphere cannot be determined. */ + virtual const Geometry::BoundingSphere *get_bounding_sphere() const { return 0; } + /** Called when starting to render a new frame. */ virtual void setup_frame() const { }