00001 00005 /* Copyright © 2009, 2010 James Legg. 00006 This program is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 */ 00011 00012 #include "MeshFaces.h" 00013 00014 #include "../stream_loader.h" 00015 #include <Debug.h> 00016 00017 #include <fstream> 00018 #include <LinearMath/btMatrix3x3.h> 00019 00020 namespace Track 00021 { 00022 00023 MeshFaces::FaceVertex::FaceVertex() 00024 { 00025 } 00026 00027 MeshFaces::FaceVertex::FaceVertex(std::size_t vertex_index) 00028 : vertex_index(vertex_index) 00029 { 00030 } 00031 00032 MeshFaces::Face::Face() 00033 { 00034 } 00035 00036 MeshFaces::Face::Face(std::size_t v1, std::size_t v2, std::size_t v3) 00037 : 00038 fv1(v1), 00039 fv2(v2), 00040 fv3(v3) 00041 { 00042 } 00043 00044 MeshFaces::Face::Face(const FaceVertex & v1, const FaceVertex & v2, const FaceVertex & v3) 00045 : 00046 fv1(v1), 00047 fv2(v2), 00048 fv3(v3) 00049 { 00050 } 00051 00052 MeshFaces::Edge::Edge(std::size_t v1, std::size_t v2) 00053 : 00054 v1(v1), 00055 v2(v2) 00056 { 00057 } 00058 00059 bool MeshFaces::Edge::operator<(MeshFaces::Edge o) const 00060 { 00061 // arrange so we are comparing the elements regardless of order. 00062 std::size_t m_small, m_large; 00063 if (v1 < v2) 00064 { 00065 m_small = v1; 00066 m_large = v2; 00067 } else { 00068 m_small = v2; 00069 m_large = v1; 00070 } 00071 std::size_t o_small, o_large; 00072 if (o.v1 < o.v2) 00073 { 00074 o_small = o.v1; 00075 o_large = o.v2; 00076 } else { 00077 o_small = o.v2; 00078 o_large = o.v1; 00079 } 00080 if (m_small < o_small) return true; 00081 if (m_small > o_small) return false; 00082 if (m_large < o_large) return true; 00083 return false; 00084 } 00085 00086 MeshFaces::FaceGraph::FaceGraph(const Face & face) 00087 : Face(face) 00088 { 00089 } 00090 00091 btVector3 MeshFaces::FaceGraph::to_face_coords(btVector3 world_coords) const 00092 { 00093 btVector3 local = world_coords - vertex_positions[0]; 00094 return btVector3(world_to_face.tdotx(local), 00095 world_to_face.tdoty(local), 00096 world_to_face.tdotz(local)); 00097 } 00098 00099 btVector3 MeshFaces::FaceGraph::to_world_coords(btVector3 face_coords) const 00100 { 00101 btVector3 local = btVector3(face_to_world.tdotx(face_coords), 00102 face_to_world.tdoty(face_coords), 00103 face_to_world.tdotz(face_coords)); 00104 return local + vertex_positions[0]; 00105 } 00106 00107 void MeshFaces::FaceGraph::set_conversions() 00108 { 00109 face_to_world = btMatrix3x3(edges[0].x(), edges[0].y(), edges[0].z(), 00110 edges[1].x(), edges[1].y(), edges[1].z(), 00111 face_normal.x(), face_normal.y(), face_normal.z()); 00112 world_to_face = face_to_world.inverse(); 00113 edge_line_segments[0] = Line(vertex_positions[0], vertex_positions[1]); 00114 edge_line_segments[1] = Line(vertex_positions[1], vertex_positions[2]); 00115 edge_line_segments[2] = Line(vertex_positions[2], vertex_positions[0]); 00116 for (int i = 0; i < 3; i++) 00117 { 00118 edge_planes[i] = edge_line_segments[i].get_plane_including(face_normal); 00119 } 00120 00121 face_plane = Plane(face_normal, -face_normal.dot(vertex_positions[0])); 00122 } 00123 00124 btVector3 MeshFaces::FaceGraph::find_nearest_point(btVector3 position) const 00125 { 00126 for (int i = 0; i < 3; i++) 00127 { 00128 if (!edge_planes[i].find_side(position)) 00129 { 00130 // outside, find nearest point on the line segment. 00131 return edge_line_segments[i].closest_point_segment(position); 00132 } 00133 } 00134 // On the inside of the triangle. 00135 // Find the nearest point to the plane, because that is the nearest point. 00136 return face_plane.find_nearest_point(position); 00137 } 00138 00139 MeshFaces::MeshFaces() 00140 { 00141 } 00142 00143 MeshFaces::MeshFaces(std::istream & source) 00144 { 00145 load_from_stream(source); 00146 } 00147 00148 MeshFaces::MeshFaces(std::string & filename) 00149 { 00150 std::ifstream file(filename.c_str()); 00151 load_from_stream(file); 00152 } 00153 00154 void MeshFaces::load_from_stream(std::istream & source) 00155 { 00156 DEBUG_MESSAGE("Loading Track::MeshFaces from stream."); 00157 00158 std::size_t number_of_vertices; 00159 source >> number_of_vertices; 00160 DEBUG_MESSAGE("Loading " << number_of_vertices << " verticies. Now at " << source.tellg()); 00161 vertices_position.reserve(number_of_vertices); 00162 for(unsigned int i = 0; i < number_of_vertices; i++) 00163 { 00164 btScalar x, y, z; 00165 source >> x >> y >> z; 00166 vertices_position.push_back(btVector3(x, y, z)); 00167 bounds |= btVector3(x, y, z); 00168 } 00169 00170 std::size_t number_of_faces; 00171 source >> number_of_faces; 00172 DEBUG_MESSAGE("Loading " << number_of_faces << " faces. Now at " << source.tellg()); 00173 faces.reserve(number_of_faces); 00174 for(unsigned int f = 0; f < number_of_faces; f++) 00175 { 00176 FaceVertex fvs[3]; 00177 for (unsigned int i = 0; i < 3; i++) 00178 { 00179 // vertex normal 00180 btScalar x, y, z; 00181 source >> x >> y >> z; 00182 fvs[i].normal = btVector3(x, y, z); 00183 00184 // texture coordinates 00185 source >> fvs[i].texture_coord_u; 00186 source >> fvs[i].texture_coord_v; 00187 00188 // vertex position index in vertices_position array. 00189 source >> fvs[i].vertex_index; 00190 } 00191 add_face(Face(fvs[0], fvs[1], fvs[2])); 00192 } 00193 DEBUG_MESSAGE("Finished loading Track::MeshFaces. Now at " << source.tellg()); 00194 } 00195 00196 MeshFaces::~MeshFaces() 00197 { 00198 } 00199 00200 btVector3 MeshFaces::get_vertex_pos(std::size_t index) const 00201 { 00202 assert(index < vertices_position.size()); 00203 return vertices_position[index]; 00204 } 00205 00206 void MeshFaces::add_vertex(const btVector3 & position) 00207 { 00208 vertices_position.push_back(position); 00209 bounds |= position; 00210 } 00211 00212 std::size_t MeshFaces::get_num_vertices() const 00213 { 00214 return vertices_position.size(); 00215 } 00216 00217 const MeshFaces::Face & MeshFaces::get_face(std::size_t index) const 00218 { 00219 assert(index < faces.size()); 00220 return faces[index]; 00221 } 00222 00223 std::vector<MeshFaces::Edge> MeshFaces::get_edges_for_face(std::size_t face_index) const 00224 { 00225 assert(face_index < faces.size()); 00226 const Face & face = faces[face_index]; 00227 00228 std::vector<MeshFaces::Edge> result; 00229 result.reserve(3); 00230 result.push_back(Edge(face.fv1.vertex_index, face.fv2.vertex_index)); 00231 result.push_back(Edge(face.fv2.vertex_index, face.fv3.vertex_index)); 00232 result.push_back(Edge(face.fv3.vertex_index, face.fv1.vertex_index)); 00233 return result; 00234 } 00235 00236 void MeshFaces::add_face(std::size_t v1, std::size_t v2, std::size_t v3) 00237 { 00238 add_face(Face(v1, v2, v3)); 00239 } 00240 00241 void MeshFaces::add_face(MeshFaces::Face face) 00242 { 00243 std::size_t face_index = faces.size(); 00244 faces.push_back(face); 00245 } 00246 00247 void MeshFaces::add_edge(std::size_t v1, std::size_t v2, std::size_t face_index, 00248 std::map<EdgeGraph, std::size_t> & edge_to_face, 00249 std::vector<std::pair<std::size_t, std::size_t> > & graph_edges, 00250 std::vector<EdgeGraph> & edge_properties) const 00251 { 00252 EdgeGraph edge(v1, v2); 00253 std::pair<std::map<EdgeGraph, std::size_t>::iterator, bool> it( 00254 edge_to_face.insert(std::pair<EdgeGraph, std::size_t>(edge, face_index)) 00255 ); 00256 if (!it.second) 00257 { 00258 // already used by one face. 00259 // add to list of graph edges. 00260 graph_edges.push_back( 00261 std::pair<std::size_t, std::size_t> 00262 (edge_to_face[edge], face_index) 00263 ); 00264 // find other edge data. 00265 edge.v1_pos = vertices_position[v1]; 00266 edge.v2_pos = vertices_position[v2]; 00267 edge.length = (edge.v1_pos - edge.v2_pos).length(); 00268 00269 edge_properties.push_back(edge); 00270 } 00271 } 00272 00273 std::size_t MeshFaces::get_number_of_faces() const 00274 { 00275 return faces.size(); 00276 } 00277 00278 MeshFaces::Graph MeshFaces::get_connectivity() const 00279 { 00280 // Find the shared edges. An edge should belong to only one face or two. 00281 // We take the index of the first face we find using an edge and store it 00282 // When we find another face using the same edge, this edge needs to be 00283 // inserted into a graph of the edges. 00284 std::map<EdgeGraph, std::size_t> edge_to_face; 00285 std::vector<std::pair<std::size_t, std::size_t> > graph_edges; 00286 std::vector<EdgeGraph> edge_properties; 00287 std::size_t face_index = 0; 00288 for (std::vector<Face>::const_iterator face_it = faces.begin(); 00289 face_it != faces.end(); 00290 face_it++, face_index++) 00291 { 00292 // find the 3 edges 00293 add_edge(face_it->fv1.vertex_index, face_it->fv2.vertex_index, 00294 face_index, 00295 edge_to_face, graph_edges, edge_properties); 00296 add_edge(face_it->fv2.vertex_index, face_it->fv3.vertex_index, 00297 face_index, 00298 edge_to_face, graph_edges, edge_properties); 00299 add_edge(face_it->fv3.vertex_index, face_it->fv1.vertex_index, 00300 face_index, 00301 edge_to_face, graph_edges, edge_properties); 00302 } 00303 // create a graph from the list of faces sharing an edge. 00304 Graph result(graph_edges.begin(), graph_edges.end(), edge_properties.begin(), 00305 faces.size()); 00306 assert(boost::num_vertices(result) == faces.size()); 00307 assert(boost::num_edges(result) == graph_edges.size()); 00308 typedef boost::graph_traits<Graph>::vertex_iterator VertexIterator; 00309 std::pair<VertexIterator, VertexIterator> vp = boost::vertices(result); 00310 for (std::vector<Face>::const_iterator face_it = faces.begin(); 00311 vp.first != vp.second; 00312 ++vp.first, face_it++) 00313 { 00314 Graph::vertex_descriptor v = *vp.first; 00315 FaceGraph & face_graph = result[v]; 00316 // copy information about the face to the graph. 00317 face_graph = FaceGraph(*face_it); 00318 // add additional data about the face. 00319 face_graph.vertex_positions[0] = vertices_position[face_it->fv1.vertex_index]; 00320 face_graph.vertex_positions[1] = vertices_position[face_it->fv2.vertex_index]; 00321 face_graph.vertex_positions[2] = vertices_position[face_it->fv3.vertex_index]; 00322 face_graph.face_centre = (face_graph.vertex_positions[0] + 00323 face_graph.vertex_positions[1] + 00324 face_graph.vertex_positions[2]) / 3.0; 00325 face_graph.edges[0] = face_graph.vertex_positions[1] - face_graph.vertex_positions[0]; 00326 face_graph.edges[1] = face_graph.vertex_positions[2] - face_graph.vertex_positions[0]; 00327 face_graph.face_normal = face_graph.edges[0].cross(face_graph.edges[1]).normalized(); 00328 face_graph.set_conversions(); 00329 } 00330 return result; 00331 } 00332 00333 MeshFaces::VertexGraph MeshFaces::get_vertex_graph() 00334 { 00335 VertexGraph result; 00336 // add vertex positions. 00337 for (std::vector<btVector3>::iterator it = vertices_position.begin(); 00338 it != vertices_position.end(); 00339 it++) 00340 { 00341 boost::add_vertex(*it, result); 00342 } 00343 // add edges 00344 for (std::vector<Face>::iterator it = faces.begin(); 00345 it != faces.end(); 00346 it++) 00347 { 00348 #define do_edge(v1, v2)\ 00349 boost::add_edge(it->fv##v1.vertex_index, it->fv##v2.vertex_index,\ 00350 FaceEdgePointers(&(*it), &(it->fv##v1), &(it->fv##v2),\ 00351 vertices_position[it->fv##v1.vertex_index].distance(vertices_position[it->fv##v2.vertex_index])),\ 00352 result) 00353 do_edge(1,2); 00354 do_edge(2,3); 00355 do_edge(3,1); 00356 #undef do_edge 00357 } 00358 return result; 00359 } 00360 00361 void MeshFaces::copy_faces(const MeshFaces & other) 00362 { 00363 faces = other.faces; 00364 // Set normals for each face vertex. 00365 for (std::vector<Face>::iterator it = faces.begin(); it != faces.end(); it++) 00366 { 00367 // solid shading: face normals are consistant across a face 00368 btVector3 & v1 = vertices_position[it->fv1.vertex_index]; 00369 btVector3 & v2 = vertices_position[it->fv2.vertex_index]; 00370 btVector3 & v3 = vertices_position[it->fv3.vertex_index]; 00371 btVector3 n = (v2-v1).cross(v3-v1).normalize(); 00372 it->fv1.normal = n; 00373 it->fv2.normal = n; 00374 it->fv3.normal = n; 00376 } 00377 } 00378 00379 void MeshFaces::add_faces(btTriangleMesh & shape) const 00380 { 00381 for (std::vector<Face>::const_iterator it = faces.begin(); it != faces.end(); it++) 00382 { 00383 btVector3 verts[3]; 00384 #define face_vertex( index, vert ) \ 00385 verts[index] = vertices_position[vert.vertex_index] 00386 00387 face_vertex(0, it->fv1); 00388 face_vertex(1, it->fv2); 00389 face_vertex(2, it->fv3); 00390 #undef face_vertex 00391 shape.addTriangle(verts[2], verts[1], verts[0]); 00392 } 00393 } 00394 00395 AxisAlignedBoundingBox MeshFaces::get_bounds() const 00396 { 00397 return bounds; 00398 } 00399 00400 void MeshFaces::merge_doubles(btScalar distance2) 00401 { 00402 // Check each vertex against each vertex before it. 00403 // If the distances are too small, remember a substitution. 00404 std::size_t offset(0); 00405 std::map<std::size_t, std::size_t> substitutions; 00406 std::set<std::size_t> deletion_queue; 00407 for(std::size_t search_index = 0; 00408 search_index < vertices_position.size(); 00409 search_index++) 00410 { 00411 bool provided_substitution = false; 00412 for(std::size_t compare_index = 0; 00413 compare_index < search_index; 00414 compare_index++) 00415 { 00416 if (vertices_position[search_index].distance2(vertices_position[compare_index]) < distance2) 00417 { 00418 // Always use the lower numbered vertex, so we don't need 00419 // change substitutions for vertices already scanned. 00420 // Use one extra layer of substitution, this corrects offset 00421 // adjustments and merging into a vertex already merged. 00422 substitutions[search_index] = substitutions[compare_index]; 00423 provided_substitution = true; 00424 deletion_queue.insert(search_index); 00425 // Now all later vertices will need a lower number. 00426 offset++; 00427 // We only merge one at a time, so don't look for more. 00428 break; 00429 } 00430 } 00431 // substitute for a lower number since preceeding vertices will 00432 // be deleted, unless we already made a substitution. 00433 if (!provided_substitution) 00434 { 00435 // We do this even if offset is 0 to make a 1-1 mapping, where 00436 // we don't need to check if a substitution has been made before 00437 // using it. 00438 substitutions[search_index] = search_index - offset; 00439 } 00440 } 00441 if (offset > 0) 00442 { 00443 // Make the substitutions. 00444 for (std::vector<Face>::iterator it = faces.begin(); 00445 it != faces.end(); it++) 00446 { 00447 std::map<std::size_t, std::size_t>::iterator sub_it; 00448 #define do_vert(vertex_number)\ 00449 sub_it = substitutions.find(it->fv##vertex_number.vertex_index);\ 00450 it->fv##vertex_number.vertex_index = sub_it->second; 00451 00452 do_vert(1); 00453 do_vert(2); 00454 do_vert(3); 00455 #undef do_vert 00456 } 00457 00458 // delete vertices no longer needed. 00459 for (std::set<std::size_t>::reverse_iterator it = deletion_queue.rbegin(); 00460 it != deletion_queue.rend(); 00461 it++) 00462 { 00463 vertices_position.erase(vertices_position.begin() + *it); 00464 } 00465 } 00466 // bounds may become minimally smaller, but we don't bother checking. 00467 } 00468 00469 void MeshFaces::operator|=(const MeshFaces & source) 00470 { 00471 // New faces will have a different vertex indecies, depening on how many 00472 // we already have. 00473 std::size_t offset = vertices_position.size(); 00474 00475 // Add vertices on the end of the list. 00476 vertices_position.insert(vertices_position.end(), 00477 source.vertices_position.begin(), 00478 source.vertices_position.end()); 00479 00480 // expand bounds to include these new vertices. 00481 bounds |= source.bounds; 00482 00483 // copy the faces in, but change their vertex indices using the offset. 00484 for (std::vector<Face>::const_iterator it = source.faces.begin(); 00485 it != source.faces.end(); 00486 it++) 00487 { 00488 Face f = *it; 00489 f.fv1.vertex_index += offset; 00490 f.fv2.vertex_index += offset; 00491 f.fv3.vertex_index += offset; 00492 // because we use add_face, edges and graph_edges are updated. 00493 add_face(f); 00494 } 00495 } 00496 00497 void MeshFaces::set_source(bool is_edge, unsigned long int object_name) 00498 { 00499 for (std::vector<Face>::iterator it = faces.begin(); 00500 it != faces.end(); 00501 it++) 00502 { 00503 it->is_edge = is_edge; 00504 it->object_name = object_name; 00505 } 00506 } 00507 00508 }
Generated at Mon Sep 6 00:41:11 2010 by Doxygen version 1.4.7 for Racer version svn335.