bool CPUElevationProducer::doCreateTile(int level, int tx, int ty, TileStorage::Slot *data) { if (Logger::DEBUG_LOGGER != NULL) { ostringstream oss; oss << "CPUElevation tile " << getId() << " " << level << " " << tx << " " << ty; Logger::DEBUG_LOGGER->log("DEM", oss.str()); } CPUTileStorage<float>::CPUSlot *cpuData = dynamic_cast<CPUTileStorage<float>::CPUSlot*>(data); assert(cpuData != NULL); int tileWidth = data->getOwner()->getTileSize(); int tileSize = tileWidth - 5; CPUTileStorage<float>::CPUSlot *parentCpuData = NULL; if (level > 0) { TileCache::Tile *t = findTile(level - 1, tx / 2, ty / 2); assert(t != NULL); parentCpuData = dynamic_cast<CPUTileStorage<float>::CPUSlot*>(t->getData()); assert(parentCpuData != NULL); } int residualTileWidth = residualTiles->getCache()->getStorage()->getTileSize(); int mod = (residualTileWidth - 2 * residualTiles->getBorder() - 1) / tileSize; int rx = (tx % mod) * tileSize; // select the xy coord in residual int ry = (ty % mod) * tileSize; TileCache::Tile *t = residualTiles->findTile(level, tx / mod, ty / mod); CPUTileStorage<float>::CPUSlot *cpuTile = NULL; bool hasResidual = residualTiles->hasTile(level, tx / mod, ty / mod); if (hasResidual) { assert(t != NULL); cpuTile = dynamic_cast<CPUTileStorage<float>::CPUSlot*>(t->getData()); assert(cpuTile != NULL); } int px = 1 + (tx % 2) * tileSize / 2; //select the xy coord in the parent tile int py = 1 + (ty % 2) * tileSize / 2; float *parentTile = NULL; if (level > 0) { parentTile = parentCpuData->data; } for (int j = 0; j < tileWidth; ++j) { for (int i = 0; i < tileWidth; ++i) { float z; float r = 0.0f; if (level == 0) { z = 0.0f; } else { if (j % 2 == 0) { if (i % 2 == 0) { z = parentTile[i / 2 + px + (j / 2 + py) * tileWidth]; } else { float z0 = parentTile[i / 2 + px - 1 + (j / 2 + py) * tileWidth]; float z1 = parentTile[i / 2 + px + (j / 2 + py) * tileWidth]; float z2 = parentTile[i / 2 + px + 1 + (j / 2 + py) * tileWidth]; float z3 = parentTile[i / 2 + px + 2 + (j / 2 + py) * tileWidth]; z = ((z1 + z2) * 9 - (z0 + z3)) / 16; } } else { if (i % 2 == 0) { float z0 = parentTile[i / 2 + px + (j / 2 - 1 + py) * tileWidth]; float z1 = parentTile[i / 2 + px + (j / 2 + py) * tileWidth]; float z2 = parentTile[i / 2 + px + (j / 2 + 1 + py) * tileWidth]; float z3 = parentTile[i / 2 + px + (j / 2 + 2 + py) * tileWidth]; z = ((z1 + z2) * 9 - (z0 + z3)) / 16; } else { int di, dj; z = 0; for (dj = -1; dj <= 2; ++dj) { float f = dj == -1 || dj == 2 ? -1/16.0f : 9/16.0f; for (di = -1; di <= 2; ++di) { float g = di == -1 || di == 2 ? -1/16.0f : 9/16.0f; z += f * g * parentTile[i / 2 + di + px + (j / 2 + dj + py) * tileWidth]; } } } } } if (hasResidual) { r = cpuTile->data[(int)(i + rx + (j + ry) * residualTileWidth)]; } cpuData->data[i + j * tileWidth] = z + r; } } return true; }
bool WaterElevationLayer::doCreateTile(int level, int tx, int ty, TileStorage::Slot *data) { if (Logger::DEBUG_LOGGER != NULL) { ostringstream oss; oss << "ElevationRoad tile " << getProducerId() << " " << level << " " << tx << " " << ty; Logger::DEBUG_LOGGER->log("DEM", oss.str()); } if (level >= displayLevel) { TileCache::Tile *t = graphProducer->findTile(level, tx, ty); assert(t != NULL); ObjectTileStorage::ObjectSlot *graphData = dynamic_cast<ObjectTileStorage::ObjectSlot*>(t->getData()); GraphPtr g = graphData->data.cast<Graph>(); if (g->getCurveCount() == 0) { return false; } ptr<FrameBuffer> fb = SceneManager::getCurrentFrameBuffer(); vec3d q = getTileCoords(level, tx, ty); vec2d nx, ny, lx, ly; getDeformParameters(q, nx, ny, lx, ly); float scale = 2.0f * (getTileSize() - 1.0f - (2.0f * getTileBorder())) / q.z; vec3d tileOffset = vec3d(q.x + q.z / 2.0f, q.y + q.z / 2.0f, scale / getTileSize()); //tileOffsetU->set(vec3f(q.x + q.z / 2.0f, q.y + q.z / 2.0f, scale / getTileSize())); tileOffsetU->set(vec3f(0.0, 0.0, 1.0)); fb->clear(false, false, true); if (g->getAreaCount() > 0) { //fillOffsetU->set(vec3f(q.x + q.z / 2.0f, q.y + q.z / 2.0f, scale / getTileSize())); fillOffsetU->set(vec3f(0.0, 0.0, 1.0)); depthU->set(0.02f); colorU->set(vec4f(0.0f, 0.0f, 0.0f, 0.0f)); fb->setDepthTest(true, ALWAYS); fb->setColorMask(false, false, false, true); fb->setDepthMask(true); mesh->setMode(TRIANGLES); mesh->clear(); tess->beginPolygon(mesh); ptr<Graph::AreaIterator> ai = g->getAreas(); while (ai->hasNext()) { AreaPtr a = ai->next(); GraphLayer::drawArea(tileOffset, a, *tess); } tess->endPolygon(); fb->draw(fillProg, *mesh); riverU->set(1); ai = g->getAreas(); while (ai->hasNext()) { AreaPtr a = ai->next(); bool island = true; for (int j = 0; j < a->getCurveCount(); ++j) { int o; island &= (a->getCurve(j, o)->getType() == WaterElevationCurveData::ISLAND); if (!island) { break; } } for (int j = 0; j < a->getCurveCount(); ++j) { int orientation; CurvePtr p = a->getCurve(j, orientation); if (island) { orientation = 1 - orientation; } else { if (p->getType() == WaterElevationCurveData::ISLAND) { continue; } } if (orientation != 0) { GraphLayer::drawCurve(tileOffset, p, vec4f(0, 12, 1, 2), fb, layerProgram, *(meshuv), &nx, &ny, &lx, &ly); } else { GraphLayer::drawCurve(tileOffset, p, vec4f(0, -12, 1, 2), fb, layerProgram, *(meshuv), &nx, &ny, &lx, &ly); } } } fb->setDepthTest(true, NOTEQUAL); fb->setColorMask(false, false, true, false); fb->setDepthMask(false); riverU->set(2); ptr<Graph::CurveIterator> ci = g->getCurves(); while (ci->hasNext()) { CurvePtr c = ci->next(); float w = c->getWidth(); float tw = w; if (w * scale <= 1 || (c->getParent() == NULL && level != 0) || c->getType() == WaterElevationCurveData::LAKE || c->getType() == WaterElevationCurveData::RIVER || c->getArea1() != NULL) {//== WaterElevationCurveData::RIVER) { continue; } ElevationCurveData *cData = dynamic_cast<ElevationCurveData*>(findCurveData(c)); ElevationGraphLayer::drawCurveAltitude(tileOffset, c, cData, tw, tw / w, max(1.0f, 1.0f / scale), false, fb, layerProgram, *meshuv, &nx, &ny, &lx, &ly); } } fb->setColorMask(false, false, true, true); fb->setDepthTest(true, LESS); fb->setDepthMask(true); riverU->set(1); ptr<Graph::CurveIterator> ci = g->getCurves(); while (ci->hasNext()) { CurvePtr c = ci->next(); float cwidth = c->getWidth(); if (cwidth * scale <= 1 || c->getType() != WaterElevationCurveData::RIVER || (c->getParent() == NULL && level != 0)) { continue; } float w = BASEWIDTH(cwidth, scale); float tw = TOTALWIDTH(w); ElevationCurveData *cData = dynamic_cast<ElevationCurveData*>(findCurveData(c)); ElevationGraphLayer::drawCurveAltitude(tileOffset, c, cData, tw, tw / w, max(1.0f, 1.0f / scale), true, fb, layerProgram, *meshuv, &nx, &ny, &lx, &ly); } fb->setColorMask(true, true, true, true); } return true; }
bool TextureLayer::doCreateTile(int level, int tx, int ty, TileStorage::Slot *data) { if (Logger::DEBUG_LOGGER != NULL) { ostringstream oss; oss << "Texture tile " << getProducerId() << " " << level << " " << tx << " " << ty; Logger::DEBUG_LOGGER->log("ORTHO", oss.str()); } if (level < minDisplayLevel) { return true; } int l = level; int x = tx; int y = ty; while (!tiles->hasTile(l, x, y)) { l -= 1; x /= 2; y /= 2; assert(l >= 0); } ptr<FrameBuffer> fb = SceneManager::getCurrentFrameBuffer(); TileCache::Tile *t = tiles->findTile(l, x, y); assert(t != NULL); GPUTileStorage::GPUSlot *gput = dynamic_cast<GPUTileStorage::GPUSlot*>(t->getData()); assert(gput != NULL); vec4f coords = tiles->getGpuTileCoords(level, tx, ty, &t); int s = tiles->getCache()->getStorage()->getTileSize(); float b = float(tiles->getBorder()) / (1 << (level - l)); float S = s / (s - 2.0f * tiles->getBorder()); // correct border vec4f coordsCorrected = coords; coordsCorrected.x -= b / gput->getWidth(); coordsCorrected.y -= b / gput->getHeight(); coordsCorrected.w *= S; samplerU->set(gput->t); coordsU->set(vec3f(coordsCorrected.x, coordsCorrected.y, coords.z)); sizeU->set(vec3f(coordsCorrected.w, coordsCorrected.w, (s / 2) * 2.0f - 2.0f * b)); if (blend.buffer != (BufferId) -1) { fb->setBlend(blend.buffer, true, blend.rgb, blend.srgb, blend.drgb, blend.alpha, blend.salpha, blend.dalpha); } else { fb->setBlend(true, blend.rgb, blend.srgb, blend.drgb, blend.alpha, blend.salpha, blend.dalpha); } fb->drawQuad(program); if (blend.buffer != (BufferId) -1) { fb->setBlend(blend.buffer, false); } else { fb->setBlend(false); } return true; }
bool HydroFlowProducer::doCreateTile(int level, int tx, int ty, TileStorage::Slot *data) { if (Logger::DEBUG_LOGGER != NULL) { ostringstream oss; oss << "Hydro tile " << getId() << " " << level << " " << tx << " " << ty; Logger::DEBUG_LOGGER->log("RIVER", oss.str()); } swHYDRODATA->start(); bool res = false; ObjectTileStorage::ObjectSlot *objectData = dynamic_cast<ObjectTileStorage::ObjectSlot*>(data); assert(objectData != NULL); TileCache::Tile::TId id = TileCache::Tile::getTId(getId(), level, tx, ty); TileCache::Tile *graphTile = graphs->findTile(level, tx, ty); assert(graphTile != NULL); ptr<Graph> graphData = dynamic_cast<ObjectTileStorage::ObjectSlot*>(graphTile->getData())->data.cast<Graph>(); float quadSize = getRootQuadSize() / (1 << level); bool diffVersion = false; if (objectData->data != NULL) { diffVersion = !objectData->data.cast<HydroFlowTile>()->equals(graphData->version, slipParameter, min((int) (quadSize / potentialDelta), displayTileSize), searchRadiusFactor);//objectData->data.cast<HydroFlowTile>()->version != graphData->version; } if (diffVersion || id != objectData->id || objectData->data == NULL ) { ptr<HydroFlowTile> hydroData; double ox = getRootQuadSize() * (double(tx) / (1 << level) - 0.5f); double oy = getRootQuadSize() * (double(ty) / (1 << level) - 0.5f); if (level >= minLevel) { if (graphData.cast<HydroGraph>() == NULL && graphData.cast<LazyHydroGraph>() == NULL) { // if the type of graph is wrong if (Logger::ERROR_LOGGER != NULL) { ostringstream oss; oss << "Bad Graph Type : Should be a [Lazy]HydroGraph."; Logger::ERROR_LOGGER->log("RIVER", oss.str()); } return false; } if (quadSize / potentialDelta < displayTileSize / 2 && level - 1 >=minLevel) { //maxLevel objectData->data = dynamic_cast<ObjectTileStorage::ObjectSlot*>(findTile(level - 1, tx / 2, ty / 2)->getData())->data; return true; } float scale = displayTileSize == -1 ? 1 : displayTileSize / quadSize; ptr<Graph::CurveIterator> ci = graphData->getCurves(); vector<ptr<HydroCurve> > banks; float width = 0.f; while(ci->hasNext()) { ptr<HydroCurve> c = ci->next().cast<HydroCurve>(); bool display = false; if (c->getType() != HydroCurve::BANK && c->getWidth() * scale > 1.0f) { display = true; if (width < c->getWidth()) { width = c->getWidth(); } } else if (c->getType() == HydroCurve::BANK && c->getRiver().id != NULL_ID) { if (c->getOwner()->getAncestor()->getCurve(c->getRiver()).cast<HydroCurve>()->getWidth() * scale > 1.0f) { display = true; } } if (display) { banks.push_back(c); } } hydroData = new HydroFlowTile(ox, oy, quadSize, slipParameter, min((int) (quadSize / potentialDelta), displayTileSize), searchRadiusFactor); hydroData->addBanks(banks, width); } else { hydroData = new HydroFlowTile(ox, oy, quadSize, slipParameter, min((int) (quadSize / potentialDelta), displayTileSize), searchRadiusFactor); } objectData->data = hydroData; hydroData->version = graphData->version; res = true; } swHYDRODATA->end(); TileProducer::doCreateTile(level, tx, ty, data); return res; }