00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef NL_COLLISION_MESH_BUILD_H
00025 #define NL_COLLISION_MESH_BUILD_H
00026
00027 #include <vector>
00028 #include <map>
00029
00030 #include "nel/misc/types_nl.h"
00031 #include "nel/misc/vector.h"
00032 #include "nel/misc/matrix.h"
00033 #include "nel/misc/file.h"
00034
00035 #include "nel/misc/vector.h"
00036 #include "nel/misc/aabbox.h"
00037
00038
00039 namespace NLPACS
00040 {
00041
00042 struct CCollisionFace
00043 {
00045
00046
00048 uint32 V[3];
00049
00051 bool Visibility[3];
00052
00054 sint32 Surface;
00055
00057 sint32 Material;
00058
00059
00060
00061
00063
00064
00066 sint32 Edge[3];
00067
00069 sint32 InternalSurface;
00070
00072 bool EdgeFlags[3];
00073
00074
00075
00076
00078 enum
00079 {
00080 ExteriorSurface = -1,
00081 InteriorSurfaceFirst = 0
00082 };
00083
00085 void serial(NLMISC::IStream &f)
00086 {
00087 f.serial(V[0]);
00088 f.serial(V[1]);
00089 f.serial(V[2]);
00090
00091 f.serial(Visibility[0]);
00092 f.serial(Visibility[1]);
00093 f.serial(Visibility[2]);
00094
00095 f.serial(Surface, Material);
00096 }
00097 };
00098
00105 class CCollisionMeshBuild
00106 {
00107 private:
00108
00109 struct CEdgeKey
00110 {
00111 uint32 V0;
00112 uint32 V1;
00113
00114 CEdgeKey() {}
00115 CEdgeKey(uint32 v0, uint32 v1) : V0(v0), V1(v1) {}
00116
00117 bool operator() (const CEdgeKey &a, const CEdgeKey &b) const
00118 {
00119 return a.V0 < b.V0 || (a.V0 == b.V0 && a.V1 < b.V1);
00120 }
00121 };
00122
00123
00124 struct CEdgeInfo
00125 {
00126 sint32 Left, LeftEdge;
00127 sint32 Right, RightEdge;
00128
00129 CEdgeInfo(sint32 left=-1, sint32 leftEdge=-1, sint32 right=-1, sint32 rightEdge=-1) : Left(left), LeftEdge(leftEdge), Right(right), RightEdge(rightEdge) {}
00130 };
00131
00132 typedef std::map<CEdgeKey, CEdgeInfo, CEdgeKey> TLinkRelloc;
00133 typedef TLinkRelloc::iterator ItTLinkRelloc;
00134
00135 public:
00136
00137
00138 public:
00140 std::vector<NLMISC::CVector> Vertices;
00141
00143 std::vector<CCollisionFace> Faces;
00144
00145
00146 public:
00147 void serial(NLMISC::IStream &f)
00148 {
00149 f.serialCont(Vertices);
00150 f.serialCont(Faces);
00151 }
00152
00153 void translate(const NLMISC::CVector &translation)
00154 {
00155 uint i;
00156 for (i=0; i<Vertices.size(); ++i)
00157 Vertices[i] += translation;
00158 }
00159
00160 void transform(const NLMISC::CMatrix &tranfo)
00161 {
00162 uint i;
00163 for (i=0; i<Vertices.size(); ++i)
00164 Vertices[i] = tranfo * Vertices[i];
00165 }
00166
00167 NLMISC::CVector computeTrivialTranslation() const
00168 {
00169 uint i;
00170 NLMISC::CAABBox bbox;
00171
00172 if (!Vertices.empty())
00173 {
00174 bbox.setCenter(Vertices[0]);
00175 for (i=1; i<Vertices.size(); ++i)
00176 bbox.extend(Vertices[i]);
00177 }
00178
00179 return -bbox.getCenter();
00180 }
00181
00182
00183 void link(bool linkInterior, std::vector<std::string> &errors)
00184 {
00185 uint i, j;
00186 TLinkRelloc relloc;
00187
00188
00189
00190 for (i=0; i<Faces.size(); ++i)
00191 {
00192 if (Faces[i].Surface == CCollisionFace::ExteriorSurface && linkInterior ||
00193 Faces[i].Surface >= CCollisionFace::InteriorSurfaceFirst && !linkInterior)
00194 continue;
00195
00196 for (j=0; j<3; ++j)
00197 {
00198 Faces[i].Edge[j] = -1;
00199
00200 uint edge = (j+2)%3;
00201 uint32 va = Faces[i].V[j],
00202 vb = Faces[i].V[(j+1)%3];
00203
00204 ItTLinkRelloc it;
00205 if ((it = relloc.find(CEdgeKey(va, vb))) != relloc.end())
00206 {
00207 CCollisionFace &left0 = Faces[(*it).second.Left];
00208 CCollisionFace &left1 = Faces[i];
00209
00210
00211 NLMISC::CVector eva = Vertices[va], evb = Vertices[vb];
00212 static char buf[512];
00213 sprintf(buf, "Edge issue: (%.2f,%.2f,%.2f)-(%.2f,%.2f,%.2f) [left face already found]\n"
00214 "left.0:%d: v0:(%.2f,%.2f) v1:(%.2f,%.2f), v2:(%.2f,%.2f) surf=%d material=%d\n"
00215 "left.1:%d: v0:(%.2f,%.2f) v1:(%.2f,%.2f), v2:(%.2f,%.2f) surf=%d material=%d",
00216 eva.x, eva.y, eva.z, evb.x, evb.y, evb.z,
00217 (*it).second.Left, Vertices[left0.V[0]].x, Vertices[left0.V[0]].y, Vertices[left0.V[1]].x, Vertices[left0.V[1]].y, Vertices[left0.V[2]].x, Vertices[left0.V[2]].y, Faces[(*it).second.Left].Surface, Faces[(*it).second.Left].Material,
00218 i, Vertices[left1.V[0]].x, Vertices[left1.V[0]].y, Vertices[left1.V[1]].x, Vertices[left1.V[1]].y, Vertices[left1.V[2]].x, Vertices[left1.V[2]].y, Faces[i].Surface, Faces[i].Material);
00219 errors.push_back(std::string(buf));
00220 continue;
00221
00222
00223 }
00224 else if ((it = relloc.find(CEdgeKey(vb, va))) != relloc.end())
00225 {
00226
00227 if ((*it).second.Right != -1)
00228 {
00229 CCollisionFace &right0 = Faces[(*it).second.Right];
00230 CCollisionFace &right1 = Faces[i];
00231 NLMISC::CVector eva = Vertices[va], evb = Vertices[vb];
00232 static char buf[512];
00233 sprintf(buf, "Edge issue: (%.2f,%.2f,%.2f)-(%.2f,%.2f,%.2f) [right face already found]\n"
00234 "right.0:%d: v0:(%.2f,%.2f) v1:(%.2f,%.2f), v2:(%.2f,%.2f)\n"
00235 "right.1:%d: v0:(%.2f,%.2f) v1:(%.2f,%.2f), v2:(%.2f,%.2f)",
00236 eva.x, eva.y, eva.z, evb.x, evb.y, evb.z,
00237 (*it).second.Right, Vertices[right0.V[0]].x, Vertices[right0.V[0]].y, Vertices[right0.V[1]].x, Vertices[right0.V[1]].y, Vertices[right0.V[2]].x, Vertices[right0.V[2]].y,
00238 i, Vertices[right1.V[0]].x, Vertices[right1.V[0]].y, Vertices[right1.V[1]].x, Vertices[right1.V[1]].y, Vertices[right1.V[2]].x, Vertices[right1.V[2]].y);
00239 errors.push_back(std::string(buf));
00240 continue;
00241
00242
00243 }
00244
00245 (*it).second.Right = i;
00246 (*it).second.RightEdge = edge;
00247 }
00248 else
00249 {
00250
00251 relloc.insert(std::make_pair(CEdgeKey(va, vb), CEdgeInfo(i, edge, -1, -1)));
00252 }
00253 }
00254 }
00255
00256
00257 ItTLinkRelloc it;
00258 for (it=relloc.begin(); it!=relloc.end(); ++it)
00259 {
00260 sint32 left, leftEdge;
00261 sint32 right, rightEdge;
00262
00263
00264 left = (*it).second.Left;
00265 leftEdge = (*it).second.LeftEdge;
00266 right = (*it).second.Right;
00267 rightEdge = (*it).second.RightEdge;
00268
00269
00270 if (left != -1)
00271 Faces[left].Edge[leftEdge] = right;
00272 if (right != -1)
00273 Faces[right].Edge[rightEdge] = left;
00274 }
00275 }
00276 };
00277
00278 };
00279
00280 #endif // NL_COLLISION_MESH_BUILD_H
00281
00282