merge with develop for jenkins build messages

This commit is contained in:
Jonathan Bosson
2017-03-03 12:10:41 -07:00
147 changed files with 3928 additions and 2721 deletions

74
Jenkinsfile vendored Normal file
View 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
'''
}
}
}

View File

@@ -90,13 +90,13 @@ void mainInitFunc() {
LDEBUG("Initializing OpenGL in OpenSpace Engine started");
OsEng.initializeGL();
LDEBUG("Initializing OpenGL in OpenSpace Engine finished");
// Find if we have at least one OpenVR window
// Save reference to first OpenVR window, which is the one we will copy to the HMD.
for (size_t i = 0; i < SgctEngine->getNumberOfWindows(); ++i) {
if (SgctEngine->getWindowPtr(i)->checkIfTagExists("OpenVR")) {
// Find if we have at least one OpenVR window
// Save reference to first OpenVR window, which is the one we will copy to the HMD.
for (size_t i = 0; i < SgctEngine->getNumberOfWindows(); ++i) {
if (SgctEngine->getWindowPtr(i)->checkIfTagExists("OpenVR")) {
#ifdef OPENVR_SUPPORT
FirstOpenVRWindow = SgctEngine->getWindowPtr(i);
FirstOpenVRWindow = SgctEngine->getWindowPtr(i);
// If we have an OpenVRWindow, initialize OpenVR.
sgct::SGCTOpenVR::initialize(
@@ -109,8 +109,8 @@ void mainInitFunc() {
#endif
break;
}
}
}
}
// Set the clear color for all non-linear projection viewports
// @CLEANUP: Why is this necessary? We can set the clear color in the configuration
@@ -142,10 +142,10 @@ void mainPostSyncPreDrawFunc() {
OsEng.postSynchronizationPreDraw();
#ifdef OPENVR_SUPPORT
if (FirstOpenVRWindow) {
// Update pose matrices for all tracked OpenVR devices once per frame
sgct::SGCTOpenVR::updatePoses();
}
if (FirstOpenVRWindow) {
// Update pose matrices for all tracked OpenVR devices once per frame
sgct::SGCTOpenVR::updatePoses();
}
#endif
LTRACE("main::postSynchronizationPreDraw(end)");
@@ -167,10 +167,10 @@ void mainRenderFunc() {
#ifdef OPENVR_SUPPORT
bool currentWindowIsHMD = FirstOpenVRWindow == _sgctEngine->getCurrentWindowPtr();
if (sgct::SGCTOpenVR::isHMDActive() && currentWindowIsHMD) {
projectionMatrix = sgct::SGCTOpenVR::getHMDCurrentViewProjectionMatrix(
projectionMatrix = sgct::SGCTOpenVR::getHMDCurrentViewProjectionMatrix(
_sgctEngine->getCurrentFrustumMode()
);
}
}
#endif
if (SgctEngine->isMaster()) {
@@ -187,10 +187,10 @@ void mainPostDrawFunc() {
LTRACE("main::mainPostDrawFunc(begin)");
#ifdef OPENVR_SUPPORT
if (FirstOpenVRWindow) {
// Copy the first OpenVR window to the HMD
sgct::SGCTOpenVR::copyWindowToHMD(FirstOpenVRWindow);
}
if (FirstOpenVRWindow) {
// Copy the first OpenVR window to the HMD
sgct::SGCTOpenVR::copyWindowToHMD(FirstOpenVRWindow);
}
#endif
OsEng.postDraw();
@@ -395,6 +395,7 @@ int main_main(int argc, char** argv) {
} // namespace
int main(int argc, char** argv) {
return main_main(argc, argv);
// We wrap the actual main function in a try catch block so that we can get and print
// some additional information in case an exception is raised
try {
@@ -406,7 +407,12 @@ int main(int argc, char** argv) {
LogMgr.flushLogs();
return EXIT_FAILURE;
}
catch (const std::exception& e) {
catch (const ghoul::AssertionException& e) {
// We don't want to catch the assertion exception as we won't be able to add a
// breakpoint for debugging
LFATALC("Assertion failed", e.what());
throw;
} catch (const std::exception& e) {
LFATALC("Exception", e.what());
LogMgr.flushLogs();
return EXIT_FAILURE;

View File

@@ -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}
)

View File

@@ -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;

View File

@@ -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 = {

View File

@@ -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 = {

View 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'

View 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
View File

@@ -0,0 +1,3 @@
return {
"kameleonmetadatatojson"
}

View 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>

View 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;
}

View File

@@ -25,6 +25,7 @@
#include <ghoul/misc/dictionary.h>
#include <iterator>
#include <sstream>
namespace std {
std::string to_string(std::string value);

View File

@@ -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;

View File

@@ -28,12 +28,16 @@
#include <memory>
namespace ghoul {
class Dictionary;
namespace logging { class Log; }
}
} // namespace ghoul
namespace openspace {
namespace documentation { struct Documentation; }
/**
* This function provides the capabilities to create a new ghoul::logging::Log from the
* provided ghoul::Dictionary%. The Dictionary must at least contain a <code>Type</code>
@@ -44,15 +48,24 @@ namespace openspace {
* created . Both logs can be customized using the <code>Append</code>,
* <code>TimeStamping</code>, <code>DateStamping</code>, <code>CategoryStamping</code>,
* and <code>LogLevelStamping</code> values.
* \param dictionary The dictionary from which the ghoul::logging::Log should be created
*
* \param dictionary The dictionary from which the ghoul::logging::Log should be created
* \return The created ghoul::logging::Log
* \post The return value will not be <code>nullptr</code>
* \throw ghoul::RuntimeError If there was an error creating the ghoul::logging::Log
* \sa ghoul::logging::TextLeg
* \sa ghoul::logging::HTMLLog
* \post The return value will not be <code>nullptr</code>
* \throw ghoul::RuntimeError If there was an error creating the ghoul::logging::Log
* \sa ghoul::logging::TextLog
* \sa ghoul::logging::HTMLLog
*/
std::unique_ptr<ghoul::logging::Log> createLog(const ghoul::Dictionary& dictionary);
/**
* Returns the Documentation that describes a Dictionary used to create a log by using the
* function createLog.
* \return The Documentation that describes an acceptable Dictionary for the method
* createLog
*/
documentation::Documentation LogFactoryDocumentation();
} // namespace openspace
#endif // __OPENSPACE_CORE___LOGFACTORY___H__

View File

@@ -25,14 +25,23 @@
#ifndef __OPENSPACE_CORE___MODULEENGINE___H__
#define __OPENSPACE_CORE___MODULEENGINE___H__
#include <openspace/util/openspacemodule.h>
#include <openspace/scripting/scriptengine.h>
#include <memory>
#include <vector>
#include <openspace/util/openspacemodule.h>
namespace ghoul {
namespace systemcapabilities {
struct Version;
} // namespace systemcapabilities
} // namespace ghoul
namespace openspace {
namespace scripting { struct LuaLibrary; }
/**
* The ModuleEngine is the central repository for registering and accessing
* OpenSpaceModule for the current application run. By initializing (#initialize) the
@@ -80,8 +89,7 @@ public:
* version of all registered modules' OpenGL versions.
* \return The combined minimum OpenGL version
*/
ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version
requiredOpenGLVersion() const;
ghoul::systemcapabilities::Version requiredOpenGLVersion() const;
/**
* Returns the Lua library that contains all Lua functions available to affect the

View File

@@ -43,26 +43,19 @@ public:
void initialize();
void setModules(std::vector<OpenSpaceModule*> modules);
void setModules(const std::vector<OpenSpaceModule*>& modules);
bool busyWaitForDecode();
bool logSGCTOutOfOrderErrors();
bool useDoubleBuffering();
private:
void initEyeSeparation();
void initSceneFiles();
void initBusyWaitForDecode();
void initLogSGCTOutOfOrderErrors();
void initUseDoubleBuffering();
properties::FloatProperty _eyeSeparation;
properties::OptionProperty _scenes;
properties::BoolProperty _busyWaitForDecode;
properties::BoolProperty _logSGCTOutOfOrderErrors;
properties::BoolProperty _useDoubleBuffering;
properties::BoolProperty _spiceUseExceptions;
};
} // namespace openspace

View File

@@ -25,80 +25,82 @@
#ifndef __OPENSPACE_CORE___SYNCENGINE___H__
#define __OPENSPACE_CORE___SYNCENGINE___H__
#include <openspace/util/syncbuffer.h>
#include <ghoul/misc/boolean.h>
#include <vector>
#include <memory>
namespace openspace {
class Syncable;
class SyncBuffer;
/**
* Manages a collection of <code>Syncable</code>s and ensures they are synchronized
* over SGCT nodes. Encoding/Decoding order is handles internally.
*/
* Manages a collection of <code>Syncable</code>s and ensures they are synchronized
* over SGCT nodes. Encoding/Decoding order is handles internally.
*/
class SyncEngine {
public:
using IsMaster = ghoul::Boolean;
/**
* Dependency injection: a SyncEngine relies on a SyncBuffer to encode the sync data.
*/
SyncEngine(SyncBuffer* syncBuffer);
* Creates a new SyncEngine which a buffer size of \p syncBufferSize
* \pre syncBufferSize must be bigger than 0
*/
SyncEngine(unsigned int syncBufferSize);
/**
* Encodes all added Syncables in the injected <code>SyncBuffer</code>.
* This method is only called on the SGCT master node
*/
* Encodes all added Syncables in the injected <code>SyncBuffer</code>.
* This method is only called on the SGCT master node
*/
void encodeSyncables();
/**
* Decodes the <code>SyncBuffer</code> into the added Syncables.
* This method is only called on the SGCT slave nodes
*/
* Decodes the <code>SyncBuffer</code> into the added Syncables.
* This method is only called on the SGCT slave nodes
*/
void decodeSyncables();
/**
* Invokes the presync method of all added Syncables
*/
void presync(bool isMaster);
* Invokes the presync method of all added Syncables
*/
void preSynchronization(IsMaster isMaster);
/**
* Invokes the postsync method of all added Syncables
*/
void postsync(bool isMaster);
* Invokes the postsync method of all added Syncables
*/
void postSynchronization(IsMaster isMaster);
/**
* Add a Syncable to be synchronized over the SGCT cluster
*/
* Add a Syncable to be synchronized over the SGCT cluster.
* \pre syncable must not be nullptr
*/
void addSyncable(Syncable* syncable);
/**
* Add multiple Syncables to be synchronized over the SGCT cluster
*/
* Add multiple Syncables to be synchronized over the SGCT cluster
* \pre syncables must not contain any nullptr
*/
void addSyncables(const std::vector<Syncable*>& syncables);
/**
* Remove a Syncable from being synchronized over the SGCT cluster
*/
* Remove a Syncable from being synchronized over the SGCT cluster
*/
void removeSyncable(Syncable* syncable);
private:
/**
* Vector of Syncables. The vectors ensures consistent encode/decode order
*/
* Vector of Syncables. The vectors ensures consistent encode/decode order
*/
std::vector<Syncable*> _syncables;
/**
* Databuffer used in encoding/decoding
*/
std::unique_ptr<SyncBuffer> _syncBuffer;
* Databuffer used in encoding/decoding
*/
SyncBuffer _syncBuffer;
};
} // namespace openspace
#endif // __OPENSPACE_CORE___SYNCENGINE___H__

View File

@@ -25,7 +25,6 @@
#ifndef __OPENSPACE_CORE___INTERACTIONHANDLER___H__
#define __OPENSPACE_CORE___INTERACTIONHANDLER___H__
#include <openspace/interaction/keyboardcontroller.h>
#include <openspace/interaction/interactionmode.h>
#include <openspace/network/parallelconnection.h>
#include <openspace/properties/propertyowner.h>

View File

@@ -25,7 +25,6 @@
#ifndef __OPENSPACE_CORE___INTERACTIONMODE___H__
#define __OPENSPACE_CORE___INTERACTIONMODE___H__
#include <openspace/interaction/keyboardcontroller.h>
#include <openspace/network/parallelconnection.h>
#include <openspace/util/mouse.h>
#include <openspace/util/keys.h>

View File

@@ -25,9 +25,10 @@
#ifndef __OPENSPACE_CORE___LUACONSOLE___H__
#define __OPENSPACE_CORE___LUACONSOLE___H__
#include <openspace/scripting/scriptengine.h>
#include <openspace/network/parallelconnection.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/keys.h>
#include <string>
@@ -35,50 +36,35 @@
namespace openspace {
class LuaConsole {
class LuaConsole : public properties::PropertyOwner {
public:
LuaConsole();
void initialize();
void deinitialize();
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
bool keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
void charCallback(unsigned int codepoint, KeyModifier modifier);
void render();
Key commandInputButton();
bool isVisible() const;
void setVisible(bool visible);
bool isRemoteScripting() const;
void setRemoteScripting(bool remoteScripting);
void toggleMode();
static scripting::LuaLibrary luaLibrary();
private:
void parallelConnectionChanged(const ParallelConnection::Status& status);
void addToCommand(std::string c);
std::string UnicodeToUTF8(unsigned int codepoint);
properties::BoolProperty _isVisible;
bool _remoteScripting;
size_t _inputPosition;
std::vector<std::string> _commandsHistory;
size_t _activeCommand;
std::vector<std::string> _commands;
std::string _filename;
struct {
int lastIndex;
bool hasInitialValue;
std::string initialValue;
} _autoCompleteInfo;
bool _isVisible;
bool _remoteScripting;
};
} // namespace openspace

View File

@@ -314,10 +314,10 @@ public:
* Property::ViewOptions::PowerScaledCoordinate = <code>powerScaledCoordinate</code>.
*/
struct ViewOptions {
static const std::string Color;
static const std::string LightPosition;
static const std::string PowerScaledScalar;
static const std::string PowerScaledCoordinate;
static const char* Color;
static const char* LightPosition;
static const char* PowerScaledScalar;
static const char* PowerScaledCoordinate;
};
/**
@@ -329,10 +329,10 @@ public:
const ghoul::Dictionary& metaData() const;
protected:
static const std::string IdentifierKey;
static const std::string NameKey;
static const std::string TypeKey;
static const std::string MetaDataKey;
static const char* IdentifierKey;
static const char* NameKey;
static const char* TypeKey;
static const char* MetaDataKey;
/**
* Creates the information that is general to every Property and adds the

View File

@@ -25,7 +25,6 @@
#ifndef __OPENSPACE_CORE___PROPERTYOWNER___H__
#define __OPENSPACE_CORE___PROPERTYOWNER___H__
#include <openspace/properties/property.h>
#include <map>
#include <string>
#include <vector>
@@ -33,6 +32,8 @@
namespace openspace {
namespace properties {
class Property;
/**
* A PropertyOwner can own Propertys or other PropertyOwner and provide access to both in
* a unified way. The <code>identifier</code>s and <code>name</code>s of Propertys and
@@ -53,7 +54,7 @@ public:
static const char URISeparator = '.';
/// The constructor initializing the PropertyOwner's name to <code>""</code>
PropertyOwner();
PropertyOwner(std::string name = "");
/**
* The destructor will remove all Propertys and PropertyOwners it owns along with

View File

@@ -43,14 +43,14 @@
namespace ghoul {
namespace filesystem {
class File;
}
namespace opengl {
class ProgramObject;
class Texture;
}
}
namespace filesystem { class File; }
namespace opengl {
class ProgramObject;
class Texture;
} // namepsace opengl
} // namespace ghoul
namespace openspace {
@@ -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;

View File

@@ -38,6 +38,7 @@ class Scale : public properties::PropertyOwner {
public:
static std::unique_ptr<Scale> createFromDictionary(const ghoul::Dictionary& dictionary);
Scale();
virtual ~Scale();
virtual bool initialize();
virtual double scaleValue() const = 0;

View File

@@ -41,6 +41,7 @@ class Translation : public properties::PropertyOwner {
public:
static std::unique_ptr<Translation> createFromDictionary(const ghoul::Dictionary& dictionary);
Translation();
virtual ~Translation();
virtual bool initialize();

View File

@@ -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__

View File

@@ -218,7 +218,6 @@ struct KeyWithModifier {
KeyWithModifier stringToKey(std::string str);
bool operator<(const KeyWithModifier& lhs, const KeyWithModifier& rhs);
static const std::map<std::string, KeyModifier> KeyModifierMapping = {
{ "SHIFT", KeyModifier::Shift },
{ "ALT", KeyModifier::Alt },

View File

@@ -29,7 +29,7 @@
#include <openspace/scripting/lualibrary.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
#include <ghoul/systemcapabilities/version.h>
#include <string>
#include <vector>
@@ -87,8 +87,7 @@ public:
* overwritten, it returns an OpenGL version of <code>3.3</code>.
* \return The minimum required OpenGL version of this OpenSpaceModule
*/
virtual ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version
requiredOpenGLVersion() const;
virtual ghoul::systemcapabilities::Version requiredOpenGLVersion() const;
protected:
/**

View File

@@ -22,36 +22,26 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___KEYBOARDCONTROLLER___H__
#define __OPENSPACE_CORE___KEYBOARDCONTROLLER___H__
#ifndef __OPENSPACE_CORE___TASK___H__
#define __OPENSPACE_CORE___TASK___H__
#include <openspace/interaction/controller.h>
#include <openspace/util/keys.h>
#include <functional>
#include <ghoul/misc/dictionary.h>
#include <openspace/documentation/documentation.h>
namespace openspace {
namespace interaction {
class KeyboardController : public Controller {
class Task {
public:
virtual ~KeyboardController() {};
virtual void keyPressed(KeyAction action, Key key, KeyModifier modifier) = 0;
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();
};
class KeyboardControllerFixed : public KeyboardController {
public:
void keyPressed(KeyAction action, Key key, KeyModifier modifier);
};
class KeyboardControllerLua : public KeyboardController {
public:
void keyPressed(KeyAction action, Key key, KeyModifier modifier);
protected:
std::string keyToString(Key key, KeyModifier mod) const;
};
} // namespace interaction
} // namespace openspace
#endif // __OPENSPACE_CORE___KEYBOARDCONTROLLER___H__
#endif // __OPENSPACE_CORE___TASK___H__

View 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__

View File

@@ -32,7 +32,7 @@ namespace openspace {
class BaseModule : public OpenSpaceModule {
public:
BaseModule();
virtual ~BaseModule() = default;
std::vector<documentation::Documentation> documentations() const override;
protected:

View File

@@ -88,7 +88,8 @@ std::unique_ptr<ModelGeometry> ModelGeometry::createFromDictionary(
}
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
: _parent(nullptr)
: properties::PropertyOwner("ModelGeometry")
, _parent(nullptr)
, _mode(GL_TRIANGLES)
{
documentation::testSpecificationAndThrow(
@@ -97,8 +98,6 @@ ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
"ModelGeometry"
);
setName("ModelGeometry");
std::string name;
bool success = dictionary.getValue(keyName, name);
ghoul_assert(success, "Name tag was not present");

View File

@@ -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})

View File

@@ -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

View File

@@ -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();
}
}
}

View File

@@ -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__

View File

@@ -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();
}
}
}

View File

@@ -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__

View File

@@ -51,6 +51,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
FloatProperty("lodScaleFactor", "lodScaleFactor",10.0f, 1.0f, 50.0f),
FloatProperty("cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f)
})
, _debugPropertyOwner("Debug")
, _debugProperties({
BoolProperty("saveOrThrowCamera", "save or throw camera", false),
BoolProperty("showChunkEdges", "show chunk edges", false),
@@ -66,6 +67,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
BoolProperty("collectStats", "collect stats", false),
BoolProperty("onlyModelSpaceRendering", "Only Model Space Rendering", false)
})
, _texturePropertyOwner("Textures")
{
setName("RenderableGlobe");
@@ -105,9 +107,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
double distance = res * _ellipsoid.maximumRadius() / tan(fov / 2);
_distanceSwitch.addSwitchValue(_chunkedLodGlobe, distance);
_debugPropertyOwner.setName("Debug");
_texturePropertyOwner.setName("Textures");
addProperty(_generalProperties.isEnabled);
addProperty(_generalProperties.atmosphereEnabled);
addProperty(_generalProperties.performShading);

View File

@@ -64,8 +64,11 @@ int BasicGrid::ySegments() const {
}
void BasicGrid::validate(int xSegments, int ySegments) {
ghoul_assert(xSegments > 0 && ySegments > 0,
"Resolution must be at least 1x1. (" << xSegments << ", " << ySegments << ")");
ghoul_assert(
xSegments > 0 && ySegments > 0,
std::string("Resolution must be at least 1x1. (") +
std::to_string(xSegments) + ", " + std::to_string(ySegments) + ")"
);
}
inline size_t BasicGrid::numElements(int xSegments, int ySegments) {

View File

@@ -30,12 +30,9 @@ namespace openspace {
namespace globebrowsing {
Layer::Layer(const ghoul::Dictionary& layerDict)
: _enabled(properties::BoolProperty("enabled", "enabled", false))
: properties::PropertyOwner(layerDict.value<std::string>("Name"))
, _enabled(properties::BoolProperty("enabled", "enabled", false))
{
std::string layerName = "error!";
layerDict.getValue("Name", layerName);
setName(layerName);
_tileProvider = std::shared_ptr<tileprovider::TileProvider>(
tileprovider::TileProvider::createFromDictionary(layerDict));

View File

@@ -30,9 +30,9 @@ namespace openspace {
namespace globebrowsing {
LayerGroup::LayerGroup(std::string name)
: _levelBlendingEnabled("blendTileLevels", "blend tile levels", true)
: properties::PropertyOwner(std::move(name))
, _levelBlendingEnabled("blendTileLevels", "blend tile levels", true)
{
setName(std::move(name));
addProperty(_levelBlendingEnabled);
}

View File

@@ -40,9 +40,9 @@ const char* LayerManager::LAYER_GROUP_NAMES[NUM_LAYER_GROUPS] = {
"WaterMasks"
};
LayerManager::LayerManager(const ghoul::Dictionary& layerGroupsDict) {
setName("Layers");
LayerManager::LayerManager(const ghoul::Dictionary& layerGroupsDict)
: properties::PropertyOwner("Layers")
{
if (NUM_LAYER_GROUPS != layerGroupsDict.size()) {
throw ghoul::RuntimeError(
"Number of Layer Groups must be equal to " + NUM_LAYER_GROUPS);

View File

@@ -28,12 +28,11 @@ namespace openspace {
namespace globebrowsing {
LayerRenderSettings::LayerRenderSettings()
: opacity(properties::FloatProperty("opacity", "opacity", 1.f, 0.f, 1.f))
: properties::PropertyOwner("Settings")
, opacity(properties::FloatProperty("opacity", "opacity", 1.f, 0.f, 1.f))
, gamma(properties::FloatProperty("gamma", "gamma", 1, 0, 5))
, multiplier(properties::FloatProperty("multiplier", "multiplier", 1.f, 0.f, 20.f))
{
setName("settings");
addProperty(opacity);
addProperty(gamma);
addProperty(multiplier);

View File

@@ -28,6 +28,8 @@
#include <ghoul/misc/dictionary.h>
#include <sstream>
namespace {
const char* KeyLevel = "Level";
const char* KeyX = "X";

View File

@@ -287,7 +287,7 @@ TimeFormat* TimeIdProviderFactory::getProvider(const std::string& format) {
}
ghoul_assert(
_timeIdProviderMap.find(format) != _timeIdProviderMap.end(),
"Unsupported Time format: " << format
"Unsupported Time format: " + format
);
return _timeIdProviderMap[format].get();
}

View File

@@ -41,16 +41,16 @@ namespace {
}
namespace openspace {
IswaBaseGroup::IswaBaseGroup(std::string name, std::string type)
:_enabled("enabled", "Enabled", true)
,_alpha("alpha", "Alpha", 0.9f, 0.0f, 1.0f)
,_delete("delete", "Delete")
,_registered(false)
,_type(type)
,_dataProcessor(nullptr)
{
setName(name);
IswaBaseGroup::IswaBaseGroup(std::string name, std::string type)
: properties::PropertyOwner(std::move(name))
, _enabled("enabled", "Enabled", true)
, _alpha("alpha", "Alpha", 0.9f, 0.0f, 1.0f)
, _delete("delete", "Delete")
, _registered(false)
, _type(type)
, _dataProcessor(nullptr)
{
addProperty(_enabled);
addProperty(_alpha);
addProperty(_delete);

View File

@@ -59,8 +59,10 @@ namespace {
namespace openspace{
IswaManager::IswaManager()
: _iswaEvent()
: properties::PropertyOwner("IswaManager")
, _iswaEvent()
{
// @CLEANUP: Make this staticly allocated ---abock
_month["JAN"] = "01";
_month["FEB"] = "02";
_month["MAR"] = "03";
@@ -99,19 +101,16 @@ IswaManager::~IswaManager(){
}
void IswaManager::addIswaCygnet(int id, std::string type, std::string group){
if(id > 0){
if (id > 0) {
createScreenSpace(id);
}else if(id < 0){
} else if(id < 0) {
// create metadata object and assign group and id
std::shared_ptr<MetadataFuture> metaFuture = std::make_shared<MetadataFuture>();
metaFuture->id = id;
metaFuture->group = group;
// Assign type of cygnet Texture/Data
if(type == _type[CygnetType::Texture]){
if (type == _type[CygnetType::Texture]) {
metaFuture->type = CygnetType::Texture;
} else if (type == _type[CygnetType::Data]) {
metaFuture->type = CygnetType::Data;
@@ -122,7 +121,7 @@ void IswaManager::addIswaCygnet(int id, std::string type, std::string group){
// This callback determines what geometry should be used and creates the right cygbet
auto metadataCallback =
[this, metaFuture](const DownloadManager::MemoryFile& file){
[this, metaFuture](const DownloadManager::MemoryFile& file) {
//Create a string from downloaded file
std::string res;
res.append(file.buffer, file.size);

View File

@@ -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;

View 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}
)

View File

@@ -0,0 +1,6 @@
set (DEFAULT_MODULE ON)
set (OPENSPACE_DEPENDENCIES
kameleon
volume
)

View 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

View File

@@ -22,52 +22,22 @@
* 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 {
namespace luascriptfunctions {
/**
* \ingroup LuaScripts
* show():
* Shows the console
*/
int show(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 0)
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
OsEng.console().setVisible(true);
return 0;
}
/**
* \ingroup LuaScripts
* hide():
* Hides the console
*/
int hide(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 0)
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
OsEng.console().setVisible(false);
return 0;
}
/**
* \ingroup LuaScripts
* toggle():
* Toggles the console
*/
int toggle(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 0)
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
OsEng.console().toggleMode();
return 0;
}
} // namespace luascriptfunctions
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__

View 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();
}
}

View File

@@ -22,58 +22,52 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___DEVICEIDENTIFIER___H__
#define __OPENSPACE_CORE___DEVICEIDENTIFIER___H__
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEREADER___H__
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEREADER___H__
// std includes
#include <array>
#include <mutex>
#include <string>
#include <memory>
#include <modules/volume/rawvolume.h>
#include <ghoul/misc/dictionary.h>
#include <ccmc/Kameleon.h>
#include <ccmc/Interpolator.h>
namespace ccmc {
class Model;
}
namespace openspace {
#define MAXDEVICES 16
enum class InputDevice {NONE, UNKNOWN, SPACENAVIGATOR, XBOX};
class DeviceIdentifier {
class KameleonVolumeReader {
public:
static DeviceIdentifier& ref();
virtual ~DeviceIdentifier();
KameleonVolumeReader(const std::string& path);
//KameleonMetaData readMetaData();
static void init();
static void deinit();
static bool isInitialized();
void scanDevices();
const int numberOfDevices() const;
const InputDevice type(const int device) const;
void update();
void update(const int device);
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;
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;
const int getButtons(const int device, unsigned char **buttons = nullptr) const;
const int getAxes(const int device, float **axespos = nullptr) const;
void get(const int device, unsigned char **buttons, float **axespos) const;
private:
// singleton
static DeviceIdentifier* this_;
DeviceIdentifier(void);
DeviceIdentifier(const DeviceIdentifier& src);
DeviceIdentifier& operator=(const DeviceIdentifier& rhs);
// member variables
int devices_;
std::array<InputDevice, MAXDEVICES> inputDevice_;
std::array<int, MAXDEVICES> numberOfAxes_;
std::array<int, MAXDEVICES> numberOfButtons_;
std::array<float *, MAXDEVICES> axesPos_;
std::array<unsigned char *, MAXDEVICES> buttons_;
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;
};
} // namespace openspace
#endif // __OPENSPACE_CORE___DEVICEIDENTIFIER___H__
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEREADER___H__

View 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;
}
}

View 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__

View 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 });
}
}

View 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__

View 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;
}

View 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;
}

View 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);
}

View 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};
}

View 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

View 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__

View 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

View 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__

View File

@@ -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 {

View File

@@ -166,7 +166,7 @@ documentation::Documentation ProjectionComponent::Documentation() {
}
ProjectionComponent::ProjectionComponent()
: properties::PropertyOwner()
: properties::PropertyOwner("ProjectionComponent")
, _performProjection("performProjection", "Perform Projections", true)
, _clearAllProjections("clearAllProjections", "Clear Projections", false)
, _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f)
@@ -175,8 +175,6 @@ ProjectionComponent::ProjectionComponent()
, _textureSizeDirty(false)
, _projectionTexture(nullptr)
{
setName("ProjectionComponent");
_shadowing.isEnabled = false;
_dilation.isEnabled = false;

View File

@@ -32,6 +32,8 @@
#include <openspace/interaction/interactionhandler.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <ghoul/logging/logmanager.h>

View File

@@ -28,10 +28,9 @@ namespace openspace {
namespace gui {
GuiComponent::GuiComponent(std::string name)
: _isEnabled("enabled", "Is Enabled", false)
: properties::PropertyOwner(std::move(name))
, _isEnabled("enabled", "Is Enabled", false)
{
setName(std::move(name));
addProperty(_isEnabled);
}

View File

@@ -59,7 +59,11 @@ void GuiOriginComponent::render() {
}
auto iCurrentFocus = std::find(nodes.begin(), nodes.end(), currentFocus);
ghoul_assert(iCurrentFocus != nodes.end(), "Focus node not found");
if (!nodes.empty()) {
// Only check if we found the current focus node if we have any nodes at all
// only then it would be a real error
ghoul_assert(iCurrentFocus != nodes.end(), "Focus node not found");
}
int currentPosition = static_cast<int>(std::distance(iCurrentFocus, nodes.begin()));
bool hasChanged = ImGui::Combo("Origin", &currentPosition, nodeNames.c_str());

View File

@@ -74,10 +74,9 @@ std::unique_ptr<PlanetGeometry> PlanetGeometry::createFromDictionary(const ghoul
}
PlanetGeometry::PlanetGeometry()
: _parent(nullptr)
{
setName("PlanetGeometry");
}
: properties::PropertyOwner("PlanetGeometry")
, _parent(nullptr)
{}
PlanetGeometry::~PlanetGeometry() {}

View File

@@ -27,6 +27,10 @@
#include <openspace/properties/propertyowner.h>
#include <memory>
namespace ghoul { class Dictionary; }
namespace openspace {
class Renderable;

View File

@@ -83,8 +83,11 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
{
std::string name;
bool success = dictionary.getValue(SceneGraphNode::KeyName, name);
ghoul_assert(success,
"RenderablePlanet need the '" << SceneGraphNode::KeyName<<"' be specified");
ghoul_assert(
success,
std::string("RenderablePlanet need the '") + SceneGraphNode::KeyName +
"' be specified"
);
ghoul::Dictionary geometryDictionary;
success = dictionary.getValue(keyGeometry, geometryDictionary);

View File

@@ -123,7 +123,7 @@ void SpiceRotation::update(const UpdateData& data) {
data.time
);
}
catch (...) {
catch (const SpiceManager::SpiceException&) {
_matrix = glm::dmat3(1.0);
}
}

View File

@@ -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__

View File

@@ -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})

View File

@@ -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;
};

View File

@@ -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();
}
}

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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__

View 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

View 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__

View File

@@ -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));
}

View 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__

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -24,7 +24,7 @@ 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}/globebrowsing.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",

View File

@@ -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

View File

@@ -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"

View File

@@ -80,7 +80,4 @@ void storeFragments(uint nFrags) {
}
#endif

Some files were not shown because too many files have changed in this diff Show More