mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 12:10:52 -06:00
Merge pull request #266 from OpenSpace/pr/kameleonvolume
Pr/kameleonvolume
This commit is contained in:
74
Jenkinsfile
vendored
Normal file
74
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
def modules = [
|
||||
"base",
|
||||
"debugging",
|
||||
"fieldlines",
|
||||
"galaxy",
|
||||
"globebrowsing",
|
||||
"iswa",
|
||||
"kameleon",
|
||||
"kameleonvolume",
|
||||
"multiresvolume",
|
||||
"newhorizons",
|
||||
"onscreengui",
|
||||
"space",
|
||||
"toyvolume",
|
||||
"volume"
|
||||
];
|
||||
|
||||
def flags = "-DGHOUL_USE_DEVIL=OFF "
|
||||
|
||||
for (module in modules) {
|
||||
flags += "-DOPENSPACE_OPENSPACE_MODULE_" + module.toUpperCase() + "=ON "
|
||||
}
|
||||
|
||||
echo flags
|
||||
|
||||
stage('Build') {
|
||||
parallel linux: {
|
||||
node('linux') {
|
||||
checkout scm
|
||||
sh 'git submodule update --init --recursive'
|
||||
sh '''
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake .. ''' +
|
||||
flags + ''' ..
|
||||
make
|
||||
'''
|
||||
}
|
||||
},
|
||||
windows: {
|
||||
node('windows') {
|
||||
checkout scm
|
||||
bat '''
|
||||
git submodule update --init --recursive
|
||||
if not exist "build" mkdir "build"
|
||||
cd build
|
||||
cmake -G "Visual Studio 14 2015 Win64" .. ''' +
|
||||
flags + ''' ..
|
||||
msbuild.exe OpenSpace.sln /m:8 /p:Configuration=Debug
|
||||
'''
|
||||
}
|
||||
},
|
||||
osx: {
|
||||
node('osx') {
|
||||
checkout scm
|
||||
sh 'git submodule update --init --recursive'
|
||||
sh '''
|
||||
export PATH=${PATH}:/usr/local/bin:/Applications/CMake.app/Contents/bin
|
||||
export CMAKE_BUILD_TOOL=/Applications/CMake.app/Contents/bin/CMake
|
||||
srcDir=$PWD
|
||||
if [ ! -d ${srcDir} ]; then
|
||||
mkdir ${srcDir}
|
||||
fi
|
||||
if [ ! -d ${srcDir}/build ]; then
|
||||
mkdir ${srcDir}/build
|
||||
fi
|
||||
cd ${srcDir}/build
|
||||
/Applications/CMake.app/Contents/bin/cmake -G Xcode -D NASM=/usr/local/Cellar/nasm/2.11.08/bin/nasm ${srcDir} .. ''' +
|
||||
flags + '''
|
||||
xcodebuild
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,26 +22,18 @@
|
||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #
|
||||
#########################################################################################
|
||||
|
||||
set(APPLICATION_NAME DataConverter)
|
||||
set(APPLICATION_NAME TaskRunner)
|
||||
set(APPLICATION_LINK_TO_OPENSPACE ON)
|
||||
|
||||
include (${GHOUL_BASE_DIR}/support/cmake/handle_external_library.cmake)
|
||||
|
||||
set(application_path ${OPENSPACE_APPS_DIR}/DataConverter)
|
||||
set(application_path ${OPENSPACE_APPS_DIR}/TaskRunner)
|
||||
|
||||
set(SOURCE_FILES
|
||||
${application_path}/main.cpp
|
||||
${application_path}/milkywayconversiontask.cpp
|
||||
${application_path}/milkywaypointsconversiontask.cpp
|
||||
)
|
||||
set(HEADER_FILES
|
||||
${application_path}/conversiontask.h
|
||||
${application_path}/milkywayconversiontask.h
|
||||
${application_path}/milkywaypointsconversiontask.h
|
||||
)
|
||||
|
||||
add_executable(${APPLICATION_NAME} MACOSX_BUNDLE
|
||||
${SOURCE_FILES}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
|
||||
@@ -33,50 +33,98 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/ghoul.h>
|
||||
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/util/progressbar.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/util/taskloader.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <openspace/scene/translation.h>
|
||||
#include <openspace/scene/rotation.h>
|
||||
#include <openspace/scene/scale.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
|
||||
#include <apps/DataConverter/milkywayconversiontask.h>
|
||||
#include <apps/DataConverter/milkywaypointsconversiontask.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
using namespace openspace;
|
||||
using namespace dataconverter;
|
||||
|
||||
ghoul::initialize();
|
||||
namespace {
|
||||
const std::string ConfigurationFile = "openspace.cfg";
|
||||
const std::string _loggerCat = "TaskRunner Main";
|
||||
}
|
||||
|
||||
void initTextureReaders() {
|
||||
#ifdef GHOUL_USE_DEVIL
|
||||
ghoul::io::TextureReader::ref().addReader(std::make_shared<ghoul::io::TextureReaderDevIL>());
|
||||
#endif // GHOUL_USE_DEVIL
|
||||
#ifdef GHOUL_USE_FREEIMAGE
|
||||
ghoul::io::TextureReader::ref().addReader(std::make_shared<ghoul::io::TextureReaderFreeImage>());
|
||||
#endif // GHOUL_USE_FREEIMAGE
|
||||
}
|
||||
|
||||
openspace::ProgressBar pb(100);
|
||||
std::function<void(float)> onProgress = [&](float progress) {
|
||||
pb.print(progress * 100);
|
||||
};
|
||||
int main(int argc, char** argv) {
|
||||
using namespace openspace;
|
||||
|
||||
// TODO: Make the converter configurable using either
|
||||
// config files (json, lua dictionaries),
|
||||
// lua scripts,
|
||||
// or at the very least: a command line interface.
|
||||
|
||||
MilkyWayConversionTask mwConversionTask(
|
||||
"F:/mw_june2016/volumeslices/img/comp/v003/frames/primary/0100/cam2_main.",
|
||||
".exr",
|
||||
1385,
|
||||
512,
|
||||
"F:/mw_june2016/mw_512_512_64_june.rawvolume",
|
||||
glm::vec3(512, 512, 64));
|
||||
ghoul::initialize();
|
||||
initTextureReaders();
|
||||
|
||||
FactoryManager::initialize();
|
||||
FactoryManager::ref().addFactory(
|
||||
std::make_unique<ghoul::TemplateFactory<Renderable>>(),
|
||||
"Renderable"
|
||||
);
|
||||
FactoryManager::ref().addFactory(
|
||||
std::make_unique<ghoul::TemplateFactory<Task>>(),
|
||||
"Task"
|
||||
);
|
||||
FactoryManager::ref().addFactory(
|
||||
std::make_unique<ghoul::TemplateFactory<Translation>>(),
|
||||
"Translation"
|
||||
);
|
||||
|
||||
FactoryManager::ref().addFactory(
|
||||
std::make_unique<ghoul::TemplateFactory<Rotation>>(),
|
||||
"Rotation"
|
||||
);
|
||||
|
||||
FactoryManager::ref().addFactory(
|
||||
std::make_unique<ghoul::TemplateFactory<Scale>>(),
|
||||
"Scale"
|
||||
);
|
||||
|
||||
openspace::ConfigurationManager configuration;
|
||||
std::string configurationFile = configuration.findConfiguration(ConfigurationFile);
|
||||
configuration.loadFromFile(configurationFile);
|
||||
|
||||
ModuleEngine moduleEngine;
|
||||
moduleEngine.initialize();
|
||||
|
||||
std::string tasksPath;
|
||||
configuration.getValue(ConfigurationManager::KeyConfigTask, tasksPath);
|
||||
|
||||
LINFO("Initialization done.");
|
||||
|
||||
TaskLoader taskLoader;
|
||||
std::vector<std::unique_ptr<Task>> tasks = taskLoader.tasksFromFile(tasksPath);
|
||||
|
||||
//MilkyWayPointsConversionTask mwpConversionTask("F:/mw_june2016/points.off", "F:/mw_june2016/points.off.binary");
|
||||
size_t nTasks = tasks.size();
|
||||
if (nTasks == 1) {
|
||||
LINFO("Task queue has 1 item");
|
||||
} else {
|
||||
LINFO("Task queue has " << tasks.size() << " items");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tasks.size(); i++) {
|
||||
Task& task = *tasks[i].get();
|
||||
LINFO("Performing task " << (i+1) << " out of " << tasks.size() << ": " << task.description());
|
||||
ProgressBar progressBar(100);
|
||||
auto onProgress = [&progressBar](float progress) {
|
||||
progressBar.print(progress * 100);
|
||||
};
|
||||
task.perform(onProgress);
|
||||
}
|
||||
|
||||
mwConversionTask.perform(onProgress);
|
||||
//mwpConversionTask.perform(onProgress);
|
||||
|
||||
|
||||
std::cout << "Done." << std::endl;
|
||||
std::cout << "Done performing tasks." << std::endl;
|
||||
|
||||
std::cin.get();
|
||||
return 0;
|
||||
@@ -1,3 +1,5 @@
|
||||
MercuryRadius = 2.4397E6;
|
||||
|
||||
return {
|
||||
-- Mercury barycenter module
|
||||
{
|
||||
@@ -22,7 +24,7 @@ return {
|
||||
Body = "MERCURY",
|
||||
Geometry = {
|
||||
Type = "SimpleSphere",
|
||||
Radius = { 2.440, 6 },
|
||||
Radius = {MercuryRadius, 1.0},
|
||||
Segments = 100
|
||||
},
|
||||
Textures = {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
SaturnRadius = 5.8232E7;
|
||||
|
||||
|
||||
return {
|
||||
-- Saturn barycenter module
|
||||
{
|
||||
@@ -23,7 +26,7 @@ return {
|
||||
Body = "SATURN BARYCENTER",
|
||||
Geometry = {
|
||||
Type = "SimpleSphere",
|
||||
Radius = { 5.8232, 7 },
|
||||
Radius = {SaturnRadius, 0},
|
||||
Segments = 100
|
||||
},
|
||||
Textures = {
|
||||
|
||||
33
data/spice/iSWAKernels/openspace_mercury.ti
Normal file
33
data/spice/iSWAKernels/openspace_mercury.ti
Normal file
@@ -0,0 +1,33 @@
|
||||
OpenSpace ecliptic frames:
|
||||
Mercury-centric Solar Ecliptic (MERCURYSE) frame
|
||||
|
||||
These frames are only defined as helper frames for OpenSpace.
|
||||
|
||||
+X is parallel to the geometric planet-sun position vector.
|
||||
|
||||
-Y axis is the normalized component of the planet's orbital vector
|
||||
|
||||
+Z axis is parallel to the cross product of the frame's +X axis
|
||||
and the frame's +Y axis.
|
||||
|
||||
\begindata
|
||||
|
||||
FRAME_MERCURYSE = 4600199
|
||||
FRAME_4600199_NAME = 'MERCURYSE'
|
||||
FRAME_4600199_CLASS = 5
|
||||
FRAME_4600199_CLASS_ID = 4600199
|
||||
FRAME_4600199_CENTER = 199
|
||||
FRAME_4600199_RELATIVE = 'J2000'
|
||||
FRAME_4600199_DEF_STYLE = 'PARAMETERIZED'
|
||||
FRAME_4600199_FAMILY = 'TWO-VECTOR'
|
||||
FRAME_4600199_PRI_AXIS = 'X'
|
||||
FRAME_4600199_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
|
||||
FRAME_4600199_PRI_OBSERVER = 'MERCURY'
|
||||
FRAME_4600199_PRI_TARGET = 'SUN'
|
||||
FRAME_4600199_PRI_ABCORR = 'NONE'
|
||||
FRAME_4600199_SEC_AXIS = 'Y'
|
||||
FRAME_4600199_SEC_VECTOR_DEF = 'OBSERVER_TARGET_VELOCITY'
|
||||
FRAME_4600199_SEC_OBSERVER = 'MERCURY'
|
||||
FRAME_4600199_SEC_TARGET = 'SUN'
|
||||
FRAME_4600199_SEC_ABCORR = 'NONE'
|
||||
FRAME_4600199_SEC_FRAME = 'J2000'
|
||||
33
data/spice/iSWAKernels/openspace_saturn.ti
Normal file
33
data/spice/iSWAKernels/openspace_saturn.ti
Normal file
@@ -0,0 +1,33 @@
|
||||
OpenSpace ecliptic frames:
|
||||
Saturn-centric Solar Ecliptic (SATURNSE) frame
|
||||
|
||||
These frames are only defined as helper frames for OpenSpace.
|
||||
|
||||
+X is parallel to the geometric planet-sun position vector.
|
||||
|
||||
-Y axis is the normalized component of the planet's orbital vector
|
||||
|
||||
+Z axis is parallel to the cross product of the frame's +X axis
|
||||
and the frame's +Y axis.
|
||||
|
||||
\begindata
|
||||
|
||||
FRAME_SATURNSE = 4500699
|
||||
FRAME_4500699_NAME = 'SATURNSE'
|
||||
FRAME_4500699_CLASS = 5
|
||||
FRAME_4500699_CLASS_ID = 4500699
|
||||
FRAME_4500699_CENTER = 6
|
||||
FRAME_4500699_RELATIVE = 'J2000'
|
||||
FRAME_4500699_DEF_STYLE = 'PARAMETERIZED'
|
||||
FRAME_4500699_FAMILY = 'TWO-VECTOR'
|
||||
FRAME_4500699_PRI_AXIS = 'X'
|
||||
FRAME_4500699_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
|
||||
FRAME_4500699_PRI_OBSERVER = 'SATURN BARYCENTER'
|
||||
FRAME_4500699_PRI_TARGET = 'SUN'
|
||||
FRAME_4500699_PRI_ABCORR = 'NONE'
|
||||
FRAME_4500699_SEC_AXIS = 'Y'
|
||||
FRAME_4500699_SEC_VECTOR_DEF = 'OBSERVER_TARGET_VELOCITY'
|
||||
FRAME_4500699_SEC_OBSERVER = 'SATURN BARYCENTER'
|
||||
FRAME_4500699_SEC_TARGET = 'SUN'
|
||||
FRAME_4500699_SEC_ABCORR = 'NONE'
|
||||
FRAME_4500699_SEC_FRAME = 'J2000'
|
||||
3
data/tasks/default.task
Normal file
3
data/tasks/default.task
Normal file
@@ -0,0 +1,3 @@
|
||||
return {
|
||||
"kameleonmetadatatojson"
|
||||
}
|
||||
59
data/web/kameleondocumentation/main.hbs
Normal file
59
data/web/kameleondocumentation/main.hbs
Normal file
@@ -0,0 +1,59 @@
|
||||
<div id="wrapper">
|
||||
<div id="sidebar-wrapper">
|
||||
<ul class="sidebar-nav">
|
||||
<li class="sidebar-brand">
|
||||
<a href="#">
|
||||
Attributes
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#global">Global</a>
|
||||
</li>
|
||||
{{#each kameleon.variableAttributes}}
|
||||
<li>
|
||||
<a href="#{{urlify @key}}">{{@key}}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<div id="page-content-wrapper">
|
||||
<div class="container-fluid documentation-container">
|
||||
<h1>OpenSpace Kameleon Documentation</h1>
|
||||
<p>Version: {{version}}</p>
|
||||
<p>CDF File: {{input}}</p>
|
||||
<h2><a href="#global" name="global">Global Attributes</a></h2>
|
||||
{{#each kameleon.globalAttributes}}
|
||||
<div class="documentation-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<p>
|
||||
<a href="#{{urlify @key}}" name="{{urlify @key}}">
|
||||
<span class="documentation-key">{{@key}}</span>
|
||||
</a>
|
||||
<p>{{this}}</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
<h2>Variable Attributes</h2>
|
||||
{{#each kameleon.variableAttributes}}
|
||||
<h3><a href="#{{urlify @key}}" name="{{@key}}">{{@key}}</a></h3>
|
||||
{{#each this}}
|
||||
<div class="documentation-item">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<p>
|
||||
<a href="#{{urlify @key}}" name="{{urlify @key}}">
|
||||
<span class="documentation-key">{{@key}}</span>
|
||||
</a>
|
||||
<p>{{this}}</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
23
data/web/kameleondocumentation/script.js
Normal file
23
data/web/kameleondocumentation/script.js
Normal file
@@ -0,0 +1,23 @@
|
||||
window.onload = function () {
|
||||
var mainTemplateElement = document.getElementById('mainTemplate');
|
||||
var mainTemplate = Handlebars.compile(mainTemplateElement.innerHTML);
|
||||
|
||||
Handlebars.registerHelper('urlify', function(options, context) {
|
||||
var data = context.data;
|
||||
var identifier = options.replace(" ", "-").toLowerCase();
|
||||
|
||||
while (data = data._parent) {
|
||||
if (data.key !== undefined) {
|
||||
identifier = data.key + "-" + identifier;
|
||||
}
|
||||
}
|
||||
|
||||
return identifier;
|
||||
});
|
||||
|
||||
var dataElement = document.getElementById('data');
|
||||
var data = JSON.parse(dataElement.innerHTML);
|
||||
|
||||
var contents = mainTemplate(data);
|
||||
document.body.innerHTML = contents;
|
||||
}
|
||||
Submodule ext/ghoul updated: e0cbca16ad...445ed6353f
@@ -68,6 +68,8 @@ public:
|
||||
static const std::string KeyFactoryDocumentation;
|
||||
/// The key that stores the location of the scene file that is initially loaded
|
||||
static const std::string KeyConfigScene;
|
||||
/// The key that stores the location of the tasks file that is initially loaded
|
||||
static const std::string KeyConfigTask;
|
||||
/// The key that stores the subdirectory containing a list of all startup scripts to
|
||||
/// be executed on application start before the scene file is loaded
|
||||
static const std::string KeyStartupScript;
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
|
||||
namespace ghoul {
|
||||
namespace systemcapabilities {
|
||||
|
||||
@@ -40,8 +42,6 @@ namespace openspace {
|
||||
|
||||
namespace scripting { struct LuaLibrary; }
|
||||
|
||||
class OpenSpaceModule;
|
||||
|
||||
/**
|
||||
* The ModuleEngine is the central repository for registering and accessing
|
||||
* OpenSpaceModule for the current application run. By initializing (#initialize) the
|
||||
|
||||
@@ -71,8 +71,8 @@ public:
|
||||
void setResolution(glm::ivec2 res) override;
|
||||
void setNAaSamples(int nAaSamples) override;
|
||||
|
||||
void preRaycast(ghoul::opengl::ProgramObject& programObject);
|
||||
void postRaycast(ghoul::opengl::ProgramObject& programObject);
|
||||
void preRaycast(const RaycasterTask& raycasterTask);
|
||||
void postRaycast(const RaycasterTask& raycasterTask);
|
||||
|
||||
void update();
|
||||
void render(float blackoutFactor, bool doPerformanceMeasurements) override;
|
||||
@@ -130,9 +130,6 @@ private:
|
||||
GLuint _vertexPositionBuffer;
|
||||
int _nAaSamples;
|
||||
|
||||
|
||||
std::unique_ptr<RendererTasks> _rendererTasks;
|
||||
std::unique_ptr<RenderData> _renderData;
|
||||
float _blackoutFactor;
|
||||
|
||||
ghoul::Dictionary _rendererData;
|
||||
|
||||
@@ -22,20 +22,18 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_APP_DATACONVERTER___CONVERSIONTASK___H__
|
||||
#define __OPENSPACE_APP_DATACONVERTER___CONVERSIONTASK___H__
|
||||
|
||||
#include <functional>
|
||||
#ifndef __OPENSPACE_CORE___DISTANCECONSTANTS___H__
|
||||
#define __OPENSPACE_CORE___DISTANCECONSTANTS___H__
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
class ConversionTask {
|
||||
public:
|
||||
virtual void perform(const std::function<void(float)>& onProgress) = 0;
|
||||
};
|
||||
namespace distanceconstants {
|
||||
const float EarthRadius = 6371;
|
||||
const float LightYear = 9.4607304725808E15;
|
||||
const float AstronomicalUnit = 1.495978707E11;
|
||||
const float Parsec = 3.0856776E16;
|
||||
}
|
||||
|
||||
} // namespace dataconverter
|
||||
} // namespace openspace
|
||||
}
|
||||
|
||||
#endif // __OPENSPACE_APP_DATACONVERTER___CONVERSIONTASK___H__
|
||||
#endif // __OPENSPACE_CORE___DISTANCECONSTANTS___H__
|
||||
47
include/openspace/util/task.h
Normal file
47
include/openspace/util/task.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___TASK___H__
|
||||
#define __OPENSPACE_CORE___TASK___H__
|
||||
|
||||
#include <functional>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class Task {
|
||||
public:
|
||||
using ProgressCallback = std::function<void(float)>;
|
||||
|
||||
virtual ~Task() = default;
|
||||
virtual void perform(const ProgressCallback& onProgress) = 0;
|
||||
virtual std::string description() = 0;
|
||||
static std::unique_ptr<Task> createFromDictionary(const ghoul::Dictionary& dictionary);
|
||||
static documentation::Documentation documentation();
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___TASK___H__
|
||||
41
include/openspace/util/taskloader.h
Normal file
41
include/openspace/util/taskloader.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___TASKLOADER___H__
|
||||
#define __OPENSPACE_CORE___TASKLOADER___H__
|
||||
|
||||
#include <string>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <openspace/util/task.h>
|
||||
|
||||
namespace openspace {
|
||||
class TaskLoader {
|
||||
public:
|
||||
std::vector<std::unique_ptr<Task>> tasksFromDictionary(const ghoul::Dictionary& dictionary);
|
||||
std::vector<std::unique_ptr<Task>> tasksFromFile(const std::string& path);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __OPENSPACE_CORE___TASKLOADER___H__
|
||||
@@ -32,7 +32,7 @@ namespace openspace {
|
||||
class BaseModule : public OpenSpaceModule {
|
||||
public:
|
||||
BaseModule();
|
||||
|
||||
virtual ~BaseModule() = default;
|
||||
std::vector<documentation::Documentation> documentations() const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -27,14 +27,18 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/galaxymodule.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/galaxyraycaster.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/milkywayconversiontask.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/milkywaypointsconversiontask.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/galaxymodule.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/galaxyraycaster.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/milkywayconversiontask.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/milkywaypointsconversiontask.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <modules/galaxy/rendering/renderablegalaxy.h>
|
||||
#include <modules/galaxy/tasks/milkywayconversiontask.h>
|
||||
#include <modules/galaxy/tasks/milkywaypointsconversiontask.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -36,6 +38,11 @@ void GalaxyModule::internalInitialize() {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
fRenderable->registerClass<RenderableGalaxy>("RenderableGalaxy");
|
||||
|
||||
auto fTask = FactoryManager::ref().factory<Task>();
|
||||
ghoul_assert(fRenderable, "No task factory existed");
|
||||
fTask->registerClass<MilkywayConversionTask>("MilkywayConversionTask");
|
||||
fTask->registerClass<MilkywayPointsConversionTask>("MilkywayPointsConversionTask");
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,30 +22,63 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <apps/DataConverter/milkywayconversiontask.h>
|
||||
#include <modules/galaxy/tasks/milkywayconversiontask.h>
|
||||
#include <modules/volume/textureslicevolumereader.h>
|
||||
#include <modules/volume/rawvolumewriter.h>
|
||||
#include <modules/volume/volumesampler.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
MilkyWayConversionTask::MilkyWayConversionTask(
|
||||
const std::string& inFilenamePrefix,
|
||||
const std::string& inFilenameSuffix,
|
||||
size_t inFirstIndex,
|
||||
size_t inNSlices,
|
||||
const std::string& outFilename,
|
||||
const glm::ivec3& outDimensions)
|
||||
: _inFilenamePrefix(inFilenamePrefix)
|
||||
, _inFilenameSuffix(inFilenameSuffix)
|
||||
, _inFirstIndex(inFirstIndex)
|
||||
, _inNSlices(inNSlices)
|
||||
, _outFilename(outFilename)
|
||||
, _outDimensions(outDimensions) {}
|
||||
namespace {
|
||||
char* KeyInFilenamePrefix = "InFilenamePrefix";
|
||||
char* KeyInFilenameSuffix = "InFilenameSuffix";
|
||||
char* KeyInFirstIndex = "InFirstIndex";
|
||||
char* KeyInNSlices = "InNSlices";
|
||||
char* KeyOutFilename = "OutFilename";
|
||||
char* KeyOutDimensions = "OutDimensions";
|
||||
}
|
||||
|
||||
|
||||
namespace openspace {
|
||||
|
||||
void MilkyWayConversionTask::perform(const std::function<void(float)>& onProgress) {
|
||||
MilkywayConversionTask::MilkywayConversionTask(const ghoul::Dictionary& dictionary) {
|
||||
std::string inFilenamePrefix;
|
||||
if (dictionary.getValue(KeyInFilenamePrefix, inFilenamePrefix)) {
|
||||
_inFilenamePrefix = inFilenamePrefix;
|
||||
}
|
||||
|
||||
std::string inFilenamePrefix;
|
||||
if (dictionary.getValue(KeyInFilenameSuffix, inFilenameSuffix)) {
|
||||
_inFilenameSuffix = inFilenameSuffix;
|
||||
}
|
||||
|
||||
size_t inFirstIndex;
|
||||
if (dictionary.getValue(KeyInFirstIndex, inFirstIndex)) {
|
||||
_inFirstIndex = inFirstIndex;
|
||||
}
|
||||
|
||||
size_t inNSlices;
|
||||
if (dictionary.getValue(KeyInNSlices, inNSlices)) {
|
||||
_inNSlices = inNSlices;
|
||||
}
|
||||
|
||||
std::string outFilename;
|
||||
if (dictionary.getValue(KeyOutFilename, outFilename)) {
|
||||
_outFilename = outFilename;
|
||||
}
|
||||
|
||||
glm::ivec3 outDimensions;
|
||||
if (dictionary.getValue(KeyOutDimensions, outDimensions)) {
|
||||
_outDimensions = outDimensions;
|
||||
}
|
||||
}
|
||||
|
||||
MilkywayConversionTask::~MilkywayConversionTask() {}
|
||||
|
||||
std::string MilkywayConversionTask::description()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void MilkywayConversionTask::perform(const Task::ProgressCallback& progressCallback) {
|
||||
std::vector<std::string> filenames;
|
||||
for (int i = 0; i < _inNSlices; i++) {
|
||||
filenames.push_back(_inFilenamePrefix + std::to_string(i + _inFirstIndex) + _inFilenameSuffix);
|
||||
@@ -67,8 +100,12 @@ void MilkyWayConversionTask::perform(const std::function<void(float)>& onProgres
|
||||
return value;
|
||||
};
|
||||
|
||||
rawWriter.write(sampleFunction, onProgress);
|
||||
rawWriter.write(sampleFunction, progressCallback);
|
||||
}
|
||||
|
||||
Documentation MilkywayConversionTask::documentation()
|
||||
{
|
||||
return Documentation();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_APP_DATACONVERTER___MILKYWAYCONVERSIONTASK___H__
|
||||
#define __OPENSPACE_APP_DATACONVERTER___MILKYWAYCONVERSIONTASK___H__
|
||||
#ifndef __OPENSPACE_MODULE_GALAXY___MILKYWAYCONVERSIONTASK___H__
|
||||
#define __OPENSPACE_MODULE_GALAXY___MILKYWAYCONVERSIONTASK___H__
|
||||
|
||||
#include <apps/DataConverter/conversiontask.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <string>
|
||||
#include <ghoul/glm.h>
|
||||
#include <functional>
|
||||
@@ -34,22 +34,18 @@
|
||||
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
/**
|
||||
* Converts a set of exr image slices to a raw volume
|
||||
* with floating point RGBA data (32 bit per channel).
|
||||
*/
|
||||
class MilkyWayConversionTask : public ConversionTask {
|
||||
class MilkywayConversionTask : public Task {
|
||||
public:
|
||||
MilkyWayConversionTask(const std::string& inFilenamePrefix,
|
||||
const std::string& inFilenameSuffix,
|
||||
size_t inFirstIndex,
|
||||
size_t inNSlices,
|
||||
const std::string& outFilename,
|
||||
const glm::ivec3& outDimensions);
|
||||
|
||||
void perform(const std::function<void(float)>& onProgress) override;
|
||||
MilkywayConversionTask(const ghoul::Dictionary& dictionary);
|
||||
virtual ~MilkywayConversionTask();
|
||||
std::string description() override;
|
||||
void perform(const Task::ProgressCallback& onProgress) override;
|
||||
static Documentation documentation();
|
||||
private:
|
||||
std::string _inFilenamePrefix;
|
||||
std::string _inFilenameSuffix;
|
||||
@@ -59,7 +55,6 @@ private:
|
||||
glm::ivec3 _outDimensions;
|
||||
};
|
||||
|
||||
} // namespace dataconverter
|
||||
} // namespace openspace
|
||||
}
|
||||
|
||||
#endif // __OPENSPACE_APP_DATACONVERTER___MILKYWAYCONVERSIONTASK___H__
|
||||
#endif // __OPENSPACE_MODULE_GALAXY___MILKYWAYCONVERSIONTASK___H__
|
||||
@@ -22,38 +22,42 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <apps/DataConverter/milkywaypointsconversiontask.h>
|
||||
#include <modules/galaxy/tasks/milkywaypointsconversiontask.h>
|
||||
#include <modules/volume/textureslicevolumereader.h>
|
||||
#include <modules/volume/rawvolumewriter.h>
|
||||
#include <modules/volume/volumesampler.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
|
||||
|
||||
MilkyWayPointsConversionTask::MilkyWayPointsConversionTask(
|
||||
/*MilkywayPointsConversionTask::MilkywayPointsConversionTask(
|
||||
const std::string& inFilename,
|
||||
const std::string& outFilename)
|
||||
: _inFilename(inFilename)
|
||||
, _outFilename(outFilename) {}
|
||||
, _outFilename(outFilename) {}*/
|
||||
|
||||
MilkywayPointsConversionTask::MilkywayPointsConversionTask(const ghoul::Dictionary & dictionary) {}
|
||||
|
||||
void MilkyWayPointsConversionTask::perform(const std::function<void(float)>& onProgress) {
|
||||
MilkywayPointsConversionTask::~MilkywayPointsConversionTask() {}
|
||||
|
||||
std::string MilkywayPointsConversionTask::description()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void MilkywayPointsConversionTask::perform(const Task::ProgressCallback & progressCallback) {
|
||||
std::ifstream in(_inFilename, std::ios::in);
|
||||
std::ofstream out(_outFilename, std::ios::out | std::ios::binary);
|
||||
|
||||
|
||||
std::string format;
|
||||
int64_t nPoints;
|
||||
in >> format >> nPoints;
|
||||
|
||||
|
||||
|
||||
size_t nFloats = nPoints * 7;
|
||||
|
||||
float* pointData = new float[nFloats];
|
||||
std::vector<float> pointData(nFloats);
|
||||
|
||||
float x, y, z, r, g, b, a;
|
||||
for (size_t i = 0; i < nPoints; ++i) {
|
||||
@@ -66,8 +70,9 @@ void MilkyWayPointsConversionTask::perform(const std::function<void(float)>& onP
|
||||
pointData[i * 7 + 4] = g;
|
||||
pointData[i * 7 + 5] = b;
|
||||
pointData[i * 7 + 6] = a;
|
||||
onProgress(static_cast<float>(i + 1) / nPoints);
|
||||
} else {
|
||||
progressCallback(static_cast<float>(i + 1) / nPoints);
|
||||
}
|
||||
else {
|
||||
std::cout << "Failed to convert point data.";
|
||||
return;
|
||||
}
|
||||
@@ -80,7 +85,9 @@ void MilkyWayPointsConversionTask::perform(const std::function<void(float)>& onP
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
||||
Documentation MilkywayPointsConversionTask::documentation()
|
||||
{
|
||||
return Documentation();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_APP_DATACONVERTER___MILKYWAYPOINTSCONVERSIONTASK___H__
|
||||
#define __OPENSPACE_APP_DATACONVERTER___MILKYWAYPOINTSCONVERSIONTASK___H__
|
||||
#ifndef __OPENSPACE_MODULE_GALAXY___MILKYWAYPOINTSCONVERSIONTASK_H__
|
||||
#define __OPENSPACE_MODULE_GALAXY___MILKYWAYPOINTSCONVERSIONTASK_H__
|
||||
|
||||
#include <apps/DataConverter/conversiontask.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <string>
|
||||
#include <ghoul/glm.h>
|
||||
#include <functional>
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
/**
|
||||
* Converts ascii based point data
|
||||
@@ -42,18 +41,18 @@ namespace dataconverter {
|
||||
* (float x, float y, float z, float r, float g, float b) * n
|
||||
* to a binary (floating point) representation with the same layout.
|
||||
*/
|
||||
class MilkyWayPointsConversionTask : public ConversionTask {
|
||||
class MilkywayPointsConversionTask : public Task {
|
||||
public:
|
||||
MilkyWayPointsConversionTask(const std::string& inFilename,
|
||||
const std::string& outFilename);
|
||||
|
||||
void perform(const std::function<void(float)>& onProgress) override;
|
||||
MilkywayPointsConversionTask(const ghoul::Dictionary& dictionary);
|
||||
virtual ~MilkywayPointsConversionTask();
|
||||
std::string description() override;
|
||||
void perform(const Task::ProgressCallback& progressCallback) override;
|
||||
static Documentation documentation();
|
||||
private:
|
||||
std::string _inFilename;
|
||||
std::string _outFilename;
|
||||
};
|
||||
|
||||
} // namespace dataconverter
|
||||
} // namespace openspace
|
||||
}
|
||||
|
||||
#endif // __OPENSPACE_APP_DATACONVERTER___MILKYWAYPOINTSCONVERSIONTASK___H__
|
||||
#endif // __OPENSPACE_MODULE_GALAXY___MILKYWAYPOINTSCONVERSIONTASK_H__
|
||||
@@ -1008,38 +1008,34 @@ glm::vec4 KameleonWrapper::classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEn
|
||||
return color;
|
||||
}
|
||||
|
||||
std::string KameleonWrapper::getParent(){
|
||||
if( _type == KameleonWrapper::Model::BATSRUS ||
|
||||
_type == KameleonWrapper::Model::OpenGGCM ||
|
||||
_type == KameleonWrapper::Model::LFM)
|
||||
{
|
||||
std::string KameleonWrapper::getParent() {
|
||||
switch (_type) {
|
||||
case KameleonWrapper::Model::BATSRUS:
|
||||
case KameleonWrapper::Model::OpenGGCM:
|
||||
case KameleonWrapper::Model::LFM:
|
||||
return "Earth";
|
||||
}else if(
|
||||
_type == KameleonWrapper::Model::ENLIL ||
|
||||
_type == KameleonWrapper::Model::MAS ||
|
||||
_type == KameleonWrapper::Model::Adapt3D ||
|
||||
_type == KameleonWrapper::Model::SWMF)
|
||||
{
|
||||
case KameleonWrapper::Model::ENLIL:
|
||||
case KameleonWrapper::Model::MAS:
|
||||
case KameleonWrapper::Model::Adapt3D:
|
||||
case KameleonWrapper::Model::SWMF:
|
||||
return "Sun";
|
||||
}else{
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string KameleonWrapper::getFrame(){
|
||||
if( _type == KameleonWrapper::Model::BATSRUS ||
|
||||
_type == KameleonWrapper::Model::OpenGGCM ||
|
||||
_type == KameleonWrapper::Model::LFM)
|
||||
{
|
||||
std::string KameleonWrapper::getFrame() {
|
||||
switch (_type) {
|
||||
case KameleonWrapper::Model::BATSRUS:
|
||||
case KameleonWrapper::Model::OpenGGCM:
|
||||
case KameleonWrapper::Model::LFM:
|
||||
return "GSM";
|
||||
}else if(
|
||||
_type == KameleonWrapper::Model::ENLIL ||
|
||||
_type == KameleonWrapper::Model::MAS ||
|
||||
_type == KameleonWrapper::Model::Adapt3D ||
|
||||
_type == KameleonWrapper::Model::SWMF)
|
||||
{
|
||||
case KameleonWrapper::Model::ENLIL:
|
||||
case KameleonWrapper::Model::MAS:
|
||||
case KameleonWrapper::Model::Adapt3D:
|
||||
case KameleonWrapper::Model::SWMF:
|
||||
return "HEEQ";
|
||||
}else{
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1050,8 +1046,6 @@ std::vector<std::string> KameleonWrapper::getVariables(){
|
||||
int numVariables = _model->getNumberOfVariables();
|
||||
|
||||
for(int i=0; i<numVariables; i++){
|
||||
// std::cout << _model->getVariableName(i) << " ";
|
||||
// std::cout << _model->getVariableName(i) << std::endl;
|
||||
variableNames.push_back(_model->getVariableName(i));;
|
||||
}
|
||||
return variableNames;
|
||||
|
||||
49
modules/kameleonvolume/CMakeLists.txt
Normal file
49
modules/kameleonvolume/CMakeLists.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
#########################################################################################
|
||||
# #
|
||||
# OpenSpace #
|
||||
# #
|
||||
# Copyright (c) 2014-2017 #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of this #
|
||||
# software and associated documentation files (the "Software"), to deal in the Software #
|
||||
# without restriction, including without limitation the rights to use, copy, modify, #
|
||||
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to #
|
||||
# permit persons to whom the Software is furnished to do so, subject to the following #
|
||||
# conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in all copies #
|
||||
# or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
||||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A #
|
||||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT #
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF #
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE #
|
||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #
|
||||
#########################################################################################
|
||||
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kameleonvolumereader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kameleonvolumereader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablekameleonvolume.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/kameleonvolumeraycaster.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleondocumentationtask.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleonmetadatatojsontask.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablekameleonvolume.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/kameleonvolumeraycaster.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleondocumentationtask.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleonmetadatatojsontask.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
create_new_module(
|
||||
"KameleonVolume"
|
||||
kameleonvolume_module
|
||||
${HEADER_FILES} ${SOURCE_FILES}
|
||||
)
|
||||
6
modules/kameleonvolume/include.cmake
Normal file
6
modules/kameleonvolume/include.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
set (DEFAULT_MODULE ON)
|
||||
|
||||
set (OPENSPACE_DEPENDENCIES
|
||||
kameleon
|
||||
volume
|
||||
)
|
||||
58
modules/kameleonvolume/kameleonvolumemodule.cpp
Normal file
58
modules/kameleonvolume/kameleonvolumemodule.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/kameleonvolume/kameleonvolumemodule.h>
|
||||
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <vector>
|
||||
|
||||
#include <modules/kameleonvolume/rendering/renderablekameleonvolume.h>
|
||||
#include <modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h>
|
||||
#include <modules/kameleonvolume/tasks/kameleondocumentationtask.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
KameleonVolumeModule::KameleonVolumeModule() : OpenSpaceModule("KameleonVolume") {}
|
||||
|
||||
void KameleonVolumeModule::internalInitialize() {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
fRenderable->registerClass<RenderableKameleonVolume>("RenderableKameleonVolume");
|
||||
|
||||
auto fTask = FactoryManager::ref().factory<Task>();
|
||||
ghoul_assert(fTask, "No task factory existed");
|
||||
fTask->registerClass<KameleonMetadataToJsonTask>("KameleonMetadataToJsonTask");
|
||||
fTask->registerClass<KameleonDocumentationTask>("KameleonDocumentationTask");
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::vector<documentation::Documentation> KameleonVolumeModule::documentations() const
|
||||
{
|
||||
return std::vector<documentation::Documentation>{KameleonMetadataToJsonTask::documentation()};
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
43
modules/kameleonvolume/kameleonvolumemodule.h
Normal file
43
modules/kameleonvolume/kameleonvolumemodule.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEMODULE___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEMODULE___H__
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class KameleonVolumeModule : public OpenSpaceModule {
|
||||
public:
|
||||
KameleonVolumeModule();
|
||||
virtual ~KameleonVolumeModule() = default;
|
||||
void internalInitialize() override;
|
||||
std::vector<documentation::Documentation> documentations() const override;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEMODULE___H__
|
||||
195
modules/kameleonvolume/kameleonvolumereader.cpp
Normal file
195
modules/kameleonvolume/kameleonvolumereader.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/kameleonvolume/kameleonvolumereader.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <ccmc/Model.h>
|
||||
#include <ccmc/BATSRUS.h>
|
||||
#include <ccmc/ENLIL.h>
|
||||
#include <ccmc/CCMCTime.h>
|
||||
#include <ccmc/Attribute.h>
|
||||
|
||||
namespace {
|
||||
const char* _loggerCat = "KameleonVolumeReader";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
KameleonVolumeReader::KameleonVolumeReader(const std::string& path)
|
||||
: _path(path)
|
||||
{
|
||||
if (!FileSys.fileExists(path)) {
|
||||
LERROR(_path << "does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
long status = _kameleon.open(_path);
|
||||
if (status != ccmc::FileReader::OK) {
|
||||
LERROR("Failed to open file " << _path << " with kameleon");
|
||||
return;
|
||||
}
|
||||
|
||||
_model = _kameleon.model;
|
||||
_interpolator = std::unique_ptr<ccmc::Interpolator>(_model->createNewInterpolator());
|
||||
}
|
||||
|
||||
std::unique_ptr<RawVolume<float>> KameleonVolumeReader::readFloatVolume(
|
||||
const glm::uvec3 & dimensions,
|
||||
const std::string & variable,
|
||||
const glm::vec3 & lowerBound,
|
||||
const glm::vec3 & upperBound) const
|
||||
{
|
||||
auto volume = std::make_unique<RawVolume<float>>(dimensions);
|
||||
const glm::vec3 dims = volume->dimensions();
|
||||
const glm::vec3 diff = upperBound - lowerBound;
|
||||
|
||||
_model->loadVariable(variable);
|
||||
|
||||
float* data = volume->data();
|
||||
for (size_t index = 0; index < volume->nCells(); index++) {
|
||||
glm::vec3 coords = volume->indexToCoords(index);
|
||||
glm::vec3 coordsZeroToOne = coords / dims;
|
||||
glm::vec3 volumeCoords = lowerBound + diff * coordsZeroToOne;
|
||||
|
||||
data[index] = _interpolator->interpolate(
|
||||
variable,
|
||||
static_cast<float>(volumeCoords[0]),
|
||||
static_cast<float>(volumeCoords[1]),
|
||||
static_cast<float>(volumeCoords[2]));
|
||||
}
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
std::vector<std::string> KameleonVolumeReader::gridVariableNames() const {
|
||||
// get the grid system string
|
||||
std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString();
|
||||
|
||||
// remove leading and trailing brackets
|
||||
gridSystem = gridSystem.substr(1, gridSystem.length() - 2);
|
||||
|
||||
// remove all whitespaces
|
||||
gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end());
|
||||
|
||||
// replace all comma signs with whitespaces
|
||||
std::replace(gridSystem.begin(), gridSystem.end(), ',', ' ');
|
||||
|
||||
// tokenize
|
||||
std::istringstream iss(gridSystem);
|
||||
std::vector<std::string> tokens{ std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{} };
|
||||
|
||||
// validate
|
||||
if (tokens.size() != 3) {
|
||||
throw ghoul::RuntimeError(
|
||||
"Expected three dimensional grid system. Got " +
|
||||
std::to_string(tokens.size()) +
|
||||
"dimensions");
|
||||
}
|
||||
|
||||
std::string x = tokens.at(0);
|
||||
std::string y = tokens.at(1);
|
||||
std::string z = tokens.at(2);
|
||||
|
||||
std::transform(x.begin(), x.end(), x.begin(), ::tolower);
|
||||
std::transform(y.begin(), y.end(), y.begin(), ::tolower);
|
||||
std::transform(z.begin(), z.end(), z.begin(), ::tolower);
|
||||
|
||||
return std::vector<std::string>{x, y, z};
|
||||
}
|
||||
|
||||
std::vector<std::string> KameleonVolumeReader::variableNames() const {
|
||||
std::vector<std::string> variableNames;
|
||||
const int nVariables = _model->getNumberOfVariables();
|
||||
for (int i = 0; i < nVariables; ++i) {
|
||||
variableNames.push_back(_model->getVariableName(i));
|
||||
}
|
||||
return variableNames;
|
||||
}
|
||||
|
||||
std::vector<std::string> KameleonVolumeReader::variableAttributeNames() const {
|
||||
return _model->getVariableAttributeNames();
|
||||
}
|
||||
|
||||
std::vector<std::string> KameleonVolumeReader::globalAttributeNames() const {
|
||||
std::vector<std::string> attributeNames;
|
||||
const int nAttributes = _model->getNumberOfGlobalAttributes();
|
||||
for (int i = 0; i < nAttributes; ++i) {
|
||||
attributeNames.push_back(_model->getGlobalAttributeName(i));
|
||||
}
|
||||
return attributeNames;
|
||||
}
|
||||
|
||||
void KameleonVolumeReader::addAttributeToDictionary(ghoul::Dictionary& dictionary, const std::string& key, ccmc::Attribute& attr) {
|
||||
ccmc::Attribute::AttributeType type = attr.getAttributeType();
|
||||
switch (type) {
|
||||
case ccmc::Attribute::AttributeType::FLOAT:
|
||||
dictionary.setValue<float>(key, attr.getAttributeFloat());
|
||||
return;
|
||||
case ccmc::Attribute::AttributeType::INT:
|
||||
dictionary.setValue<int>(key, attr.getAttributeInt());
|
||||
return;
|
||||
case ccmc::Attribute::AttributeType::STRING:
|
||||
dictionary.setValue<std::string>(key, attr.getAttributeString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary KameleonVolumeReader::readMetaData() const {
|
||||
ghoul::Dictionary globalAttributesDictionary;
|
||||
for (const std::string& attributeName : globalAttributeNames()) {
|
||||
ccmc::Attribute attribute = _model->getGlobalAttribute(attributeName);
|
||||
addAttributeToDictionary(globalAttributesDictionary, attributeName, attribute);
|
||||
}
|
||||
|
||||
ghoul::Dictionary variableDictionary;
|
||||
std::vector<std::string> varAttrNames = variableAttributeNames();
|
||||
for (const std::string& variableName : variableNames()) {
|
||||
ghoul::Dictionary variableAttributesDictionary;
|
||||
for (const std::string& attributeName : varAttrNames) {
|
||||
ccmc::Attribute attribute = _model->getVariableAttribute(variableName, attributeName);
|
||||
addAttributeToDictionary(variableAttributesDictionary, attributeName, attribute);
|
||||
}
|
||||
variableDictionary.setValue(variableName, variableAttributesDictionary);
|
||||
}
|
||||
|
||||
return {
|
||||
{"globalAttributes", std::move(globalAttributesDictionary) },
|
||||
{"variableAttributes", std::move(variableDictionary) }
|
||||
};
|
||||
}
|
||||
|
||||
float KameleonVolumeReader::minValue(const std::string & variable) const {
|
||||
return _model->getVariableAttribute(variable, "actual_min").getAttributeFloat();
|
||||
}
|
||||
|
||||
float KameleonVolumeReader::maxValue(const std::string & variable) const {
|
||||
return _model->getVariableAttribute(variable, "actual_max").getAttributeFloat();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -22,65 +22,52 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___RENDERABLEVOLUMEGL___H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___RENDERABLEVOLUMEGL___H__
|
||||
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEREADER___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEREADER___H__
|
||||
|
||||
#include <modules/volume/rendering/renderablevolume.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <modules/volume/rawvolume.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
// Forward declare to minimize dependencies
|
||||
namespace ghoul {
|
||||
namespace filesystem {
|
||||
class File;
|
||||
}
|
||||
namespace opengl {
|
||||
class ProgramObject;
|
||||
class Texture;
|
||||
}
|
||||
#include <ccmc/Kameleon.h>
|
||||
#include <ccmc/Interpolator.h>
|
||||
|
||||
namespace ccmc {
|
||||
class Model;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableVolumeGL: public RenderableVolume {
|
||||
class KameleonVolumeReader {
|
||||
public:
|
||||
RenderableVolumeGL(const ghoul::Dictionary& dictionary);
|
||||
~RenderableVolumeGL();
|
||||
|
||||
bool initialize() override;
|
||||
bool deinitialize() override;
|
||||
KameleonVolumeReader(const std::string& path);
|
||||
//KameleonMetaData readMetaData();
|
||||
|
||||
bool isReady() const override;
|
||||
std::unique_ptr<RawVolume<float>> readFloatVolume(
|
||||
const glm::uvec3& dimensions,
|
||||
const std::string& variable,
|
||||
const glm::vec3& lowerBound,
|
||||
const glm::vec3& upperBound) const;
|
||||
ghoul::Dictionary readMetaData() const;
|
||||
float minValue(const std::string& variable) const;
|
||||
float maxValue(const std::string& variable) const;
|
||||
|
||||
virtual void render(const RenderData& data) override;
|
||||
virtual void update(const UpdateData& data) override;
|
||||
std::vector<std::string> gridVariableNames() const;
|
||||
std::vector<std::string> gridUnits() const;
|
||||
std::vector<std::string> variableNames() const;
|
||||
std::vector<std::string> variableAttributeNames() const;
|
||||
std::vector<std::string> globalAttributeNames() const;
|
||||
|
||||
private:
|
||||
ghoul::Dictionary _hintsDictionary;
|
||||
static void addAttributeToDictionary(ghoul::Dictionary& dictionary, const std::string& key, ccmc::Attribute& attr);
|
||||
std::string _path;
|
||||
ccmc::Kameleon _kameleon;
|
||||
ccmc::Model* _model;
|
||||
std::unique_ptr<ccmc::Interpolator> _interpolator;
|
||||
|
||||
std::string _filename;
|
||||
|
||||
std::string _transferFunctionName;
|
||||
std::string _volumeName;
|
||||
|
||||
std::string _transferFunctionPath;
|
||||
std::string _samplerFilename;
|
||||
|
||||
ghoul::filesystem::File* _transferFunctionFile;
|
||||
|
||||
ghoul::opengl::Texture* _volume;
|
||||
ghoul::opengl::Texture* _transferFunction;
|
||||
|
||||
GLuint _boxArray;
|
||||
GLuint _vertexPositionBuffer;
|
||||
ghoul::opengl::ProgramObject* _boxProgram;
|
||||
glm::vec3 _boxScaling;
|
||||
psc _pscOffset;
|
||||
float _w;
|
||||
|
||||
bool _updateTransferfunction;
|
||||
int _id;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___RENDERABLEVOLUMEGL___H__
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEREADER___H__
|
||||
179
modules/kameleonvolume/rendering/kameleonvolumeraycaster.cpp
Normal file
179
modules/kameleonvolume/rendering/kameleonvolumeraycaster.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/kameleonvolume/rendering/kameleonvolumeraycaster.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <sstream>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <modules/kameleonvolume/rendering/renderablekameleonvolume.h>
|
||||
|
||||
|
||||
namespace {
|
||||
const char* GlslRaycastPath = "${MODULES}/kameleonvolume/shaders/raycast.glsl";
|
||||
const char* GlslHelperPath = "${MODULES}/kameleonvolume/shaders/helper.glsl";
|
||||
const char* GlslBoundsVsPath = "${MODULES}/kameleonvolume/shaders/boundsvs.glsl";
|
||||
const char* GlslBoundsFsPath = "${MODULES}/kameleonvolume/shaders/boundsfs.glsl";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
KameleonVolumeRaycaster::KameleonVolumeRaycaster(
|
||||
std::shared_ptr<ghoul::opengl::Texture> texture,
|
||||
std::shared_ptr<TransferFunction> transferFunction,
|
||||
std::shared_ptr<VolumeClipPlanes> clipPlanes)
|
||||
: _volumeTexture(texture)
|
||||
, _transferFunction(transferFunction)
|
||||
, _clipPlanes(clipPlanes)
|
||||
, _boundingBox(glm::vec3(1.0)) {}
|
||||
|
||||
KameleonVolumeRaycaster::~KameleonVolumeRaycaster() {}
|
||||
|
||||
void KameleonVolumeRaycaster::initialize() {
|
||||
_boundingBox.initialize();
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::deinitialize() {
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation
|
||||
glm::dmat4(data.modelTransform.rotation) * // Spice rotation
|
||||
glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale)));
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
program.setUniform("modelViewTransform", glm::mat4(modelViewTransform));
|
||||
program.setUniform("projectionTransform", data.camera.projectionMatrix());
|
||||
|
||||
// Cull back face
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// Render bounding geometry
|
||||
_boundingBox.render();
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) *
|
||||
glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale)));
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
program.setUniform("modelViewTransform", glm::mat4(modelViewTransform));
|
||||
program.setUniform("projectionTransform", data.camera.projectionMatrix());
|
||||
|
||||
// Cull front face
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
// Render bounding geometry
|
||||
_boundingBox.render();
|
||||
|
||||
// Restore defaults
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
|
||||
std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id);
|
||||
program.setUniform(stepSizeUniformName, _stepSize);
|
||||
|
||||
std::string id = std::to_string(data.id);
|
||||
|
||||
_tfUnit = std::make_unique<ghoul::opengl::TextureUnit>();
|
||||
_tfUnit->activate();
|
||||
_transferFunction->getTexture().bind();
|
||||
program.setUniform("transferFunction_" + id, _tfUnit->unitNumber());
|
||||
|
||||
_textureUnit = std::make_unique<ghoul::opengl::TextureUnit>();
|
||||
_textureUnit->activate();
|
||||
_volumeTexture->bind();
|
||||
program.setUniform("volumeTexture_" + id, _textureUnit->unitNumber());
|
||||
|
||||
program.setUniform("gridType_" + id, static_cast<int>(_gridType));
|
||||
|
||||
std::vector<glm::vec3> clipNormals = _clipPlanes->normals();
|
||||
std::vector<glm::vec2> clipOffsets = _clipPlanes->offsets();
|
||||
int nClips = clipNormals.size();
|
||||
|
||||
program.setUniform("nClips_" + id, nClips);
|
||||
program.setUniform("clipNormals_" + id, clipNormals.data(), nClips);
|
||||
program.setUniform("clipOffsets_" + id, clipOffsets.data(), nClips);
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
|
||||
// For example: release texture units
|
||||
_textureUnit = nullptr;
|
||||
_tfUnit = nullptr;
|
||||
}
|
||||
|
||||
bool KameleonVolumeRaycaster::cameraIsInside(const RenderData & data, glm::vec3 & localPosition)
|
||||
{
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) *
|
||||
glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale)));
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
glm::vec4 modelPos = glm::inverse(modelViewTransform) * glm::vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
localPosition = (glm::vec3(modelPos) + glm::vec3(0.5));
|
||||
return (localPosition.x > 0 && localPosition.y > 0 && localPosition.z > 0 && localPosition.x < 1 && localPosition.y < 1 && localPosition.z < 1);
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getBoundsVsPath() const {
|
||||
return GlslBoundsVsPath;
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getBoundsFsPath() const {
|
||||
return GlslBoundsFsPath;
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getRaycastPath() const {
|
||||
return GlslRaycastPath;
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getHelperPath() const {
|
||||
return GlslHelperPath;
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::setStepSize(float stepSize) {
|
||||
_stepSize = stepSize;
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::setGridType(VolumeGridType gridType) {
|
||||
_gridType = gridType;
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::setModelTransform(const glm::mat4 & transform) {
|
||||
_modelTransform = transform;
|
||||
}
|
||||
|
||||
}
|
||||
95
modules/kameleonvolume/rendering/kameleonvolumeraycaster.h
Normal file
95
modules/kameleonvolume/rendering/kameleonvolumeraycaster.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMERAYCASTER___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMERAYCASTER___H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/util/boxgeometry.h>
|
||||
#include <openspace/rendering/transferfunction.h>
|
||||
#include <modules/volume/rendering/volumeclipplanes.h>
|
||||
|
||||
#include <modules/volume/volumegridtype.h>
|
||||
|
||||
namespace ghoul {
|
||||
namespace opengl {
|
||||
class Texture;
|
||||
class ProgramObject;
|
||||
class TextureUnit;
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderData;
|
||||
class RaycastData;
|
||||
|
||||
class KameleonVolumeRaycaster : public VolumeRaycaster {
|
||||
public:
|
||||
|
||||
KameleonVolumeRaycaster(
|
||||
std::shared_ptr<ghoul::opengl::Texture> texture,
|
||||
std::shared_ptr<TransferFunction> transferFunction,
|
||||
std::shared_ptr<VolumeClipPlanes> clipPlanes);
|
||||
|
||||
virtual ~KameleonVolumeRaycaster();
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
void renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
bool cameraIsInside(const RenderData& data, glm::vec3& localPosition) override;
|
||||
|
||||
std::string getBoundsVsPath() const override;
|
||||
std::string getBoundsFsPath() const override;
|
||||
std::string getRaycastPath() const override;
|
||||
std::string getHelperPath() const override;
|
||||
|
||||
void setStepSize(float stepSize);
|
||||
void setGridType(VolumeGridType gridType);
|
||||
void setModelTransform(const glm::mat4& transform);
|
||||
private:
|
||||
std::shared_ptr<VolumeClipPlanes> _clipPlanes;
|
||||
std::shared_ptr<ghoul::opengl::Texture> _volumeTexture;
|
||||
std::shared_ptr<TransferFunction> _transferFunction;
|
||||
BoxGeometry _boundingBox;
|
||||
VolumeGridType _gridType;
|
||||
glm::mat4 _modelTransform;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::TextureUnit> _tfUnit;
|
||||
std::unique_ptr<ghoul::opengl::TextureUnit> _textureUnit;
|
||||
float _stepSize;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMERAYCASTER___H__
|
||||
392
modules/kameleonvolume/rendering/renderablekameleonvolume.cpp
Normal file
392
modules/kameleonvolume/rendering/renderablekameleonvolume.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/kameleonvolume/rendering/renderablekameleonvolume.h>
|
||||
#include <modules/kameleonvolume/kameleonvolumereader.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <modules/volume/rawvolumereader.h>
|
||||
#include <modules/volume/rawvolumewriter.h>
|
||||
#include <modules/volume/rawvolume.h>
|
||||
|
||||
namespace {
|
||||
const char* _loggerCat = "RenderableKameleonVolume";
|
||||
}
|
||||
|
||||
namespace {
|
||||
const char* KeyDimensions = "Dimensions";
|
||||
const char* KeyStepSize = "StepSize";
|
||||
const char* KeyTransferFunction = "TransferFunction";
|
||||
const char* KeySource = "Source";
|
||||
const char* KeyVariable = "Variable";
|
||||
const char* KeyLowerDomainBound = "LowerDomainBound";
|
||||
const char* KeyUpperDomainBound = "UpperDomainBound";
|
||||
const char* KeyDomainScale = "DomainScale";
|
||||
const char* KeyLowerValueBound = "LowerValueBound";
|
||||
const char* KeyUpperValueBound = "UpperValueBound";
|
||||
const char* KeyClipPlanes = "ClipPlanes";
|
||||
const char* KeyCache = "Cache";
|
||||
const char* KeyGridType = "GridType";
|
||||
const char* ValueSphericalGridType = "Spherical";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _dimensions("dimensions", "Dimensions")
|
||||
, _variable("variable", "Variable")
|
||||
, _lowerDomainBound("lowerDomainBound", "Lower Domain Bound")
|
||||
, _upperDomainBound("upperDomainBound", "Upper Domain Bound")
|
||||
, _domainScale("domainScale", "Domain scale")
|
||||
, _autoDomainBounds(false)
|
||||
, _lowerValueBound("lowerValueBound", "Lower Value Bound", 0.0, 0.0, 1)
|
||||
, _upperValueBound("upperValueBound", "Upper Value Bound", 1, 0.01, 1)
|
||||
, _autoValueBounds(false)
|
||||
, _gridType("gridType", "Grid Type", properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _autoGridType(false)
|
||||
, _clipPlanes(nullptr)
|
||||
, _stepSize("stepSize", "Step Size", 0.02, 0.01, 1)
|
||||
, _sourcePath("sourcePath", "Source Path")
|
||||
, _transferFunctionPath("transferFunctionPath", "Transfer Function Path")
|
||||
, _raycaster(nullptr)
|
||||
, _transferFunction(nullptr)
|
||||
, _cache("cache", "Cache") {
|
||||
|
||||
glm::vec3 dimensions;
|
||||
if (dictionary.getValue(KeyDimensions, dimensions)) {
|
||||
_dimensions = dimensions;
|
||||
} else {
|
||||
LWARNING("No dimensions specified for volumetric data, falling back to 32^3");
|
||||
_dimensions = glm::uvec3(32, 32, 32);
|
||||
}
|
||||
|
||||
float stepSize;
|
||||
if (dictionary.getValue(KeyStepSize, stepSize)) {
|
||||
_stepSize = stepSize;
|
||||
}
|
||||
|
||||
std::string transferFunctionPath;
|
||||
if (dictionary.getValue(KeyTransferFunction, transferFunctionPath)) {
|
||||
_transferFunctionPath = transferFunctionPath;
|
||||
_transferFunction = std::make_shared<TransferFunction>(absPath(transferFunctionPath));
|
||||
}
|
||||
|
||||
std::string sourcePath;
|
||||
if (dictionary.getValue(KeySource, sourcePath)) {
|
||||
_sourcePath = absPath(sourcePath);
|
||||
}
|
||||
|
||||
std::string variable;
|
||||
if (dictionary.getValue(KeyVariable, variable)) {
|
||||
_variable = variable;
|
||||
}
|
||||
|
||||
glm::vec3 lowerDomainBound;
|
||||
if (dictionary.getValue(KeyLowerDomainBound, lowerDomainBound)) {
|
||||
_lowerDomainBound = lowerDomainBound;
|
||||
}
|
||||
else {
|
||||
_autoDomainBounds = true;
|
||||
}
|
||||
|
||||
glm::vec3 upperDomainBound;
|
||||
if (dictionary.getValue(KeyUpperDomainBound, upperDomainBound)) {
|
||||
_upperDomainBound = upperDomainBound;
|
||||
}
|
||||
else {
|
||||
_autoDomainBounds = true;
|
||||
}
|
||||
|
||||
glm::vec3 domainScale;
|
||||
if (dictionary.getValue(KeyDomainScale, domainScale)) {
|
||||
_domainScale = domainScale;
|
||||
} else {
|
||||
_domainScale = glm::vec3(1, 1, 1); // Assume meters if nothing else is specified.
|
||||
}
|
||||
|
||||
float lowerValueBound;
|
||||
if (dictionary.getValue(KeyLowerValueBound, lowerValueBound)) {
|
||||
_lowerValueBound = lowerValueBound;
|
||||
}
|
||||
else {
|
||||
_autoValueBounds = true;
|
||||
}
|
||||
|
||||
float upperValueBound;
|
||||
if (dictionary.getValue(KeyUpperValueBound, upperValueBound)) {
|
||||
_upperValueBound = upperValueBound;
|
||||
}
|
||||
else {
|
||||
_autoValueBounds = true;
|
||||
}
|
||||
|
||||
ghoul::Dictionary clipPlanesDictionary;
|
||||
dictionary.getValue(KeyClipPlanes, clipPlanesDictionary);
|
||||
_clipPlanes = std::make_shared<VolumeClipPlanes>(clipPlanesDictionary);
|
||||
_clipPlanes->setName("clipPlanes");
|
||||
|
||||
bool cache;
|
||||
if (dictionary.getValue(KeyCache, cache)) {
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
_gridType.addOption(static_cast<int>(VolumeGridType::Cartesian), "Cartesian grid");
|
||||
_gridType.addOption(static_cast<int>(VolumeGridType::Spherical), "Spherical grid");
|
||||
_gridType.setValue(static_cast<int>(VolumeGridType::Cartesian));
|
||||
|
||||
std::string gridType;
|
||||
if (dictionary.getValue(KeyGridType, gridType)) {
|
||||
if (gridType == ValueSphericalGridType) {
|
||||
_gridType.setValue(static_cast<int>(VolumeGridType::Spherical));
|
||||
} else {
|
||||
_autoGridType = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderableKameleonVolume::~RenderableKameleonVolume() {}
|
||||
|
||||
bool RenderableKameleonVolume::initialize() {
|
||||
load();
|
||||
|
||||
_volumeTexture->uploadTexture();
|
||||
_transferFunction->update();
|
||||
|
||||
_raycaster = std::make_unique<KameleonVolumeRaycaster>(_volumeTexture, _transferFunction, _clipPlanes);
|
||||
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
_gridType.onChange([this] {
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
});
|
||||
_raycaster->setGridType(static_cast<VolumeGridType>(_gridType.value()));
|
||||
_gridType.onChange([this] {
|
||||
_raycaster->setGridType(static_cast<VolumeGridType>(_gridType.value()));
|
||||
});
|
||||
|
||||
updateRaycasterModelTransform();
|
||||
_lowerDomainBound.onChange([this] {
|
||||
updateRaycasterModelTransform();
|
||||
});
|
||||
_upperDomainBound.onChange([this] {
|
||||
updateRaycasterModelTransform();
|
||||
});
|
||||
|
||||
_raycaster->initialize();
|
||||
|
||||
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
|
||||
|
||||
auto onChange = [&](bool enabled) {
|
||||
if (enabled) {
|
||||
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
|
||||
}
|
||||
else {
|
||||
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
|
||||
}
|
||||
};
|
||||
|
||||
onEnabledChange(onChange);
|
||||
|
||||
_clipPlanes->initialize();
|
||||
|
||||
addProperty(_dimensions);
|
||||
addProperty(_stepSize);
|
||||
addProperty(_transferFunctionPath);
|
||||
addProperty(_sourcePath);
|
||||
addProperty(_variable);
|
||||
addProperty(_lowerDomainBound);
|
||||
addProperty(_upperDomainBound);
|
||||
addProperty(_domainScale);
|
||||
addProperty(_lowerValueBound);
|
||||
addProperty(_upperValueBound);
|
||||
addProperty(_gridType);
|
||||
addProperty(_cache);
|
||||
addPropertySubOwner(_clipPlanes.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::updateRaycasterModelTransform() {
|
||||
glm::vec3 lowerBoundingBoxBound = _domainScale.value() * _lowerDomainBound.value();
|
||||
glm::vec3 upperBoundingBoxBound = _domainScale.value() * _upperDomainBound.value();
|
||||
|
||||
glm::vec3 scale = upperBoundingBoxBound - lowerBoundingBoxBound;
|
||||
glm::vec3 translation = (lowerBoundingBoxBound + upperBoundingBoxBound) * 0.5f;
|
||||
|
||||
glm::mat4 modelTransform = glm::translate(glm::mat4(1.0), translation);
|
||||
modelTransform = glm::scale(modelTransform, scale);
|
||||
_raycaster->setModelTransform(modelTransform);
|
||||
}
|
||||
|
||||
|
||||
bool RenderableKameleonVolume::cachingEnabled() {
|
||||
return _cache;
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::load() {
|
||||
if (!FileSys.fileExists(_sourcePath)) {
|
||||
LERROR("File " << _sourcePath << " does not exist.");
|
||||
return;
|
||||
}
|
||||
if (!cachingEnabled()) {
|
||||
loadFromPath(_sourcePath);
|
||||
return;
|
||||
}
|
||||
ghoul::filesystem::File sourceFile(_sourcePath);
|
||||
std::string cachePath = FileSys.cacheManager()->cachedFilename(
|
||||
sourceFile.baseName(),
|
||||
cacheSuffix(),
|
||||
ghoul::filesystem::CacheManager::Persistent::Yes
|
||||
);
|
||||
if (FileSys.fileExists(cachePath)) {
|
||||
loadRaw(cachePath);
|
||||
} else {
|
||||
loadFromPath(_sourcePath);
|
||||
storeRaw(cachePath);
|
||||
}
|
||||
}
|
||||
|
||||
std::string RenderableKameleonVolume::cacheSuffix() {
|
||||
glm::vec3 dims = _dimensions.value();
|
||||
return "." + _variable.value() +
|
||||
"." + std::to_string(dims[0]) +
|
||||
"x" + std::to_string(dims[1]) +
|
||||
"x" + std::to_string(dims[2]);
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::loadFromPath(const std::string& path) {
|
||||
ghoul::filesystem::File file(path);
|
||||
std::string extension = file.fileExtension();
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
if (extension == "cdf") {
|
||||
loadCdf(path);
|
||||
} else {
|
||||
loadRaw(path);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::loadRaw(const std::string& path) {
|
||||
RawVolumeReader<float> reader(path, _dimensions);
|
||||
_rawVolume = reader.read();
|
||||
updateTextureFromVolume();
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::loadCdf(const std::string& path) {
|
||||
KameleonVolumeReader reader(path);
|
||||
|
||||
if (_autoValueBounds) {
|
||||
_lowerValueBound = reader.minValue(_variable);
|
||||
_upperValueBound = reader.maxValue(_variable);
|
||||
}
|
||||
|
||||
std::vector<std::string> variables = reader.gridVariableNames();
|
||||
|
||||
if (variables.size() == 3 && _autoDomainBounds) {
|
||||
_lowerDomainBound = glm::vec3(
|
||||
reader.minValue(variables[0]),
|
||||
reader.minValue(variables[1]),
|
||||
reader.minValue(variables[2]));
|
||||
|
||||
_upperDomainBound = glm::vec3(
|
||||
reader.maxValue(variables[0]),
|
||||
reader.maxValue(variables[1]),
|
||||
reader.maxValue(variables[2]));
|
||||
}
|
||||
|
||||
if (variables.size() == 3 && _autoGridType) {
|
||||
if (variables[0] == "r" && variables[0] == "theta" && variables[0] == "phi") {
|
||||
_gridType.setValue(static_cast<int>(VolumeGridType::Spherical));
|
||||
}
|
||||
else {
|
||||
_gridType.setValue(static_cast<int>(VolumeGridType::Cartesian));
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary dict = reader.readMetaData();
|
||||
_rawVolume = reader.readFloatVolume(_dimensions, _variable, _lowerDomainBound, _upperDomainBound);
|
||||
updateTextureFromVolume();
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::updateTextureFromVolume() {
|
||||
_normalizedVolume = std::make_unique<RawVolume<GLfloat>>(_dimensions);
|
||||
float* in = _rawVolume->data();
|
||||
GLfloat* out = _normalizedVolume->data();
|
||||
float min = _lowerValueBound;
|
||||
float diff = _upperValueBound - _lowerValueBound;
|
||||
|
||||
for (size_t i = 0; i < _normalizedVolume->nCells(); ++i) {
|
||||
out[i] = glm::clamp((in[i] - min) / diff, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
_volumeTexture = std::make_shared<ghoul::opengl::Texture>(
|
||||
_dimensions,
|
||||
ghoul::opengl::Texture::Format::Red,
|
||||
GL_RED,
|
||||
GL_FLOAT,
|
||||
ghoul::opengl::Texture::FilterMode::Linear,
|
||||
ghoul::opengl::Texture::WrappingMode::Repeat
|
||||
);
|
||||
|
||||
void* data = reinterpret_cast<void*>(_normalizedVolume->data());
|
||||
_volumeTexture->setPixelData(data, ghoul::opengl::Texture::TakeOwnership::No);
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::storeRaw(const std::string& path) {
|
||||
RawVolumeWriter<float> writer(path);
|
||||
writer.write(*_rawVolume);
|
||||
}
|
||||
|
||||
bool RenderableKameleonVolume::deinitialize() {
|
||||
if (_raycaster) {
|
||||
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
|
||||
_raycaster = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderableKameleonVolume::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::update(const UpdateData& data) {
|
||||
if (_raycaster) {
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::render(const RenderData& data, RendererTasks& tasks) {
|
||||
tasks.raycasterTasks.push_back({ _raycaster.get(), data });
|
||||
}
|
||||
|
||||
}
|
||||
103
modules/kameleonvolume/rendering/renderablekameleonvolume.h
Normal file
103
modules/kameleonvolume/rendering/renderablekameleonvolume.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___RENDERABLEKAMELEONVOLUME___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___RENDERABLEKAMELEONVOLUME___H__
|
||||
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/util/boxgeometry.h>
|
||||
#include <openspace/util/blockplaneintersectiongeometry.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/rendering/transferfunction.h>
|
||||
#include <modules/kameleon/include/kameleonwrapper.h>
|
||||
#include <modules/volume/rawvolume.h>
|
||||
#include <modules/kameleonvolume/rendering/kameleonvolumeraycaster.h>
|
||||
|
||||
#include <modules/volume/rendering/volumeclipplanes.h>
|
||||
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct RenderData;
|
||||
|
||||
class RenderableKameleonVolume : public Renderable {
|
||||
public:
|
||||
RenderableKameleonVolume(const ghoul::Dictionary& dictionary);
|
||||
~RenderableKameleonVolume();
|
||||
|
||||
bool initialize() override;
|
||||
bool deinitialize() override;
|
||||
bool isReady() const override;
|
||||
void render(const RenderData& data, RendererTasks& tasks) override;
|
||||
void update(const UpdateData& data) override;
|
||||
bool cachingEnabled();
|
||||
|
||||
private:
|
||||
void load();
|
||||
void loadFromPath(const std::string& path);
|
||||
void loadRaw(const std::string& path);
|
||||
void loadCdf(const std::string& path);
|
||||
void storeRaw(const std::string& path);
|
||||
|
||||
std::string cacheSuffix();
|
||||
void updateTextureFromVolume();
|
||||
void updateRaycasterModelTransform();
|
||||
|
||||
properties::UVec3Property _dimensions;
|
||||
properties::StringProperty _variable;
|
||||
properties::Vec3Property _lowerDomainBound;
|
||||
properties::Vec3Property _upperDomainBound;
|
||||
properties::Vec3Property _domainScale;
|
||||
bool _autoDomainBounds;
|
||||
|
||||
properties::FloatProperty _lowerValueBound;
|
||||
properties::FloatProperty _upperValueBound;
|
||||
bool _autoValueBounds;
|
||||
|
||||
properties::OptionProperty _gridType;
|
||||
bool _autoGridType;
|
||||
|
||||
std::shared_ptr<VolumeClipPlanes> _clipPlanes;
|
||||
|
||||
properties::FloatProperty _stepSize;
|
||||
properties::StringProperty _sourcePath;
|
||||
properties::StringProperty _transferFunctionPath;
|
||||
properties::BoolProperty _cache;
|
||||
|
||||
|
||||
std::unique_ptr<RawVolume<float>> _rawVolume;
|
||||
std::unique_ptr<RawVolume<GLfloat>> _normalizedVolume;
|
||||
std::unique_ptr<KameleonVolumeRaycaster> _raycaster;
|
||||
|
||||
std::shared_ptr<ghoul::opengl::Texture> _volumeTexture;
|
||||
std::shared_ptr<TransferFunction> _transferFunction;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___RENDERABLEKAMELEONVOLUME___H__
|
||||
40
modules/kameleonvolume/shaders/boundsfs.glsl
Normal file
40
modules/kameleonvolume/shaders/boundsfs.glsl
Normal file
@@ -0,0 +1,40 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
in vec4 positionLocalSpace;
|
||||
in vec4 positionCameraSpace;
|
||||
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 fragColor = vec4(positionLocalSpace.xyz+0.5, 1.0);
|
||||
vec4 position = positionCameraSpace;
|
||||
float depth = pscDepth(position);
|
||||
|
||||
Fragment frag;
|
||||
frag.color = fragColor;
|
||||
frag.depth = depth;
|
||||
return frag;
|
||||
}
|
||||
48
modules/kameleonvolume/shaders/boundsvs.glsl
Normal file
48
modules/kameleonvolume/shaders/boundsvs.glsl
Normal file
@@ -0,0 +1,48 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 vertPosition;
|
||||
|
||||
uniform mat4 modelViewTransform;
|
||||
uniform mat4 projectionTransform;
|
||||
|
||||
out vec4 positionLocalSpace;
|
||||
out vec4 positionCameraSpace;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
void main() {
|
||||
|
||||
positionLocalSpace = vec4(vertPosition, 1.0);
|
||||
positionCameraSpace = modelViewTransform * positionLocalSpace;
|
||||
|
||||
vec4 positionClipSpace = projectionTransform * positionCameraSpace;
|
||||
vec4 positionScreenSpace = z_normalization(positionClipSpace);
|
||||
|
||||
//positionScreenSpace.z = 1.0;
|
||||
// project the position to view space
|
||||
gl_Position = positionScreenSpace;
|
||||
}
|
||||
42
modules/kameleonvolume/shaders/helper.glsl
Normal file
42
modules/kameleonvolume/shaders/helper.glsl
Normal file
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#define KAMELEON_PI 3.14159265358979323846 /* pi */
|
||||
#define KAMELEON_SQRT1_3 0.57735026919 /* 1/sqrt(3) */
|
||||
|
||||
vec3 kameleon_cartesianToSpherical(vec3 zeroToOneCoords) {
|
||||
// Put cartesian in [-1..1] range first
|
||||
const vec3 cartesian = vec3(-1.0,-1.0,-1.0) + zeroToOneCoords * 2.0f;
|
||||
|
||||
const float r = length(cartesian);
|
||||
float theta, phi;
|
||||
|
||||
if (r == 0.0) {
|
||||
theta = phi = 0.0;
|
||||
} else {
|
||||
theta = acos(cartesian.z/r) / KAMELEON_PI;
|
||||
phi = (KAMELEON_PI + atan(cartesian.y, cartesian.x)) / (2.0*KAMELEON_PI );
|
||||
}
|
||||
return vec3(r * KAMELEON_SQRT1_3, theta, phi);
|
||||
}
|
||||
80
modules/kameleonvolume/shaders/raycast.glsl
Normal file
80
modules/kameleonvolume/shaders/raycast.glsl
Normal file
@@ -0,0 +1,80 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
uniform float maxStepSize#{id} = 0.02;
|
||||
uniform sampler3D volumeTexture_#{id};
|
||||
uniform sampler1D transferFunction_#{id};
|
||||
uniform int gridType_#{id} = 0;
|
||||
|
||||
uniform int nClips_#{id};
|
||||
uniform vec3 clipNormals_#{id}[8];
|
||||
uniform vec2 clipOffsets_#{id}[8];
|
||||
|
||||
|
||||
void sample#{id}(vec3 samplePos,
|
||||
vec3 dir,
|
||||
inout vec3 accumulatedColor,
|
||||
inout vec3 accumulatedAlpha,
|
||||
inout float stepSize) {
|
||||
|
||||
vec3 transformedPos = samplePos;
|
||||
if (gridType_#{id} == 1) {
|
||||
transformedPos = kameleon_cartesianToSpherical(samplePos);
|
||||
}
|
||||
|
||||
|
||||
float clipAlpha = 1.0;
|
||||
vec3 centerToPos = transformedPos - vec3(0.5);
|
||||
|
||||
|
||||
for (int i = 0; i < nClips_#{id} && i < 8; i++) {
|
||||
vec3 clipNormal = clipNormals_#{id}[i];
|
||||
float clipBegin = clipOffsets_#{id}[i].x;
|
||||
float clipEnd = clipBegin + clipOffsets_#{id}[i].y;
|
||||
clipAlpha *= smoothstep(clipBegin, clipEnd, dot(centerToPos, clipNormal));
|
||||
}
|
||||
|
||||
if (clipAlpha > 0) {
|
||||
float val = texture(volumeTexture_#{id}, transformedPos).r;
|
||||
vec4 color = texture(transferFunction_#{id}, val);
|
||||
vec3 backColor = color.rgb;
|
||||
vec3 backAlpha = color.aaa;
|
||||
|
||||
backColor *= stepSize * clipAlpha;
|
||||
backAlpha *= stepSize * clipAlpha;
|
||||
|
||||
backColor = clamp(backColor, 0.0, 1.0);
|
||||
backAlpha = clamp(backAlpha, 0.0, 1.0);
|
||||
|
||||
vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha;
|
||||
accumulatedColor += oneMinusFrontAlpha * backColor;
|
||||
accumulatedAlpha += oneMinusFrontAlpha * backAlpha;
|
||||
}
|
||||
|
||||
stepSize = maxStepSize#{id};
|
||||
}
|
||||
|
||||
float stepSize#{id}(vec3 samplePos, vec3 dir) {
|
||||
return maxStepSize#{id};
|
||||
}
|
||||
162
modules/kameleonvolume/tasks/kameleondocumentationtask.cpp
Normal file
162
modules/kameleonvolume/tasks/kameleondocumentationtask.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/kameleonvolume/tasks/kameleondocumentationtask.h>
|
||||
#include <modules/kameleonvolume/kameleonvolumereader.h>
|
||||
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
#include <ghoul/misc/dictionaryjsonformatter.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
const char* KeyInput = "Input";
|
||||
const char* KeyOutput = "Output";
|
||||
const char* MainTemplateFilename = "${OPENSPACE_DATA}/web/kameleondocumentation/main.hbs";
|
||||
const char* HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const char* JsFilename = "${OPENSPACE_DATA}/web/kameleondocumentation/script.js";
|
||||
const char* BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const char* CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
KameleonDocumentationTask::KameleonDocumentationTask(const ghoul::Dictionary& dictionary) {
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"KameleonDocumentationTask"
|
||||
);
|
||||
|
||||
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
|
||||
_outputPath = absPath(dictionary.value<std::string>(KeyOutput));
|
||||
}
|
||||
|
||||
std::string KameleonDocumentationTask::description() {
|
||||
return "Extract metadata from cdf-file " + _inputPath + " and output html documentation to " + _outputPath;
|
||||
}
|
||||
|
||||
void KameleonDocumentationTask::perform(const Task::ProgressCallback & progressCallback) {
|
||||
KameleonVolumeReader reader(_inputPath);
|
||||
ghoul::Dictionary kameleonDictionary = reader.readMetaData();
|
||||
progressCallback(0.33f);
|
||||
ghoul::DictionaryJsonFormatter formatter;
|
||||
|
||||
|
||||
ghoul::Dictionary dictionary = {
|
||||
{"kameleon", std::move(kameleonDictionary)},
|
||||
{"version",
|
||||
std::to_string(OPENSPACE_VERSION_MAJOR) + "." +
|
||||
std::to_string(OPENSPACE_VERSION_MINOR) + "." +
|
||||
std::to_string(OPENSPACE_VERSION_PATCH)
|
||||
},
|
||||
{"input", _inputPath}
|
||||
};
|
||||
|
||||
std::string json = formatter.format(dictionary);
|
||||
progressCallback(0.66f);
|
||||
|
||||
std::ifstream handlebarsInput(absPath(HandlebarsFilename));
|
||||
std::ifstream jsInput(absPath(JsFilename));
|
||||
|
||||
std::string jsContent;
|
||||
std::back_insert_iterator<std::string> jsInserter(jsContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{handlebarsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{jsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
|
||||
std::ifstream bootstrapInput(absPath(BootstrapFilename));
|
||||
std::ifstream cssInput(absPath(CssFilename));
|
||||
|
||||
std::string cssContent;
|
||||
std::back_insert_iterator<std::string> cssInserter(cssContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{bootstrapInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{cssInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
|
||||
std::ifstream mainTemplateInput(absPath(MainTemplateFilename));
|
||||
std::string mainTemplateContent{ std::istreambuf_iterator<char>{mainTemplateInput},
|
||||
std::istreambuf_iterator<char>{}};
|
||||
|
||||
std::ofstream file;
|
||||
file.exceptions(~std::ofstream::goodbit);
|
||||
file.open(_outputPath);
|
||||
|
||||
std::stringstream html;
|
||||
html << "<!DOCTYPE html>\n"
|
||||
<< "<html>\n"
|
||||
<< "\t<head>\n"
|
||||
<< "\t\t<script id=\"mainTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
<< mainTemplateContent << "\n"
|
||||
<< "\t\t</script>\n"
|
||||
<< "\t\t<script id=\"data\" type=\"application/json\">\n"
|
||||
<< json << "\n"
|
||||
<< "\t</script>\n"
|
||||
<< "\t<script>\n"
|
||||
<< jsContent << "\n"
|
||||
<< "\t</script>\n"
|
||||
<< "\t<style type=\"text/css\">\n"
|
||||
<< cssContent << "\n"
|
||||
<< "\t</style>\n"
|
||||
<< "\t\t<title>Documentation</title>\n"
|
||||
<< "\t</head>\n"
|
||||
<< "\t<body>\n"
|
||||
<< "\t</body>\n"
|
||||
<< "</html>\n";
|
||||
|
||||
file << html.str();
|
||||
|
||||
progressCallback(1.0f);
|
||||
}
|
||||
|
||||
documentation::Documentation KameleonDocumentationTask::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"KameleonDocumentationTask",
|
||||
"kameleon_documentation_task",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringEqualVerifier("KameleonDocumentationTask"),
|
||||
"The type of this task"
|
||||
},
|
||||
{
|
||||
KeyInput,
|
||||
new StringAnnotationVerifier("A file path to a cdf file"),
|
||||
"The cdf file to extract data from"
|
||||
},
|
||||
{
|
||||
KeyOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
"The html file to write documentation to"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
45
modules/kameleonvolume/tasks/kameleondocumentationtask.h
Normal file
45
modules/kameleonvolume/tasks/kameleondocumentationtask.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONDOCUMENTATIONTASK___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONDOCUMENTATIONTASK___H__
|
||||
|
||||
#include <openspace/util/task.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class KameleonDocumentationTask : public Task {
|
||||
public:
|
||||
KameleonDocumentationTask(const ghoul::Dictionary& dictionary);
|
||||
std::string description() override;
|
||||
void perform(const Task::ProgressCallback& progressCallback) override;
|
||||
static documentation::Documentation documentation();
|
||||
private:
|
||||
std::string _inputPath;
|
||||
std::string _outputPath;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONDOCUMENTATIONTASK___H__
|
||||
94
modules/kameleonvolume/tasks/kameleonmetadatatojsontask.cpp
Normal file
94
modules/kameleonvolume/tasks/kameleonmetadatatojsontask.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h>
|
||||
#include <modules/kameleonvolume/kameleonvolumereader.h>
|
||||
#include <string>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <ghoul/misc/dictionaryjsonformatter.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
const char* KeyInput = "Input";
|
||||
const char* KeyOutput = "Output";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
KameleonMetadataToJsonTask::KameleonMetadataToJsonTask(const ghoul::Dictionary& dictionary) {
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"KameleonMetadataToJsonTask"
|
||||
);
|
||||
|
||||
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
|
||||
_outputPath = absPath(dictionary.value<std::string>(KeyOutput));
|
||||
}
|
||||
|
||||
std::string KameleonMetadataToJsonTask::description() {
|
||||
return "Extract metadata from cdf-file " + _inputPath + " and write as json to " + _outputPath;
|
||||
}
|
||||
|
||||
void KameleonMetadataToJsonTask::perform(const Task::ProgressCallback & progressCallback) {
|
||||
KameleonVolumeReader reader(_inputPath);
|
||||
ghoul::Dictionary dictionary = reader.readMetaData();
|
||||
progressCallback(0.5f);
|
||||
ghoul::DictionaryJsonFormatter formatter;
|
||||
std::string json = formatter.format(dictionary);
|
||||
std::ofstream output(_outputPath);
|
||||
output << json;
|
||||
progressCallback(1.0f);
|
||||
}
|
||||
|
||||
documentation::Documentation KameleonMetadataToJsonTask::documentation()
|
||||
{
|
||||
using namespace documentation;
|
||||
return {
|
||||
"KameleonMetadataToJsonTask",
|
||||
"kameleon_metadata_to_json_task",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringEqualVerifier("KameleonMetadataToJsonTask"),
|
||||
"The type of this task"
|
||||
},
|
||||
{
|
||||
KeyInput,
|
||||
new StringAnnotationVerifier("A file path to a cdf file"),
|
||||
"The cdf file to extract data from"
|
||||
},
|
||||
{
|
||||
KeyOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
"The json file to export data into"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace openspace
|
||||
45
modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h
Normal file
45
modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONMETADATATOJSONTASK___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONMETADATATOJSONTASK___H__
|
||||
|
||||
#include <openspace/util/task.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class KameleonMetadataToJsonTask : public Task {
|
||||
public:
|
||||
KameleonMetadataToJsonTask(const ghoul::Dictionary& dictionary);
|
||||
std::string description() override;
|
||||
void perform(const Task::ProgressCallback& progressCallback) override;
|
||||
static documentation::Documentation documentation();
|
||||
private:
|
||||
std::string _inputPath;
|
||||
std::string _outputPath;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONMETADATATOJSONTASK___H__
|
||||
@@ -47,7 +47,8 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
MultiresVolumeRaycaster::MultiresVolumeRaycaster(std::shared_ptr<TSP> tsp,
|
||||
MultiresVolumeRaycaster::MultiresVolumeRaycaster(
|
||||
std::shared_ptr<TSP> tsp,
|
||||
std::shared_ptr<AtlasManager> atlasManager,
|
||||
std::shared_ptr<TransferFunction> transferFunction)
|
||||
: _tsp(tsp)
|
||||
@@ -112,11 +113,9 @@ void MultiresVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl:
|
||||
_atlasManager->textureAtlas().bind();
|
||||
program.setUniform("textureAtlas_" + id, _atlasUnit->unitNumber());
|
||||
|
||||
|
||||
_atlasMapBinding = std::make_unique<ghoul::opengl::BufferBinding<ghoul::opengl::bufferbinding::Buffer::ShaderStorage>>();
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, _atlasMapBinding->bindingNumber(), _atlasManager->atlasMapBuffer());
|
||||
program.setSsboBinding("atlasMapBlock_" + id, _atlasMapBinding->bindingNumber());
|
||||
|
||||
|
||||
program.setUniform("gridType_" + id, static_cast<int>(_tsp->header().gridType_));
|
||||
program.setUniform("maxNumBricksPerAxis_" + id, static_cast<unsigned int>(_tsp->header().xNumBricks_));
|
||||
@@ -155,7 +154,8 @@ bool MultiresVolumeRaycaster::cameraIsInside(const RenderData& data, glm::vec3&
|
||||
}
|
||||
|
||||
void MultiresVolumeRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
|
||||
// For example: release texture units
|
||||
_atlasUnit = nullptr;
|
||||
_tfUnit = nullptr;
|
||||
}
|
||||
|
||||
std::string MultiresVolumeRaycaster::getBoundsVsPath() const {
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_SPACE___BASEMODULE___H__
|
||||
#define __OPENSPACE_MODULE_SPACE___BASEMODULE___H__
|
||||
#ifndef __OPENSPACE_MODULE_SPACE___SPACEMODULE___H__
|
||||
#define __OPENSPACE_MODULE_SPACE___SPACEMODULE___H__
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace openspace {
|
||||
class SpaceModule : public OpenSpaceModule {
|
||||
public:
|
||||
SpaceModule();
|
||||
|
||||
virtual ~SpaceModule() = default;
|
||||
std::vector<documentation::Documentation> documentations() const override;
|
||||
|
||||
protected:
|
||||
@@ -41,4 +41,4 @@ protected:
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_SPACE___BASEMODULE___H__
|
||||
#endif // __OPENSPACE_MODULE_SPACE___SPACEMODULE___H__
|
||||
|
||||
@@ -35,9 +35,12 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/textureslicevolumereader.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lrucache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linearlrucache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumegridtype.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumeutils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplane.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplanes.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
@@ -48,6 +51,8 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/textureslicevolumereader.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumeutils.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplane.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplanes.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
|
||||
@@ -25,25 +25,31 @@
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___RAWVOLUME___H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___RAWVOLUME___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename Voxel>
|
||||
class RawVolume {
|
||||
public:
|
||||
typedef Voxel VoxelType;
|
||||
RawVolume(const glm::ivec3& dimensions);
|
||||
glm::ivec3 dimensions() const;
|
||||
void setDimensions(const glm::ivec3& dimensions);
|
||||
VoxelType get(const glm::ivec3& coordinates) const;
|
||||
RawVolume(const glm::uvec3& dimensions);
|
||||
glm::uvec3 dimensions() const;
|
||||
void setDimensions(const glm::uvec3& dimensions);
|
||||
size_t nCells() const;
|
||||
VoxelType get(const glm::uvec3& coordinates) const;
|
||||
VoxelType get(const size_t index) const;
|
||||
void set(const glm::ivec3& coordinates, const VoxelType& value);
|
||||
void set(const glm::uvec3& coordinates, const VoxelType& value);
|
||||
void set(size_t index, const VoxelType& value);
|
||||
void forEachVoxel(const std::function<void(const glm::ivec3&, const VoxelType&)>& fn);
|
||||
void forEachVoxel(const std::function<void(const glm::uvec3&, const VoxelType&)>& fn);
|
||||
const VoxelType* data() const;
|
||||
size_t coordsToIndex(const glm::uvec3& cartesian) const;
|
||||
glm::uvec3 indexToCoords(size_t linear) const;
|
||||
VoxelType* data();
|
||||
private:
|
||||
size_t coordsToIndex(const glm::ivec3& cartesian) const;
|
||||
glm::ivec3 indexToCoords(size_t linear) const;
|
||||
glm::ivec3 _dimensions;
|
||||
glm::uvec3 _dimensions;
|
||||
std::vector<VoxelType> _data;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,31 +23,39 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/volume/volumeutils.h>
|
||||
#include "rawvolume.h"
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolume<VoxelType>::RawVolume(const glm::ivec3& dimensions)
|
||||
RawVolume<VoxelType>::RawVolume(const glm::uvec3& dimensions)
|
||||
: _dimensions(dimensions)
|
||||
, _data(static_cast<size_t>(dimensions.x) *
|
||||
static_cast<size_t>(dimensions.y) *
|
||||
static_cast<size_t>(dimensions.z)) {}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolume<VoxelType>::dimensions() const {
|
||||
glm::uvec3 RawVolume<VoxelType>::dimensions() const {
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
|
||||
void RawVolume<VoxelType>::setDimensions(const glm::uvec3& dimensions) {
|
||||
_dimensions = dimensions;
|
||||
_data.resize(static_cast<size_t>(dimensions.x) *
|
||||
static_cast<size_t>(dimensions.y) *
|
||||
static_cast<size_t>(dimensions.z));
|
||||
_data.resize(nCells());
|
||||
}
|
||||
|
||||
template<typename VoxelType>
|
||||
size_t RawVolume<VoxelType>::nCells() const
|
||||
{
|
||||
return static_cast<size_t>(
|
||||
static_cast<size_t>(_dimensions.x) *
|
||||
static_cast<size_t>(_dimensions.y) *
|
||||
static_cast<size_t>(_dimensions.z));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::get(const glm::ivec3& coordinates) const {
|
||||
VoxelType RawVolume<VoxelType>::get(const glm::uvec3& coordinates) const {
|
||||
return get(coordsToIndex(coordinates, dimensions()));
|
||||
}
|
||||
|
||||
@@ -57,7 +65,7 @@ VoxelType RawVolume<VoxelType>::get(size_t index) const {
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::set(const glm::ivec3& coordinates, const VoxelType& value) {
|
||||
void RawVolume<VoxelType>::set(const glm::uvec3& coordinates, const VoxelType& value) {
|
||||
return set(coordsToIndex(coordinates, dimensions()), value);
|
||||
}
|
||||
|
||||
@@ -68,27 +76,21 @@ void RawVolume<VoxelType>::set(size_t index, const VoxelType& value) {
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::forEachVoxel(
|
||||
const std::function<void(const glm::ivec3&, const VoxelType&)>& fn)
|
||||
const std::function<void(const glm::uvec3&, const VoxelType&)>& fn)
|
||||
{
|
||||
|
||||
glm::ivec3 dims = dimensions();
|
||||
size_t nVals = static_cast<size_t>(dims.x) *
|
||||
static_cast<size_t>(dims.y) *
|
||||
static_cast<size_t>(dims.z);
|
||||
|
||||
for (size_t i = 0; i < nVals; i++) {
|
||||
for (size_t i = 0; i < nCells(); i++) {
|
||||
glm::ivec3 coords = indexToCoords(i);
|
||||
fn(coords, _data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolume<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
|
||||
size_t RawVolume<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolume<VoxelType>::indexToCoords(size_t linear) const {
|
||||
glm::uvec3 RawVolume<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
@@ -96,5 +98,11 @@ template <typename VoxelType>
|
||||
VoxelType* RawVolume<VoxelType>::data() {
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
const VoxelType* RawVolume<VoxelType>::data() const {
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -34,18 +34,18 @@ template <typename Voxel>
|
||||
class RawVolumeReader {
|
||||
public:
|
||||
typedef Voxel VoxelType;
|
||||
RawVolumeReader(const std::string& path, const glm::ivec3& dimensions);
|
||||
glm::ivec3 dimensions() const;
|
||||
RawVolumeReader(const std::string& path, const glm::uvec3& dimensions);
|
||||
glm::uvec3 dimensions() const;
|
||||
std::string path() const;
|
||||
void setPath(const std::string& path);
|
||||
void setDimensions(const glm::ivec3& dimensions);
|
||||
void setDimensions(const glm::uvec3& dimensions);
|
||||
//VoxelType get(const glm::ivec3& coordinates) const; // TODO: Implement this
|
||||
//VoxelType get(const size_t index) const; // TODO: Implement this
|
||||
std::unique_ptr<RawVolume<VoxelType>> read();
|
||||
private:
|
||||
size_t coordsToIndex(const glm::ivec3& cartesian) const;
|
||||
glm::ivec3 indexToCoords(size_t linear) const;
|
||||
glm::ivec3 _dimensions;
|
||||
size_t coordsToIndex(const glm::uvec3& cartesian) const;
|
||||
glm::uvec3 indexToCoords(size_t linear) const;
|
||||
glm::uvec3 _dimensions;
|
||||
std::string _path;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,18 +28,18 @@ namespace openspace {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolumeReader<VoxelType>::RawVolumeReader(const std::string& path,
|
||||
const glm::ivec3& dimensions)
|
||||
const glm::uvec3& dimensions)
|
||||
: _path(path)
|
||||
, _dimensions(dimensions)
|
||||
{}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeReader<VoxelType>::dimensions() const {
|
||||
glm::uvec3 RawVolumeReader<VoxelType>::dimensions() const {
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeReader<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
|
||||
void RawVolumeReader<VoxelType>::setDimensions(const glm::uvec3& dimensions) {
|
||||
_dimensions = dimensions;
|
||||
}
|
||||
|
||||
@@ -68,19 +68,19 @@ VoxelType RawVolumeReader<VoxelType>::get(size_t index) const {
|
||||
}*/
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolumeReader<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
|
||||
size_t RawVolumeReader<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeReader<VoxelType>::indexToCoords(size_t linear) const {
|
||||
glm::uvec3 RawVolumeReader<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
|
||||
template <typename VoxelType>
|
||||
std::unique_ptr<RawVolume<VoxelType>> RawVolumeReader<VoxelType>::read() {
|
||||
glm::ivec3 dims = dimensions();
|
||||
glm::uvec3 dims = dimensions();
|
||||
std::unique_ptr<RawVolume<VoxelType>> volume =
|
||||
std::make_unique<RawVolume<VoxelType>>(dims);
|
||||
|
||||
|
||||
@@ -36,13 +36,13 @@ class RawVolumeWriter {
|
||||
public:
|
||||
RawVolumeWriter(std::string path, size_t bufferSize = 1024);
|
||||
void setPath(const std::string& path);
|
||||
glm::ivec3 dimensions() const;
|
||||
void setDimensions(const glm::ivec3& dimensions);
|
||||
void write(const std::function<VoxelType(const glm::ivec3&)>& fn,
|
||||
glm::uvec3 dimensions() const;
|
||||
void setDimensions(const glm::uvec3& dimensions);
|
||||
void write(const std::function<VoxelType(const glm::uvec3&)>& fn,
|
||||
const std::function<void(float t)>& onProgress = [](float t) {});
|
||||
void write(const RawVolume<VoxelType>& volume);
|
||||
|
||||
size_t coordsToIndex(const glm::ivec3& coords) const;
|
||||
size_t coordsToIndex(const glm::uvec3& coords) const;
|
||||
glm::ivec3 indexToCoords(size_t linear) const;
|
||||
private:
|
||||
glm::ivec3 _dimensions;
|
||||
|
||||
@@ -33,7 +33,7 @@ template <typename VoxelType>
|
||||
, _bufferSize(bufferSize) {}
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolumeWriter<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
|
||||
size_t RawVolumeWriter<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
@@ -43,21 +43,21 @@ glm::ivec3 RawVolumeWriter<VoxelType>::indexToCoords(size_t linear) const {
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeWriter<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
|
||||
void RawVolumeWriter<VoxelType>::setDimensions(const glm::uvec3& dimensions) {
|
||||
_dimensions = dimensions;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeWriter<VoxelType>::dimensions() const {
|
||||
glm::uvec3 RawVolumeWriter<VoxelType>::dimensions() const {
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeWriter<VoxelType>::write(const std::function<VoxelType(const glm::ivec3&)>& fn,
|
||||
void RawVolumeWriter<VoxelType>::write(const std::function<VoxelType(const glm::uvec3&)>& fn,
|
||||
const std::function<void(float t)>& onProgress)
|
||||
{
|
||||
glm::ivec3 dims = dimensions();
|
||||
glm::uvec3 dims = dimensions();
|
||||
|
||||
size_t size = static_cast<size_t>(dims.x) *
|
||||
static_cast<size_t>(dims.y) *
|
||||
@@ -86,14 +86,11 @@ void RawVolumeWriter<VoxelType>::write(const std::function<VoxelType(const glm::
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeWriter<VoxelType>::write(const RawVolume<VoxelType>& volume) {
|
||||
glm::ivec3 dims = dimensions();
|
||||
ghoul_assert(dims == volume.dims(), "Dimensions of input and output volume must agree");
|
||||
setDimensions(volume.dimensions());
|
||||
reinterpret_cast<const char*>(volume.data());
|
||||
|
||||
const char* buffer = reinterpret_cast<char*>(volume.data());
|
||||
size_t length = static_cast<size_t>(dims.x) *
|
||||
static_cast<size_t>(dims.y) *
|
||||
static_cast<size_t>(dims.z) *
|
||||
sizeof(VoxelType);
|
||||
const char* const buffer = reinterpret_cast<const char*>(volume.data());
|
||||
size_t length = volume.nCells() * sizeof(VoxelType);
|
||||
|
||||
std::ofstream file(_path, std::ios::binary);
|
||||
file.write(buffer, length);
|
||||
|
||||
@@ -1,461 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
// open space includes
|
||||
#include <modules/volume/rendering/renderablevolume.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <modules/kameleon/include/kameleonwrapper.h>
|
||||
#include <openspace/util/progressbar.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderableVolume";
|
||||
|
||||
bool hasExtension (std::string const &filepath, std::string const &extension)
|
||||
{
|
||||
std::string ending = "." + extension;
|
||||
if (filepath.length() > ending.length()) {
|
||||
return (0 == filepath.compare (filepath.length() - ending.length(), ending.length(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T stringToNumber(const std::string& number, std::function<T(T)> f = nullptr) {
|
||||
static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value,
|
||||
"Must be integral or floating point");
|
||||
std::stringstream ss;
|
||||
T templateNumber = {0};
|
||||
ss << number;
|
||||
ss >> templateNumber;
|
||||
if( ! f)
|
||||
return templateNumber;
|
||||
|
||||
return f(templateNumber);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) : Renderable(dictionary) {
|
||||
}
|
||||
|
||||
RenderableVolume::~RenderableVolume() {
|
||||
}
|
||||
|
||||
ghoul::opengl::Texture* RenderableVolume::loadVolume(
|
||||
const std::string& filepath,
|
||||
const ghoul::Dictionary& hintsDictionary) {
|
||||
|
||||
if( ! FileSys.fileExists(filepath)) {
|
||||
LWARNING("Could not load volume, could not find '" << filepath << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(hasExtension(filepath, "raw")) {
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
ghoul::RawVolumeReader rawReader(hints);
|
||||
return rawReader.read(filepath);
|
||||
} else if(hasExtension(filepath, "cdf")) {
|
||||
|
||||
ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear;
|
||||
ghoul::opengl::Texture::WrappingMode wrappingmode = ghoul::opengl::Texture::WrappingMode::ClampToEdge;
|
||||
|
||||
glm::size3_t dimensions(1,1,1);
|
||||
double tempValue;
|
||||
if (hintsDictionary.hasKey("Dimensions.1") &&
|
||||
hintsDictionary.getValue("Dimensions.1", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[0] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.2") &&
|
||||
hintsDictionary.getValue("Dimensions.2", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[1] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.3") &&
|
||||
hintsDictionary.getValue("Dimensions.3", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[2] = intVal;
|
||||
}
|
||||
|
||||
std::string variableCacheString = "";
|
||||
if (hintsDictionary.hasKey("Variable")) {
|
||||
hintsDictionary.getValue("Variable", variableCacheString);
|
||||
} else if(hintsDictionary.hasKey("Variables")) {
|
||||
std::string xVariable, yVariable, zVariable;
|
||||
bool xVar, yVar, zVar;
|
||||
xVar = hintsDictionary.getValue("Variables.1", xVariable);
|
||||
yVar = hintsDictionary.getValue("Variables.2", yVariable);
|
||||
zVar = hintsDictionary.getValue("Variables.3", zVariable);
|
||||
if (xVar && yVar && zVar) {
|
||||
variableCacheString = xVariable + "." + yVariable + "." + zVariable;
|
||||
}
|
||||
}
|
||||
|
||||
bool cache = false;
|
||||
hintsDictionary.hasKey("Cache");
|
||||
if (hintsDictionary.hasKey("Cache"))
|
||||
hintsDictionary.getValue("Cache", cache);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "." << dimensions[0] << "x" << dimensions[1] << "x" << dimensions[2] << "." << "." << variableCacheString << ".cache";
|
||||
|
||||
// = filepath + ss.str();
|
||||
ghoul::filesystem::File ghlFile(filepath);
|
||||
std::string cachepath = FileSys.cacheManager()->cachedFilename(ghlFile.baseName(),
|
||||
ss.str(), true);
|
||||
if (cache && FileSys.fileExists(cachepath)) {
|
||||
|
||||
#define VOLUME_LOAD_PROGRESSBAR
|
||||
std::ifstream file(cachepath, std::ios::binary | std::ios::in);
|
||||
if (file.is_open()) {
|
||||
size_t length = dimensions[0] * dimensions[1] * dimensions[2];
|
||||
float* data = new float[length];
|
||||
#ifdef VOLUME_LOAD_PROGRESSBAR
|
||||
LINFO("Loading cache: " << cachepath);
|
||||
ProgressBar pb(static_cast<int>(dimensions[2]));
|
||||
for (size_t i = 0; i < dimensions[2]; ++i) {
|
||||
size_t offset = length / dimensions[2];
|
||||
std::streamsize offsetsize = sizeof(float)*offset;
|
||||
file.read(reinterpret_cast<char*>(data + offset * i), offsetsize);
|
||||
pb.print(static_cast<int>(i));
|
||||
}
|
||||
#else
|
||||
file.read(reinterpret_cast<char*>(data), sizeof(float)*length);
|
||||
#endif
|
||||
file.close();
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, filtermode, wrappingmode);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
KameleonWrapper kw(filepath);
|
||||
std::string variableString;
|
||||
if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) {
|
||||
float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
if(cache) {
|
||||
std::ofstream file(cachepath, std::ios::binary | std::ios::out);
|
||||
if (file.is_open()) {
|
||||
size_t length = dimensions[0] * dimensions[1] * dimensions[2];
|
||||
file.write(reinterpret_cast<const char*>(data), sizeof(float)*length);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, filtermode, wrappingmode);
|
||||
} else if (hintsDictionary.hasKey("Variables")) {
|
||||
std::string xVariable, yVariable, zVariable;
|
||||
bool xVar, yVar, zVar;
|
||||
xVar = hintsDictionary.getValue("Variables.1", xVariable);
|
||||
yVar = hintsDictionary.getValue("Variables.2", yVariable);
|
||||
zVar = hintsDictionary.getValue("Variables.3", zVariable);
|
||||
|
||||
if (!xVar || !yVar || !zVar) {
|
||||
LERROR("Error reading variables! Must be 3 and must exist in CDF data");
|
||||
} else {
|
||||
|
||||
float* data = kw.getUniformSampledVectorValues(xVariable, yVariable, zVariable, dimensions);
|
||||
if(cache) {
|
||||
//FILE* file = fopen (cachepath.c_str(), "wb");
|
||||
std::ofstream file(cachepath, std::ios::in | std::ios::binary);
|
||||
size_t length = dimensions[0] * dimensions[1] * dimensions[2];
|
||||
file.write(reinterpret_cast<char*>(data), sizeof(float)*length);
|
||||
file.close();
|
||||
}
|
||||
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT, filtermode, wrappingmode);
|
||||
}
|
||||
|
||||
} else {
|
||||
LWARNING("Hints does not specify a 'Variable' or 'Variables'");
|
||||
}
|
||||
} else {
|
||||
LWARNING("No valid file extension.");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glm::vec3 RenderableVolume::getVolumeOffset(
|
||||
const std::string& filepath,
|
||||
const ghoul::Dictionary& hintsDictionary) {
|
||||
|
||||
KameleonWrapper kw(filepath);
|
||||
return kw.getModelBarycenterOffset();
|
||||
}
|
||||
|
||||
ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
|
||||
ghoul::RawVolumeReader::ReadHints hints;
|
||||
hints._dimensions = glm::ivec3(1, 1, 1);
|
||||
hints._format = ghoul::opengl::Texture::Format::Red;
|
||||
hints._internalFormat = GL_R8;
|
||||
|
||||
// parse hints
|
||||
double tempValue;
|
||||
if (dictionary.hasKey("Dimensions.1") && dictionary.getValue("Dimensions.1", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
hints._dimensions[0] = intVal;
|
||||
}
|
||||
if (dictionary.hasKey("Dimensions.2") && dictionary.getValue("Dimensions.2", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
hints._dimensions[1] = intVal;
|
||||
}
|
||||
if (dictionary.hasKey("Dimensions.3") && dictionary.getValue("Dimensions.3", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
hints._dimensions[2] = intVal;
|
||||
}
|
||||
|
||||
std::string format;
|
||||
if (dictionary.hasKey("Format") && dictionary.getValue("Format", format)) {
|
||||
if(format == "RED") {
|
||||
hints._format = ghoul::opengl::Texture::Format::Red;
|
||||
} else if(format == "RG") {
|
||||
hints._format = ghoul::opengl::Texture::Format::RG;
|
||||
} else if(format == "RGB") {
|
||||
hints._format = ghoul::opengl::Texture::Format::RGB;
|
||||
} else if(format == "RGBA") {
|
||||
hints._format = ghoul::opengl::Texture::Format::RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
format = "";
|
||||
if (dictionary.hasKey("InternalFormat") && dictionary.getValue("InternalFormat", format)) {
|
||||
if(format == "R8") {
|
||||
hints._internalFormat = GL_R8;
|
||||
} else if(format == "RG8") {
|
||||
hints._internalFormat = GL_RG8;
|
||||
} else if(format == "RGB8") {
|
||||
hints._internalFormat = GL_RGB8;
|
||||
} else if(format == "RGBA8") {
|
||||
hints._internalFormat = GL_RGB8;
|
||||
} else if(format == "R32F") {
|
||||
hints._internalFormat = GL_R32F;
|
||||
} else if(format == "RG32F") {
|
||||
hints._internalFormat = GL_RG32F;
|
||||
} else if(format == "RGB32F") {
|
||||
hints._internalFormat = GL_RGB32F;
|
||||
} else if(format == "RGBA32F") {
|
||||
hints._internalFormat = GL_RGB32F;
|
||||
}
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string& filepath) {
|
||||
|
||||
std::string f = absPath(filepath);
|
||||
|
||||
if ( ! FileSys.fileExists(f)) {
|
||||
return nullptr;
|
||||
}
|
||||
ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear;
|
||||
ghoul::opengl::Texture::WrappingMode wrappingmode = ghoul::opengl::Texture::WrappingMode::ClampToEdge;
|
||||
|
||||
|
||||
// check if not a txt based texture
|
||||
if ( ! hasExtension(filepath, "txt")) {
|
||||
ghoul::opengl::Texture* t = ghoul::io::TextureReader::ref().loadTexture(f).get();
|
||||
t->setWrapping(wrappingmode);
|
||||
return t;
|
||||
}
|
||||
|
||||
// it is a txt based texture
|
||||
std::ifstream in;
|
||||
in.open(filepath.c_str());
|
||||
if (!in.is_open()) {
|
||||
LERROR("Could not open file " << f);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int width = 512;
|
||||
float lower = 0.0f;
|
||||
float upper = 1.0f;
|
||||
|
||||
struct mappingKey {
|
||||
float position{0.0f};
|
||||
glm::vec4 color{0.0f,0.0f,0.0f,0.0f};
|
||||
|
||||
mappingKey(float p, const glm::vec4& c): position(p), color(c){};
|
||||
mappingKey(float p): position(p), color(glm::vec4(0.0f)){};
|
||||
bool operator<(const mappingKey& rhs) {return position < rhs.position;};
|
||||
};
|
||||
|
||||
std::vector<mappingKey> mappingKeys;
|
||||
|
||||
auto widthValidator = [](size_t in) { if(in > 0) return in; return static_cast<size_t>(1); };
|
||||
auto upperLowerValidator = [](float in) { return glm::clamp(in, 0.0f, 1.0f); };
|
||||
auto intensityValidator = [](float in) { return glm::clamp(in, 0.0f, 1.0f); };
|
||||
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
|
||||
glm::vec4 rgba = glm::vec4(0.0f);
|
||||
// tokenize the line
|
||||
std::istringstream iss(line);
|
||||
std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};
|
||||
|
||||
size_t tokenSize =tokens.size();
|
||||
if (tokenSize > 0) {
|
||||
std::string key = tokens.at(0);
|
||||
if(key == "width" && tokenSize == 2) {
|
||||
width = static_cast<int>(stringToNumber<size_t>(tokens.at(1), widthValidator));
|
||||
} else if(key == "lower" && tokenSize == 2) {
|
||||
lower = stringToNumber<float>(tokens.at(1), upperLowerValidator);
|
||||
} else if(key == "upper" && tokenSize == 2) {
|
||||
upper = stringToNumber<float>(tokens.at(1),upperLowerValidator);
|
||||
} else if(key == "mappingkey" && tokenSize == 6) {
|
||||
float intensity = stringToNumber<float>(tokens.at(1), intensityValidator);
|
||||
for(int i = 0; i < 4; ++i)
|
||||
rgba[i] = stringToNumber<float>(tokens.at(i+2));
|
||||
|
||||
mappingKeys.push_back({intensity, rgba});
|
||||
}
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
|
||||
|
||||
if (mappingKeys.size() < 1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// for(auto key: mappingKeys) {
|
||||
// glm::vec4 rgba = key.color;
|
||||
// LDEBUG("i: " << key.position << ", rgba: (" << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << ")");
|
||||
// }
|
||||
// LDEBUG("insert....");
|
||||
|
||||
if (mappingKeys.front().position > lower){
|
||||
mappingKeys.insert(mappingKeys.begin(), {lower,mappingKeys.front().color});
|
||||
}
|
||||
|
||||
if (mappingKeys.back().position < upper){
|
||||
mappingKeys.push_back({upper,mappingKeys.back().color});
|
||||
}
|
||||
|
||||
|
||||
// for(auto key: mappingKeys) {
|
||||
// glm::vec4 rgba = key.color;
|
||||
// LDEBUG("i: " << key.position << ", rgba: (" << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << ")");
|
||||
// }
|
||||
|
||||
// allocate new float array with zeros
|
||||
float* transferFunction = new float[width*4]();
|
||||
for (int i = 0; i < 4*width; ++i) {
|
||||
transferFunction[i] = 0.0f;
|
||||
}
|
||||
|
||||
size_t lowerIndex = static_cast<size_t>(floorf(lower*static_cast<float>(width-1)));
|
||||
size_t upperIndex = static_cast<size_t>(floorf(upper*static_cast<float>(width-1)));
|
||||
|
||||
// LDEBUG("width: " << width);
|
||||
// LDEBUG("lower: " << lower);
|
||||
// LDEBUG("upper: " << upper);
|
||||
// LDEBUG("lowerIndex: " << lowerIndex);
|
||||
// LDEBUG("upperIndex: " << upperIndex);
|
||||
|
||||
|
||||
auto prevKey = mappingKeys.begin();
|
||||
auto currentKey = prevKey + 1;
|
||||
auto lastKey = mappingKeys.end() -1;
|
||||
|
||||
for (size_t i=lowerIndex; i<=upperIndex; i++) {
|
||||
|
||||
float fpos = static_cast<float>(i)/static_cast<float>(width-1);
|
||||
|
||||
if (fpos > (*currentKey).position) {
|
||||
prevKey = currentKey;
|
||||
currentKey++;
|
||||
if (currentKey == mappingKeys.end()) {
|
||||
currentKey = lastKey;
|
||||
}
|
||||
}
|
||||
|
||||
float dist = fpos-(*prevKey).position;
|
||||
float weight = dist/((*currentKey).position-(*prevKey).position);
|
||||
|
||||
//LDEBUG("fpos: " << fpos);
|
||||
//LDEBUG("(*prevKey).position: " << (*prevKey).position);
|
||||
//LDEBUG("(*currentKey).position: " << (*currentKey).position);
|
||||
//LDEBUG("weight: " << weight);
|
||||
|
||||
for (size_t channel=0; channel<4; ++channel) {
|
||||
size_t position = 4*i + channel;
|
||||
// Interpolate linearly between prev and next mapping key
|
||||
|
||||
//LDEBUG("i: " << i);
|
||||
//LDEBUG("position: " << position);
|
||||
//LDEBUG("(*prevKey).first " << (*prevKey).first);
|
||||
//LDEBUG("(*currentKey).first " << (*currentKey).first);
|
||||
//LDEBUG("dist: " << dist);
|
||||
//LDEBUG("weight: " << weight);
|
||||
float value =
|
||||
((*prevKey).color[channel]*(1.f-weight) + (*currentKey).color[channel]*weight)/255.f;
|
||||
transferFunction[position] = value;
|
||||
|
||||
//LDEBUG("["<< position <<"] " << value);
|
||||
|
||||
}
|
||||
// LDEBUG(std::fixed << std::setw(10) << std::left << std::setprecision(8) << weight << ", (" <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+0] << ", " <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+1] << ", " <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+2] << ", " <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+3] << ")");
|
||||
}
|
||||
|
||||
// for (int i = 0; i <= width; ++i) {
|
||||
|
||||
// LDEBUG(std::fixed << "(" <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+0] << ", " <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+1] << ", " <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+2] << ", " <<
|
||||
// std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+3] << ")");
|
||||
// }
|
||||
|
||||
return new ghoul::opengl::Texture(transferFunction,
|
||||
glm::size3_t(width,1,1),ghoul::opengl::Texture::Format::RGBA,
|
||||
GL_RGBA, GL_FLOAT,filtermode, wrappingmode);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -1,323 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/volume/rendering/renderablevolumegl.h>
|
||||
|
||||
#include <openspace/abuffer/abuffer.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <modules/kameleon/include/kameleonwrapper.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderableVolumeGL";
|
||||
const std::string KeyVolume = "Volume";
|
||||
const std::string KeyHints = "Hints";
|
||||
const std::string KeyTransferFunction = "TransferFunction";
|
||||
const std::string KeySampler = "Sampler";
|
||||
const std::string KeyBoxScaling = "BoxScaling";
|
||||
const std::string KeyVolumeName = "VolumeName";
|
||||
const std::string KeyTransferFunctionName = "TransferFunctionName";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary)
|
||||
: RenderableVolume(dictionary)
|
||||
, _transferFunctionName("")
|
||||
, _volumeName("")
|
||||
, _volume(nullptr)
|
||||
, _transferFunction(nullptr)
|
||||
, _boxArray(0)
|
||||
, _vertexPositionBuffer(0)
|
||||
, _boxProgram(nullptr)
|
||||
, _boxScaling(1.0, 1.0, 1.0)
|
||||
, _w(0.f)
|
||||
, _updateTransferfunction(false)
|
||||
, _id(-1)
|
||||
{
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(SceneGraphNode::KeyName, name);
|
||||
assert(success);
|
||||
|
||||
_filename = "";
|
||||
success = dictionary.getValue(KeyVolume, _filename);
|
||||
if (!success) {
|
||||
LERROR("Node '" << name << "' did not contain a valid '" << KeyVolume << "'");
|
||||
return;
|
||||
}
|
||||
_filename = absPath(_filename);
|
||||
if (_filename == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
LDEBUG("Volume Filename: " << _filename);
|
||||
|
||||
dictionary.getValue(KeyHints, _hintsDictionary);
|
||||
|
||||
_transferFunction = nullptr;
|
||||
_transferFunctionFile = nullptr;
|
||||
_transferFunctionPath = "";
|
||||
success = dictionary.getValue(KeyTransferFunction, _transferFunctionPath);
|
||||
if (!success) {
|
||||
LERROR("Node '" << name << "' did not contain a valid '" <<
|
||||
KeyTransferFunction << "'");
|
||||
return;
|
||||
}
|
||||
_transferFunctionPath = absPath(_transferFunctionPath);
|
||||
_transferFunctionFile = new ghoul::filesystem::File(_transferFunctionPath, true);
|
||||
|
||||
_samplerFilename = "";
|
||||
success = dictionary.getValue(KeySampler, _samplerFilename);
|
||||
if (!success) {
|
||||
LERROR("Node '" << name << "' did not contain a valid '" << KeySampler << "'");
|
||||
return;
|
||||
}
|
||||
_samplerFilename = absPath(_samplerFilename);
|
||||
|
||||
KameleonWrapper kw(_filename);
|
||||
auto t = kw.getGridUnits();
|
||||
if (dictionary.hasKey(KeyBoxScaling)) {
|
||||
glm::vec4 scalingVec4(_boxScaling, _w);
|
||||
success = dictionary.getValue(KeyBoxScaling, scalingVec4);
|
||||
if (success) {
|
||||
_boxScaling = scalingVec4.xyz();
|
||||
_w = scalingVec4.w;
|
||||
}
|
||||
else {
|
||||
success = dictionary.getValue(KeyBoxScaling, _boxScaling);
|
||||
if (!success) {
|
||||
LERROR("Node '" << name << "' did not contain a valid '" <<
|
||||
KeyBoxScaling << "'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Automatic scale detection from model
|
||||
_boxScaling = kw.getModelScale();
|
||||
if (std::get<0>(t) == "R" && std::get<1>(t) == "R" && std::get<2>(t) == "R") {
|
||||
// Earth radius
|
||||
_boxScaling.x *= 6.371f;
|
||||
_boxScaling.y *= 6.371f;
|
||||
_boxScaling.z *= 6.371f;
|
||||
_w = 6;
|
||||
}
|
||||
else if (std::get<0>(t) == "m" && std::get<1>(t) == "radian" && std::get<2>(t) == "radian") {
|
||||
// For spherical coordinate systems the radius is in meter
|
||||
_w = -log10(1.0f/kw.getGridMax().x);
|
||||
}
|
||||
else {
|
||||
LWARNING("Unsupported units for automatic scale detection");
|
||||
}
|
||||
}
|
||||
|
||||
_pscOffset = kw.getModelBarycenterOffset();
|
||||
if (std::get<0>(t) == "R" && std::get<1>(t) == "R" && std::get<2>(t) == "R") {
|
||||
// Earth radius
|
||||
_pscOffset[0] *= 6.371f;
|
||||
_pscOffset[1] *= 6.371f;
|
||||
_pscOffset[2] *= 6.371f;
|
||||
_pscOffset[3] = 6;
|
||||
}
|
||||
else {
|
||||
// Current spherical models no need for offset
|
||||
}
|
||||
|
||||
dictionary.getValue(KeyVolumeName, _volumeName);
|
||||
dictionary.getValue(KeyTransferFunctionName, _transferFunctionName);
|
||||
|
||||
setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling)*pow(10,_w)));
|
||||
}
|
||||
|
||||
RenderableVolumeGL::~RenderableVolumeGL() {
|
||||
}
|
||||
|
||||
bool RenderableVolumeGL::isReady() const {
|
||||
bool ready = true;
|
||||
ready &= (_boxProgram != nullptr);
|
||||
ready &= (_volume != nullptr);
|
||||
ready &= (_transferFunction != nullptr);
|
||||
return ready;
|
||||
}
|
||||
|
||||
bool RenderableVolumeGL::initialize() {
|
||||
// @TODO fix volume and transferfunction names --jonasstrandstedt
|
||||
if(_filename != "") {
|
||||
_volume = loadVolume(_filename, _hintsDictionary);
|
||||
_volume->uploadTexture();
|
||||
OsEng.renderEngine().aBuffer()->addVolume(_volumeName, _volume);
|
||||
}
|
||||
|
||||
if(_transferFunctionPath != "") {
|
||||
_transferFunction = loadTransferFunction(_transferFunctionPath);
|
||||
_transferFunction->uploadTexture();
|
||||
OsEng.renderEngine().aBuffer()->addTransferFunction(_transferFunctionName, _transferFunction);
|
||||
|
||||
auto textureCallback = [this](const ghoul::filesystem::File& file) {
|
||||
_updateTransferfunction = true;
|
||||
};
|
||||
_transferFunctionFile->setCallback(textureCallback);
|
||||
}
|
||||
|
||||
// add the sampler and get the ID
|
||||
_id = OsEng.renderEngine().aBuffer()->addSamplerfile(_samplerFilename);
|
||||
|
||||
OsEng.configurationManager().getValue("RaycastProgram", _boxProgram);
|
||||
|
||||
// ============================
|
||||
// GEOMETRY (box)
|
||||
// ============================
|
||||
const GLfloat size = 0.5f;
|
||||
const GLfloat vertex_data[] = {
|
||||
// x, y, z, s,
|
||||
-size, -size, size, _w,
|
||||
size, size, size, _w,
|
||||
-size, size, size, _w,
|
||||
-size, -size, size, _w,
|
||||
size, -size, size, _w,
|
||||
size, size, size, _w,
|
||||
|
||||
-size, -size, -size, _w,
|
||||
size, size, -size, _w,
|
||||
-size, size, -size, _w,
|
||||
-size, -size, -size, _w,
|
||||
size, -size, -size, _w,
|
||||
size, size, -size, _w,
|
||||
|
||||
size, -size, -size, _w,
|
||||
size, size, size, _w,
|
||||
size, -size, size, _w,
|
||||
size, -size, -size, _w,
|
||||
size, size, -size, _w,
|
||||
size, size, size, _w,
|
||||
|
||||
-size, -size, -size, _w,
|
||||
-size, size, size, _w,
|
||||
-size, -size, size, _w,
|
||||
-size, -size, -size, _w,
|
||||
-size, size, -size, _w,
|
||||
-size, size, size, _w,
|
||||
|
||||
-size, size, -size, _w,
|
||||
size, size, size, _w,
|
||||
-size, size, size, _w,
|
||||
-size, size, -size, _w,
|
||||
size, size, -size, _w,
|
||||
size, size, size, _w,
|
||||
|
||||
-size, -size, -size, _w,
|
||||
size, -size, size, _w,
|
||||
-size, -size, size, _w,
|
||||
-size, -size, -size, _w,
|
||||
size, -size, -size, _w,
|
||||
size, -size, size, _w,
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &_boxArray); // generate array
|
||||
glBindVertexArray(_boxArray); // bind array
|
||||
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
return isReady();
|
||||
}
|
||||
|
||||
bool RenderableVolumeGL::deinitialize() {
|
||||
if (_volume)
|
||||
delete _volume;
|
||||
if (_transferFunctionFile)
|
||||
delete _transferFunctionFile;
|
||||
if (_transferFunction)
|
||||
delete _transferFunction;
|
||||
_volume = nullptr;
|
||||
_transferFunctionFile = nullptr;
|
||||
_transferFunction = nullptr;
|
||||
|
||||
glDeleteVertexArrays(1, &_boxArray);
|
||||
glGenBuffers(1, &_vertexPositionBuffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableVolumeGL::render(const RenderData& data) {
|
||||
if(_updateTransferfunction) {
|
||||
_updateTransferfunction = false;
|
||||
ghoul::opengl::Texture* transferFunction = loadTransferFunction(_transferFunctionPath);
|
||||
if(transferFunction) {
|
||||
const void* data = transferFunction->pixelData();
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, *transferFunction);
|
||||
_transferFunction->bind();
|
||||
glTexImage1D( GL_TEXTURE_1D, 0, _transferFunction->internalFormat(),
|
||||
static_cast<GLsizei>(_transferFunction->width()),0, _transferFunction->format(),
|
||||
_transferFunction->dataType(), data);
|
||||
delete transferFunction;
|
||||
LDEBUG("Updated transferfunction!");
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 transform = glm::mat4(1.0);
|
||||
transform = glm::scale(transform, _boxScaling);
|
||||
|
||||
// fetch data
|
||||
psc currentPosition = data.position;
|
||||
currentPosition += _pscOffset; // Move box to model barycenter
|
||||
|
||||
_boxProgram->activate();
|
||||
_boxProgram->setUniform("volumeType", _id);
|
||||
_boxProgram->setUniform("modelViewProjection", data.camera.viewProjectionMatrix());
|
||||
_boxProgram->setUniform("modelTransform", transform);
|
||||
setPscUniforms(_boxProgram, &data.camera, currentPosition);
|
||||
|
||||
// make sure GL_CULL_FACE is enabled (it should be)
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Draw backface
|
||||
glCullFace(GL_FRONT);
|
||||
glBindVertexArray(_boxArray);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6*6);
|
||||
|
||||
// Draw frontface (now the normal cull face is is set)
|
||||
glCullFace(GL_BACK);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6*6);
|
||||
|
||||
_boxProgram->deactivate();
|
||||
}
|
||||
|
||||
void RenderableVolumeGL::update(const UpdateData& data) {
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
59
modules/volume/rendering/volumeclipplane.cpp
Normal file
59
modules/volume/rendering/volumeclipplane.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/volume/rendering/volumeclipplanes.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
|
||||
namespace openspace {
|
||||
|
||||
VolumeClipPlane::VolumeClipPlane(const ghoul::Dictionary& dictionary)
|
||||
: _normal("normal", "Normal", glm::vec3(1.0, 0.0, 0.0), glm::vec3(-1.0), glm::vec3(1.0))
|
||||
, _offsets("offsets", "Offsets", glm::vec2(-2.0, 0.0), glm::vec2(-2.0, 0.0), glm::vec2(2.0, 1.0))
|
||||
{
|
||||
glm::vec3 normal;
|
||||
glm::vec2 offsets;
|
||||
dictionary.getValue("Normal", normal);
|
||||
dictionary.getValue("Offsets", offsets);
|
||||
|
||||
_normal = normal;
|
||||
_offsets = offsets;
|
||||
}
|
||||
|
||||
void VolumeClipPlane::initialize()
|
||||
{
|
||||
addProperty(_normal);
|
||||
addProperty(_offsets);
|
||||
}
|
||||
|
||||
glm::vec3 VolumeClipPlane::normal() {
|
||||
return glm::normalize(_normal.value());
|
||||
}
|
||||
|
||||
glm::vec2 VolumeClipPlane::offsets() {
|
||||
return _offsets;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -22,42 +22,32 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___RENDERABLEVOLUME___H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___RENDERABLEVOLUME___H__
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANE___H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANE___H__
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/io/volume/rawvolumereader.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
|
||||
// Forward declare to minimize dependencies
|
||||
namespace ghoul {
|
||||
namespace filesystem {
|
||||
class File;
|
||||
}
|
||||
namespace opengl {
|
||||
class Texture;
|
||||
}
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableVolume: public Renderable {
|
||||
class VolumeClipPlane : public properties::PropertyOwner {
|
||||
public:
|
||||
// constructors & destructor
|
||||
RenderableVolume(const ghoul::Dictionary& dictionary);
|
||||
~RenderableVolume();
|
||||
|
||||
protected:
|
||||
ghoul::opengl::Texture* loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary);
|
||||
glm::vec3 getVolumeOffset(const std::string& filepath, const ghoul::Dictionary& hintsDictionary);
|
||||
ghoul::RawVolumeReader::ReadHints readHints(const ghoul::Dictionary& dictionary);
|
||||
ghoul::opengl::Texture* loadTransferFunction(const std::string& filepath);
|
||||
|
||||
VolumeClipPlane(const ghoul::Dictionary& dictionary);
|
||||
virtual ~VolumeClipPlane() = default;
|
||||
virtual void initialize();
|
||||
glm::vec3 normal();
|
||||
glm::vec2 offsets();
|
||||
private:
|
||||
properties::Vec3Property _normal;
|
||||
properties::Vec2Property _offsets;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___RENDERABLEVOLUME___H__
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANE___H__
|
||||
72
modules/volume/rendering/volumeclipplanes.cpp
Normal file
72
modules/volume/rendering/volumeclipplanes.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/volume/rendering/volumeclipplanes.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
|
||||
namespace openspace {
|
||||
|
||||
VolumeClipPlanes::VolumeClipPlanes(const ghoul::Dictionary& dictionary)
|
||||
: _nClipPlanes("nClipPlanes", "Number of clip planes", 0, 0, 10)
|
||||
{
|
||||
std::vector<std::string> keys = dictionary.keys();
|
||||
for (const std::string& key : keys) {
|
||||
ghoul::Dictionary cutPlaneDictionary;
|
||||
dictionary.getValue(key, cutPlaneDictionary);
|
||||
auto clipPlane = std::make_shared<VolumeClipPlane>(cutPlaneDictionary);
|
||||
clipPlane->setName(key);
|
||||
_clipPlanes.push_back(clipPlane);
|
||||
}
|
||||
_nClipPlanes = keys.size();
|
||||
}
|
||||
|
||||
void VolumeClipPlanes::initialize() {
|
||||
addProperty(_nClipPlanes);
|
||||
for (const auto& clipPlane : _clipPlanes) {
|
||||
addPropertySubOwner(clipPlane.get());
|
||||
clipPlane->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeClipPlanes::deinitialize() {}
|
||||
|
||||
std::vector<glm::vec3> VolumeClipPlanes::normals() {
|
||||
std::vector<glm::vec3> normals;
|
||||
for (const auto& clipPlane : _clipPlanes) {
|
||||
normals.push_back(clipPlane->normal());
|
||||
}
|
||||
return normals;
|
||||
}
|
||||
|
||||
std::vector<glm::vec2> VolumeClipPlanes::offsets() {
|
||||
std::vector<glm::vec2> offsets;
|
||||
for (const auto& clipPlane : _clipPlanes) {
|
||||
offsets.push_back(clipPlane->offsets());
|
||||
}
|
||||
return offsets;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
57
modules/volume/rendering/volumeclipplanes.h
Normal file
57
modules/volume/rendering/volumeclipplanes.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANES___H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANES___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/properties/scalarproperty.h>
|
||||
|
||||
#include <modules/volume/rendering/volumeclipplane.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace ghoul {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class VolumeClipPlanes : public properties::PropertyOwner {
|
||||
public:
|
||||
VolumeClipPlanes(const ghoul::Dictionary& dictionary);
|
||||
virtual ~VolumeClipPlanes() = default;
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
std::vector<glm::vec3> normals();
|
||||
std::vector<glm::vec2> offsets();
|
||||
private:
|
||||
properties::IntProperty _nClipPlanes;
|
||||
std::vector<std::shared_ptr<VolumeClipPlane>> _clipPlanes;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANES___H__
|
||||
@@ -29,7 +29,7 @@ namespace openspace {
|
||||
template <typename VoxelType>
|
||||
VoxelType TextureSliceVolumeReader<VoxelType>::get(const glm::ivec3& coordinates) const {
|
||||
ghoul::opengl::Texture& slice = getSlice(coordinates.z);
|
||||
return slice.texel<VoxelType>(glm::ivec2(coordinates));
|
||||
return slice.texel<VoxelType>(glm::uvec2(coordinates.x, coordinates.y));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@@ -52,7 +52,8 @@ void TextureSliceVolumeReader<VoxelType>::initialize() {
|
||||
std::shared_ptr<ghoul::opengl::Texture> firstSlice =
|
||||
ghoul::io::TextureReader::ref().loadTexture(_paths[0]);
|
||||
|
||||
_sliceDimensions = firstSlice->dimensions();
|
||||
glm::uvec3 dimensions = firstSlice->dimensions();
|
||||
_sliceDimensions = glm::uvec2(dimensions.x, dimensions.y);
|
||||
_initialized = true;
|
||||
_cache.set(0, firstSlice);
|
||||
}
|
||||
@@ -72,7 +73,8 @@ ghoul::opengl::Texture& TextureSliceVolumeReader<VoxelType>::getSlice(int sliceI
|
||||
std::shared_ptr<ghoul::opengl::Texture> texture =
|
||||
ghoul::io::TextureReader::ref().loadTexture(_paths[sliceIndex]);
|
||||
|
||||
glm::ivec2 dims = texture->dimensions();
|
||||
glm::uvec3 dimensions = texture->dimensions();
|
||||
glm::ivec2 dims = glm::uvec2(dimensions.x, dimensions.y);
|
||||
ghoul_assert(dims == _sliceDimensions, "Slice dimensions do not agree.");
|
||||
_cache.set(sliceIndex, std::move(texture));
|
||||
}
|
||||
|
||||
33
modules/volume/volumegridtype.h
Normal file
33
modules/volume/volumegridtype.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___VOLUMEGRIDTYPE_H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___VOLUMEGRIDTYPE_H__
|
||||
|
||||
enum class VolumeGridType : int {
|
||||
Cartesian = 0,
|
||||
Spherical = 1
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___VOLUMEGRIDTYPE_H__
|
||||
@@ -29,8 +29,6 @@
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
#include <modules/volume/rendering/renderablevolumegl.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
VolumeModule::VolumeModule()
|
||||
@@ -38,8 +36,7 @@ VolumeModule::VolumeModule()
|
||||
{}
|
||||
|
||||
void VolumeModule::internalInitialize() {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
namespace openspace {
|
||||
namespace volumeutils {
|
||||
|
||||
size_t coordsToIndex(const glm::vec3& coords, const glm::ivec3& dims) {
|
||||
size_t coordsToIndex(const glm::uvec3& coords, const glm::uvec3& dims) {
|
||||
size_t w = dims.x;
|
||||
size_t h = dims.y;
|
||||
// size_t d = dims.z;
|
||||
@@ -39,7 +39,7 @@ size_t coordsToIndex(const glm::vec3& coords, const glm::ivec3& dims) {
|
||||
return coords.z * (h * w) + coords.y * w + coords.x;
|
||||
}
|
||||
|
||||
glm::vec3 indexToCoords(size_t index, const glm::ivec3& dims) {
|
||||
glm::uvec3 indexToCoords(size_t index, const glm::uvec3& dims) {
|
||||
size_t w = dims.x;
|
||||
size_t h = dims.y;
|
||||
size_t d = dims.z;
|
||||
@@ -48,7 +48,7 @@ glm::vec3 indexToCoords(size_t index, const glm::ivec3& dims) {
|
||||
size_t y = (index / w) % h;
|
||||
size_t z = index / w / h;
|
||||
|
||||
return glm::ivec3(x, y, z);
|
||||
return glm::uvec3(x, y, z);
|
||||
}
|
||||
|
||||
} // namespace volumeutils
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
namespace openspace {
|
||||
namespace volumeutils {
|
||||
|
||||
size_t coordsToIndex(const glm::vec3& coords, const glm::ivec3& dimensions);
|
||||
glm::vec3 indexToCoords(size_t index, const glm::ivec3& dimensions);
|
||||
size_t coordsToIndex(const glm::uvec3& coords, const glm::uvec3& dimensions);
|
||||
glm::uvec3 indexToCoords(size_t index, const glm::uvec3& dimensions);
|
||||
|
||||
} // namespace volumeutils
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ return {
|
||||
|
||||
-- Sets the scene that is to be loaded by OpenSpace. A scene file is a description
|
||||
-- of all entities that will be visible during an instance of OpenSpace
|
||||
Scene = "${SCENE}/default.scene",
|
||||
|
||||
Scene = "${SCENE}/volumes.scene",
|
||||
Task = "${TASKS}/default.task",
|
||||
-- Scene = "${SCENE}/globebrowsing.scene",
|
||||
-- Scene = "${SCENE}/rosetta.scene",
|
||||
-- Scene = "${SCENE}/dawn.scene",
|
||||
@@ -37,6 +37,7 @@ return {
|
||||
SHADERS = "${BASE_PATH}/shaders",
|
||||
OPENSPACE_DATA = "${BASE_PATH}/data",
|
||||
SCENE = "${OPENSPACE_DATA}/scene",
|
||||
TASKS = "${OPENSPACE_DATA}/tasks",
|
||||
SPICE = "${OPENSPACE_DATA}/spice",
|
||||
MODULES = "${BASE_PATH}/modules",
|
||||
TESTDIR = "${BASE_PATH}/tests",
|
||||
|
||||
@@ -80,47 +80,6 @@ vec4 z_normalization(vec4 v_in) {
|
||||
return v_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the length of a vector.
|
||||
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
|
||||
*/
|
||||
float safeLength(vec4 v) {
|
||||
float m = max(max(max(abs(v.x), abs(v.y)), abs(v.z)), abs(v.w));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float safeLength(vec3 v) {
|
||||
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float safeLength(vec2 v) {
|
||||
float m = max(abs(v.x), abs(v.y));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a vector
|
||||
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
|
||||
*/
|
||||
vec3 safeNormalize(vec3 v) {
|
||||
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
|
||||
return normalize(v / m);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a psc vector to a float
|
||||
*/
|
||||
@@ -135,27 +94,4 @@ float pscToLinear(vec2 position) {
|
||||
return pow(k, position.y) * position.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive floating point distance [0, 10^27]
|
||||
* (size of observable universe)
|
||||
* to a float in the range [-1, 1], suitable for depth buffer storage.
|
||||
* Note: This needs to be a monotonic function, so that the value can
|
||||
* still be used for depth comparison.
|
||||
*/
|
||||
float normalizeFloat(float inpt) {
|
||||
if (inpt > 1.0) {
|
||||
return inpt / pow(10, 27);
|
||||
} else {
|
||||
return inpt - 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
float denormalizeFloat(float inpt) {
|
||||
if (inpt < 0.0) {
|
||||
return inpt + 1.0;
|
||||
} else {
|
||||
return inpt * pow(10, 27);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#ifndef POWERSCALING_FS_H_HGLSL
|
||||
#define POWERSCALING_FS_H_HGLSL
|
||||
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
// Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD!
|
||||
|
||||
#include "powerScalingMath.hglsl"
|
||||
|
||||
@@ -80,7 +80,4 @@ void storeFragments(uint nFrags) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <#{fragmentPath}>
|
||||
#include "abufferfragment.glsl"
|
||||
#include "abufferresources.glsl"
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
out vec4 _out_color_;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "abufferfragment.glsl"
|
||||
#include "abufferresources.glsl"
|
||||
#include "fragment.glsl"
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
#include "floatoperations.glsl"
|
||||
#include "blending.glsl"
|
||||
#include "rand.glsl"
|
||||
|
||||
|
||||
93
shaders/floatoperations.glsl
Normal file
93
shaders/floatoperations.glsl
Normal file
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef _FLOATOPERATIONS_GLSL_
|
||||
#define _FLOATOPERATIONS_GLSL_
|
||||
|
||||
|
||||
/**
|
||||
* Convert a positive floating point distance [0, 10^27]
|
||||
* (size of observable universe)
|
||||
* to a float in the range [-1, 1], suitable for depth buffer storage.
|
||||
* Note: This needs to be a monotonic function, so that the value can
|
||||
* still be used for depth comparison.
|
||||
*/
|
||||
float normalizeFloat(float inpt) {
|
||||
if (inpt > 1.0) {
|
||||
return inpt / pow(10, 27);
|
||||
} else {
|
||||
return inpt - 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
float denormalizeFloat(float inpt) {
|
||||
if (inpt < 0.0) {
|
||||
return inpt + 1.0;
|
||||
} else {
|
||||
return inpt * pow(10, 27);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the length of a vector.
|
||||
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
|
||||
*/
|
||||
float safeLength(vec4 v) {
|
||||
float m = max(max(max(abs(v.x), abs(v.y)), abs(v.z)), abs(v.w));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float safeLength(vec3 v) {
|
||||
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float safeLength(vec2 v) {
|
||||
float m = max(abs(v.x), abs(v.y));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a vector
|
||||
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
|
||||
*/
|
||||
vec3 safeNormalize(vec3 v) {
|
||||
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
|
||||
return normalize(v / m);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -25,7 +25,7 @@
|
||||
#version __CONTEXT__
|
||||
|
||||
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
#include "floatoperations.glsl"
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
out vec4 _out_color_;
|
||||
|
||||
29
shaders/framebuffer/inside.glsl
Normal file
29
shaders/framebuffer/inside.glsl
Normal file
@@ -0,0 +1,29 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
void getEntry(inout vec3 entryPos, inout float entryDepth) {
|
||||
entryPos = cameraPosInRaycaster;
|
||||
entryDepth = 0;
|
||||
}
|
||||
32
shaders/framebuffer/outside.glsl
Normal file
32
shaders/framebuffer/outside.glsl
Normal file
@@ -0,0 +1,32 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
void getEntry(inout vec3 entryPos, inout float entryDepth) {
|
||||
// fetch entry point from rendered fragment
|
||||
Fragment f = getFragment();
|
||||
entryPos = f.color.xyz;
|
||||
entryDepth = f.depth;
|
||||
}
|
||||
@@ -34,9 +34,7 @@ uniform vec2 windowSize;
|
||||
|
||||
#include "blending.glsl"
|
||||
#include "rand.glsl"
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
#for id, helperPath in helperPaths
|
||||
#include <#{helperPath}>
|
||||
@@ -46,19 +44,17 @@ uniform vec2 windowSize;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
|
||||
#define ALPHA_LIMIT 0.99
|
||||
#define RAYCAST_MAX_STEPS 1000
|
||||
#define MAX_AA_SAMPLES 8
|
||||
|
||||
uniform int nAaSamples;
|
||||
|
||||
#include <#{getEntryPath}>
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 texCoord = vec2(gl_FragCoord.xy / windowSize);
|
||||
|
||||
|
||||
vec4 exitColorTexture = texture(exitColorTexture, texCoord);
|
||||
if (exitColorTexture.a < 1.0) {
|
||||
discard;
|
||||
@@ -68,22 +64,11 @@ void main() {
|
||||
vec3 exitPos = exitColorTexture.rgb;
|
||||
float exitDepth = denormalizeFloat(texture(exitDepthTexture, texCoord).x);
|
||||
|
||||
|
||||
|
||||
float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0
|
||||
|
||||
vec3 entryPos;
|
||||
float entryDepth;
|
||||
|
||||
if (insideRaycaster) {
|
||||
entryPos = cameraPosInRaycaster;
|
||||
entryDepth = 0;
|
||||
} else {
|
||||
// fetch entry point from rendered fragment
|
||||
Fragment f = getFragment();
|
||||
entryPos = f.color.xyz;
|
||||
entryDepth = f.depth;
|
||||
}
|
||||
getEntry(entryPos, entryDepth);
|
||||
|
||||
vec3 position = entryPos;
|
||||
vec3 diff = exitPos - entryPos;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
#include "floatoperations.glsl"
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
out vec4 _out_color_;
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
|
||||
layout (location = 0) out vec4 finalColor;
|
||||
uniform float blackoutFactor;
|
||||
uniform int nAaSamples;
|
||||
|
||||
@@ -149,6 +149,8 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/util/syncbuffer.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/syncdata.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/histogram.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/task.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/taskloader.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/time.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/timemanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/time_lua.inl
|
||||
@@ -288,6 +290,8 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/spicemanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/syncbuffer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/syncdata.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/task.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/taskloader.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/time.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/timemanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/timerange.h
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
@@ -57,6 +59,7 @@ const string ConfigurationManager::KeyKeyboardShortcuts = "KeyboardShortcuts";
|
||||
const string ConfigurationManager::KeyDocumentation = "Documentation";
|
||||
const string ConfigurationManager::KeyFactoryDocumentation = "FactoryDocumentation";
|
||||
const string ConfigurationManager::KeyConfigScene = "Scene";
|
||||
const string ConfigurationManager::KeyConfigTask = "Task";
|
||||
|
||||
const string ConfigurationManager::KeyLogging = "Logging";
|
||||
const string ConfigurationManager::PartLogLevel = "LogLevel";
|
||||
|
||||
@@ -52,6 +52,14 @@ documentation::Documentation ConfigurationManager::Documentation() {
|
||||
"the Scene documentation.",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyConfigTask,
|
||||
new StringAnnotationVerifier(
|
||||
"A valid task file as described in the Task documentation"),
|
||||
"The root task to be performed when launching the task runner "
|
||||
"applicaition.",
|
||||
Optional::Yes
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyPaths,
|
||||
new StringListVerifier,
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/translation.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
@@ -151,6 +152,10 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
|
||||
std::make_unique<ghoul::TemplateFactory<Scale>>(),
|
||||
"Scale"
|
||||
);
|
||||
FactoryManager::ref().addFactory(
|
||||
std::make_unique<ghoul::TemplateFactory<Task>>(),
|
||||
"Task"
|
||||
);
|
||||
|
||||
SpiceManager::initialize();
|
||||
Time::initialize();
|
||||
|
||||
@@ -268,9 +268,6 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
|
||||
RenderData data{ *_camera, psc(), doPerformanceMeasurements, renderBinMask };
|
||||
RendererTasks tasks;
|
||||
_scene->render(data, tasks);
|
||||
|
||||
_rendererTasks = std::make_unique<RendererTasks>(tasks);
|
||||
_renderData = std::make_unique<RenderData>(data);
|
||||
_blackoutFactor = blackoutFactor;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
|
||||
@@ -314,10 +311,21 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
|
||||
|
||||
// END TEMPORARY GAMMA CORRECTION.
|
||||
|
||||
preRaycast(*_resolveProgram);
|
||||
_resolveProgram->setUniform("mainColorTexture", _mainColorTextureUnit->unitNumber());
|
||||
_resolveProgram->setUniform("mainDepthTexture", _mainDepthTextureUnit->unitNumber());
|
||||
_resolveProgram->setUniform("blackoutFactor", _blackoutFactor);
|
||||
_resolveProgram->setUniform("nAaSamples", _nAaSamples);
|
||||
|
||||
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
|
||||
preRaycast(raycasterTask);
|
||||
}
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
postRaycast(*_resolveProgram);
|
||||
|
||||
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
|
||||
postRaycast(raycasterTask);
|
||||
}
|
||||
|
||||
_resolveProgram->deactivate();
|
||||
|
||||
@@ -326,32 +334,27 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
|
||||
}
|
||||
|
||||
|
||||
void ABufferRenderer::preRaycast(ghoul::opengl::ProgramObject& program) {
|
||||
void ABufferRenderer::preRaycast(const RaycasterTask& raycasterTask) {
|
||||
VolumeRaycaster& raycaster = *raycasterTask.raycaster;
|
||||
const RaycastData& raycastData = _raycastData[&raycaster];
|
||||
const RenderData& renderData = raycasterTask.renderData;
|
||||
|
||||
program.setUniform("mainColorTexture", _mainColorTextureUnit->unitNumber());
|
||||
program.setUniform("mainDepthTexture", _mainDepthTextureUnit->unitNumber());
|
||||
|
||||
for (const auto& raycastData : _raycastData) {
|
||||
raycastData.first->preRaycast(raycastData.second, program);
|
||||
raycaster.preRaycast(raycastData, *_resolveProgram);
|
||||
|
||||
glm::vec3 localCameraPosition;
|
||||
bool cameraIsInside = raycastData.first->cameraIsInside(*_renderData, localCameraPosition);
|
||||
int uniformIndex = raycastData.second.id + 1; // uniforms are indexed from 1 (not from 0)
|
||||
program.setUniform("insideRaycaster" + std::to_string(uniformIndex), cameraIsInside);
|
||||
if (cameraIsInside) {
|
||||
program.setUniform("cameraPosInRaycaster" + std::to_string(uniformIndex), localCameraPosition);
|
||||
}
|
||||
glm::vec3 localCameraPosition;
|
||||
bool cameraIsInside = raycaster.cameraIsInside(renderData, localCameraPosition);
|
||||
int uniformIndex = raycastData.id + 1; // uniforms are indexed from 1 (not from 0)
|
||||
_resolveProgram->setUniform("insideRaycaster" + std::to_string(uniformIndex), cameraIsInside);
|
||||
if (cameraIsInside) {
|
||||
_resolveProgram->setUniform("cameraPosInRaycaster" + std::to_string(uniformIndex), localCameraPosition);
|
||||
}
|
||||
|
||||
// 3b: Set "global" uniforms, and start the resolve pass.
|
||||
program.setUniform("blackoutFactor", _blackoutFactor);
|
||||
program.setUniform("nAaSamples", _nAaSamples);
|
||||
}
|
||||
|
||||
void ABufferRenderer::postRaycast(ghoul::opengl::ProgramObject& program) {
|
||||
for (const auto& raycastData : _raycastData) {
|
||||
raycastData.first->postRaycast(raycastData.second, program);
|
||||
}
|
||||
void ABufferRenderer::postRaycast(const RaycasterTask& raycasterTask) {
|
||||
VolumeRaycaster& raycaster = *raycasterTask.raycaster;
|
||||
const RaycastData& raycastData = _raycastData[&raycaster];
|
||||
|
||||
raycaster.postRaycast(raycastData, *_resolveProgram);
|
||||
}
|
||||
|
||||
void ABufferRenderer::setScene(Scene* scene) {
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace {
|
||||
const std::string _loggerCat = "FramebufferRenderer";
|
||||
const std::string ExitFragmentShaderPath = "${SHADERS}/framebuffer/exitframebuffer.frag";
|
||||
const std::string RaycastFragmentShaderPath = "${SHADERS}/framebuffer/raycastframebuffer.frag";
|
||||
const std::string GetEntryInsidePath = "${SHADERS}/framebuffer/inside.glsl";
|
||||
const std::string GetEntryOutsidePath = "${SHADERS}/framebuffer/outside.glsl";
|
||||
const std::string RenderFragmentShaderPath = "${SHADERS}/framebuffer/renderframebuffer.frag";
|
||||
}
|
||||
|
||||
@@ -286,20 +288,28 @@ void FramebufferRenderer::updateRaycastData() {
|
||||
|
||||
try {
|
||||
_exitPrograms[raycaster] = ghoul::opengl::ProgramObject::Build("Volume " + std::to_string(data.id) + " exit", vsPath, ExitFragmentShaderPath, dict);
|
||||
}
|
||||
catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
try {
|
||||
_raycastPrograms[raycaster] = ghoul::opengl::ProgramObject::Build("Volume " + std::to_string(data.id) + " raycast", vsPath, RaycastFragmentShaderPath, dict);
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
try {
|
||||
ghoul::Dictionary outsideDict = dict;
|
||||
outsideDict.setValue("getEntryPath", GetEntryOutsidePath);
|
||||
_raycastPrograms[raycaster] = ghoul::opengl::ProgramObject::Build(
|
||||
"Volume " + std::to_string(data.id) + " raycast",
|
||||
vsPath,
|
||||
RaycastFragmentShaderPath,
|
||||
outsideDict);
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
try {
|
||||
ghoul::Dictionary insideDict = dict;
|
||||
insideDict.setValue("getEntryPath", GetEntryInsidePath);
|
||||
_insideRaycastPrograms[raycaster] = ghoul::opengl::ProgramObject::Build(
|
||||
"Volume " + std::to_string(data.id) + " inside raycast",
|
||||
"${SHADERS}/framebuffer/resolveframebuffer.vert",
|
||||
RaycastFragmentShaderPath, dict);
|
||||
RaycastFragmentShaderPath,
|
||||
insideDict);
|
||||
}
|
||||
catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
@@ -359,26 +369,22 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
|
||||
|
||||
|
||||
ghoul::opengl::ProgramObject* insideRaycastProgram = _raycastPrograms[raycaster].get();
|
||||
|
||||
glm::vec3 cameraPosition;
|
||||
bool cameraIsInside = raycaster->cameraIsInside(raycasterTask.renderData, cameraPosition);
|
||||
ghoul::opengl::ProgramObject* raycastProgram = nullptr;
|
||||
|
||||
if (cameraIsInside) {
|
||||
raycastProgram = _insideRaycastPrograms[raycaster].get();
|
||||
if (raycastProgram = _insideRaycastPrograms[raycaster].get()) {
|
||||
raycastProgram->activate();
|
||||
raycastProgram->setUniform("cameraPosInRaycaster", cameraPosition);
|
||||
}
|
||||
} else {
|
||||
raycastProgram = _raycastPrograms[raycaster].get();
|
||||
if (raycastProgram = _raycastPrograms[raycaster].get()) {
|
||||
raycastProgram->activate();
|
||||
}
|
||||
}
|
||||
|
||||
if (raycastProgram) {
|
||||
raycastProgram->activate();
|
||||
|
||||
raycastProgram->setUniform("insideRaycaster", cameraIsInside);
|
||||
raycastProgram->setUniform("cameraPosInRaycaster", cameraPosition);
|
||||
|
||||
raycaster->preRaycast(_raycastData[raycaster], *raycastProgram);
|
||||
|
||||
ghoul::opengl::TextureUnit exitColorTextureUnit;
|
||||
|
||||
@@ -42,7 +42,7 @@ ProgressBar::~ProgressBar() {
|
||||
}
|
||||
|
||||
void ProgressBar::print(int current) {
|
||||
float progress = static_cast<float>(current) / static_cast<float>(_end - 1);
|
||||
float progress = static_cast<float>(current) / static_cast<float>(_end);
|
||||
int iprogress = static_cast<int>(progress*100.0f);
|
||||
if (iprogress != _previous) {
|
||||
int pos = static_cast<int>(static_cast<float>(_width)* progress);
|
||||
|
||||
70
src/util/task.cpp
Normal file
70
src/util/task.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/task.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "Task";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation Task::documentation() {
|
||||
using namespace openspace::documentation;
|
||||
return{
|
||||
"Renderable",
|
||||
"renderable",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringAnnotationVerifier("A valid Task created by a factory"),
|
||||
"This key specifies the type of Task that gets created. It has to be one"
|
||||
"of the valid Tasks that are available for creation (see the "
|
||||
"FactoryDocumentation for a list of possible Tasks), which depends on "
|
||||
"the configration of the application",
|
||||
Optional::No
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
std::unique_ptr<Task> Task::createFromDictionary(const ghoul::Dictionary& dictionary) {
|
||||
openspace::documentation::testSpecificationAndThrow(documentation::Documentation(), dictionary, "Task");
|
||||
std::string taskType = dictionary.value<std::string>("Type");
|
||||
auto factory = FactoryManager::ref().factory<Task>();
|
||||
std::unique_ptr<Task> task = factory->create(taskType, dictionary);
|
||||
|
||||
if (task == nullptr) {
|
||||
LERROR("Failed to create a Task object of type '" << taskType << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(task);
|
||||
}
|
||||
|
||||
}
|
||||
87
src/util/taskloader.cpp
Normal file
87
src/util/taskloader.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/taskloader.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
#include <ghoul/misc/onscopeexit.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
const char* _loggerCat = "TaskRunner";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
std::vector<std::unique_ptr<Task>> TaskLoader::tasksFromDictionary(const ghoul::Dictionary& tasksDictionary) {
|
||||
std::vector<std::unique_ptr<Task>> tasks;
|
||||
std::vector<std::string> keys = tasksDictionary.keys();
|
||||
for (const std::string key : keys) {
|
||||
std::string taskName;
|
||||
ghoul::Dictionary subTask;
|
||||
if (tasksDictionary.getValue(key, taskName)) {
|
||||
std::string path = "${TASKS}/" + taskName + ".task";
|
||||
std::vector<std::unique_ptr<Task>> subTasks = tasksFromFile(path);
|
||||
std::move(subTasks.begin(), subTasks.end(), std::back_inserter(tasks));
|
||||
} else if (tasksDictionary.getValue(key, subTask)) {
|
||||
std::string taskType = subTask.value<std::string>("Type");
|
||||
std::unique_ptr<Task> task = Task::createFromDictionary(subTask);
|
||||
if (task == nullptr) {
|
||||
LERROR("Failed to create a Task object of type '" << taskType << "'");
|
||||
}
|
||||
tasks.push_back(std::move(task));
|
||||
}
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Task>> TaskLoader::tasksFromFile(const std::string& path) {
|
||||
std::string absTasksFile = absPath(path);
|
||||
using RawPath = ghoul::filesystem::FileSystem::RawPath;
|
||||
if (!FileSys.fileExists(absTasksFile, RawPath::Yes)) {
|
||||
LERROR("Could not load tasks file '" << absTasksFile << "'. " <<
|
||||
"File not found");
|
||||
return std::vector<std::unique_ptr<Task>>();
|
||||
}
|
||||
|
||||
ghoul::Dictionary tasksDictionary;
|
||||
try {
|
||||
ghoul::lua::loadDictionaryFromFile(
|
||||
absTasksFile,
|
||||
tasksDictionary
|
||||
);
|
||||
} catch (...) {
|
||||
LERROR("Could not load tasks file '" << absTasksFile << "'. " <<
|
||||
"Lua parse error");
|
||||
return std::vector<std::unique_ptr<Task>>();
|
||||
}
|
||||
return tasksFromDictionary(tasksDictionary);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -21,6 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/transformationmanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
Reference in New Issue
Block a user