diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 5e3b96fba70cc59e6cf6f27af0e6ea7e24e05eea..36c8b2d74e96595db4fa13db24a6992cc27484f0 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -58,6 +58,7 @@ Heightmap::Heightmap(std::string filename): _filename(filename) { _minZ = min(_data, 2, 3); _maxZ = max(_data, 2, 3); _zRangeUm = (_maxZ - _minZ) / 10.; //in um + _zRangeUmOffset = 0.f; std::cout << "Identified z range: " << _zRangeUm << " um (" << _minZ << " - " << _maxZ << ")" << std::endl; /*Throw if _zRange is less than 1 A (i.e. it's probably 0)*/ if (_zRangeUm < 1e-4) { @@ -76,6 +77,8 @@ Heightmap::Heightmap(std::string filename): _filename(filename) { _minZ = min(_data, 2, 3); //should be 0 _maxZ = max(_data, 2, 3); //should be 1 + std::cout << "Identified z range " << _minZ << " - " << _maxZ << std::endl; + /*Initialize Renderer Infrastructure*/ glGenBuffers(1, &_vbo); glGenBuffers(1, &_ebo); @@ -172,6 +175,8 @@ Heightmap::Heightmap(std::string filename): _filename(filename) { std::string fragFile = std::string(SHADER_LOC) + std::string("heightmap0.frag"); _shader_ptr = ResourceManager::fetch_shader(vertFile, fragFile); _scale = 0.5f; + _modelSpaceRot = glm::mat4(1.f); + _highlightingRadius = 0.05f; _shader_ptr->use(); _shader_ptr->setFloat("scale", _scale); _shader_ptr->setFloat("minZ", static_cast<float>(_minZ)); @@ -186,8 +191,10 @@ Heightmap::Heightmap(std::string filename): _filename(filename) { _shader_ptr->setFloat("plotLineAlongY_x", -99999.f); _shader_ptr->setVec3("light_pos", glm::vec3(0.f, 0.f, 10.f)); _shader_ptr->setInt("lighting_enabled", 1); - _shader_ptr->setFloat("highlightingRadius", 0.05f); + _shader_ptr->setFloat("highlightingRadius", _highlightingRadius); _shader_ptr->setInt("highlightingEnabled", 0); + _shader_ptr->setMat4("modelSpaceRot", _modelSpaceRot); + _shader_ptr->setFloat("originZ", _data[2]); _shader_ptr->unuse(); /*Setup Framebuffer*/ @@ -269,13 +276,33 @@ float Heightmap::getSurfaceHeight(unsigned x, unsigned y, glm::mat4 projection, _framebuffer_ptr->unbind(); if (defo_um != -1.f) { - return defo_um * _zRangeUm; + return defo_um * _zRangeUm - _zRangeUmOffset; } else { return NOT_ON_SURFACE; } } +float Heightmap::getAverageSurfaceHeight(glm::vec2 xy) { + float total_height = 0.f; + unsigned num_values = 0; + float rad_sq = _highlightingRadius * _highlightingRadius; + for (size_t i = 0; i < _data.size() / 3; ++i) { + if (std::pow(_data[3 * i] - xy[0], 2) + std::pow(_data[3 * i + 1] - xy[1], 2) < rad_sq) { + if (_data[3 * i + 2] != BAD_Z_VALUE) { + total_height += _data[3 * i + 2]; + ++num_values; + } + } + } + if (num_values != 0) { + return total_height / static_cast<float>(num_values); + } + else { + return -1.f; + } +} + void Heightmap::updatePlotWindow(){ size_t slashpos = _filename.rfind("\\"); std::string drumname = _filename.substr(slashpos + 1, _filename.length() - slashpos - 1); @@ -319,6 +346,10 @@ float Heightmap::zRangeUm() const { return _zRangeUm; } +void Heightmap::setZRangeUmOffset(float offset) { + _zRangeUmOffset += offset; +} + //Shader control void Heightmap::enableLighting() { _shader_ptr->use(); @@ -345,12 +376,46 @@ void Heightmap::disableHighlighting() { _shader_ptr->unuse(); } +void Heightmap::calculateNewZRange(glm::mat4 rot) { + float maxiZ = -99999.f; + float miniZ = 99999.f; + for (size_t i = 0; i < _data.size() / 3; ++i) { + if (_data[3 * i + 2] == BAD_Z_VALUE) { + continue; + } + else { + glm::vec4 newP = rot * glm::vec4(_data[3 * i], _data[3 * i + 1], _data[3 * i + 2], 1.f); + if (newP.z > maxiZ) { + maxiZ = newP.z; + } + if (newP.z < miniZ) { + miniZ = newP.z; + } + } + } + _maxZ = maxiZ; + _minZ = miniZ; + _shader_ptr->use(); + _shader_ptr->setFloat("minZ", static_cast<float>(_minZ)); + _shader_ptr->setFloat("maxZ", static_cast<float>(_maxZ)); + _shader_ptr->unuse(); +} + +void Heightmap::setModelspaceRot(glm::mat4 rot) { + _modelSpaceRot = rot * _modelSpaceRot; + _shader_ptr->use(); + _shader_ptr->setMat4("modelSpaceRot", _modelSpaceRot); + _shader_ptr->unuse(); +} + void Heightmap::_plotHeightLineAlongX(const float y){ if(y != _last_plotAlongX_y){ _last_plotAlongX_y = y; if(y > _maxY || y < _minY){ return; } + //setup translation vector + float z_offset = _data[2]; //find correct i (row) //TODO: This has to change when _data changes size_t stride = 3; @@ -369,7 +434,14 @@ void Heightmap::_plotHeightLineAlongX(const float y){ for(size_t j = 0; j < _Nx; ++j){ _plotAlongX_data_x[j] = _data[stride * j * _Ny + stride * i]; if (_data[stride * j * _Ny + stride * i + 2] != BAD_Z_VALUE) { - _plotAlongX_data_h[j] = _minZ + _zRangeUm * _data[stride * j * _Ny + stride * i + 2]; + //transform data + float x = _data[stride * j * _Ny + stride * i]; + float y = _data[stride * j * _Ny + stride * i + 1]; + float z = _data[stride * j * _Ny + stride * i + 2]; + glm::vec4 data(x, y, z - z_offset, 1.); + data = _modelSpaceRot * data; + float transformed_z = data.z + z_offset; + _plotAlongX_data_h[j] = _zRangeUm * (transformed_z - _minZ) / (_maxZ - _minZ) - _zRangeUmOffset; } else { _plotAlongX_data_h[j] = NAN; @@ -391,6 +463,8 @@ void Heightmap::_plotHeightLineAlongY(const float x){ if(x > _maxX || x < _minX){ return; } + //setup translation vector + float z_offset = _data[2]; //find correct i (column) //TODO: This has to change when _data changes size_t stride = 3; @@ -409,7 +483,14 @@ void Heightmap::_plotHeightLineAlongY(const float x){ for(size_t j = 0; j < _Ny; ++j){ _plotAlongY_data_y[j] = _data[stride * _Ny * i + stride * j + 1]; if (_data[stride * _Ny * i + stride * j + 2] != BAD_Z_VALUE) { - _plotAlongY_data_h[j] = _minZ + _zRangeUm * _data[stride * _Ny * i + stride * j + 2]; + //transform data + float x = _data[stride * _Ny * i + stride * j]; + float y = _data[stride * _Ny * i + stride * j + 1]; + float z = _data[stride * _Ny * i + stride * j + 2]; + glm::vec4 data(x, y, z - z_offset, 1.); + data = _modelSpaceRot * data; + float transformed_z = data.z + z_offset; + _plotAlongY_data_h[j] = _zRangeUm * (transformed_z - _minZ) / (_maxZ - _minZ) - _zRangeUmOffset; } else { _plotAlongY_data_h[j] = NAN;