void Polygroup::addPoly(const Poly& poly) { bool add(true); int polyX(poly.getPoint(0).x), polyZ(poly.getPoint(0).z); for(std::vector<Poly>::iterator gridIt(grid[polyX][polyZ].begin());gridIt!=grid[polyX][polyZ].end();++gridIt) { if((*gridIt)==poly) { add=false; } } if(add){ grid[polyX][polyZ].push_back(poly); lowEfficientPolys.push_back(poly); if(!initialSetup) { //create a new thread and run the polygon reduction again } else { highEfficientPolys.push_back(poly); } } }
void Polygroup::removePoly(const Poly& poly) { int polyX(poly.getPoint(0).x), polyZ(poly.getPoint(0).z); //Remove poly from the grid for(std::vector<Poly>::iterator gridIt(grid[polyX][polyZ].begin());gridIt!=grid[polyX][polyZ].end();++gridIt) { if((*gridIt)==poly) { grid[polyX][polyZ].erase(gridIt); } } //Remove poly from the low efficiency poly list for(std::vector<Poly>::iterator lowIt(lowEfficientPolys.begin());lowIt!=lowEfficientPolys.end();++lowIt) { if((*lowIt)==poly) { lowEfficientPolys.erase(lowIt); } } if(!initialSetup) { //create a new thread and run the polygon reduction again } }
float LantirnClass::FeatureCollisionPrediction (AircraftClass* self, float zOffset, BOOL MeasureHorizontally, BOOL GreatestAspect, float Clearance, float GridSizeNM, float boxScale, float *featureHeight) { CampBaseClass* objective; //get all objectives within GridSizeNM miles #ifdef VU_GRID_TREE_Y_MAJOR VuGridIterator gridIt(ObjProxList, self->YPos(), self->XPos(), GridSizeNM * NM_TO_FT); #else VuGridIterator gridIt(ObjProxList, self->XPos(), self->YPos(), GridSizeNM * NM_TO_FT); #endif SimBaseClass *foundFeature = NULL; SimBaseClass *testFeature; float radius; Tpoint pos, fpos, vec, p3, collide; BOOL firstFeature; float MaxDistance = 2 * GridSizeNM * NM_TO_FT; float ClosestDistance = 10 * GridSizeNM * NM_TO_FT; float move_vector; float Aspect = -90.0F; *featureHeight = 0.0F; // get the 1st objective and iterate through the list objective = (CampBaseClass*)gridIt.GetFirst(); while ( objective ) { if (objective->GetComponents()) { pos.x = self->XPos(); pos.y = self->YPos(); pos.z = self->ZPos() + zOffset; //check for MaxDistance in the direction of our vector! vec.x = self->XDelta(); vec.y = self->YDelta(); vec.z = self->ZDelta(); move_vector = (float)sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z); vec.x *= MaxDistance / move_vector; vec.y *= MaxDistance / move_vector; vec.z *= MaxDistance / move_vector; if (MeasureHorizontally) vec.z = 0; p3.x = (float)fabs( vec.x ); p3.y = (float)fabs( vec.y ); p3.z = (float)fabs( vec.z ); // loop thru each element in the objective VuListIterator featureWalker(objective->GetComponents()); testFeature = (SimBaseClass*) featureWalker.GetFirst(); firstFeature = TRUE; while (testFeature) { if (testFeature->drawPointer) { // get feature's radius and position radius = testFeature->drawPointer->Radius(); if(self->drawPointer) radius += self->drawPointer->Radius(); radius += Clearance; testFeature->drawPointer->GetPosition( &fpos ); // test with gross level bounds of object if (fabs (pos.x - fpos.x) < radius + p3.x && fabs (pos.y - fpos.y) < radius + p3.y && fabs (pos.z - fpos.z) < radius + p3.z ) { //Check for tall objects when doing horizontal check!!! float sizeX, sizeY, sizeZ; sizeX = ((DrawableBSP*)(testFeature->drawPointer))->instance.BoxFront(); sizeX -= ((DrawableBSP*)(testFeature->drawPointer))->instance.BoxBack(); sizeX = (float)(fabs)(sizeX); sizeY = ((DrawableBSP*)(testFeature->drawPointer))->instance.BoxRight(); sizeY -= ((DrawableBSP*)(testFeature->drawPointer))->instance.BoxLeft(); sizeY = (float)(fabs)(sizeY); sizeZ = ((DrawableBSP*)(testFeature->drawPointer))->instance.BoxTop(); sizeZ -= ((DrawableBSP*)(testFeature->drawPointer))->instance.BoxBottom(); sizeZ = (float)(fabs)(sizeZ); float groundRadius = max(sizeX, sizeY); //only for horizontal checks float NewBoxScale = boxScale; if ((groundRadius < 2.2F*Clearance) && MeasureHorizontally) NewBoxScale = boxScale * (2.2F*Clearance + groundRadius)/ groundRadius; //Check to see if out flight vector line intersects feature's box * boxScale (safety margin) if ( testFeature->drawPointer->GetRayHit( &pos, &vec, &collide, NewBoxScale ) ) { collide.x = (float)fabs(collide.x - pos.x); collide.y = (float)fabs(collide.y - pos.y); collide.z = (float)fabs(collide.z - pos.z); float Distance = (float)sqrt(collide.x*collide.x + collide.y*collide.y + collide.z*collide.z); //Remember this one, either closest one, or tallest one from our point of view. if (!GreatestAspect) { if (Distance < ClosestDistance) { ClosestDistance = Distance; *featureHeight = sizeZ; } } else { float newAspect = RTD*(float)atan2(sizeZ -(-self->ZPos()+self->af->groundZ), Distance); if (newAspect > Aspect && Distance < 2*MaxDistance) { Aspect = newAspect; ClosestDistance = Distance; *featureHeight = sizeZ; } } } } } testFeature = (SimBaseClass*) featureWalker.GetNext(); firstFeature = FALSE; } } objective = (CampBaseClass*)gridIt.GetNext(); } if (ClosestDistance < 2*MaxDistance) return ClosestDistance; //yes! We found a feature within range... else return -1.0F; //we ain't found sh*t... }
void Polygroup::polygonReduction() { //This function will be started in a new thread by the calling function so it will not interfere with main operation highEfficientPolys.clear(); highPolyReady=false; std::vector<Poly> gridCopy[10][10]; logger->LogMessage(LOG_POLYGON,"\nStarting new polygon reduction. Printing grid of heights:\n\n"); for(int x(0);x<10;++x) { for(int z(0);z<10;++z) { for(std::vector<Poly>::iterator copyIt(grid[x][z].begin());copyIt!=grid[x][z].end();++copyIt) { gridCopy[x][z].push_back((*copyIt)); logger->LogMessage(3,uiCore->intToString(gridCopy[x][z][0].getPoint(0).y) + " "); } } logger->LogMessage(3,"\n"); } for(int xPos(0);xPos<10;++xPos) { for(int zPos(0);zPos<10;++zPos) { for(std::vector<Poly>::iterator gridIt(gridCopy[xPos][zPos].begin());gridIt!=gridCopy[xPos][zPos].end();++gridIt) { bool breakout=false; if(gridIt->getNormal()==Vector3<s32>(0,1,0) || gridIt->getNormal()==Vector3<s32>(0,-1,0)) { Poly storedPoly((*gridIt)); int xPlus(0),zPlus(0); bool xFailed(false),zFailed(false); while(!xFailed || !zFailed) { if(!xFailed) { ++xPlus; for(int nextX(zPos);nextX<=(zPos+zPlus);++nextX) { if(xPos+xPlus==10 && !xFailed) { xFailed=true; if(xPlus>0) --xPlus; } else { bool fail(true); for(std::vector<Poly>::iterator posIt(gridCopy[xPos+xPlus][nextX].begin());posIt!=gridCopy[xPos+xPlus][nextX].end();++posIt) { if((posIt->getNormal()==storedPoly.getNormal()) && (posIt->getPoint(0).y==storedPoly.getPoint(0).y)) { fail=false; break; } } if(fail) { xFailed=true; if(xPlus>0) --xPlus; } } } } if(!zFailed) { ++zPlus; for(int nextZ(xPos);nextZ<=(xPos+xPlus);++nextZ) { if(zPos+zPlus==10 && !zFailed) { zFailed=true; if(zPlus>0) --zPlus; } else { bool fail(true); for(std::vector<Poly>::iterator posIt(gridCopy[nextZ][zPos+zPlus].begin());posIt!=gridCopy[nextZ][zPos+zPlus].end();++posIt) { if((posIt->getNormal()==storedPoly.getNormal()) && (posIt->getPoint(0).y==storedPoly.getPoint(0).y)) { fail=false; break; } } if(fail) { zFailed=true; if(zPlus>0) --zPlus; } } } } } Poly newPoly(storedPoly.getPoint(0), Vector3<s32>(storedPoly.getPoint(0).x,storedPoly.getPoint(0).y,storedPoly.getPoint(0).z+zPlus+1), Vector3<s32>(storedPoly.getPoint(0).x+xPlus+1,storedPoly.getPoint(0).y,storedPoly.getPoint(0).z+zPlus+1), Vector3<s32>(storedPoly.getPoint(0).x+xPlus+1,storedPoly.getPoint(0).y,storedPoly.getPoint(0).z), storedPoly.getType()); //removing +1 temporarily for(int x(xPos);x<=xPos+xPlus;++x) { for(int z(zPos);z<=zPos+zPlus;++z) { for(std::vector<Poly>::iterator posIt(gridCopy[x][z].begin());posIt!=gridCopy[x][z].end();++posIt) { if(posIt->getNormal()==storedPoly.getNormal() && (posIt->getPoint(0).y==storedPoly.getPoint(0).y)) { gridCopy[x][z].erase(posIt); logger->LogMessage(LOG_POLYGON,"Deleting Poly from grid at X: " + uiCore->intToString(x) + " Z: " + uiCore->intToString(z) + "\n"); breakout=true; break; } } } } highEfficientPolys.push_back(newPoly); logger->LogMessage(LOG_POLYGON,"Creating new Poly:\n"); logger->LogMessage(LOG_POLYGON,"minX: " + uiCore->intToString(newPoly.getPoint(0).x) + " minZ: " + uiCore->intToString(newPoly.getPoint(0).z) + "\n"); logger->LogMessage(LOG_POLYGON,"maxX: " + uiCore->intToString(newPoly.getPoint(2).x-1) + " maxZ: " + uiCore->intToString(newPoly.getPoint(2).z-1) + "\n"); } else { highEfficientPolys.push_back((*gridIt)); } if(breakout) break; } } } highPolyReady=true; }