00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __GEOMETRY_TRIANGLES__H__
00013 #define __GEOMETRY_TRIANGLES__H__
00014
00015 #include <vector>
00016 #include <wx/sstream.h>
00017 #include "geometry.h"
00018
00019
00020 namespace VRUT
00021 {
00023 class GeometryTriangles : public Geometry
00024 {
00025 public:
00026 typedef unsigned Indice;
00027 typedef VECTOR2 TexCoord;
00029 enum PRIMITIVE_TYPE
00030 {
00031 TRI_LIST,
00032 TRI_FAN,
00033 TRI_STRIP,
00034 POLYGON,
00035 LINES,
00036 LINE_STRIP,
00037 POINTS,
00038 QUADS
00039 };
00040 typedef std::vector<std::pair<Indice, PRIMITIVE_TYPE> > TriDescList;
00041
00043 std::vector<VECTOR3> vertices;
00045 std::vector<Indice> indices;
00047 std::vector<VECTOR3> normals;
00049 std::vector<TexCoord> texCoords;
00051 TriDescList triDescList;
00052
00054 GeometryTriangles(const wxString & _name) : Geometry(_name)
00055 {
00056 type = GEOMETRY_TRIANGLE;
00057 }
00058
00060 GeometryTriangles(const GeometryTriangles & g) : Geometry(g)
00061 {
00062 indices.assign(g.indices.begin(), g.indices.end());
00063 normals.assign(g.normals.begin(), g.normals.end());
00064 texCoords.assign(g.texCoords.begin(), g.texCoords.end());
00065 triDescList.assign(g.triDescList.begin(), g.triDescList.end());
00066 vertices.assign(g.vertices.begin(), g.vertices.end());
00067 }
00068
00070 virtual void BuildAABB()
00071 {
00072 if (!vertices.empty())
00073 {
00074 std::vector<VECTOR3>::const_iterator v = vertices.begin();
00075 aabb.MinBound = aabb.MaxBound = *v;
00076 VECTOR3 * minB = &aabb.MinBound;
00077 VECTOR3 * maxB = &aabb.MaxBound;
00078 for (++v; v != vertices.end(); v++)
00079 {
00080 if (v->x < minB->x)
00081 minB->x = v->x;
00082 else if (v->x > maxB->x)
00083 maxB->x = v->x;
00084 if (v->y < minB->y)
00085 minB->y = v->y;
00086 else if (v->y > maxB->y)
00087 maxB->y = v->y;
00088 if (v->z < minB->z)
00089 minB->z = v->z;
00090 else if (v->z > maxB->z)
00091 maxB->z = v->z;
00092 }
00094 if (ABS(minB->x - maxB->x) < EPSILON)
00095 {
00096 minB->x -= EPSILON;
00097 maxB->x += EPSILON;
00098 }
00099 if (ABS(minB->y - maxB->y) < EPSILON)
00100 {
00101 minB->y -= EPSILON;
00102 maxB->y += EPSILON;
00103 }
00104 if (ABS(minB->z - maxB->z) < EPSILON)
00105 {
00106 minB->z -= EPSILON;
00107 maxB->z += EPSILON;
00108 }
00109 }
00110 else
00111 {
00112 aabb.MinBound = aabb.MaxBound = VECTOR3(0,0,0);
00113 }
00114 }
00115
00117 virtual std::vector<Triangle> Triangulate() const
00118 {
00119 size_t indiceIndex = 0;
00120 size_t maxInd = indices.size();
00121 std::vector<Triangle> triangleList;
00122
00123 for (GeometryTriangles::TriDescList::const_iterator indPrimType = triDescList.begin();
00124 indPrimType != triDescList.end(); indPrimType++)
00125 {
00126 GeometryTriangles::TriDescList::const_iterator endIndPrimType = indPrimType + 1;
00127 size_t endInd = ( endIndPrimType == triDescList.end() ? maxInd : endIndPrimType->first );
00128 endInd = __min( endInd, maxInd );
00129
00130 switch (indPrimType->second)
00131 {
00132 case GeometryTriangles::TRI_LIST:
00133 for ( ; indiceIndex + 2 < endInd; )
00134 {
00135 Triangle triangle;
00136 triangle.v1 = vertices[indices[indiceIndex++]]._v;
00137 triangle.v2 = vertices[indices[indiceIndex++]]._v;
00138 triangle.v3 = vertices[indices[indiceIndex++]]._v;
00139 triangleList.push_back(triangle);
00140 }
00141 break;
00142 case GeometryTriangles::TRI_FAN:
00143 case GeometryTriangles::POLYGON:
00144 {
00145 VECTOR3 last1, last2;
00146 if (indiceIndex + 1 < endInd)
00147 {
00148 last1 = vertices[indices[indiceIndex++]]._v;
00149 last2 = vertices[indices[indiceIndex++]]._v;
00150 }
00151 for ( ; indiceIndex < endInd; )
00152 {
00153 VECTOR3 next = vertices[indices[indiceIndex++]]._v;
00154 triangleList.push_back(Triangle(last1, last2, next));
00155 last2 = next;
00156 }
00157 }
00158 break;
00159 case GeometryTriangles::TRI_STRIP:
00160 {
00161 VECTOR3 last1, last2;
00162 if (indiceIndex + 1 < endInd)
00163 {
00164 last1 = vertices[indices[indiceIndex++]]._v;
00165 last2 = vertices[indices[indiceIndex++]]._v;
00166 }
00167 bool sw = true;
00168 for ( ; indiceIndex < endInd; sw = !sw)
00169 {
00170 VECTOR3 next = vertices[indices[indiceIndex++]]._v;
00171 if (sw)
00172 triangleList.push_back(Triangle(last1, next, last2));
00173 else
00174 triangleList.push_back(Triangle(last1, last2, next));
00175 last1 = last2;
00176 last2 = next;
00177 }
00178 }
00179 break;
00180 case GeometryTriangles::QUADS:
00181 for ( ; indiceIndex + 3 < endInd; )
00182 {
00183 VECTOR3 v0 = vertices[indices[indiceIndex++]]._v;
00184 VECTOR3 v1 = vertices[indices[indiceIndex++]]._v;
00185 VECTOR3 v2 = vertices[indices[indiceIndex++]]._v;
00186 VECTOR3 v3 = vertices[indices[indiceIndex++]]._v;
00187 triangleList.push_back(Triangle(v0, v1, v2));
00188 triangleList.push_back(Triangle(v0, v2, v3));
00189 }
00190 break;
00191 default:
00192 break;
00193 }
00194 }
00195 return triangleList;
00196 }
00197
00200 virtual bool Intersects(const Ray & ray, float * dist = (float *)NULL) const
00201 {
00202 float bestDist = MAX_FLOAT;
00203 bool found = false;
00204 size_t indiceIndex = 0;
00205 size_t maxInd = indices.size();
00206
00207 for (GeometryTriangles::TriDescList::const_iterator indPrimType = triDescList.begin();
00208 indPrimType != triDescList.end(); indPrimType++)
00209 {
00210 GeometryTriangles::TriDescList::const_iterator endIndPrimType = indPrimType + 1;
00211 size_t endInd = ( endIndPrimType == triDescList.end() ? maxInd : endIndPrimType->first );
00212 endInd = __min( endInd, maxInd );
00213
00214 switch (indPrimType->second)
00215 {
00216 case GeometryTriangles::TRI_LIST:
00217 for ( ; indiceIndex + 2 < endInd; )
00218 {
00219 VECTOR3 v0 = vertices[indices[indiceIndex++]]._v;
00220 VECTOR3 v1 = vertices[indices[indiceIndex++]]._v;
00221 VECTOR3 v2 = vertices[indices[indiceIndex++]]._v;
00222 float actDist;
00223 if (ray.IntersectsTri(v0, v1, v2, &actDist) && actDist < bestDist)
00224 {
00225 found = true;
00226 bestDist = actDist;
00227 }
00228 }
00229 break;
00230 case GeometryTriangles::TRI_FAN:
00231 case GeometryTriangles::POLYGON:
00232 {
00233 VECTOR3 last1, last2;
00234 if (indiceIndex + 1 < endInd)
00235 {
00236 last1 = vertices[indices[indiceIndex++]]._v;
00237 last2 = vertices[indices[indiceIndex++]]._v;
00238 }
00239 for ( ; indiceIndex < endInd; )
00240 {
00241 VECTOR3 next = vertices[indices[indiceIndex++]]._v;
00242 float actDist;
00243 if (ray.IntersectsTri(last1, last2, next, &actDist) && actDist < bestDist)
00244 {
00245 found = true;
00246 bestDist = actDist;
00247 }
00248 last2 = next;
00249 }
00250 }
00251 break;
00252 case GeometryTriangles::TRI_STRIP:
00253 {
00254 VECTOR3 last1, last2;
00255 if (indiceIndex + 1 < endInd)
00256 {
00257 last1 = vertices[indices[indiceIndex++]]._v;
00258 last2 = vertices[indices[indiceIndex++]]._v;
00259 }
00260 bool sw = true;
00261 for ( ; indiceIndex < endInd; sw = !sw)
00262 {
00263 VECTOR3 next = vertices[indices[indiceIndex++]]._v;
00264 float actDist;
00265 if (sw)
00266 {
00267 if (ray.IntersectsTri(last1, next, last2, &actDist) && actDist < bestDist)
00268 {
00269 found = true;
00270 bestDist = actDist;
00271 }
00272 }
00273 else
00274 {
00275 if (ray.IntersectsTri(last1, last2, next, &actDist) && actDist < bestDist)
00276 {
00277 found = true;
00278 bestDist = actDist;
00279 }
00280 }
00281 last1 = last2;
00282 last2 = next;
00283 }
00284 }
00285 break;
00286 case GeometryTriangles::QUADS:
00287 for ( ; indiceIndex + 3 < endInd; )
00288 {
00289 VECTOR3 v0 = vertices[indices[indiceIndex++]]._v;
00290 VECTOR3 v1 = vertices[indices[indiceIndex++]]._v;
00291 VECTOR3 v2 = vertices[indices[indiceIndex++]]._v;
00292 VECTOR3 v3 = vertices[indices[indiceIndex++]]._v;
00293 float actDist;
00294 if (ray.IntersectsTri(v0, v1, v2, &actDist) && actDist < bestDist)
00295 {
00296 found = true;
00297 bestDist = actDist;
00298 }
00299 if (ray.IntersectsTri(v0, v2, v3, &actDist) && actDist < bestDist)
00300 {
00301 found = true;
00302 bestDist = actDist;
00303 }
00304 }
00305 break;
00306 default:
00307 break;
00308 }
00309 }
00310
00311 if (found && dist)
00312 *dist = bestDist;
00313
00314 return found;
00315 }
00316
00317 virtual bool CastRay(const Ray & ray, RayIntersectionInfo &info) const {
00318 float bestDist = 1e9f;
00319 size_t bestIndex = (size_t)~(size_t(0));
00320 size_t indiceIndex = 0;
00321 size_t maxInd = indices.size();
00322
00323 for (GeometryTriangles::TriDescList::const_iterator indPrimType = triDescList.begin();
00324 indPrimType != triDescList.end(); indPrimType++)
00325 {
00326 GeometryTriangles::TriDescList::const_iterator endIndPrimType = indPrimType + 1;
00327 size_t endInd = ( endIndPrimType == triDescList.end() ? maxInd : endIndPrimType->first );
00328 endInd = __min( endInd, maxInd );
00329
00330 switch (indPrimType->second)
00331 {
00332 case GeometryTriangles::TRI_LIST:
00333 for ( ; indiceIndex + 2 < endInd; )
00334 {
00335 VECTOR3 v0 = vertices[indices[indiceIndex++]]._v;
00336 VECTOR3 v1 = vertices[indices[indiceIndex++]]._v;
00337 VECTOR3 v2 = vertices[indices[indiceIndex++]]._v;
00338 float actDist;
00339 if (ray.IntersectsTri(v0, v1, v2, &actDist) && actDist < bestDist)
00340 {
00341 bestIndex = indiceIndex-1;
00342 info.normal = Normalize(CrossProd(v0-v1, v2-v1));
00343 bestDist = actDist;
00344 }
00345 }
00346 break;
00347 case GeometryTriangles::TRI_FAN:
00348 case GeometryTriangles::POLYGON:
00349 {
00350 VECTOR3 last1, last2;
00351 if (indiceIndex + 1 < endInd)
00352 {
00353 last1 = vertices[indices[indiceIndex++]]._v;
00354 last2 = vertices[indices[indiceIndex++]]._v;
00355 }
00356 for ( ; indiceIndex < endInd; )
00357 {
00358 VECTOR3 next = vertices[indices[indiceIndex++]]._v;
00359 float actDist;
00360 if (ray.IntersectsTri(last1, last2, next, &actDist) && actDist < bestDist)
00361 {
00362 bestIndex = indiceIndex-1;
00363 info.normal = Normalize(CrossProd(last1-last2, next-last2));
00364 bestDist = actDist;
00365 }
00366 last2 = next;
00367 }
00368 }
00369 break;
00370 case GeometryTriangles::TRI_STRIP:
00371 {
00372 VECTOR3 last1, last2;
00373 if (indiceIndex + 1 < endInd)
00374 {
00375 last1 = vertices[indices[indiceIndex++]]._v;
00376 last2 = vertices[indices[indiceIndex++]]._v;
00377 }
00378 bool sw = true;
00379 for ( ; indiceIndex < endInd; sw = !sw)
00380 {
00381 VECTOR3 next = vertices[indices[indiceIndex++]]._v;
00382 float actDist;
00383 if (sw)
00384 {
00385 if (ray.IntersectsTri(last1, next, last2, &actDist) && actDist < bestDist)
00386 {
00387 bestIndex = indiceIndex-1;
00388 info.normal = Normalize(CrossProd(last1-next, last2-next));
00389 bestDist = actDist;
00390 }
00391 }
00392 else
00393 {
00394 if (ray.IntersectsTri(last1, last2, next, &actDist) && actDist < bestDist)
00395 {
00396 bestIndex = indiceIndex-1;
00397 info.normal = Normalize(CrossProd(last1-last2, next-last2));
00398 bestDist = actDist;
00399 }
00400 }
00401 last1 = last2;
00402 last2 = next;
00403 }
00404 }
00405 break;
00406 case GeometryTriangles::QUADS:
00407 for ( ; indiceIndex + 3 < endInd; )
00408 {
00409 VECTOR3 v0 = vertices[indices[indiceIndex++]]._v;
00410 VECTOR3 v1 = vertices[indices[indiceIndex++]]._v;
00411 VECTOR3 v2 = vertices[indices[indiceIndex++]]._v;
00412 VECTOR3 v3 = vertices[indices[indiceIndex++]]._v;
00413 float actDist;
00414 if (ray.IntersectsTri(v0, v1, v2, &actDist) && actDist < bestDist)
00415 {
00416 bestIndex = indiceIndex-2;
00417 info.normal = Normalize(CrossProd(v0-v1, v2-v1));
00418 bestDist = actDist;
00419 }
00420 if (ray.IntersectsTri(v0, v2, v3, &actDist) && actDist < bestDist)
00421 {
00422 bestIndex = indiceIndex-1;
00423 info.normal = Normalize(CrossProd(v0-v2, v3-v2));
00424 bestDist = actDist;
00425 }
00426 }
00427 break;
00428 default:
00429 break;
00430 }
00431 }
00432
00433 if (bestIndex!=(size_t)~(size_t(0))) {
00434 info.dist = bestDist;
00435 info.geometryID = bestIndex;
00436 return true;
00437 }
00438
00439 return false;
00440 }
00441
00442 virtual void AddBox(const vector3 &position, const vector3 &size)
00443 {
00444 float box[6];
00445 box[0] = position._v[0];
00446 box[1] = position._v[1];
00447 box[2] = position._v[2];
00448 box[3] = position._v[0]+size._v[0];
00449 box[4] = position._v[1]+size._v[1];
00450 box[5] = position._v[2]+size._v[2];
00451 GeometryTriangles::Indice startInd = GeometryTriangles::Indice(vertices.size());
00452
00453 std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> indType(startInd, GeometryTriangles::QUADS);
00454 triDescList.push_back(indType);
00455
00456 float norms[]={0.0f,0.0f,1.0f, 0.0f,0.0f,-1.0f, -1.0f,0.0f,0.0f, 1.0f,0.0f,0.0f, 0.0f,1.0f,0.0f, 0.0f,1.0f,0.0f};
00457 float textC[]={0.0f,0.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f,1.0f};
00458 int verI[]={0,1,5, 3,1,5, 3,4,5, 0,4,5, 3,1,2, 0,1,2, 0,4,2, 3,4,2, 0,1,2, 0,1,5, 0,4,5, 0,4,2, 3,1,5, 3,1,2, 3,4,2, 3,4,5, 0,4,5, 3,4,5, 3,4,2, 0,4,2, 0,1,5, 3,1,5, 3,1,2, 0,1,2};
00459 size_t k=0;
00460 for (size_t i=0; i<6; i++)
00461 {
00462 for (size_t j=0; j<4; j++)
00463 {
00464 normals.push_back(VECTOR3(norms+i*3));
00465 texCoords.push_back(GeometryTriangles::TexCoord(textC+j*2));
00466 vertices.push_back(VECTOR3(box[verI[k]], box[verI[k+1]], box[verI[k+2]]));
00467 k+=3;
00468 indices.push_back(startInd++);
00469 }
00470 }
00471 }
00472
00474 virtual wxString ToString() const
00475 {
00476 wxStringOutputStream strout;
00477 wxTextOutputStream txtout(strout);
00478 txtout << Geometry::ToString().c_str();
00479 txtout << wxT("Vertices:");
00480 for (std::vector<VECTOR3>::const_iterator vecIt = vertices.begin(); vecIt != vertices.end(); vecIt++)
00481 txtout << wxT(" ") << vecIt->ToString();
00482
00483 txtout << wxT("\nNormals:");
00484 for (std::vector<VECTOR3>::const_iterator normIt = normals.begin(); normIt != normals.end(); normIt++)
00485 txtout << wxT(" ") << normIt->ToString();
00486
00487 txtout << wxT("\nIndices:");
00488 size_t indiceIndex = 0;
00489 size_t maxInd = indices.size();
00490 for (GeometryTriangles::TriDescList::const_iterator indPrimType = triDescList.begin();
00491 indPrimType != triDescList.end(); indPrimType++)
00492 {
00493 txtout << wxT("\n Primitive type: ") << indPrimType->second << wxT("\n");
00494 GeometryTriangles::TriDescList::const_iterator endIndPrimType = indPrimType + 1;
00495 size_t endInd = ( endIndPrimType == triDescList.end() ? maxInd : endIndPrimType->first );
00496 endInd = __min( endInd, maxInd );
00497
00498 for ( ; indiceIndex < endInd; indiceIndex++)
00499 txtout << wxT(" ") << unsigned(indices[indiceIndex]);
00500 }
00501 txtout << wxT("\n");
00502 return strout.GetString();
00503 }
00505 virtual Geometry * Clone() const
00506 {
00507 return new GeometryTriangles(*this);
00508 }
00509 };
00510 };
00511
00512
00513 #endif