mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 12:10:52 -06:00
Merge remote-tracking branch 'origin/kameleon' into properties
This commit is contained in:
@@ -95,6 +95,15 @@ if(OPENCL_FOUND)
|
||||
set(GHOUL_DEPENDENCIES ${GHOUL_DEPENDENCIES} ${OPENCL_LIBRARIES})
|
||||
endif(OPENCL_FOUND)
|
||||
|
||||
# Kameleon
|
||||
option(KAMELEON_LIBRARY_ONLY "Build with Kameleon as library only" ON)
|
||||
option(BUILD_SHARED_LIBS "Build Shared Libraries" ON)
|
||||
set(KAMELEON_ROOT_DIR ${OPENSPACE_EXT_DIR}/kameleon)
|
||||
set(KAMELEON_INCLUDES ${KAMELEON_ROOT_DIR}/src)
|
||||
add_subdirectory(${KAMELEON_ROOT_DIR})
|
||||
include_directories(${KAMELEON_INCLUDES})
|
||||
set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ccmc)
|
||||
|
||||
if (APPLE)
|
||||
include_directories(/Developer/Headers/FlatCarbon)
|
||||
find_library(CARBON_LIBRARY Carbon)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Cluster masterAddress="localhost">
|
||||
<Settings>
|
||||
<Display swapInterval="0" />
|
||||
<Display swapInterval="1" />
|
||||
</Settings>
|
||||
<Node address="localhost" port="20401">
|
||||
<Window fullScreen="false">
|
||||
|
||||
Submodule ext/ghoul updated: 9809d59260...8b8b348e6f
@@ -71,7 +71,7 @@ public:
|
||||
bool CalculateTemporalError();
|
||||
|
||||
int * Data() { return &data_[0]; }
|
||||
unsigned int Size() { return data_.size(); }
|
||||
size_t Size() { return data_.size(); }
|
||||
|
||||
// TODO support dimensions of differens sizes
|
||||
unsigned int BrickDim() const { return xBrickDim_; }
|
||||
|
||||
@@ -58,13 +58,19 @@ public:
|
||||
void mouseScrollWheelCallback(int pos);
|
||||
|
||||
private:
|
||||
glm::vec3 mapToTrackball(glm::vec2 mousePos);
|
||||
void trackballRotate(int x, int y);
|
||||
|
||||
Camera *camera_;
|
||||
Camera* camera_;
|
||||
bool enabled_;
|
||||
SceneGraphNode *node_;
|
||||
|
||||
double dt_;
|
||||
|
||||
|
||||
glm::vec3 _lastTrackballPos;
|
||||
bool _leftMouseButtonDown, _isMouseBeingPressedAndHeld;
|
||||
|
||||
// used for calling when updating and deallocation
|
||||
std::vector<ExternalControl*> controllers_;
|
||||
|
||||
@@ -75,4 +81,4 @@ private:
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#ifndef INTERFACE_H_
|
||||
#define INTERFACE_H_
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
@@ -31,7 +32,6 @@
|
||||
|
||||
namespace openspace {
|
||||
class Interface {
|
||||
|
||||
struct Node {
|
||||
std::string _key;
|
||||
std::string _value;
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
void callback(const char * receivedChars);
|
||||
|
||||
private:
|
||||
|
||||
void handleNodes();
|
||||
void loadIntoNodes(const boost::property_tree::ptree& tree, std::string parent = "", const int depth = 0);
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
|
||||
protected:
|
||||
std::string findPath(const std::string& path);
|
||||
ghoul::opengl::Texture* loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary);
|
||||
ghoul::RawVolumeReader::ReadHints readHints(const ghoul::Dictionary& dictionary);
|
||||
ghoul::opengl::Texture* loadTransferFunction(const std::string& filepath);
|
||||
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
#define SGCT_WINDOWS_INCLUDE
|
||||
#include <sgct.h>
|
||||
|
||||
namespace sgct_utils {
|
||||
class SGCTBox;
|
||||
}
|
||||
|
||||
//#include <vector>
|
||||
//#include <string>
|
||||
#ifdef __APPLE__
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <ghoul/opencl/clcommandqueue.h>
|
||||
#include <ghoul/opencl/clprogram.h>
|
||||
#include <ghoul/opencl/clkernel.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -75,7 +74,7 @@ private:
|
||||
|
||||
// Volumes
|
||||
std::vector<std::string> _volumePaths;
|
||||
std::vector<ghoul::RawVolumeReader::ReadHints> _volumeHints;
|
||||
std::vector<ghoul::Dictionary> _volumeHints;
|
||||
|
||||
// Textures
|
||||
ghoul::opengl::Texture* _output;
|
||||
@@ -98,6 +97,8 @@ private:
|
||||
ghoul::opencl::CLWorkSize* _ws;
|
||||
ghoul::filesystem::File* _kernelSourceFile;
|
||||
std::vector<std::pair<ghoul::opencl::CLProgram::Option, bool> > _kernelOptions;
|
||||
std::vector<std::string> _kernelIncludes;
|
||||
std::vector<std::pair<std::string,std::string> > _kernelDefinitions;
|
||||
bool _programUpdateOnSave;
|
||||
|
||||
// mutexes to prevent inconsistencies
|
||||
@@ -105,10 +106,10 @@ private:
|
||||
std::mutex* _textureLock;
|
||||
|
||||
ghoul::opengl::ProgramObject *_quadProgram;
|
||||
sgct_utils::SGCTBox* _boundingBox;
|
||||
GLuint _screenQuad;
|
||||
|
||||
VolumeRaycasterBox* _colorBoxRenderer;
|
||||
glm::vec3 _boxScaling;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
namespace sgct_utils {
|
||||
class SGCTBox;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableVolumeGL: public RenderableVolume {
|
||||
|
||||
@@ -25,13 +25,18 @@
|
||||
#ifndef VOLUMERAYCASTERBOX_H_
|
||||
#define VOLUMERAYCASTERBOX_H_
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
// forward declare private objects
|
||||
namespace sgct_utils {
|
||||
class SGCTBox;
|
||||
}
|
||||
namespace ghoul {
|
||||
namespace opengl {
|
||||
class FramebufferObject;
|
||||
class ProgramObject;
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -40,7 +45,7 @@ public:
|
||||
VolumeRaycasterBox();
|
||||
~VolumeRaycasterBox();
|
||||
bool initialize();
|
||||
void render(glm::mat4 MVP);
|
||||
void render(const glm::mat4& MVP);
|
||||
|
||||
ghoul::opengl::Texture* backFace();
|
||||
ghoul::opengl::Texture* frontFace();
|
||||
@@ -56,5 +61,5 @@ private:
|
||||
glm::size2_t _dimensions;
|
||||
};
|
||||
|
||||
} /* namespace openspace */
|
||||
#endif /* VOLUMERAYCASTERBOX_H_ */
|
||||
} // namespace openspace
|
||||
#endif // VOLUMERAYCASTERBOX_H_
|
||||
|
||||
58
include/openspace/util/kameleonwrapper.h
Normal file
58
include/openspace/util/kameleonwrapper.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 *
|
||||
* *
|
||||
* 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 KAMELEONWRAPPER_H_
|
||||
#define KAMELEONWRAPPER_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/std_based_type.hpp>
|
||||
|
||||
namespace ccmc {
|
||||
class Model;
|
||||
class Interpolator;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class KameleonWrapper {
|
||||
public:
|
||||
|
||||
enum class Model {
|
||||
ENLIL, // Heliosphere
|
||||
BATSRUS // Magnetosphere
|
||||
};
|
||||
|
||||
KameleonWrapper(const std::string& filename, Model model);
|
||||
~KameleonWrapper();
|
||||
float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions);
|
||||
|
||||
private:
|
||||
ccmc::Model* _model;
|
||||
Model _type;
|
||||
ccmc::Interpolator* _interpolator;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // KAMELEONWRAPPER_H_
|
||||
28
kernels/helpers/volume_helpers.cl
Normal file
28
kernels/helpers/volume_helpers.cl
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
float3 CartesianToSpherical(float3 _cartesian);
|
||||
float intensityNormalizer(float intensity, float iMin, float iMax);
|
||||
|
||||
float3 CartesianToSpherical(float3 _cartesian) {
|
||||
// Put cartesian in [-1..1] range first
|
||||
_cartesian = (float3)(-1.0) + 2.0f* _cartesian;
|
||||
float r = length(_cartesian);
|
||||
float theta, phi;
|
||||
if (r == 0.0) {
|
||||
theta = phi = 0.0;
|
||||
} else {
|
||||
theta = acospi(_cartesian.z/r);
|
||||
phi = (M_PI + atan2(_cartesian.y, _cartesian.x)) / (2.0*M_PI);
|
||||
}
|
||||
r = r / native_sqrt(3.0f);
|
||||
// Sampler ignores w component
|
||||
return (float3)(r, theta, phi);
|
||||
}
|
||||
|
||||
float intensityNormalizer(float intensity, float iMin, float iMax) {
|
||||
float i = clamp(intensity, iMin, iMax);
|
||||
i = (i - iMin) / (iMax - iMin);
|
||||
return clamp(i, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
104
kernels/helpers/volume_raycasting.cl
Normal file
104
kernels/helpers/volume_raycasting.cl
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
#define EARLY_RAY_TERMINATION_OPACITY 0.95
|
||||
|
||||
void raySetup(float3 first, float3 last, float3 dimension, float3* rayDirection, float* tIncr, float* tEnd);
|
||||
bool earlyRayTermination(float4* color, float maxOpacity);
|
||||
|
||||
|
||||
#define RC_DEFINE_TEXTUE_COORDINATES(coords) \
|
||||
int2 coords = (int2)(get_global_id(0), get_global_id(1))
|
||||
|
||||
#define RC_DEFINE_VOLUME3D_DIMENSIONS(dimension, volume) \
|
||||
float3 dimension; \
|
||||
{ \
|
||||
int4 idim = get_image_dim(volume); \
|
||||
dimension = (float3)(idim.x,idim.y,idim.z); \
|
||||
}
|
||||
|
||||
|
||||
//#define RC_DEFINE_VARIABLES(dimension, intCoords)
|
||||
|
||||
/***
|
||||
* Calculates the direction of the ray and returns the number
|
||||
* of steps and the direction.
|
||||
***/
|
||||
void raySetup(float3 first, float3 last, float3 dimension, float3* rayDirection, float* tIncr, float* tEnd) {
|
||||
float samplingRate_ = 1.0f;
|
||||
*rayDirection = last - first;
|
||||
*tEnd = length(*rayDirection);
|
||||
*rayDirection = normalize(*rayDirection);
|
||||
*tIncr = 1.0/(samplingRate_*length((*rayDirection)*dimension));
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* Applies early ray termination. The current opacity is compared to
|
||||
* the maximum opacity. In case it is greater, the opacity is set to
|
||||
* 1.0 and true is returned, otherwise false is returned.
|
||||
***/
|
||||
bool earlyRayTermination(float4* color, float maxOpacity) {
|
||||
if ((*color).a >= maxOpacity) {
|
||||
(*color).a = 1.0f;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define RC_EARLY_RAY_TERMINATION(opacity, maxOpacity, finished) \
|
||||
finished = earlyRayTermination(&opacity, maxOpacity)
|
||||
|
||||
#define RC_BEGIN_LOOP_FOR \
|
||||
for (int loop=0; !finished && loop<RAYCASTING_LOOP_COUNT; ++loop) {
|
||||
#define RC_END_LOOP_BRACES }
|
||||
|
||||
/***
|
||||
* The beginning of a typical raycasting loop.
|
||||
*/
|
||||
#define RC_BEGIN_LOOP \
|
||||
bool finished = false; \
|
||||
float t = 0.0f; \
|
||||
int RAYCASTING_LOOP_COUNT = tEnd / tIncr; \
|
||||
RC_BEGIN_LOOP_FOR
|
||||
|
||||
|
||||
/***
|
||||
* The end of a typical raycasting loop. If adaptive sampling
|
||||
* is used for rendering bricked volumes, t is increased by a
|
||||
* multiple of tIncr, thereby skipping several samples.
|
||||
*/
|
||||
#ifdef ADAPTIVE_SAMPLING
|
||||
#define RC_END_LOOP(result) \
|
||||
RC_EARLY_RAY_TERMINATION(result, EARLY_RAY_TERMINATION_OPACITY, finished); \
|
||||
t += (tIncr * float(numberOfSkippedSamples)); \
|
||||
finished = finished || (t > tEnd); \
|
||||
RC_END_LOOP_BRACES
|
||||
#else
|
||||
#define RC_END_LOOP(result) \
|
||||
RC_EARLY_RAY_TERMINATION(result, EARLY_RAY_TERMINATION_OPACITY, finished); \
|
||||
t += tIncr; \
|
||||
finished = finished || (t > tEnd); \
|
||||
RC_END_LOOP_BRACES
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* In order to keep the shaders as free as possible from dealing
|
||||
* with bricking and adaptive sampling, these defines can be placed
|
||||
* before and after the compositing function calls to enable adaptive
|
||||
* sampling when bricking is used. For normal datasets these defines
|
||||
* will have no impact at all.
|
||||
*/
|
||||
#ifdef ADAPTIVE_SAMPLING
|
||||
#define RC_BEGIN_COMPOSITING \
|
||||
for (int i=0; i<numberOfSkippedSamples; i++) {
|
||||
#else
|
||||
#define RC_BEGIN_COMPOSITING
|
||||
#endif
|
||||
|
||||
#ifdef ADAPTIVE_SAMPLING
|
||||
#define RC_END_COMPOSITING \
|
||||
}
|
||||
#else
|
||||
#define RC_END_COMPOSITING
|
||||
#endif
|
||||
@@ -10,4 +10,5 @@ return {
|
||||
CONFIG = "${BASE_PATH}/config"
|
||||
},
|
||||
sgctConfig = "${SGCT}/single.xml",
|
||||
--sgctConfig = "${SGCT}/single_sbs_stereo.xml",
|
||||
}
|
||||
@@ -35,8 +35,6 @@
|
||||
#include <openspace/util//spice.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/logging/consolelog.h>
|
||||
@@ -45,7 +43,6 @@
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
#include <ghoul/cmdparser/commandlineparser.h>
|
||||
#include <ghoul/cmdparser/commandlinecommand.h>
|
||||
|
||||
#include <ghoul/opencl/clcontext.h>
|
||||
#include <ghoul/opencl/clprogram.h>
|
||||
#include <ghoul/opencl/clkernel.h>
|
||||
@@ -215,6 +212,12 @@ bool OpenSpaceEngine::isInitialized() {
|
||||
|
||||
bool OpenSpaceEngine::initialize() {
|
||||
|
||||
// clear the screen so the user don't have to see old buffer contents from the graphics card
|
||||
glClearColor(0,0,0,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
GLFWwindow* win = sgct::Engine::instance()->getActiveWindowPtr()->getWindowHandle();
|
||||
glfwSwapBuffers(win);
|
||||
|
||||
// Register the filepaths from static function enables easy testing
|
||||
//registerFilePaths();
|
||||
_context.createContextFromGLContext();
|
||||
@@ -244,8 +247,6 @@ bool OpenSpaceEngine::initialize() {
|
||||
DeviceIdentifier::init();
|
||||
DeviceIdentifier::ref().scanDevices();
|
||||
_engine->_interactionHandler->connectDevices();
|
||||
|
||||
//_flare = new Flare();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -282,8 +283,6 @@ void OpenSpaceEngine::preSynchronization() {
|
||||
|
||||
_interactionHandler->update(dt);
|
||||
_interactionHandler->lockControls();
|
||||
|
||||
//_flare->preSync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,28 +291,24 @@ void OpenSpaceEngine::postSynchronizationPreDraw() {
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::render() {
|
||||
//_flare->render();
|
||||
_renderEngine->render();
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::postDraw() {
|
||||
if (sgct::Engine::instance()->isMaster()) {
|
||||
_interactionHandler->unlockControls();
|
||||
//_flare->postDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::keyboardCallback(int key, int action) {
|
||||
if (sgct::Engine::instance()->isMaster()) {
|
||||
_interactionHandler->keyboardCallback(key, action);
|
||||
//_flare->keyboard(key, action);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::mouseButtonCallback(int key, int action) {
|
||||
if (sgct::Engine::instance()->isMaster()) {
|
||||
_interactionHandler->mouseButtonCallback(key, action);
|
||||
//_flare->mouse(key, action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,11 +321,9 @@ void OpenSpaceEngine::mouseScrollWheelCallback(int pos) {
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::encode() {
|
||||
//_flare->encode();
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::decode() {
|
||||
//_flare->decode();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
|
||||
// open space includes
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
#include <openspace/interaction/deviceidentifier.h>
|
||||
#include <openspace/interaction/externalcontrol/randomexternalcontrol.h>
|
||||
#include <openspace/interaction/externalcontrol/joystickexternalcontrol.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/psc.h>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
// std includes
|
||||
#include <cassert>
|
||||
|
||||
std::string _loggerCat = "InteractionHandler";
|
||||
|
||||
namespace openspace {
|
||||
|
||||
InteractionHandler::InteractionHandler() {
|
||||
@@ -19,11 +24,13 @@ InteractionHandler::InteractionHandler() {
|
||||
enabled_ = true;
|
||||
node_ = nullptr;
|
||||
dt_ = 0.0;
|
||||
_lastTrackballPos = glm::vec3(0.5);
|
||||
_leftMouseButtonDown = false;
|
||||
_isMouseBeingPressedAndHeld = false;
|
||||
}
|
||||
|
||||
InteractionHandler::~InteractionHandler() {
|
||||
for (size_t i = 0; i < controllers_.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < controllers_.size(); ++i) {
|
||||
delete controllers_[i];
|
||||
}
|
||||
}
|
||||
@@ -225,6 +232,75 @@ double InteractionHandler::getDt() {
|
||||
return dt_;
|
||||
}
|
||||
|
||||
glm::vec3 InteractionHandler::mapToTrackball(glm::vec2 mousePos) {
|
||||
const float RADIUS = 0.5; // Sphere radius
|
||||
glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0);
|
||||
|
||||
// Mapping according to Holroyds trackball
|
||||
// Piece-wise sphere + hyperbolic sheet
|
||||
if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) {
|
||||
//Spherical Region
|
||||
out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y);
|
||||
out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0;
|
||||
} else { //Hyperbolic Region - for smooth z values
|
||||
out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y));
|
||||
}
|
||||
|
||||
return glm::normalize(out);
|
||||
}
|
||||
|
||||
void InteractionHandler::trackballRotate(int x, int y) {
|
||||
// Normalize mouse coordinates to [0,1]
|
||||
float width = sgct::Engine::instance()->getActiveXResolution();
|
||||
float height = sgct::Engine::instance()->getActiveYResolution();
|
||||
glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height);
|
||||
mousePos[1] = 0.5;
|
||||
|
||||
glm::vec3 curTrackballPos = mapToTrackball(mousePos);
|
||||
// LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z);
|
||||
|
||||
// Disable movement on the first click for extra smoothness
|
||||
if (!_isMouseBeingPressedAndHeld) {
|
||||
_lastTrackballPos = curTrackballPos;
|
||||
_isMouseBeingPressedAndHeld = true;
|
||||
}
|
||||
|
||||
if (curTrackballPos != _lastTrackballPos) {
|
||||
// calculate rotation angle (in radians), rotation axis and quaternion
|
||||
float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos);
|
||||
rotationAngle *= getDt()*100.0f;
|
||||
glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos);
|
||||
rotationAxis = glm::normalize(rotationAxis);
|
||||
glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis);
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
orbit(glm::inverse(quaternion));
|
||||
camera_->rotate(quaternion);
|
||||
// camera_->compileViewRotationMatrix();
|
||||
/*
|
||||
psc nodePos = node_->getWorldPosition();
|
||||
psc camPos = camera_->getPosition();
|
||||
glm::mat4 transMatrix = glm::translate(glm::mat4(1.0), nodePos.getVec3f()-camPos.getVec3f());
|
||||
glm::mat4 transBackMatrix = glm::translate(glm::mat4(1.0), camPos.getVec3f()-nodePos.getVec3f());
|
||||
glm::vec4 translated = transMatrix*glm::vec4(camPos.getVec3f(), 1.0);
|
||||
glm::vec4 postRot = glm::rotate(quaternion, translated);
|
||||
glm::vec4 newCamPos = transBackMatrix*glm::vec4(postRot.x, postRot.y, postRot.z, 1.0);
|
||||
camera_->setPosition(psc::CreatePSC(newCamPos.x, newCamPos.y, newCamPos.z));
|
||||
camera_->rotate(glm::inverse(quaternion));
|
||||
camera_->compileViewRotationMatrix();
|
||||
*/
|
||||
// node_->calculateBoundingSphere();
|
||||
|
||||
// glm::vec3 camPos = *sgct::Engine::instance()->getUserPtr()->getPosPtr();
|
||||
// sgct::Engine::instance()->getUserPtr()->setOrientation(quaternion.w, quaternion.x, quaternion.y, quaternion.z);
|
||||
// sgct::Engine::instance()->getUserPtr()->setPos(glm::rotate(quaternion, camPos));
|
||||
|
||||
|
||||
_lastTrackballPos = curTrackballPos;
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::keyboardCallback(int key, int action) {
|
||||
// TODO package in script
|
||||
const double speed = 2.75;
|
||||
@@ -270,11 +346,11 @@ void InteractionHandler::keyboardCallback(int key, int action) {
|
||||
rotate(rot);
|
||||
}
|
||||
if (key == 'R') {
|
||||
pss dist(-speed * dt, 8.0);
|
||||
pss dist(-speed * dt, 0.0);
|
||||
distance(dist);
|
||||
}
|
||||
if (key == 'F') {
|
||||
pss dist(speed * dt, 8.0);
|
||||
pss dist(speed * dt, 0.0);
|
||||
distance(dist);
|
||||
}
|
||||
/*
|
||||
@@ -309,9 +385,18 @@ void InteractionHandler::mouseButtonCallback(int key, int action) {
|
||||
//if(mouseControl_ != nullptr) {
|
||||
// mouseControl_->mouseButtonCallback(key,action);
|
||||
//}
|
||||
if (key == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
|
||||
_leftMouseButtonDown = true;
|
||||
else if (key == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) {
|
||||
_leftMouseButtonDown = false;
|
||||
_isMouseBeingPressedAndHeld = false;
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::mousePositionCallback(int x, int y) {
|
||||
if (_leftMouseButtonDown)
|
||||
trackballRotate(x,y);
|
||||
|
||||
//if(mouseControl_ != nullptr) {
|
||||
// mouseControl_->mousePosCallback(x,y);
|
||||
//}
|
||||
@@ -324,4 +409,4 @@ void InteractionHandler::mouseScrollWheelCallback(int pos) {
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace openspace
|
||||
|
||||
@@ -23,20 +23,21 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interface/interface.h>
|
||||
|
||||
/*
|
||||
#include <sgct.h>
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
*/
|
||||
namespace openspace {
|
||||
|
||||
Interface::Interface(OpenSpaceEngine* engine) : _engine(engine) {}
|
||||
Interface::~Interface() {}
|
||||
|
||||
void Interface::callback(const char* receivedChars) {
|
||||
/*
|
||||
std::cout << receivedChars;
|
||||
|
||||
boost::property_tree::ptree pt;
|
||||
@@ -47,26 +48,25 @@ void Interface::callback(const char* receivedChars) {
|
||||
loadIntoNodes(pt);
|
||||
handleNodes(); // Issue commands
|
||||
_nodes.clear(); // Clean up after commands are issued
|
||||
*/
|
||||
}
|
||||
|
||||
void Interface::handleNodes() {
|
||||
/*
|
||||
for (int i = 0; i < _nodes.size(); ++i) {
|
||||
Node node = _nodes.at(i);
|
||||
if (node == "stats") {
|
||||
sgct::Engine::instance()->setDisplayInfoVisibility(atoi(node._value.c_str()));
|
||||
} else if (node == "graph") {
|
||||
sgct::Engine::instance()->setStatsGraphVisibility(atoi(node._value.c_str()));
|
||||
} /*else if (node == "renderer") {
|
||||
if (strcmp(node._value.c_str(), "volumeraycaster") == 0)
|
||||
_engine->setRenderer(OpenSpaceEngine::Renderers::VolumeRaycaster);
|
||||
else if (strcmp(node._value.c_str(), "flare") == 0)
|
||||
_engine->setRenderer(OpenSpaceEngine::Renderers::Flare);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// http://duck-wrath.blogspot.com/2012/02/how-to-recursive-parse.html
|
||||
void Interface::loadIntoNodes(const boost::property_tree::ptree& tree, std::string parent, const int depth) {
|
||||
/*
|
||||
BOOST_FOREACH( boost::property_tree::ptree::value_type const&v, tree.get_child("") ) {
|
||||
boost::property_tree::ptree subtree = v.second;
|
||||
std::string value = v.second.data();
|
||||
@@ -88,6 +88,7 @@ void Interface::loadIntoNodes(const boost::property_tree::ptree& tree, std::stri
|
||||
// recursive go down the hierarchy
|
||||
loadIntoNodes(subtree,key,depth+1);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -115,8 +115,8 @@ void RenderablePlanet::render(const Camera *camera, const psc &thisPosition) {
|
||||
|
||||
// scale the planet to appropriate size since the planet is a unit sphere
|
||||
glm::mat4 transform = glm::mat4(1);
|
||||
transform = glm::rotate(transform, 4.1f*static_cast<float>(sgct::Engine::instance()->getTime()), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
// transform = glm::rotate(transform, 4.1f*static_cast<float>(sgct::Engine::instance()->getTime()), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
// setup the data to the shader
|
||||
programObject_->setUniform("ViewProjection", camera->getViewProjectionMatrix());
|
||||
programObject_->setUniform("ModelTransform", transform);
|
||||
@@ -142,4 +142,4 @@ void RenderablePlanet::update() {
|
||||
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace openspace
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/kameleonwrapper.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#include <iostream>
|
||||
@@ -41,10 +43,11 @@
|
||||
namespace {
|
||||
std::string _loggerCat = "RenderableVolume";
|
||||
|
||||
bool hasEnding (std::string const &fullString, std::string const &ending)
|
||||
bool hasExtension (std::string const &filepath, std::string const &extension)
|
||||
{
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
|
||||
std::string ending = "." + extension;
|
||||
if (filepath.length() > ending.length()) {
|
||||
return (0 == filepath.compare (filepath.length() - ending.length(), ending.length(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -96,6 +99,66 @@ std::string RenderableVolume::findPath(const std::string& path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
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")) {
|
||||
|
||||
std::string modelString;
|
||||
if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) {
|
||||
KameleonWrapper::Model model;
|
||||
if (modelString == "BATSRUS") {
|
||||
model = KameleonWrapper::Model::BATSRUS;
|
||||
} else if (modelString == "ENLIL") {
|
||||
model = KameleonWrapper::Model::ENLIL;
|
||||
} else {
|
||||
LWARNING("Hints does not specify a valid 'Model'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string variableString;
|
||||
if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) {
|
||||
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;
|
||||
}
|
||||
|
||||
KameleonWrapper kw(filepath, model);
|
||||
float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
} else {
|
||||
LWARNING("Hints does not specify a 'Variable'");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
LWARNING("Hints does not specify a 'Model'");
|
||||
} else {
|
||||
LWARNING("No valid file extension.");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
|
||||
ghoul::RawVolumeReader::ReadHints hints;
|
||||
hints._dimensions = glm::ivec3(1, 1, 1);
|
||||
@@ -165,8 +228,8 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string
|
||||
}
|
||||
|
||||
// check if not a txt based texture
|
||||
if ( ! hasEnding(filepath, ".txt")) {
|
||||
return ghoul::opengl::loadTexture(f);;
|
||||
if ( ! hasExtension(filepath, "txt")) {
|
||||
return ghoul::opengl::loadTexture(f);
|
||||
}
|
||||
|
||||
// it is a txt based texture
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/opencl/clworksize.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -63,7 +64,8 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona
|
||||
RenderableVolume(dictionary),
|
||||
_output(nullptr),
|
||||
_clBackTexture(0), _clFrontTexture(0), _clOutput(0),
|
||||
_kernelSourceFile(nullptr), _programUpdateOnSave(false), _colorBoxRenderer(nullptr) {
|
||||
_kernelSourceFile(nullptr), _programUpdateOnSave(false), _colorBoxRenderer(nullptr),
|
||||
_boxScaling(1.0,1.0,1.0) {
|
||||
|
||||
_kernelLock = new std::mutex;
|
||||
_textureLock = new std::mutex;
|
||||
@@ -85,10 +87,9 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona
|
||||
ghoul::Dictionary hintsDictionary;
|
||||
if(volume.hasKey("Hints"))
|
||||
volume.getValue("Hints", hintsDictionary);
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
|
||||
_volumePaths.push_back(file);
|
||||
_volumeHints.push_back(hints);
|
||||
_volumeHints.push_back(hintsDictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,6 +162,30 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary includeDictionary;
|
||||
if (kernelDictionary.hasKey("Includes") && kernelDictionary.getValue("Includes", includeDictionary)) {
|
||||
auto keys = includeDictionary.keys();
|
||||
for(auto key: keys) {
|
||||
std::string includePath;
|
||||
if(includeDictionary.getValue(key, includePath)) {
|
||||
if(FileSys.directoryExists(includePath)) {
|
||||
_kernelIncludes.push_back(absPath(includePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary defineDictionary;
|
||||
if (kernelDictionary.hasKey("Definitions") && kernelDictionary.getValue("Definitions", defineDictionary)) {
|
||||
auto keys = defineDictionary.keys();
|
||||
for(auto key: keys) {
|
||||
std::string defintion;
|
||||
if(defineDictionary.getValue(key, defintion)) {
|
||||
_kernelDefinitions.push_back(std::make_pair(key, defintion));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (kernelPath != "") {
|
||||
@@ -168,6 +193,24 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona
|
||||
}
|
||||
|
||||
_colorBoxRenderer = new VolumeRaycasterBox();
|
||||
double tempValue;
|
||||
if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) {
|
||||
if(tempValue > 0.0) {
|
||||
_boxScaling[0] = tempValue;
|
||||
}
|
||||
}
|
||||
if(dictionary.hasKey("BoxScaling.2") && dictionary.getValue("BoxScaling.2", tempValue)) {
|
||||
if(tempValue > 0.0) {
|
||||
_boxScaling[1] = tempValue;
|
||||
}
|
||||
}
|
||||
if(dictionary.hasKey("BoxScaling.3") && dictionary.getValue("BoxScaling.3", tempValue)) {
|
||||
if(tempValue > 0.0) {
|
||||
_boxScaling[2] = tempValue;
|
||||
}
|
||||
}
|
||||
|
||||
setBoundingSphere(pss::CreatePSS(_boxScaling.length()));
|
||||
}
|
||||
|
||||
RenderableVolumeExpert::~RenderableVolumeExpert() {
|
||||
@@ -204,13 +247,16 @@ bool RenderableVolumeExpert::initialize() {
|
||||
}
|
||||
|
||||
for (int i = 0; i < _volumePaths.size(); ++i) {
|
||||
ghoul::RawVolumeReader rawReader(_volumeHints.at(i));
|
||||
ghoul::opengl::Texture* volume = rawReader.read(_volumePaths.at(i));
|
||||
// volume->uploadTexture();
|
||||
cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume);
|
||||
|
||||
_volumes.push_back(volume);
|
||||
_clVolumes.push_back(volumeTexture);
|
||||
ghoul::opengl::Texture* volume = loadVolume(_volumePaths.at(i), _volumeHints.at(i));
|
||||
if(volume) {
|
||||
volume->uploadTexture();
|
||||
|
||||
LDEBUG("Creating CL texture from GL texture with path '" << _volumePaths.at(i) << "'");
|
||||
cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume);
|
||||
|
||||
_volumes.push_back(volume);
|
||||
_clVolumes.push_back(volumeTexture);
|
||||
}
|
||||
}
|
||||
|
||||
// ------ SETUP GEOMETRY ----------------
|
||||
@@ -252,6 +298,7 @@ bool RenderableVolumeExpert::initialize() {
|
||||
|
||||
_colorBoxRenderer->initialize();
|
||||
glm::size2_t dimensions = _colorBoxRenderer->dimensions();
|
||||
|
||||
ghoul::opengl::Texture* backTexture = _colorBoxRenderer->backFace();
|
||||
ghoul::opengl::Texture* frontTexture = _colorBoxRenderer->frontFace();
|
||||
_output = new ghoul::opengl::Texture(glm::size3_t(dimensions[0],dimensions[1],1));
|
||||
@@ -267,7 +314,7 @@ bool RenderableVolumeExpert::initialize() {
|
||||
// Compile kernels
|
||||
safeKernelCompilation();
|
||||
|
||||
|
||||
// create work group
|
||||
size_t local_x = 32;
|
||||
size_t local_y = 32;
|
||||
while (local_x > 1) {
|
||||
@@ -281,7 +328,6 @@ bool RenderableVolumeExpert::initialize() {
|
||||
local_y /= 2;
|
||||
}
|
||||
_ws = new ghoul::opencl::CLWorkSize({dimensions[0],dimensions[1]}, {local_x,local_y});
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -296,18 +342,21 @@ void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPositio
|
||||
if( ! _kernel.isValidKernel())
|
||||
return;
|
||||
|
||||
float speed = 50.0f;
|
||||
float time = sgct::Engine::getTime();
|
||||
glm::mat4 transform = camera->getViewProjectionMatrix();
|
||||
psc camPos = camera->getPosition();
|
||||
psc relative = thisPosition-camPos;
|
||||
double factor = pow(10.0,relative[3]);
|
||||
glm::mat4 camTransform = camera->getViewRotationMatrix();
|
||||
|
||||
double factor = pow(10.0,thisPosition[3]);
|
||||
transform = glm::translate(transform, glm::vec3(thisPosition[0]*factor, thisPosition[1]*factor, thisPosition[2]*factor));
|
||||
transform = glm::rotate(transform, time*speed, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
glm::mat4 transform = camera->getViewProjectionMatrix();
|
||||
transform = transform*camTransform;
|
||||
transform = glm::translate(transform, glm::vec3(relative[0]*factor, relative[1]*factor, relative[2]*factor));
|
||||
transform = glm::scale(transform, _boxScaling);
|
||||
_colorBoxRenderer->render(transform);
|
||||
|
||||
_textureLock->lock();
|
||||
_kernelLock->lock();
|
||||
|
||||
// tell opengl to finish everything before opencl takes ownerhip (uses) the textures
|
||||
glFinish();
|
||||
|
||||
// Aquire GL objects
|
||||
@@ -330,8 +379,12 @@ void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPositio
|
||||
_quadProgram->activate();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
_output->bind();
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// enable blending
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
@@ -339,6 +392,11 @@ void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPositio
|
||||
_kernelLock->unlock();
|
||||
_textureLock->unlock();
|
||||
|
||||
// disable blending
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
|
||||
_quadProgram->deactivate();
|
||||
}
|
||||
|
||||
@@ -353,6 +411,14 @@ void RenderableVolumeExpert::safeKernelCompilation() {
|
||||
for(auto option: _kernelOptions) {
|
||||
tmpProgram.setOption(option.first, option.second);
|
||||
}
|
||||
|
||||
for(auto defintion: _kernelDefinitions) {
|
||||
tmpProgram.addDefinition(defintion.first, defintion.second);
|
||||
}
|
||||
|
||||
// add the include directories
|
||||
tmpProgram.addIncludeDirectory(_kernelIncludes);
|
||||
|
||||
if(tmpProgram.build()) {
|
||||
ghoul::opencl::CLKernel tmpKernel = tmpProgram.createKernel("volumeraycaster");
|
||||
if(tmpKernel.isValidKernel()) {
|
||||
@@ -384,7 +450,6 @@ void RenderableVolumeExpert::safeKernelCompilation() {
|
||||
if(argumentError)
|
||||
return;
|
||||
|
||||
|
||||
tmpKernel.setArgument(0, &_clFrontTexture);
|
||||
tmpKernel.setArgument(1, &_clBackTexture);
|
||||
tmpKernel.setArgument(2, &_clOutput);
|
||||
@@ -429,24 +494,24 @@ void RenderableVolumeExpert::safeUpdateTexture(const ghoul::filesystem::File& fi
|
||||
|
||||
// create the new texture
|
||||
ghoul::opengl::Texture* newTexture = loadTransferFunction(file.path());
|
||||
|
||||
if(newTexture) {
|
||||
|
||||
// upload the new texture and create a cl memory
|
||||
newTexture->uploadTexture();
|
||||
cl_mem clNewTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *newTexture);
|
||||
|
||||
// check if opencl memory is unsuccessfull
|
||||
if(clNewTexture == 0) {
|
||||
delete newTexture;
|
||||
return;
|
||||
}
|
||||
|
||||
// everything is ok, critical point to replace current texture pointers
|
||||
// everything seems ok, critical point to replace current texture pointers
|
||||
_textureLock->lock();
|
||||
|
||||
// deallocate current texture
|
||||
delete _transferFunctions.at(fileID);
|
||||
clReleaseMemObject(_clTransferFunctions.at(fileID));
|
||||
delete _transferFunctions.at(fileID);
|
||||
|
||||
// set the new texture
|
||||
_transferFunctions.at(fileID) = newTexture;
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <ghoul/opencl/clworksize.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <sgct.h>
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
@@ -39,29 +41,25 @@ using namespace ghoul::opengl;
|
||||
|
||||
namespace openspace {
|
||||
|
||||
VolumeRaycasterBox::VolumeRaycasterBox() {
|
||||
VolumeRaycasterBox::VolumeRaycasterBox(): _fbo(nullptr), _backTexture(nullptr),
|
||||
_frontTexture(nullptr), _boxProgram(nullptr), _boundingBox(nullptr) {
|
||||
|
||||
}
|
||||
|
||||
VolumeRaycasterBox::~VolumeRaycasterBox() {}
|
||||
VolumeRaycasterBox::~VolumeRaycasterBox() {
|
||||
if(_boundingBox)
|
||||
delete _boundingBox;
|
||||
|
||||
if(_fbo) {
|
||||
_fbo->detachAll(); // maybe not needed
|
||||
delete _fbo;
|
||||
}
|
||||
}
|
||||
|
||||
bool VolumeRaycasterBox::initialize() {
|
||||
_boundingBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular);
|
||||
|
||||
// ------ SETUP SHADER -----------------
|
||||
_boxProgram = new ProgramObject("RaycastBoxProgram");
|
||||
/*
|
||||
ShaderObject* vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex,
|
||||
absPath("${BASE_PATH}/shaders/exitpoints.vert"));
|
||||
ShaderObject* fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment,
|
||||
absPath("${BASE_PATH}/shaders/exitpoints.frag"));
|
||||
|
||||
|
||||
_boxProgram->attachObject(vertexShader);
|
||||
_boxProgram->attachObject(fragmentShader);
|
||||
_boxProgram->compileShaderObjects();
|
||||
_boxProgram->linkProgramObject();
|
||||
*/
|
||||
OsEng.configurationManager().getValue("RaycastProgram", _boxProgram);
|
||||
_MVPLocation = _boxProgram->uniformLocation("modelViewProjection");
|
||||
|
||||
@@ -69,49 +67,68 @@ bool VolumeRaycasterBox::initialize() {
|
||||
_fbo = new FramebufferObject();
|
||||
_fbo->activate();
|
||||
|
||||
// changed from getActiveXResolution to getCurrentViewportPixelCoords because
|
||||
// if there are more viewports in the same screen.
|
||||
//size_t x = sgct::Engine::instance()->getActiveXResolution();
|
||||
//size_t y = sgct::Engine::instance()->getActiveYResolution();
|
||||
int x1, xSize, y1, ySize;
|
||||
sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize);
|
||||
size_t x = xSize;
|
||||
size_t y = ySize;
|
||||
|
||||
size_t x = sgct::Engine::instance()->getActiveXResolution();
|
||||
size_t y = sgct::Engine::instance()->getActiveYResolution();
|
||||
_dimensions = glm::size2_t(x, y);
|
||||
|
||||
_backTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1));
|
||||
_frontTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1));
|
||||
_backTexture = new Texture(glm::size3_t(x,y,1));
|
||||
_frontTexture = new Texture(glm::size3_t(x,y,1));
|
||||
_backTexture->uploadTexture();
|
||||
_frontTexture->uploadTexture();
|
||||
_fbo->attachTexture(_backTexture, GL_COLOR_ATTACHMENT0);
|
||||
_fbo->attachTexture(_frontTexture, GL_COLOR_ATTACHMENT1);
|
||||
|
||||
_fbo->deactivate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VolumeRaycasterBox::render(glm::mat4 MVP) {
|
||||
GLuint activeFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO
|
||||
void VolumeRaycasterBox::render(const glm::mat4& MVP) {
|
||||
GLuint activeFBO = FramebufferObject::getActiveObject(); // Save SGCTs main FBO
|
||||
_fbo->activate();
|
||||
_boxProgram->activate();
|
||||
_boxProgram->setUniform(_MVPLocation, MVP);
|
||||
|
||||
sgct_core::Frustum::FrustumMode mode = sgct::Engine::instance()->
|
||||
getActiveWindowPtr()->
|
||||
getCurrentViewport()->
|
||||
getEye();
|
||||
|
||||
// oh god why..?
|
||||
if(mode == sgct_core::Frustum::FrustumMode::Mono ||
|
||||
mode == sgct_core::Frustum::FrustumMode::StereoLeftEye) {
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
}
|
||||
|
||||
// make sure GL_CULL_FACE is enabled (it should be)
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Draw backface
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT);
|
||||
_boundingBox->draw();
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// Draw frontface
|
||||
// Draw frontface (now the normal cull face is is set)
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
_boundingBox->draw();
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
_boxProgram->deactivate();
|
||||
_fbo->deactivate();
|
||||
|
||||
// rebind the previous FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, activeFBO);
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ bool SceneGraph::initialize() {
|
||||
// TODO: Set scaling dependent on the position and distance
|
||||
// set position for camera
|
||||
psc cameraPosition = positionNode->getPosition();
|
||||
cameraPosition += psc(0.0,0.0,1.0,2.0);
|
||||
cameraPosition += psc(0.0,0.0,2.0,0.0);
|
||||
c->setPosition(cameraPosition);
|
||||
c->setCameraDirection(glm::vec3(0,0,-1));
|
||||
c->setScaling(glm::vec2(1.0,0.0));
|
||||
|
||||
@@ -44,6 +44,7 @@ const glm::mat4 & Camera::getViewRotationMatrix() const {
|
||||
|
||||
void Camera::compileViewRotationMatrix() {
|
||||
// convert from quaternion to rotationmatrix using glm
|
||||
|
||||
viewRotationMatrix_ = glm::mat4_cast(viewRotation_);
|
||||
|
||||
// the camera matrix needs to be rotated inverse to the world
|
||||
|
||||
248
src/util/kameleonwrapper.cpp
Normal file
248
src/util/kameleonwrapper.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 *
|
||||
* *
|
||||
* 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 <ghoul/logging/logmanager.h>
|
||||
#include <openspace/util/kameleonwrapper.h>
|
||||
|
||||
#include <ccmc/Model.h>
|
||||
#include <ccmc/Interpolator.h>
|
||||
#include <ccmc/BATSRUS.h>
|
||||
#include <ccmc/ENLIL.h>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
std::string _loggerCat = "KameleonWrapper";
|
||||
|
||||
KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _type(model) {
|
||||
switch (_type) {
|
||||
case Model::BATSRUS:
|
||||
_model = new ccmc::BATSRUS();
|
||||
if(!_model) LERROR("BATSRUS:Failed to create model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("BATSRUS:Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("BATSRUS:Failed to create interpolator");
|
||||
break;
|
||||
case Model::ENLIL:
|
||||
_model = new ccmc::ENLIL();
|
||||
if(!_model) LERROR("Failed to create model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("Failed to create interpolator");
|
||||
break;
|
||||
default:
|
||||
LERROR("No valid model type provided!");
|
||||
}
|
||||
}
|
||||
|
||||
KameleonWrapper::~KameleonWrapper() {
|
||||
delete _model;
|
||||
delete _interpolator;
|
||||
}
|
||||
|
||||
float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::size3_t outDimensions) {
|
||||
assert(_model && _interpolator);
|
||||
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
|
||||
assert(_type == Model::ENLIL || _type == Model::BATSRUS);
|
||||
LINFO("Loading CDF data");
|
||||
|
||||
int size = outDimensions.x*outDimensions.y*outDimensions.z;
|
||||
float* data = new float[size];
|
||||
|
||||
// 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) {
|
||||
LERROR("Something went wrong");
|
||||
delete[] data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string v_x = tokens.at(0), v_y = tokens.at(1), v_z = tokens.at(2);
|
||||
/*
|
||||
for(auto t: tokens)
|
||||
LDEBUG("t: " << t);
|
||||
*/
|
||||
/*
|
||||
LERROR("getVariableAttributeNames");
|
||||
std::vector<std::string> attributeNames = _model->getVariableAttributeNames();
|
||||
for(auto name : attributeNames)
|
||||
LDEBUG(name);
|
||||
*/
|
||||
//_model->getVa
|
||||
|
||||
//auto fan = std::find(attributeNames.begin(), attributeNames.end(), "");
|
||||
|
||||
|
||||
//KameleonWrapper (Debug) grid_system_1
|
||||
//KameleonWrapper (Debug) grid_1_type
|
||||
|
||||
LDEBUG("Using coordinate system: " << v_x << ", " << v_y << ", " << v_z);
|
||||
|
||||
float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat();
|
||||
float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat();
|
||||
float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat();
|
||||
float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat();
|
||||
float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat();
|
||||
float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat();
|
||||
float varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat();
|
||||
float varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat();
|
||||
|
||||
float stepX = (xMax-xMin)/(static_cast<float>(outDimensions.x));
|
||||
float stepY = (yMax-yMin)/(static_cast<float>(outDimensions.y));
|
||||
float stepZ = (zMax-zMin)/(static_cast<float>(outDimensions.z));
|
||||
|
||||
|
||||
LDEBUG(v_x << "Min: " << xMin);
|
||||
LDEBUG(v_x << "Max: " << xMax);
|
||||
LDEBUG(v_y << "Min: " << yMin);
|
||||
LDEBUG(v_y << "Max: " << yMax);
|
||||
LDEBUG(v_z << "Min: " << zMin);
|
||||
LDEBUG(v_z << "Max: " << zMax);
|
||||
LDEBUG(var << "Min: " << varMin);
|
||||
LDEBUG(var << "Max: " << varMax);
|
||||
|
||||
int barWidth = 70;
|
||||
int lastiProgress = -1;
|
||||
for (int x = 0; x < outDimensions.x; ++x) {
|
||||
float progress = static_cast<float>(x) / static_cast<float>(outDimensions.x-1);
|
||||
int iprogress = static_cast<int>(progress*100.0f);
|
||||
if (iprogress != lastiProgress) {
|
||||
|
||||
int pos = barWidth * progress;
|
||||
int eqWidth = pos+1;
|
||||
int spWidth = barWidth - pos + 2;
|
||||
std::cout << "[" << std::setfill('=') << std::setw(eqWidth)
|
||||
<< ">" << std::setfill(' ') << std::setw(spWidth)
|
||||
<< "] " << iprogress << " % \r" << std::flush;
|
||||
}
|
||||
lastiProgress = iprogress;
|
||||
|
||||
for (int y = 0; y < outDimensions.y; ++y) {
|
||||
for (int z = 0; z < outDimensions.z; ++z) {
|
||||
|
||||
int index = x + y*outDimensions.x + z*outDimensions.x*outDimensions.y;
|
||||
|
||||
if(_type == Model::BATSRUS) {
|
||||
float xPos = xMin + stepX*x;
|
||||
float yPos = yMin + stepY*y;
|
||||
float zPos = zMin + stepZ*z;
|
||||
|
||||
// get interpolated data value for (xPos, yPos, zPos)
|
||||
float value = _interpolator->interpolate(var, xPos, yPos, zPos);
|
||||
|
||||
// scale to [0,1]
|
||||
data[index] = (value-varMin)/(varMax-varMin);
|
||||
} else if (_type == Model::ENLIL) {
|
||||
//LDEBUG("data: " << theval);
|
||||
|
||||
// Calculate array index
|
||||
//unsigned int index = r + theta*xDim_ + phi*xDim_*yDim_;
|
||||
|
||||
// Put r in the [0..sqrt(3)] range
|
||||
float rNorm = sqrt(3.0)*(float)x/(float)(outDimensions.x-1);
|
||||
|
||||
// Put theta in the [0..PI] range
|
||||
float thetaNorm = M_PI*(float)y/(float)(outDimensions.y-1);
|
||||
|
||||
// Put phi in the [0..2PI] range
|
||||
float phiNorm = 2.0*M_PI*(float)z/(float)(outDimensions.z-1);
|
||||
|
||||
// Go to physical coordinates before sampling
|
||||
float rPh = xMin + rNorm*(xMax-xMin);
|
||||
float thetaPh = thetaNorm;
|
||||
//phi range needs to be mapped to the slightly different
|
||||
// model range to avoid gaps in the data
|
||||
// Subtract a small term to avoid rounding errors when comparing
|
||||
// to phiMax.
|
||||
float phiPh = zMin + phiNorm/(2.0*M_PI)*(zMax-zMin-0.000001);
|
||||
|
||||
// Hardcoded variables (rho or rho - rho_back)
|
||||
// TODO Don't hardcode, make more flexible
|
||||
float varValue = 0.f;//, rho_back = 0.f, diff = 0.f;
|
||||
// See if sample point is inside domain
|
||||
if (rPh < xMin || rPh > xMax || thetaPh < yMin ||
|
||||
thetaPh > yMax || phiPh < zMin || phiPh > zMax) {
|
||||
if (phiPh > zMax) {
|
||||
std::cout << "Warning: There might be a gap in the data\n";
|
||||
}
|
||||
// Leave values at zero if outside domain
|
||||
} else { // if inside
|
||||
|
||||
// ENLIL CDF specific hacks!
|
||||
// Convert from meters to AU for interpolator
|
||||
rPh /= ccmc::constants::AU_in_meters;
|
||||
// Convert from colatitude [0, pi] rad to latitude [-90, 90] degrees
|
||||
thetaPh = -thetaPh*180.f/M_PI+90.f;
|
||||
// Convert from [0, 2pi] rad to [0, 360] degrees
|
||||
phiPh = phiPh*180.f/M_PI;
|
||||
// Sample
|
||||
varValue = _interpolator->interpolate(var, rPh, thetaPh, phiPh);
|
||||
//rho_back = _interpolator->interpolate("rho-back",rPh,thetaPh,phiPh);
|
||||
|
||||
// Calculate difference (or just rho)
|
||||
//diff = rho;
|
||||
//diff = rho - rho_back;
|
||||
|
||||
// Clamp to 0
|
||||
//if (diff < 0.f) diff = 0.f;
|
||||
}
|
||||
//if(var < 0.0f) var = 0.0f;
|
||||
//data[index] = var;
|
||||
data[index] = (varValue-varMin)/(varMax-varMin);
|
||||
//LDEBUG("varValue:" << varValue);
|
||||
//LDEBUG("data[index]:" << data[index]);
|
||||
//data[index] = var;
|
||||
//data[index] = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
LINFO("Done!");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user