HeightMapPlane* HeightMap::streamPlaneAt(float x, float y) { wlock(); int planePosition = getPlanePosition(x, y); HeightMapPlane* plane = planes[planePosition]; if (plane != NULL) { unlock(); return plane; } if (planeQueue.size() < PLANELIMIT) { plane = planes[planePosition] = new HeightMapPlane(planePosition, PLANEWIDTH); } else { plane = planeQueue.remove(); planes[plane->getIndex()] = NULL; planes[planePosition] = plane; plane->setIndex(planePosition); } planeQueue.add(plane); int planeOffset = planePosition * PLANEWIDTH * PLANEWIDTH * HEIGHTSIZE; reader->read(plane->getBuffer(), planeOffset, PLANEWIDTH * PLANEWIDTH * HEIGHTSIZE); unlock(); return plane; }
bool ZIntCuboidFace::hasOverlap(const ZIntCuboidFace &face) const { if (getAxis() != face.getAxis() || getPlanePosition() != face.getPlanePosition()) { return false; } if (getLowerBound(0) > face.getUpperBound(0)) { return false; } if (getLowerBound(1) > face.getUpperBound(1)) { return false; } if (face.getLowerBound(0) > getUpperBound(0)) { return false; } if (face.getLowerBound(1) > getUpperBound(1)) { return false; } return true; }
bool ZIntCuboidFace::contains(int x, int y, int z) const { int u = 0; int v = 0; int w = 0; switch (getAxis()) { case NeuTube::X_AXIS: u = y; v = z; w = x; break; case NeuTube::Y_AXIS: u = x; v = z; w = y; break; case NeuTube::Z_AXIS: u = x; v = y; w = z; break; } if (w != getPlanePosition()) { return false; } return getLowerBound(0) <= u && getUpperBound(0) >= u && getLowerBound(1) <= v && getUpperBound(1) >= v; }
ZIntPoint ZIntCuboidFace::getCornerCoordinates(int index) const { ZIntPoint pt; Corner corner = getCorner(index); switch (getAxis()) { case NeuTube::X_AXIS: pt.set(getPlanePosition(), corner.getX(), corner.getY()); break; case NeuTube::Y_AXIS: pt.set(corner.getX(), getPlanePosition(), corner.getY()); break; case NeuTube::Z_AXIS: pt.set(corner.getX(), corner.getY(), getPlanePosition()); break; } return pt; }
ZIntCuboidFaceArray ZIntCuboidFace::cropBy(const ZIntCuboidFace &face) const { ZIntCuboidFaceArray faceArray; if (hasOverlap(face)) { if (isWithin(face)) { return faceArray; } else { ZIntCuboidFace subface(getAxis(), isNormalPositive()); subface.setZ(getPlanePosition()); subface.set(getFirstCorner(), Corner(getUpperBound(0), face.getLowerBound(1) - 1)); faceArray.appendValid(subface); subface.set(Corner(getLowerBound(0), imax2(getLowerBound(1), face.getLowerBound(1))), Corner(face.getLowerBound(0) - 1, getUpperBound(1))); faceArray.appendValid(subface); subface.set(Corner(face.getUpperBound(0) + 1, imax2(getLowerBound(1), face.getLowerBound(1))), getLastCorner()); faceArray.appendValid(subface); subface.set(Corner(imax2(getLowerBound(0), face.getLowerBound(0)), face.getUpperBound(1) + 1), Corner(imin2(getUpperBound(0), face.getUpperBound(0)), getUpperBound(1))); faceArray.appendValid(subface); } #if 0 else if (face.isWithin(*this)) { ZIntCuboidFace subface(getAxis(), isNormalPositive()); secondCorner.set(getUpperBound(0), face.getLowerBound(1)); subface.set(getFirstCorner(), secondCorner); faceArray.appendValid(subface); subface.set(Corner(getLowerBound(0), face.getLowerBound(1)), face.getCorner(2)); faceArray.appendValid(subface); subface.set(Corner(getLowerBound(0), face.getUpperBound(1)), getLastCorner()); faceArray.appendValid(subface); } else { } #endif } else {
float HeightMap::getHeight(float x, float y) { if (reader == NULL) return 0; if (std::isinf(x) || std::isnan(x) || std::isinf(y) || std::isnan(y)) return 0; float retHeight = 0; try { int planePosition = getPlanePosition(x, y); rlock(); HeightMapPlane* plane = planes[planePosition]; if (plane == NULL) { //System::out << "Streaming in heightplane number " << planePosition << ".\n"; runlock(); plane = streamPlaneAt(x, y); rlock(); } int width = (int) (x + ORIGOSHIFT) % PLANEWIDTH; int height = (int) (y + ORIGOSHIFT) % PLANEWIDTH; retHeight = plane->getHeight(width, height); runlock(); } catch (...) { runlock(); throw; } return retHeight; }