template<typename T> bool RenderVisitor::visit(QuadNode<T,InstanceTree::MIN_TREE_SIZE>* node, int32_t d) { if (d==0) visited = 0; int32_t x = node->x(); int32_t y = node->y(); int32_t size = node->size(); ++visited; CellGrid *cg = m_layer->getCellGrid(); ///we have checked for null pointer in quadtreerenderer::render().. no need to check again ExactModelCoordinate emc= cg->toMapCoordinates(ExactModelCoordinate( x,y) );//0.5 for each cell's half-width ScreenPoint scrpt1 =m_camera->toScreenCoordinates( emc ); emc= cg->toMapCoordinates(ExactModelCoordinate( x,y+size) );// this size usage is wrong.. me thinks ScreenPoint scrpt2 =m_camera->toScreenCoordinates( emc ); emc= cg->toMapCoordinates(ExactModelCoordinate( x+size,y) ); ScreenPoint scrpt3 =m_camera->toScreenCoordinates( emc ); emc= cg->toMapCoordinates(ExactModelCoordinate( x+size,y+size) ); ScreenPoint scrpt4 =m_camera->toScreenCoordinates( emc ); m_renderbackend->drawLine(Point(scrpt1.x,scrpt1.y), Point(scrpt2.x,scrpt2.y), 255, 255, 255); m_renderbackend->drawLine(Point(scrpt1.x,scrpt1.y), Point(scrpt3.x,scrpt3.y), 255, 255, 255); m_renderbackend->drawLine(Point(scrpt3.x,scrpt3.y), Point(scrpt4.x,scrpt4.y), 255, 255, 255); m_renderbackend->drawLine(Point(scrpt2.x,scrpt2.y), Point(scrpt4.x,scrpt4.y), 255, 255, 255); return true; }
void CellSelectionRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { if (m_locations.empty()) { return; } std::vector<Location>::const_iterator locit = m_locations.begin(); for (; locit != m_locations.end(); locit++) { const Location loc = *locit; if (layer != loc.getLayer()) { continue; } CellGrid* cg = layer->getCellGrid(); if (!cg) { FL_WARN(_log, "No cellgrid assigned to layer, cannot draw selection"); continue; } std::vector<ExactModelCoordinate> vertices; cg->getVertices(vertices, loc.getLayerCoordinates()); std::vector<ExactModelCoordinate>::const_iterator it = vertices.begin(); ScreenPoint firstpt = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); Point pt1(firstpt.x, firstpt.y); Point pt2; ++it; for (; it != vertices.end(); it++) { ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); pt2.x = pts.x; pt2.y = pts.y; Point cpt1 = pt1; Point cpt2 = pt2; m_renderbackend->drawLine(cpt1, cpt2, m_color.r, m_color.g, m_color.b); pt1 = pt2; } m_renderbackend->drawLine(pt2, Point(firstpt.x, firstpt.y), m_color.r, m_color.g, m_color.b); } }
void BlockingInfoRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { CellGrid* cg = layer->getCellGrid(); if (!cg) { FL_WARN(_log, "No cellgrid assigned to layer, cannot draw grid"); return; } Rect cv = cam->getViewPort(); RenderList::const_iterator instance_it = instances.begin(); for (;instance_it != instances.end(); ++instance_it) { Instance* instance = (*instance_it)->instance; if (!instance->getObject()->isBlocking() || !instance->isBlocking()) { continue; } std::vector<ExactModelCoordinate> vertices; cg->getVertices(vertices, instance->getLocationRef().getLayerCoordinates()); std::vector<ExactModelCoordinate>::const_iterator it = vertices.begin(); int halfind = vertices.size() / 2; ScreenPoint firstpt = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); Point pt1(firstpt.x, firstpt.y); Point pt2; ++it; for (; it != vertices.end(); it++) { ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); pt2.x = pts.x; pt2.y = pts.y; Point cpt1 = pt1; Point cpt2 = pt2; m_renderbackend->drawLine(cpt1, cpt2, m_color.r, m_color.g, m_color.b); pt1 = pt2; } m_renderbackend->drawLine(pt2, Point(firstpt.x, firstpt.y), m_color.r, m_color.g, m_color.b); ScreenPoint spt1 = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[0])); Point pt3(spt1.x, spt1.y); ScreenPoint spt2 = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[halfind])); Point pt4(spt2.x, spt2.y); m_renderbackend->drawLine(pt3, pt4, m_color.r, m_color.g, m_color.b); } }
BOOST_FIXTURE_TEST_CASE(checkGhosts, Fixture) { /* create particles in a regular grid on the world, one per inner cell on each node */ CellGrid cGrid = domdec->getCellGrid(); NodeGrid nGrid = domdec->getNodeGrid(); // global number of cells per dimension (counted over all nodes) int totalCells[3]; for (int i = 0; i < 3; ++i) { totalCells[i] = cGrid.getGridSize(i)*nGrid.getGridSize(i); } int c = 0; for(int x = 0; x < cGrid.getGridSize(0); ++x) { for(int y = 0; y < cGrid.getGridSize(1); ++y) { for(int z = 0; z < cGrid.getGridSize(2); ++z) { Int3D ipos(x, y, z); // center particle in cell's global position Real3D pos; for (int i = 0; i < 3; ++i) { ipos[i] += nGrid.getNodePosition(i)*cGrid.getGridSize(i); pos[i] = (0.5 + ipos[i])*cGrid.getCellSize(i); } Particle *p = domdec->addParticle(c++, pos); p->type() = 10000*ipos[0] + 100*ipos[1] + ipos[2]; BOOST_TEST_MESSAGE("generated particle with type " << p->type()); } } } BOOST_TEST_MESSAGE("resort particles"); domdec->decompose(); BOOST_TEST_MESSAGE("done with resort particles"); /* now check that each cell has one particle, and at the proper position */ for(ESPPIterator<CellList> it(domdec->getLocalCells()); it.isValid(); ++it) { bool failed = true; ParticleList &pl = (*it)->particles; int cnt = pl.size(); // map back cell to coordinates Int3D ipos; cGrid.mapIndexToPosition(ipos, *it - domdec->getFirstCell()); BOOST_CHECK_EQUAL(cnt, 1); if (cnt == 1) { /* recalculate expected particles position. Remember that this time ipos is a ghost frame position, not a inner position. Shift accordingly */ Real3D pos; /* for checking the encoded type, we need the original cell */ int origcpos[3]; for (int i = 0; i < 3; ++i) { /* absolute cell location. Since coordinates should get folded, also the ghost particles should have their positions in the center of their cell */ int ip = ipos[i] - cGrid.getFrameWidth() + nGrid.getNodePosition(i)*cGrid.getGridSize(i); pos[i] = (0.5 + ip)*cGrid.getCellSize(i); // now backfold for type encoding if (ip < 0) { ip += totalCells[i]; } else if (ip >= totalCells[i]) { ip -= totalCells[i]; } origcpos[i] = ip; /* for the force test, set force according to original's absolute position that means that the forces on any ghost should always be the same as for its real particle. */ pl[0].force()[i] = origcpos[i]; } size_t type = 10000*origcpos[0] + 100*origcpos[1] + origcpos[2]; BOOST_CHECK_EQUAL(pl[0].type(), type); failed = pl[0].type() != type; Real3D delta = pos - pl[0].position(); real dst = delta * delta; failed |= dst > 1e-10; BOOST_CHECK_SMALL(dst, 1e-10); if (failed) { BOOST_TEST_MESSAGE("error at particle: expected " << pos << " type " << type << ", got " << pl[0].position() << " type " << pl[0].type()); } } if (failed) { BOOST_TEST_MESSAGE("error at cell: " << ipos << " on node " << nGrid.getNodePosition(0) << " " << nGrid.getNodePosition(1) << " " << nGrid.getNodePosition(2)); } } BOOST_TEST_MESSAGE("collect ghost forces"); domdec->collectGhostForces(); /* now check that the forces on the particles are correct */ for(ESPPIterator<CellList> it(domdec->getRealCells()); it.isValid(); ++it) { ParticleList &pl = (*it)->particles; int cnt = pl.size(); // map back cell to coordinates Int3D ipos; cGrid.mapIndexToPosition(ipos, *it - domdec->getFirstCell()); if (cnt == 1) { // see which how many ghosts should be there int ghostCnt = 0; for (int nx = -1; nx <= +1; ++nx) { if (nx == -1 && ipos[0] != cGrid.getInnerCellsBegin(0)) continue; if (nx == +1 && ipos[0] != cGrid.getInnerCellsEnd(0) - 1) continue; for (int ny = -1; ny <= +1; ++ny) { if (ny == -1 && ipos[1] != cGrid.getInnerCellsBegin(1)) continue; if (ny == +1 && ipos[1] != cGrid.getInnerCellsEnd(1) - 1) continue; for (int nz = -1; nz <= +1; ++nz) { if (nz == -1 && ipos[2] != cGrid.getInnerCellsBegin(2)) continue; if (nz == +1 && ipos[2] != cGrid.getInnerCellsEnd(2) - 1) continue; ghostCnt++; } } } BOOST_TEST_MESSAGE("expect " << ghostCnt << " ghosts for particle at " << ipos); // calculate expected force from absolute cell location Real3D force; for (int i = 0; i < 3; ++i) { real ap = ipos[i] - cGrid.getFrameWidth() + nGrid.getNodePosition(i)*cGrid.getGridSize(i); force[i] = ap*ghostCnt; } Real3D delta = force - pl[0].force(); real dst = delta * delta; BOOST_CHECK_SMALL(dst, 1e-10); if (dst > 1e-10) { BOOST_TEST_MESSAGE("error at cell: " << ipos << " on node " << nGrid.getNodePosition(0) << " " << nGrid.getNodePosition(1) << " " << nGrid.getNodePosition(2) << " expect force " << force << " got force " << pl[0].force()); } } } BOOST_TEST_MESSAGE("done with collect ghost forces"); }
void GridRenderer::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances) { CellGrid* cg = layer->getCellGrid(); if (!cg) { FL_WARN(_log, "No cellgrid assigned to layer, cannot draw grid"); return; } // // // //render elev_coord box // //draw front quad // // 1,1,1 // //1,-1,1 // //-1,-1,1 // //-1,1,1 Point a,b,c,d; ScreenPoint copt1 =cam->toScreenCoordinates(ExactModelCoordinate(1,1,1) ); ScreenPoint copt2 =cam->toScreenCoordinates(ExactModelCoordinate(1,-1,1) ); Point coptt1(copt1.x,copt1.y); Point coptt2(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,15, 15, 200); a = coptt1; copt1 =cam->toScreenCoordinates(ExactModelCoordinate(1,-1,1) ); copt2 =cam->toScreenCoordinates(ExactModelCoordinate(-1,-1,1) ); coptt1 = Point(copt1.x,copt1.y); coptt2 = Point(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,15, 15, 200); b = coptt1; copt1 =cam->toScreenCoordinates(ExactModelCoordinate(-1,-1,1) ); copt2 =cam->toScreenCoordinates(ExactModelCoordinate(-1,1,1) ); coptt1 = Point(copt1.x,copt1.y); coptt2 = Point(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,15, 15, 200); c = coptt1; copt1 =cam->toScreenCoordinates(ExactModelCoordinate(-1,1,1) ); copt2 =cam->toScreenCoordinates(ExactModelCoordinate(1,1,1) ); coptt1 = Point(copt1.x,copt1.y); coptt2 = Point(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,15, 15, 20); d = coptt1; m_renderbackend->drawQuad(a,b,c,d,15, 15, 200); // // // //draw back quad copt1 =cam->toScreenCoordinates(ExactModelCoordinate(-1,-1,-1) ); copt2 =cam->toScreenCoordinates(ExactModelCoordinate(-1,1,-1) ); coptt1 = Point(copt1.x,copt1.y); coptt2 = Point(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,200, 200, 200); copt1 =cam->toScreenCoordinates(ExactModelCoordinate(-1,1,-1) ); copt2 =cam->toScreenCoordinates(ExactModelCoordinate(1,1,-1) ); coptt1 = Point(copt1.x,copt1.y); coptt2 = Point(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,200, 200, 200); copt1 =cam->toScreenCoordinates(ExactModelCoordinate(1,1,-1) ); copt2 =cam->toScreenCoordinates(ExactModelCoordinate(1,-1,-1) ); coptt1 = Point(copt1.x,copt1.y); coptt2 = Point(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,200, 200, 200); copt1 =cam->toScreenCoordinates(ExactModelCoordinate(1,-1,-1) ); copt2 =cam->toScreenCoordinates(ExactModelCoordinate(-1,-1,-1) ); coptt1 = Point(copt1.x,copt1.y); coptt2 = Point(copt2.x,copt2.y); m_renderbackend->drawLine(coptt1,coptt2 ,200, 200, 200); Rect cv = cam->getViewPort(); std::vector<Instance*>::const_iterator instance_it = instances.begin(); for (;instance_it != instances.end(); ++instance_it) { Instance* instance = *instance_it; std::vector<ExactModelCoordinate> vertices; cg->getVertices(vertices, instance->getLocationRef().getLayerCoordinates()); std::vector<ExactModelCoordinate>::const_iterator it = vertices.begin(); ScreenPoint firstpt = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); Point pt1(firstpt.x, firstpt.y); Point pt2; ++it; for (; it != vertices.end(); it++) { ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); pt2.x = pts.x; pt2.y = pts.y; Point cpt1 = pt1; Point cpt2 = pt2; /* FIXME: limit grid drawing to current camera view port code below does not do it, but may act as a starting point int cvx2 = cv.x+cv.w; int cvy2 = cv.y+cv.h; if (((pt1.x < cv.x) && (pt2.x < cv.x)) || ((pt1.x > cvx2) && (pt2.x > cvx2)) || ((pt1.y < cv.y) && (pt2.y < cv.y)) || ((pt1.y > cvy2) && (pt2.y > cvy2))) { pt1 = pt2; continue; } if (cpt1.x < cv.x) cpt1.x = cv.x; if (cpt2.x < cv.x) cpt2.x = cv.x; if (cpt1.y < cv.y) cpt1.y = cv.y; if (cpt2.y < cv.y) cpt2.y = cv.y; if (cpt1.x > cvx2) cpt1.x = cvx2; if (cpt2.x > cvx2) cpt2.x = cvx2; if (cpt1.y > cvy2) cpt1.y = cvy2; if (cpt2.y > cvy2) cpt2.y = cvy2; */ m_renderbackend->drawLine(cpt1, cpt2, 0, 255, 0); pt1 = pt2; } m_renderbackend->drawLine(pt2, Point(firstpt.x, firstpt.y), 0, 255, 0); } }
int main(int argc, char* args[]) { bool quit = false; // Has the user quit? bool showgrid = true; // Should the grid be drawn? coords mousepos; // Initialise everything if (SDL_Init(SDL_INIT_EVERYTHING) == -1) { return 1; // An error occurred } screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); // If there was an error in setting up the screen if (screen == NULL) { return 1; } // Set the screen caption SDL_WM_SetCaption("Game of Life", NULL); // Create the cell grid CellGrid* cells = new CellGrid(); // While the user hasn't quit while (quit == false) { // While there's an event to handle while (SDL_PollEvent(&event)) { // If the user has quit if (event.type == SDL_QUIT) { quit = true; // This exits the loop } // Mouse motion else if (event.type == SDL_MOUSEMOTION) { mousepos.x = event.motion.x; mousepos.y = event.motion.y; // Mouse button held if (SDL_BUTTON(SDL_GetMouseState(NULL, NULL)) == SDL_BUTTON_LEFT) { int col, row; col = (mousepos.x / CELL_SIZE); row = (mousepos.y / CELL_SIZE); cells->ActivateCell(col, row); } else if (SDL_BUTTON(SDL_GetMouseState(NULL, NULL)) == SDL_BUTTON_MIDDLE) { int col, row; col = (mousepos.x / CELL_SIZE); row = (mousepos.y / CELL_SIZE); cells->KillCell(col, row); } } // Mouse click else if (event.type == SDL_MOUSEBUTTONDOWN) { if (SDL_BUTTON(SDL_GetMouseState(NULL, NULL)) == SDL_BUTTON_LEFT) { int col, row; col = (mousepos.x / CELL_SIZE); row = (mousepos.y / CELL_SIZE); cells->ActivateCell(col, row); } else if (SDL_BUTTON(SDL_GetMouseState(NULL, NULL)) == SDL_BUTTON_MIDDLE) { int col, row; col = (mousepos.x / CELL_SIZE); row = (mousepos.y / CELL_SIZE); cells->KillCell(col, row); } } // Keypress else if (event.type == SDL_KEYDOWN) { switch(event.key.keysym.sym) { case SDLK_p: cells->TogglePause(); break; case SDLK_r: cells->Clear(); break; case SDLK_g: if (showgrid) showgrid = false; else showgrid = true; break; } } } // Redraw redraw(cells, showgrid); // Update the screen if (SDL_Flip(screen) == -1) { return 1; // An error occurred } // Update the cells cells->update(); // Restrict the framerate (so as to limit CPU usage) SDL_Delay(10); } clean_up(cells); return 0; }