bool ComputeAStar( SpatialGraphKDNode* pSourceNode, SpatialGraphKDNode* pDestNode, Vector2List& path ) { AStarSearch<SearchInterface> search; SearchInterface pStart(pSourceNode); SearchInterface pEnd(pDestNode); search.SetStartAndGoalStates( pStart, pEnd ); while( AStarSearch<SearchInterface>::SEARCH_STATE_SEARCHING == search.SearchStep() ) { } int curState = search.GetState(); if( curState == AStarSearch<SearchInterface>::SEARCH_STATE_SUCCEEDED ) { //Get path for( SearchInterface* pCur = search.GetSolutionStart(); pCur != NULL; pCur = search.GetSolutionNext() ) { path.push_back( pCur->pNode->BBox.Centroid() ); } search.FreeSolutionNodes(); return true; } return false; }
bool TerrainBlock::castRayI(const Point3F &start, const Point3F &end, RayInfo *info, bool collideEmpty) { lineCount = 0; lineStart = start; lineEnd = end; info->object = this; if(start.x == end.x && start.y == end.y) { if (end.z == start.z) return false; F32 height; if(!getNormalAndHeight(Point2F(start.x, start.y), &info->normal, &height, true)) return false; F32 t = (height - start.z) / (end.z - start.z); if(t < 0 || t > 1) return false; info->t = t; return true; } F32 invBlockWorldSize = 1 / F32(mSquareSize * BlockSquareWidth); Point3F pStart(start.x * invBlockWorldSize, start.y * invBlockWorldSize, start.z); Point3F pEnd(end.x * invBlockWorldSize, end.y * invBlockWorldSize, end.z); int blockX = (S32)mFloor(pStart.x); int blockY = (S32)mFloor(pStart.y); int dx, dy; F32 invDeltaX; if(pEnd.x == pStart.x) { calcInterceptX = calcInterceptNone; invDeltaX = 0; dx = 0; } else { invDeltaX = 1 / (pEnd.x - pStart.x); calcInterceptX = calcInterceptV; if(pEnd.x < pStart.x) dx = -1; else dx = 1; } F32 invDeltaY; if(pEnd.y == pStart.y) { calcInterceptY = calcInterceptNone; invDeltaY = 0; dy = 0; } else { invDeltaY = 1 / (pEnd.y - pStart.y); calcInterceptY = calcInterceptV; if(pEnd.y < pStart.y) dy = -1; else dy = 1; } F32 startT = 0; for(;;) { F32 nextXInt = calcInterceptX(pStart.x, invDeltaX, (F32)(blockX + (dx == 1))); F32 nextYInt = calcInterceptY(pStart.y, invDeltaY, (F32)(blockY + (dy == 1))); F32 intersectT = 1; if(nextXInt < intersectT) intersectT = nextXInt; if(nextYInt < intersectT) intersectT = nextYInt; if(castRayBlock(pStart, pEnd, Point2I(blockX * BlockSquareWidth, blockY * BlockSquareWidth), BlockShift, invDeltaX, invDeltaY, startT, intersectT, info, collideEmpty)) { info->normal.z *= BlockSquareWidth * mSquareSize; info->normal.normalize(); return true; } startT = intersectT; if(intersectT >= 1) break; if(nextXInt < nextYInt) blockX += dx; else if(nextYInt < nextXInt) blockY += dy; else { blockX += dx; blockY += dy; } } return false; }
void RS_Line::draw(RS_Painter* painter, RS_GraphicView* view, double& patternOffset) { if (painter==NULL || view==NULL) { return; } //only draw the visible portion of line QVector<RS_Vector> endPoints(0); RS_Vector vpMin(view->toGraph(0,view->getHeight())); RS_Vector vpMax(view->toGraph(view->getWidth(),0)); QPolygonF visualBox(QRectF(vpMin.x,vpMin.y,vpMax.x-vpMin.x, vpMax.y-vpMin.y)); if( getStartpoint().isInWindowOrdered(vpMin, vpMax) ) endPoints<<getStartpoint(); if( getEndpoint().isInWindowOrdered(vpMin, vpMax) ) endPoints<<getEndpoint(); if(endPoints.size()<2){ QVector<RS_Vector> vertex; for(unsigned short i=0;i<4;i++){ const QPointF& vp(visualBox.at(i)); vertex<<RS_Vector(vp.x(),vp.y()); } for(unsigned short i=0;i<4;i++){ RS_Line line(NULL,RS_LineData(vertex.at(i),vertex.at((i+1)%4))); auto&& vpIts=RS_Information::getIntersection(static_cast<RS_Entity*>(this), &line, true); if( vpIts.size()==0) continue; endPoints<<vpIts.get(0); } } if(endPoints.size()<2) return; if( (endPoints[0] - getStartpoint()).squared() > (endPoints[1] - getStartpoint()).squared() ) std::swap(endPoints[0],endPoints[1]); RS_Vector pStart(view->toGui(endPoints.at(0))); RS_Vector pEnd(view->toGui(endPoints.at(1))); // std::cout<<"draw line: "<<pStart<<" to "<<pEnd<<std::endl; RS_Vector direction=pEnd-pStart; if(isHelpLayer(true) && direction.squared() > RS_TOLERANCE){ //extend line on a help layer to fill the whole view RS_Vector lb(0,0); RS_Vector rt(view->getWidth(),view->getHeight()); QList<RS_Vector> rect; rect<<lb<<RS_Vector(rt.x,lb.y); rect<<rt<<RS_Vector(lb.x,rt.y); rect<<lb; RS_VectorSolutions sol; RS_Line dLine(pStart,pEnd); for(int i=0;i<4;i++){ RS_Line bLine(rect.at(i),rect.at(i+1)); RS_VectorSolutions sol2=RS_Information::getIntersection(&bLine, &dLine); if( sol2.getNumber()>0 && bLine.isPointOnEntity(sol2.get(0),RS_TOLERANCE)) { sol.push_back(sol2.get(0)); } } switch(sol.getNumber()){ case 2: pStart=sol.get(0); pEnd=sol.get(1); break; case 3: case 4: pStart=sol.get(0); pEnd=sol.get(2); break; default: return; } direction=pEnd-pStart; } double length=direction.magnitude(); patternOffset -= length; if (( !isSelected() && ( getPen().getLineType()==RS2::SolidLine || view->getDrawingMode()==RS2::ModePreview)) ) { //if length is too small, attempt to draw the line, could be a potential bug painter->drawLine(pStart,pEnd); return; } // double styleFactor = getStyleFactor(view); // Pattern: RS_LineTypePattern* pat; if (isSelected()) { // styleFactor=1.; pat = &patternSelected; } else { pat = view->getPattern(getPen().getLineType()); } if (pat==NULL) { // patternOffset -= length; RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Line::draw: Invalid line pattern"); painter->drawLine(pStart,pEnd); return; } // patternOffset = remainder(patternOffset - length-0.5*pat->totalLength,pat->totalLength)+0.5*pat->totalLength; if(length<=RS_TOLERANCE){ painter->drawLine(pStart,pEnd); return; //avoid division by zero } direction/=length; //cos(angle), sin(angle) // Pen to draw pattern is always solid: RS_Pen pen = painter->getPen(); pen.setLineType(RS2::SolidLine); painter->setPen(pen); // index counter int i; // pattern segment length: double patternSegmentLength = pat->totalLength; // create pattern: RS_Vector* dp=new RS_Vector[pat->num > 0?pat->num:0]; double* ds=new double[pat->num > 0?pat->num:0]; if (pat->num >0 ){ double dpmm=static_cast<RS_PainterQt*>(painter)->getDpmm(); for (i=0; i<pat->num; ++i) { // ds[j]=pat->pattern[i] * styleFactor; //fixme, styleFactor support needed ds[i]=dpmm*pat->pattern[i]; if( fabs(ds[i]) < 1. ) ds[i] = (ds[i]>=0.)?1.:-1.; dp[i] = direction*fabs(ds[i]); } }else { delete[] dp; delete[] ds; RS_DEBUG->print(RS_Debug::D_WARNING,"invalid line pattern for line, draw solid line instread"); painter->drawLine(view->toGui(getStartpoint()), view->toGui(getEndpoint())); return; } double total= remainder(patternOffset-0.5*patternSegmentLength,patternSegmentLength) -0.5*patternSegmentLength; // double total= patternOffset-patternSegmentLength; RS_Vector p1,p2,p3; RS_Vector curP(pStart+direction*total); double t2; for(int j=0;total<length;j=(j+1)%i) { // line segment (otherwise space segment) t2=total+fabs(ds[j]); p3=curP+dp[j]; if (ds[j]>0.0 && t2 > 0.0) { // drop the whole pattern segment line, for ds[i]<0: // trim end points of pattern segment line to line p1 =(total > -0.5)? curP:pStart; p2 =(t2<length+0.5)?p3:pEnd; painter->drawLine(p1,p2); } total=t2; curP=p3; } delete[] dp; delete[] ds; }
void RS_Line::draw(RS_Painter* painter, RS_GraphicView* view, double& patternOffset) { if (painter==NULL || view==NULL) { return; } //visible in grahic view if(isVisibleInWindow(view)==false) return; RS_Vector pStart(view->toGui(getStartpoint())); RS_Vector pEnd(view->toGui(getEndpoint())); // std::cout<<"draw line: "<<pStart<<" to "<<pEnd<<std::endl; RS_Vector direction=pEnd-pStart; if(isHelpLayer(true) && direction.squared() > RS_TOLERANCE){ //extend line on a help layer to fill the whole view RS_Vector lb(0,0); RS_Vector rt(view->getWidth(),view->getHeight()); QList<RS_Vector> rect; rect<<lb<<RS_Vector(rt.x,lb.y); rect<<rt<<RS_Vector(lb.x,rt.y); rect<<lb; RS_VectorSolutions sol; RS_Line dLine(pStart,pEnd); for(int i=0;i<4;i++){ RS_Line bLine(rect.at(i),rect.at(i+1)); RS_VectorSolutions sol2=RS_Information::getIntersection(&bLine, &dLine); if( sol2.getNumber()>0 && bLine.isPointOnEntity(sol2.get(0),RS_TOLERANCE)) { sol.push_back(sol2.get(0)); } } switch(sol.getNumber()){ case 2: pStart=sol.get(0); pEnd=sol.get(1); break; case 3: case 4: pStart=sol.get(0); pEnd=sol.get(2); break; default: return; } direction=pEnd-pStart; } double length=direction.magnitude(); patternOffset -= length; if (( !isSelected() && ( getPen().getLineType()==RS2::SolidLine || view->getDrawingMode()==RS2::ModePreview)) ) { //if length is too small, attempt to draw the line, could be a potential bug painter->drawLine(pStart,pEnd); return; } // double styleFactor = getStyleFactor(view); // Pattern: RS_LineTypePattern* pat; if (isSelected()) { // styleFactor=1.; pat = &patternSelected; } else { pat = view->getPattern(getPen().getLineType()); } if (pat==NULL) { // patternOffset -= length; RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Line::draw: Invalid line pattern"); painter->drawLine(pStart,pEnd); return; } // patternOffset = remainder(patternOffset - length-0.5*pat->totalLength,pat->totalLength)+0.5*pat->totalLength; if(length<=RS_TOLERANCE){ painter->drawLine(pStart,pEnd); return; //avoid division by zero } direction/=length; //cos(angle), sin(angle) // Pen to draw pattern is always solid: RS_Pen pen = painter->getPen(); pen.setLineType(RS2::SolidLine); painter->setPen(pen); // index counter int i; // pattern segment length: double patternSegmentLength = pat->totalLength; // create pattern: RS_Vector* dp=new RS_Vector[pat->num > 0?pat->num:0]; double* ds=new double[pat->num > 0?pat->num:0]; if (pat->num >0 ){ for (i=0; i<pat->num; ++i) { // ds[j]=pat->pattern[i] * styleFactor; //fixme, styleFactor support needed ds[i]=pat->pattern[i] ; dp[i] = direction*fabs(ds[i]); } }else { delete[] dp; delete[] ds; RS_DEBUG->print(RS_Debug::D_WARNING,"invalid line pattern for line, draw solid line instread"); painter->drawLine(view->toGui(getStartpoint()), view->toGui(getEndpoint())); return; } double total= remainder(patternOffset-0.5*patternSegmentLength,patternSegmentLength) -0.5*patternSegmentLength; // double total= patternOffset-patternSegmentLength; RS_Vector p1,p2,p3; RS_Vector curP(pStart+direction*total); double t2; for(int j=0;total<length;j=(j+1)%i) { // line segment (otherwise space segment) t2=total+fabs(ds[j]); p3=curP+dp[j]; if (ds[j]>0.0 && t2 > 0.0) { // drop the whole pattern segment line, for ds[i]<0: // trim end points of pattern segment line to line p1 =(total > -0.5)? curP:pStart; p2 =(t2<length+0.5)?p3:pEnd; painter->drawLine(p1,p2); } total=t2; curP=p3; } delete[] dp; delete[] ds; }
void ItemSerializer::toJson(std::ostream& out, const sserialize::Static::Array< sserialize::Static::spatial::GeoPolygon >& polys) const { out << "["; if (polys.size()) { sserialize::Static::spatial::GeoMultiPolygon::PolygonList::const_iterator pIt(polys.cbegin()), pEnd(polys.cend()); sserialize::Static::spatial::GeoMultiPolygon::PolygonList::const_reference gp(*pIt); out << "["; toJson(out, gp.cbegin(), gp.cend()); out << "]"; for(++pIt; pIt != pEnd; ++pIt) { out << ",["; gp = *pIt; toJson(out, gp.cbegin(), gp.cend()); out << "]"; } } out << "]"; }
void GameEngine::generateLevel() { //Clear out the last level for (vector<Actor*>::iterator it = monsters.begin(); it != monsters.end(); ++it) delete (*it); monsters.clear(); for (vector<Pickup*>::iterator it = pickups.begin(); it != pickups.end(); ++it) delete (*it); pickups.clear(); map.clear(); playableMap.clear(); //Set tile graphics for curr floor if (currLevel == 1) { wallTile = 0x103; floorTile = 0x100; } else if (currLevel > 1) { wallTile = 0x14D; floorTile = 0x13E; delete boss; } //Initialize the outer map vector for (int i = 0; i < worldSize; i++) { vector<Cell> v; map.push_back(v); } //Generate the map boundaries lib.loop_portion(Point(0, 0), Point(worldSize, worldSize), [&](Point p) { Cell c(p, 2, wallTile, 0); map[p.x()].push_back(c); }); //Generate the random rooms for (int i = 0; i < rand() % 130 + 100; i++) { Point pStart((rand() % 55 + 1), (rand() % 55 + 1)); Point pEnd(pStart.x() + (rand() % 6 + 3), pStart.y() + (rand() % 6 + 3)); fillBox(pStart, pEnd); } //Flood fill to connect the world int currZone = 0; vector<int> zoneSize; lib.loop_portion(Point(0, 0), Point(worldSize, worldSize), [&](Point p) { if (map[p.x()][p.y()].getCellType() != 2 && map[p.x()][p.y()].getZone() == 0) { currZone++; int size = floodFill(map[p.x()][p.y()].getLoc(), currZone, 0); zoneSize.push_back(size); } }); //Get biggest zone in array int max = zoneSize[0]; int largestZone = 0; for (unsigned int i = 1; i < zoneSize.size(); i++) { if (zoneSize[i] > max) { largestZone = i; max = zoneSize[i]; } } largestZone++; //Offset for vector index //Get rid of everything but largest zone int end = worldSize - 1; lib.loop_portion(Point(0, 0), Point(worldSize, worldSize), [&](Point p) { Cell& c = map[p.x()][p.y()]; if (c.getZone() != largestZone) { if ((p.x() + 1 < end && map[p.x() + 1][p.y()].getZone() == largestZone) || (p.x() - 1 > 0 && map[p.x() - 1][p.y()].getZone() == largestZone) || (p.y() + 1 < end && map[p.x()][p.y() + 1].getZone() == largestZone) || (p.y() - 1 > 0 && map[p.x()][p.y() - 1].getZone() == largestZone) || (p.x() - 1 > 0 && p.y() - 1 > 0 && map[p.x() - 1][p.y() - 1].getZone() == largestZone) || (p.x() - 1 > 0 && p.y() + 1 < end && map[p.x() - 1][p.y() + 1].getZone() == largestZone) || (p.x() + 1 < end && p.y() - 1 > 0 && map[p.x() + 1][p.y() - 1].getZone() == largestZone) || (p.x() + 1 < end && p.y() + 1 < end && map[p.x() + 1][p.y() + 1].getZone() == largestZone)) { c.setTile(wallTile); c.setTileType(2); } else { c.setTile(0); c.setTileType(2); } } else if (c.getLoc().x() == end) c.setTile(0); }); //Set player starting position lib.loop_portion(Point(0, 0), Point(worldSize - 1, worldSize - 1), [&](Point p) { if (map[p.x()][p.y()].getZone() != 0 && map[p.x()][p.y()].getCellType() != 2) playableMap.push_back(map[p.x()][p.y()].getLoc()); }); //Add monsters for (unsigned int i = 0; i < playableMap.size(); i++) { int chance = rand() % 30; if (chance == 15) { //Make the monster ActorDef def = pickfromtable<ActorDef>(actordefs); monsters.push_back(new Actor(def, playableMap[i], false, false)); map[playableMap[i].x()][playableMap[i].y()].setActor(monsters.back()); //Give chance to spawn with item chance = rand() % 5 + 1; //Give 10% chance to spawn if (chance == 3) { PickupDef def = pickfromtable<PickupDef>(pickupdefs); pickups.push_back(new Pickup(def, playableMap[i])); map[playableMap[i].x()][playableMap[i].y()].setPickup(pickups.back()); } } } //Set starting pos Point heroLoc = getRandomLoc(); screenOrientation = heroLoc; hero->setLoc(screenOrientation); //Add stairs, shop, boss stairLoc = addToRandomLoc(Cell(Point(), 5, 0x1A0, -1)); shop = Shop(addToRandomLoc(Cell(Point(), 6, 0x0C0, -1)), currLevel, pickupdefs, &lib, hero, &log, &invLog); bossLoc = addToRandomLoc(Cell(Point(), 7, 0x1AB, -1)); bossInRoomLoc = Point(5, 2); //Instantiate the boss map for (int i = 0; i < bossMapSize; i++) { vector<Cell> row; for (int j = 0; j < bossMapSize; j++) { if (i == 0 || i == bossMapSize - 1 || j == 0 || j == bossMapSize - 1) row.push_back(Cell(Point(i, j), 2, 0x14B, 1)); else row.push_back(Cell(Point(i, j), 1, 0x122, 1)); } bossMap.push_back(row); } //Add the boss to its location in the boss map int which = rand() % bossdefs.size(); boss = new Actor(bossdefs[which], bossInRoomLoc, false, true); bossMap[bossInRoomLoc.x()][bossInRoomLoc.y()].setActor(boss); }