using namespace std;
using namespace Msp;
-namespace {
-
-bool compare_z(const R2C2::Vector &p1, const R2C2::Vector &p2)
-{
- return p1.z<p2.z;
-}
-
-template<typename Iter>
-Iter graham_scan(Iter begin, Iter end)
-{
- // http://en.wikipedia.org/wiki/Graham_scan
-
- // Find point with lowest X coordinate
- R2C2::Vector lowest = *begin;
- for(Iter i=begin; i!=end; ++i)
- if(i->x<lowest.x || (i->x==lowest.x && i->y>lowest.y))
- lowest = *i;
-
- // Compute tangents and sort points
- for(Iter i=begin; i!=end; ++i)
- i->z = (i->x==lowest.x ? 1e5/(i->y-lowest.y-1) : (i->y-lowest.y)/(i->x-lowest.x));
- sort(begin, end, compare_z);
-
- for(Iter k=begin, i=k++, j=k++;; )
- {
- // Compute winding by cross product
- float turn = cross(*j-*i, *k-*j).z;
-
- if(turn<1e-5)
- {
- // Right turn - throw the middle point away
- // Special case for collinear vertices in the beginning
- if(i==begin)
- j = k++;
- else
- j = i--;
- }
- else
- {
- // Left turn - store the middle point and advance
- if(++i!=j)
- *i = *j;
- j = k++;
- }
-
- // Cycle back to beginning and terminate after checking the last point
- if(k==end)
- k = begin;
- else if(j==begin)
- return ++i;
- }
-}
-
-}
-
namespace R2C2 {
TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt):
catalogue(cat3d),
mesh(0),
- object(0)
+ object(0),
+ own_data(false)
{
const Catalogue &cat = cat3d.get_catalogue();
const vector<TrackPart> &parts = tt.get_parts();
string obj_name = tt.get_object();
if(!obj_name.empty())
- {
object = &catalogue.get<GL::Object>(obj_name);
- const GL::Mesh *m = object->get_mesh();
- const GL::VertexArray &vertices = m->get_vertices();
- int vertex_offs = vertices.get_format().offset(GL::VERTEX2);
- if(vertex_offs>=0)
- {
- for(unsigned i=0; i<vertices.size(); ++i)
- {
- const float *v = vertices[i]+vertex_offs;
- border.push_back(Vector(v[0], v[1], 0));
- }
- }
- }
else
{
mesh = new GL::Mesh((GL::NORMAL3, GL::TEXCOORD2, GL::VERTEX3));
object = new GL::Object;
object->set_mesh(mesh);
object->set_technique(&catalogue.get<GL::Technique>(cat.get_track_technique()));
+
+ own_data = true;
}
unsigned paths = tt.get_paths();
}
path_meshes.push_back(m);
}
-
- min_z = max_z = border.front().z;
- for(vector<Vector>::iterator i=border.begin(); i!=border.end(); ++i)
- {
- min_z = min(min_z, i->z);
- max_z = max(max_z, i->z);
- }
- border.erase(graham_scan(border.begin(), border.end()), border.end());
}
TrackType3D::~TrackType3D()
{
for(vector<GL::Mesh *>::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i)
delete *i;
-}
-
-void TrackType3D::get_bounds(const Angle &angle, Vector &minp, Vector &maxp) const
-{
- Transform trans = Transform::rotation(-angle, Vector(0, 0, 1));
-
- minp = maxp = Vector();
- minp.z = min_z;
- maxp.z = max_z;
-
- for(vector<Vector>::const_iterator i=border.begin(); i!=border.end(); ++i)
+ if(own_data)
{
- Vector v = trans.transform(*i);
-
- minp.x = min(minp.x, v.x);
- minp.y = min(minp.y, v.y);
- maxp.x = max(maxp.x, v.x);
- maxp.y = max(maxp.y, v.y);
+ delete object;
+ delete mesh;
}
}
bld.normal(n.x, n.y, n.z);
bld.vertex(p.x, p.y, p.z);
-
- border.push_back(p);
}
}