/// \brief Set the BasePoint value at a given base point coordinate. /// /// Set the BasePoint value for the given coordinate on the base /// point grid. /// If inserting this BasePoint completes the set of points required /// to define one or more Segment objects which were not yet defined, /// new Segment objects are created. If this replaces a point for one /// or more Segment objects that were already defined, the contents of /// those Segment objects are invalidated. /// @param x coordinate on the base point grid. /// @param y coordinate on the base point grid. /// @param z BasePoint value to be used at the given coordinate. void Terrain::setBasePoint(int x, int y, const BasePoint& z) { m_basePoints[x][y] = z; bool pointIsSet[3][3]; BasePoint existingPoint[3][3]; for(int i = x - 1, ri = 0; i < x + 2; ++i, ++ri) { for(int j = y - 1, rj = 0; j < y + 2; ++j, ++rj) { pointIsSet[ri][rj] = getBasePoint(i, j, existingPoint[ri][rj]); } } for(int i = x - 1, ri = 0; i < x + 1; ++i, ++ri) { for(int j = y - 1, rj = 0; j < y + 1; ++j, ++rj) { Segment * s = getSegment(i, j); if (s == 0) { bool complete = pointIsSet[ri][rj] && pointIsSet[ri + 1][rj + 1] && pointIsSet[ri + 1][rj] && pointIsSet[ri][rj + 1]; if (!complete) { continue; } s = new Segment(i * m_res, j * m_res, m_res); Matrix<2, 2, BasePoint> & cp = s->getControlPoints(); float min = existingPoint[ri][rj].height(); float max = existingPoint[ri][rj].height(); for(unsigned int k = 0; k < 2; ++k) { for(unsigned int l = 0; l < 2; ++l) { cp(k, l) = existingPoint[ri + k][rj + l]; min = std::min(cp(k, l).height(), min); max = std::max(cp(k, l).height(), max); } } s->setMinMax(min, max); Effectorstore::iterator I = m_effectors.begin(); Effectorstore::iterator Iend = m_effectors.end(); for (; I != Iend; ++I) { I->first->addToSegment(*s); } // apply shaders last, after all other data is in place if (isShaded()) { addSurfaces(*s); } m_segments[i][j] = s; continue; } s->setCornerPoint(ri ? 0 : 1, rj ? 0 : 1, z); } } }
/// \brief Set the BasePoint value at a given base point coordinate. /// /// Set the BasePoint value for the given coordinate on the base /// point grid. /// If inserting this BasePoint completes the set of points required /// to define one or more Segment objects which were not yet defined, /// new Segment objects are created. If this replaces a point for one /// or more Segment objects that were already defined, the contents of /// those Segment objects are invalidated. /// @param x coordinate on the base point grid. /// @param z coordinate on the base point grid. /// @param y BasePoint value to be used at the given coordinate. void Terrain::setBasePoint(int x, int z, const BasePoint& y) { m_basePoints[x][z] = y; bool pointIsSet[3][3]; BasePoint existingPoint[3][3]; for(int i = x - 1, ri = 0; i < x + 2; ++i, ++ri) { for(int j = z - 1, rj = 0; j < z + 2; ++j, ++rj) { pointIsSet[ri][rj] = getBasePoint(i, j, existingPoint[ri][rj]); } } for(int i = x - 1, ri = 0; i < x + 1; ++i, ++ri) { for(int j = z - 1, rj = 0; j < z + 1; ++j, ++rj) { Segment * s = getSegmentAtIndex(i, j); if (s == 0) { bool complete = pointIsSet[ri][rj] && pointIsSet[ri + 1][rj + 1] && pointIsSet[ri + 1][rj] && pointIsSet[ri][rj + 1]; if (!complete) { continue; } s = new Segment(i * m_res, j * m_res, m_res); Matrix<2, 2, BasePoint> & cp = s->getControlPoints(); for(unsigned int k = 0; k < 2; ++k) { for(unsigned int l = 0; l < 2; ++l) { cp(k, l) = existingPoint[ri + k][rj + l]; } } for (auto& entry : m_terrainMods) { const TerrainMod* terrainMod = std::get<0>(entry.second); if (terrainMod->checkIntersects(*s)) { s->updateMod(entry.first, terrainMod); } } // apply shaders last, after all other data is in place if (isShaded()) { addSurfaces(*s); } m_segments[i][j] = s; continue; } s->setCornerPoint(ri ? 0 : 1, rj ? 0 : 1, y); } } }