#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(). |