]> git.tdb.fi Git - r2c2.git/commitdiff
Allow objects to override the shape specified in their type
authorMikko Rasa <tdb@tdb.fi>
Sun, 20 Oct 2013 13:04:24 +0000 (16:04 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 20 Oct 2013 13:04:24 +0000 (16:04 +0300)
source/designer/selectionwrap.cpp
source/designer/selectionwrap.h
source/libr2c2/object.cpp
source/libr2c2/object.h

index fcc4df6b2a7fc561915a22e008782be322773b27..79268743b20de383d176fd46c63ac5549a03b38b 100644 (file)
@@ -18,6 +18,8 @@ SelectionWrap::~SelectionWrap()
 {
        for(map<const ObjectType *, GL::Mesh *>::iterator i=meshes.begin(); i!=meshes.end(); ++i)
                delete i->second;
+       for(map<const Object *, GL::Mesh *>::iterator i=transient_meshes.begin(); i!=transient_meshes.end(); ++i)
+               delete i->second;
 }
 
 void SelectionWrap::render(GL::Renderer &renderer, const GL::Tag &) const
@@ -40,13 +42,30 @@ void SelectionWrap::selection_changed()
        {
                Wrap wrap;
                wrap.object = *i;
-               wrap.mesh = &get_mesh((*i)->get_type());
+               wrap.mesh = &get_mesh(**i);
                wraps.push_back(wrap);
        }
+
+       set<const Object *> cobjects(objects.begin(), objects.end());
+       for(map<const Object *, GL::Mesh *>::iterator i=transient_meshes.begin(); i!=transient_meshes.end(); )
+       {
+               if(!cobjects.count(i->first))
+               {
+                       delete i->second;
+                       transient_meshes.erase(i++);
+               }
+               else
+                       ++i;
+       }
 }
 
-GL::Mesh &SelectionWrap::get_mesh(const ObjectType &type)
+const GL::Mesh &SelectionWrap::get_mesh(const Object &obj)
 {
+       map<const Object *, GL::Mesh *>::iterator i = transient_meshes.find(&obj);
+       if(i!=transient_meshes.end())
+               return *i->second;
+
+       const ObjectType &type = obj.get_type();
        map<const ObjectType *, GL::Mesh *>::iterator j = meshes.find(&type);
        if(j!=meshes.end())
                return *j->second;
@@ -55,7 +74,7 @@ GL::Mesh &SelectionWrap::get_mesh(const ObjectType &type)
        GL::MeshBuilder bld(*mesh);
        bld.color(0.0f, 1.0f, 0.0f, 1.0f);
 
-       const Shape *shape = type.get_shape();
+       const Shape *shape = obj.get_shape();
        if(!shape)
                throw logic_error("No shape");
        
@@ -70,7 +89,10 @@ GL::Mesh &SelectionWrap::get_mesh(const ObjectType &type)
        bld.vertex(min_pt.x-0.005, max_pt.y+0.005);
        bld.end();
 
-       meshes[&type] = mesh;
+       if(shape!=type.get_shape())
+               transient_meshes[&obj] = mesh;
+       else
+               meshes[&type] = mesh;
 
        return *mesh;
 }
index 743280985675ca3c1699780a55824e01b9f47532..ee23d800d74eb19c24d4f6ac2079229405144f65 100644 (file)
@@ -15,11 +15,12 @@ private:
        struct Wrap
        {
                R2C2::Object *object;
-               Msp::GL::Mesh *mesh;
+               const Msp::GL::Mesh *mesh;
        };
 
        Selection &selection;
        std::map<const R2C2::ObjectType *, Msp::GL::Mesh *> meshes;
+       std::map<const R2C2::Object *, Msp::GL::Mesh *> transient_meshes;
        std::list<Wrap> wraps;
 
 public:
@@ -30,7 +31,7 @@ public:
 
 private:
        void selection_changed();
-       Msp::GL::Mesh &get_mesh(const R2C2::ObjectType &);
+       const Msp::GL::Mesh &get_mesh(const R2C2::Object &);
 };
 
 #endif
index d7c7db25e68beaeac81923f5eb2e6258b10e2e7d..7a23d11a04e4779ee13da5e094a80a059cc4f147 100644 (file)
@@ -5,6 +5,11 @@ using namespace std;
 
 namespace R2C2 {
 
+Object::Object(Layout &l):
+       layout(l),
+       shape(0)
+{ }
+
 Snap Object::get_snap_node(unsigned) const
 {
        throw out_of_range("Object::get_snap_node");
@@ -83,26 +88,33 @@ void Object::break_links()
                break_link(i);
 }
 
+const Shape *Object::get_shape() const
+{
+       if(shape)
+               return shape;
+       return get_type().get_shape();
+}
+
 bool Object::collide_ray(const Ray &ray) const
 {
-       const Shape *shape = get_type().get_shape();
-       if(!shape)
+       const Shape *s = get_shape();
+       if(!s)
                return false;
 
        Transform reverse_trans = Transform::rotation(rotation, Vector(0, 0, -1))*
                Transform::translation(-position);
-       return shape->check_intersection(reverse_trans.transform(ray));
+       return s->check_intersection(reverse_trans.transform(ray));
 }
 
 BoundingBox Object::get_bounding_box() const
 {
-       const Shape *shape = get_type().get_shape();
-       if(!shape)
+       const Shape *s = get_shape();
+       if(!s)
                return BoundingBox();
 
        Transform trans = Transform::translation(position)*
                Transform::rotation(rotation, Vector(0, 0, 1));
-       return trans.transform(shape->get_axis_aligned_bounding_box());
+       return trans.transform(s->get_axis_aligned_bounding_box());
 }
 
 } // namespace R2C2
index f8e895848f7ef17e17c59c1f535962a7a2dff12b..22937921d47a92190edb2d8abc76ca254b9a761b 100644 (file)
@@ -19,8 +19,9 @@ protected:
        Vector position;
        Angle rotation;
        Angle tilt;
+       Shape *shape;
 
-       Object(Layout &l): layout(l) { }
+       Object(Layout &);
 public:
        virtual ~Object() { }
 
@@ -51,6 +52,7 @@ public:
        virtual bool break_link(unsigned) { return false; }
        virtual void break_links();
 
+       const Shape *get_shape() const;
        virtual bool collide_ray(const Ray &) const;
        virtual BoundingBox get_bounding_box() const;
 };