#include <mini_col.h>
Nevrax France
Definition at line 54 of file mini_col.h.
Public Member Functions | |
| void | addZone (uint16 zoneId) |
| Add a zone to the collision system. Zone must be loaded into the landscape before. | |
| CMiniCol () | |
| Constructor. | |
| void | getFaces (std::vector< CTriangle > &triresult, const CAABBox &bbox) |
| bool | getGroundNormal (const CVector &pos, CVector &normal, float hup=0.5, float hbot=1000) |
| void | init (CLandscape *land, float radMin=100, float radDelta=50) |
| Init the size of the collision system, and init it with the landscape. | |
| void | removeZone (uint16 zoneId) |
| Remove a zone from the collision system. Zone do not have to be loaded into the landscape. | |
| void | setCenter (const CVector ¢er) |
| Reset the center of interset of the collision zone. | |
| bool | snapToGround (CVector &pos, float hup=0.5, float hbot=1000) |
| bool | testMove (const CVector &prec, CVector &cur) |
Private Types | |
| typedef CQuadGrid< CFace > | TGrid |
| typedef std::set< CZoneIdent > | TZoneSet |
Private Member Functions | |
| void | addFaces (const std::vector< CTriangle > &faces, uint16 zoneId, uint16 patchId) |
| void | addLandscapePart (uint16 zoneId, uint16 patchId) |
| void | removeLandScapePart (uint16 zoneId, uint16 patchId, const CBSphere &sphere) |
Private Attributes | |
| TGrid | _Grid |
| CRefPtr< CLandscape > | _Landscape |
| float | _RadMax |
| float | _RadMin |
| TZoneSet | _Zones |
|
|
Definition at line 134 of file mini_col.h. |
|
|
Definition at line 135 of file mini_col.h. |
|
|
Constructor.
Definition at line 47 of file mini_col.cpp. References _RadMax, _RadMin, NL3D::CQuadGrid< T >::create(), and NL3D::GridEltSize.
|
|
||||||||||||||||
|
Definition at line 56 of file mini_col.cpp. References NLMISC::CAABBox::extend(), NL3D::CMiniCol::CFace::Face, NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NL3D::CQuadGrid< T >::insert(), NLMISC::CPlane::make(), NL3D::CMiniCol::CFace::PatchId, NL3D::CMiniCol::CFace::Plane, NLMISC::CAABBox::setCenter(), sint, uint16, NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, and NL3D::CMiniCol::CFace::ZoneId. Referenced by addLandscapePart().
00057 {
00058 for(sint i=0;i<(sint)faces.size();i++)
00059 {
00060 const CTriangle &f= faces[i];
00061 CAABBox box;
00062 box.setCenter(f.V0);
00063 box.extend(f.V1);
00064 box.extend(f.V2);
00065 CFace node;
00066 node.Face= f;
00067 node.Plane.make(f.V0, f.V1, f.V2);
00068 node.ZoneId= zoneId;
00069 node.PatchId=patchId;
00070 _Grid.insert(box.getMin(), box.getMax(), node);
00071 }
00072 }
|
|
||||||||||||
|
Definition at line 76 of file mini_col.cpp. References addFaces(), and uint16. Referenced by setCenter().
00077 {
00078 vector<CTriangle> faces;
00079 _Landscape->buildCollideFaces(zoneId, patchId, faces);
00080 addFaces(faces, zoneId, patchId);
00081 }
|
|
|
Add a zone to the collision system. Zone must be loaded into the landscape before.
Definition at line 116 of file mini_col.cpp. References _Zones, NLMISC::CBSphere::Center, NLMISC::CAABBoxExt::getCenter(), NL3D::CZone::getNumPatchs(), NL3D::CZone::getPatchBSphere(), NLMISC::CAABBoxExt::getRadius(), NL3D::CZone::getZoneBB(), nlassert, NL3D::CMiniCol::CZoneIdent::Patchs, NLMISC::CBSphere::Radius, sint, NL3D::CMiniCol::CZoneIdent::Sphere, uint16, and NL3D::CMiniCol::CZoneIdent::ZoneId.
00117 {
00118 CZoneIdent newZone;
00119
00120 // landscape must have been inited.
00121 nlassert(_Landscape);
00122 const CZone *zone= _Landscape->getZone(zoneId);
00123 // zone must be loaded into landscape.
00124 nlassert(zone);
00125
00126 // Fill the newzone.
00127 newZone.ZoneId= zoneId;
00128 newZone.Sphere.Center= zone->getZoneBB().getCenter();
00129 newZone.Sphere.Radius= zone->getZoneBB().getRadius();
00130 newZone.Patchs.resize(zone->getNumPatchs());
00131 for(sint i=0;i<zone->getNumPatchs();i++)
00132 {
00133 newZone.Patchs[i].Sphere= zone->getPatchBSphere(i);
00134 }
00135
00136 // Add it to the set (if not already done...).
00137 _Zones.insert(newZone);
00138 }
|
|
||||||||||||
|
This function get the faces which intersect a bbox.. Definition at line 467 of file mini_col.cpp. References NL3D::CQuadGrid< T >::begin(), NL3D::CQuadGrid< T >::end(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NLMISC::CAABBox::intersect(), NL3D::CQuadGrid< T >::select(), NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, and NLMISC::CTriangle::V2.
00468 {
00469 triresult.clear();
00470
00471 // Select.
00472 _Grid.select(bbox.getMin(),bbox.getMax());
00473
00474 // For each face, test if it is under pos, then test if height is correct.
00475 CQuadGrid<CFace>::CIterator iFace;
00476 for(iFace= _Grid.begin();iFace!=_Grid.end();iFace++)
00477 {
00478 CTriangle &face= (*iFace).Face;
00479
00480 if(bbox.intersect(face.V0, face.V1, face.V2))
00481 {
00482 triresult.push_back(face);
00483 }
00484 }
00485
00486 }
|
|
||||||||||||||||||||
|
This function get the ground normal under a position. hbot and hup are the margin where face can be taken. Definition at line 341 of file mini_col.cpp. References NL3D::CQuadGrid< T >::begin(), NL3D::CQuadGrid< T >::end(), NLMISC::CAABBox::extend(), NLMISC::CPlane::getNormal(), height, NLMISC::CAABBox::include(), NLMISC::CPlane::intersect(), NL3D::CQuadGrid< T >::select(), NLMISC::CAABBox::setCenter(), NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z.
00342 {
00343 CVector b1,b2;
00344 bool found=false;
00345 float height=0.0;
00346
00347
00348 // Select quad nodes which contains pos.
00349 b1=b2=pos;
00350 b1.z-= hbot;
00351 b2.z+= hup;
00352 // Select.
00353 _Grid.select(b1,b2);
00354
00355 // For each face, test if it is under pos, then test if height is correct.
00356 CQuadGrid<CFace>::CIterator iFace;
00357 for(iFace= _Grid.begin();iFace!=_Grid.end();iFace++)
00358 {
00359 CTriangle &pFace= (*iFace).Face;
00360 CPlane &pPlane= (*iFace).Plane;
00361 // Order is important.
00362 CVector &p0= pFace.V0;
00363 CVector &p1= pFace.V1;
00364 CVector &p2= pFace.V2;
00365
00366 // TOIMP: This is VERY SLOW!!! (hope that the quadtree will help, but it still very slow...).
00367
00368 // Yoyo Debug, test, if the point may be IN the bbox.
00369 CAABBox bbFace;
00370 bbFace.setCenter(p0);
00371 bbFace.extend(p1);
00372 bbFace.extend(p2);
00373 CVector bext=p0;
00374 bext.z= maxof(p0.z, p1.z, p2.z)+hbot;
00375 bbFace.extend(bext);
00376 bext.z= minof(p0.z, p1.z, p2.z)-hup;
00377 bbFace.extend(bext);
00378 if(!bbFace.include(pos))
00379 continue;
00380
00381 // Test if the face enclose the pos in X/Y plane.
00382 // NB: compute and using a BBox to do a rapid test is not a very good idea, since it will
00383 // add an overhead which is NOT negligeable compared to the following test.
00384 float a,b,c; // 2D cartesian coefficients of line in plane X/Y.
00385 // Line p0-p1.
00386 a= -(p1.y-p0.y);
00387 b= (p1.x-p0.x);
00388 c= -(p0.x*a + p0.y*b);
00389 if( (a*pos.x + b*pos.y + c) < 0) continue;
00390 // Line p1-p2.
00391 a= -(p2.y-p1.y);
00392 b= (p2.x-p1.x);
00393 c= -(p1.x*a + p1.y*b);
00394 if( (a*pos.x + b*pos.y + c) < 0) continue;
00395 // Line p2-p0.
00396 a= -(p0.y-p2.y);
00397 b= (p0.x-p2.x);
00398 c= -(p2.x*a + p2.y*b);
00399 if( (a*pos.x + b*pos.y + c) < 0) continue;
00400
00401
00402 // Compute the possible height.
00403 CVector tmp;
00404 // intersect the vertical line with the plane.
00405 tmp= pPlane.intersect(pos, pos-CVector(0,0,100));
00406 float h= tmp.z;
00407 // Test if it would fit in the wanted field.
00408 if(h>pos.z+hup) continue;
00409 if(h<pos.z-hbot) continue;
00410
00411 // OK!!
00412 if(!found)
00413 {
00414 found=true;
00415 height=h;
00416 normal= pPlane.getNormal();
00417 }
00418 else
00419 {
00420 if(h>height)
00421 {
00422 normal= pPlane.getNormal();
00423 height= h;
00424 }
00425 }
00426 }
00427
00428 return found;
00429 }
|
|
||||||||||||||||
|
Init the size of the collision system, and init it with the landscape.
Definition at line 107 of file mini_col.cpp. References _RadMax, and _RadMin.
00108 {
00109 _Landscape= land;
00110 _RadMin= radMin;
00111 _RadMax= radMin+radDelta;
00112 }
|
|
||||||||||||||||
|
Definition at line 85 of file mini_col.cpp. References NL3D::CQuadGrid< T >::begin(), NLMISC::CBSphere::Center, NL3D::CQuadGrid< T >::end(), NL3D::CQuadGrid< T >::erase(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NLMISC::CBSphere::Radius, NL3D::CQuadGrid< T >::select(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), and uint16. Referenced by removeZone(), and setCenter().
00086 {
00087 // Build the AAbox which englobe the bsphere of the patch.
00088 CAABBox bb;
00089 bb.setCenter(sphere.Center);
00090 float l= sphere.Radius;
00091 bb.setHalfSize(CVector(l,l,l));
00092
00093 // For optimisation, select only faces which are IN the bbox of the patch.
00094 _Grid.select(bb.getMin(), bb.getMax());
00095 CQuadGrid<CFace>::CIterator iFace;
00096 for(iFace= _Grid.begin();iFace!=_Grid.end();)
00097 {
00098 if((*iFace).isFromPatch(zoneId, patchId))
00099 iFace= _Grid.erase(iFace);
00100 else
00101 iFace++;
00102 }
00103 }
|
|
|
Remove a zone from the collision system. Zone do not have to be loaded into the landscape.
Definition at line 142 of file mini_col.cpp. References _Zones, NL3D::CMiniCol::CPatchIdent::Inserted, NL3D::CMiniCol::CZoneIdent::NPatchInserted, NL3D::CMiniCol::CZoneIdent::Patchs, removeLandScapePart(), sint, NL3D::CMiniCol::CPatchIdent::Sphere, uint16, and NL3D::CMiniCol::CZoneIdent::ZoneId.
00143 {
00144 CZoneIdent delZone;
00145
00146
00147 // First, delete all patch from the grid.
00148 //=======================================
00149 // Fill the key part only.
00150 delZone.ZoneId= zoneId;
00151 // Find the zone (or quit).
00152 TZoneSet::iterator itZone;
00153 itZone= _Zones.find(delZone);
00154 if(itZone==_Zones.end())
00155 return;
00156
00157 CZoneIdent &zone= const_cast<CZoneIdent&>(*itZone);
00158 for(sint i=0;i<(sint)zone.Patchs.size();i++)
00159 {
00160 CPatchIdent &pa= zone.Patchs[i];
00161 if(pa.Inserted)
00162 {
00163 // Reject the patch.
00164 removeLandScapePart(zone.ZoneId, i, pa.Sphere);
00165 pa.Inserted= false;
00166 zone.NPatchInserted--;
00167 }
00168 }
00169
00170 // Then, delete it.
00171 //=================
00172 _Zones.erase(delZone);
00173
00174 }
|
|
|
Reset the center of interset of the collision zone.
Definition at line 178 of file mini_col.cpp. References _RadMax, _RadMin, _Zones, addLandscapePart(), NLMISC::CBSphere::Center, NL3D::CMiniCol::CPatchIdent::Inserted, NLMISC::CBSphere::intersect(), NL3D::CMiniCol::CZoneIdent::NPatchInserted, NL3D::CMiniCol::CZoneIdent::Patchs, removeLandScapePart(), sint, NL3D::CMiniCol::CPatchIdent::Sphere, NL3D::CMiniCol::CZoneIdent::Sphere, NLMISC::CVector::z, and NL3D::CMiniCol::CZoneIdent::ZoneId.
00179 {
00180 CBSphere BMin(center, _RadMin), BMax(center, _RadMax);
00181
00182 // For all zones, test if must insert patchs..
00183 TZoneSet::iterator itZone;
00184 for(itZone= _Zones.begin();itZone!=_Zones.end();itZone++)
00185 {
00186 CZoneIdent &zone= const_cast<CZoneIdent&>(*itZone);
00187
00188 // Tests must be done in 2D...
00189 BMin.Center.z= zone.Sphere.Center.z;
00190 BMax.Center.z= zone.Sphere.Center.z;
00191
00192 // Must test first if the zone is IN the area.
00193 //=============================================
00194 bool zoneIn= false;
00195 if(zone.NPatchInserted==0)
00196 {
00197 if(BMin.intersect(zone.Sphere))
00198 zoneIn= true;
00199 }
00200 else
00201 zoneIn= true;
00202
00203 // Then for all patchs, must test if the patch must be inserted, or rejected.
00204 //=============================================
00205 if(zoneIn)
00206 {
00207 for(sint i=0;i<(sint)zone.Patchs.size();i++)
00208 {
00209 CPatchIdent &pa= zone.Patchs[i];
00210
00211 // Tests must be done in 2D...
00212 BMin.Center.z= pa.Sphere.Center.z;
00213 BMax.Center.z= pa.Sphere.Center.z;
00214
00215 if(pa.Inserted)
00216 {
00217 // Reject the patch, if entirely OUT the max radius.
00218 if(!BMax.intersect(pa.Sphere))
00219 {
00220 removeLandScapePart(zone.ZoneId, i, pa.Sphere);
00221 pa.Inserted= false;
00222 zone.NPatchInserted--;
00223 }
00224 }
00225 else
00226 {
00227 // Insert the pacth, if only partially IN the min radius.
00228 if(BMin.intersect(pa.Sphere))
00229 {
00230 addLandscapePart(zone.ZoneId, i);
00231 pa.Inserted= true;
00232 zone.NPatchInserted++;
00233 }
00234 }
00235 }
00236 }
00237 }
00238 }
|
|
||||||||||||||||
|
This function snap a position on the current set of faces. hbot and hup are the margin where pos.z can't change. (the pos can't move higher than +hup and lower than -hbot) Definition at line 242 of file mini_col.cpp. References NL3D::CQuadGrid< T >::begin(), NL3D::CQuadGrid< T >::end(), height, NLMISC::CPlane::intersect(), NL3D::CQuadGrid< T >::select(), NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z. Referenced by testMove().
00243 {
00244 CVector b1,b2;
00245 bool found=false;
00246 float height;
00247
00248
00249 // Select quad nodes which contains pos.
00250 b1=b2=pos;
00251 b1.z-= hbot;
00252 b2.z+= hup;
00253 // Select.
00254 _Grid.select(b1,b2);
00255
00256 // For each face, test if it is under pos, then test if height is correct.
00257 CQuadGrid<CFace>::CIterator iFace;
00258 for(iFace= _Grid.begin();iFace!=_Grid.end();iFace++)
00259 {
00260 CTriangle &pFace= (*iFace).Face;
00261 CPlane &pPlane= (*iFace).Plane;
00262 // Order is important.
00263 CVector &p0= pFace.V0;
00264 CVector &p1= pFace.V1;
00265 CVector &p2= pFace.V2;
00266
00267 // TOIMP: This is VERY SLOW!!! (hope that the quadtree will help, but it still very slow...).
00268
00269 // Yoyo Debug, test, if the point may be IN the bbox.
00270 /*CAABBox bbFace;
00271 bbFace.setCenter(p0);
00272 bbFace.extend(p1);
00273 bbFace.extend(p2);
00274 CVector bext=p0;
00275 bext.z= maxof(p0.z, p1.z, p2.z)+hbot;
00276 bbFace.extend(bext);
00277 bext.z= minof(p0.z, p1.z, p2.z)-hup;
00278 bbFace.extend(bext);
00279 if(!bbFace.include(pos))
00280 continue;*/
00281
00282 // Test if the face enclose the pos in X/Y plane.
00283 // NB: compute and using a BBox to do a rapid test is not a very good idea, since it will
00284 // add an overhead which is NOT negligeable compared to the following test.
00285 float a,b,c; // 2D cartesian coefficients of line in plane X/Y.
00286 // Line p0-p1.
00287 a= -(p1.y-p0.y);
00288 b= (p1.x-p0.x);
00289 c= -(p0.x*a + p0.y*b);
00290 if( (a*pos.x + b*pos.y + c) < 0) continue;
00291 // Line p1-p2.
00292 a= -(p2.y-p1.y);
00293 b= (p2.x-p1.x);
00294 c= -(p1.x*a + p1.y*b);
00295 if( (a*pos.x + b*pos.y + c) < 0) continue;
00296 // Line p2-p0.
00297 a= -(p0.y-p2.y);
00298 b= (p0.x-p2.x);
00299 c= -(p2.x*a + p2.y*b);
00300 if( (a*pos.x + b*pos.y + c) < 0) continue;
00301
00302
00303 // Compute the possible height.
00304 CVector tmp;
00305 // intersect the vertical line with the plane.
00306 tmp= pPlane.intersect(pos, pos-CVector(0,0,100));
00307
00308 /*
00309 // CTriangle intersect() method.
00310 CVector tmp;
00311 if(pFace.intersect(b1, b2, tmp, pPlane))
00312 */
00313 {
00314 float h= tmp.z;
00315 // Test if it would fit in the wanted field.
00316 if(h>pos.z+hup) continue;
00317 if(h<pos.z-hbot) continue;
00318
00319 // OK!!
00320 if(!found)
00321 {
00322 found=true;
00323 height=h;
00324 }
00325 else
00326 {
00327 height= max(height,h);
00328 }
00329 }
00330 }
00331
00332 if(found)
00333 pos.z= height;
00334
00335 return found;
00336 }
|
|
||||||||||||
|
This function test if a move is OK, by snaping it to ground, and test if angle is<45deg. If !OK, cur is set to prec, and false is returned. Definition at line 433 of file mini_col.cpp. References NLMISC::CVector::norm(), NLMISC::CVector::normalize(), NLMISC::Pi, and snapToGround().
00434 {
00435 CVector dir= cur-prec;
00436 dir.normalize();
00437
00438 // Angle max.
00439 float anglemax= 65; // 65 degrees.
00440 anglemax= (float)tan( anglemax*Pi/180);
00441
00442 // Must not go to near of a wall.
00443 CVector test= cur+dir*0.5;
00444 float norm= (test-prec).norm();
00445 norm*=anglemax;
00446 if(!snapToGround(test, norm, norm))
00447 {
00448 cur= prec;
00449 return false;
00450 }
00451 else
00452 {
00453 // Must test and snap the current position.
00454 norm= (cur-prec).norm();
00455 norm*=anglemax;
00456 if(!snapToGround(cur, norm, norm))
00457 {
00458 cur= prec;
00459 return false;
00460 }
00461 }
00462 return true;
00463 }
|
|
|
Definition at line 140 of file mini_col.h. |
|
|
Definition at line 138 of file mini_col.h. |
|
|
Definition at line 139 of file mini_col.h. Referenced by CMiniCol(), init(), and setCenter(). |
|
|
Definition at line 139 of file mini_col.h. Referenced by CMiniCol(), init(), and setCenter(). |
|
|
Definition at line 141 of file mini_col.h. Referenced by addZone(), removeZone(), and setCenter(). |
1.3.6