Merge remote-tracking branch 'origin/feature/iSWA' into develop

Conflicts:
	data/scene/default.scene
	scripts/bind_keys.lua
This commit is contained in:
Alexander Bock
2016-06-01 19:46:23 +02:00
123 changed files with 257840 additions and 392 deletions

2
.gitignore vendored
View File

@@ -116,6 +116,8 @@ data/scene/dawn/vestaprojection/textures/projectMe.png
data/spice/MAR063.BSP
data/spice/de430_1850-2150.bsp
data/spice/jup260.bsp
data/BATSRUS.cdf
data/ENLIL.cdf
data/scene/newhorizons/pluto/pluto/images
data/spice/nh_kernels/
data/scene/jupiter/jupiter/textures/Jupiter-text.png

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" ?>
<Cluster masterAddress="127.0.0.1">
<Node address="127.0.0.1" port="20401">
<Window fullScreen="false" numberOfSamples="0" border="true">
<Window fullScreen="false" numberOfSamples="8" border="true">
<Pos x="10" y="100" />
<Size x="320" y="480" />
<Viewport>
@@ -17,7 +17,7 @@
</Viewplane>
</Viewport>
</Window>
<Window fullScreen="false" numberOfSamples="0" border="false">
<Window fullScreen="false" numberOfSamples="8" border="false">
<Pos x="340" y="100" />
<Size x="320" y="480" />
<Viewport>

32
data/cdflist.json Normal file
View File

@@ -0,0 +1,32 @@
[
{"group" : "CCMC-3D-CDF",
"fieldlinefile" : "${OPENSPACE_DATA}/scene/iswa/cdf/fieldlines.json",
"cdfs" : [
{
"name" : "CCMC-00:00:00",
"path" : "${OPENSPACE_DATA}/../../GM_CDF/3d__var_1_e20000101-000000-000.out.cdf",
"date" : "2000-01-01T00:00:00.00"
},
{
"name" : "CCMC-00:30:00",
"path" : "${OPENSPACE_DATA}/../../GM_CDF/3d__var_1_e20000101-003000-000.out.cdf",
"date" : "2000-01-01T00:30:00.00"
},
{
"name" : "CCMC-01:00:00",
"path" : "${OPENSPACE_DATA}/../../GM_CDF/3d__var_1_e20000101-010000-000.out.cdf",
"date" : "2000-01-01T10:00:00.00"
},
{
"name" : "CCMC-01:30:00",
"path" : "${OPENSPACE_DATA}/../../GM_CDF/3d__var_1_e20000101-013000-000.out.cdf",
"date" : "2000-01-01T01:30:00.00"
},
{
"name" : "CCMC-02:00:00",
"path" : "${OPENSPACE_DATA}/../../GM_CDF/3d__var_1_e20000101-020000-000.out.cdf",
"date" : "2000-01-01T02:00:00.00"
}
]
}
]

40
data/cdflist.txt Normal file
View File

@@ -0,0 +1,40 @@
{"cdfgroups" : [{
"group" : "CCMC-3D-CDF",
"fieldlinefile" : "${OPENSPACE_DATA}/scene/iswa/cdf/fieldlines.json",
"cdfs" : [
{
"name" : "CCMC-00:00:00",
"path" : "../../GM_CDF/3d__var_1_e20000101-000000-000.out.cdf"
"time" : "2000-01-01T00:00:00.00"
},
{
"name" : "CCMC-00:30:00",
"path" : "../../GM_CDF/3d__var_1_e20000101-003000-000.out.cdf"
"time" : "2000-01-01T00:00:00.00"
},
{
"name" : "CCMC-01:00:00",
"path" : "../../GM_CDF/3d__var_1_e20000101-010000-000.out.cdf"
"time" : "2000-01-01T10:00:00.00"
},
{
"name" : "CCMC-01:30:00",
"path" : "../../GM_CDF/3d__var_1_e20000101-013000-000.out.cdf"
"time" : "2000-01-01T01:30:00.00"
},
{
"name" : "CCMC-02:00:00",
"path" : "../../GM_CDF/3d__var_1_e20000101-020000-000.out.cdf"
"time" : "2000-01-01T02:00:00.00"
},
]
}
]
}
CCMC-3D-CDF
${OPENSPACE_DATA}/scene/iswa/cdf/fieldlines.json
CCMC-00:00:00 ../../GM_CDF/3d__var_1_e20000101-000000-000.out.cdf 2000-01-01T00:00:00.00
CCMC-00:30:00 ../../GM_CDF/3d__var_1_e20000101-003000-000.out.cdf 2000-01-01T00:30:00.00
CCMC-01:00:00 ../../GM_CDF/3d__var_1_e20000101-010000-000.out.cdf 2000-01-01T01:00:00.00
CCMC-01:30:00 ../../GM_CDF/3d__var_1_e20000101-013000-000.out.cdf 2000-01-01T01:30:00.00
CCMC-02:00:00 ../../GM_CDF/3d__var_1_e20000101-020000-000.out.cdf 2000-01-01T02:00:00.00

231917
data/ionosphere_variables.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,8 @@ local file3 = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_open_sout
local file4 = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_solar_wind_all.txt';
local file5 = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_separatrix_seeds_all.txt';
local volumeFile = '${OPENSPACE_DATA}/batsrus.cdf';
return {
{
Name = "Fieldlines1",
@@ -16,7 +18,7 @@ return {
Type = "RenderableFieldlines",
VectorField = {
Type = "VolumeKameleon",
File = "${OPENSPACE_DATA}/batsrus.cdf",
File = volumeFile,
Model = "BATSRUS",
Variables = {"bx", "by", "bz"}
},
@@ -42,7 +44,7 @@ return {
Type = "RenderableFieldlines",
VectorField = {
Type = "VolumeKameleon",
File = "${OPENSPACE_DATA}/batsrus.cdf",
File = volumeFile,
Model = "BATSRUS",
Variables = {"bx", "by", "bz"}
},
@@ -68,7 +70,7 @@ return {
Type = "RenderableFieldlines",
VectorField = {
Type = "VolumeKameleon",
File = "${OPENSPACE_DATA}/batsrus.cdf",
File = volumeFile,
Model = "BATSRUS",
Variables = {"bx", "by", "bz"}
},
@@ -94,7 +96,7 @@ return {
Type = "RenderableFieldlines",
VectorField = {
Type = "VolumeKameleon",
File = "${OPENSPACE_DATA}/batsrus.cdf",
File = volumeFile,
Model = "BATSRUS",
Variables = {"bx", "by", "bz"}
},
@@ -120,7 +122,7 @@ return {
Type = "RenderableFieldlines",
VectorField = {
Type = "VolumeKameleon",
File = "${OPENSPACE_DATA}/batsrus.cdf",
File = volumeFile,
Model = "BATSRUS",
Variables = {"bx", "by", "bz"}
},

View File

@@ -0,0 +1,7 @@
{
"Separatrix Seeds": "${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_separatrix_seeds_all.txt",
"Closed Seeds": "${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_closed_seeds_all.txt",
"Open North Seeds": "${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_open_north_all.txt",
"Open South Seeds": "${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_open_south_all.txt",
"Solar Wind Seeds": "${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_solar_wind_all.txt"
}

View File

@@ -0,0 +1 @@
${SCENE}/iswa/tfs/colormap_autumn.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

View File

@@ -0,0 +1 @@
${SCENE}/iswa/tfs/colormap_hot.jpg

View File

@@ -0,0 +1 @@
${SCENE}/iswa/tfs/colormap_parula.jpg

BIN
data/scene/iswa/tfs/red.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

View File

@@ -0,0 +1,3 @@
${SCENE}/iswa/tfs/red.jpg
${SCENE}/iswa/tfs/green.jpg
${SCENE}/iswa/tfs/blue.jpg

View File

@@ -208,7 +208,7 @@ return {
Size = {1.0, 6.4},
Origin = "Center",
Billboard = true,
ProjectionListener = true,
ProjectionListener = false,
Texture = "textures/Pluto-Text.png"
},
Ephemeris = {

View File

@@ -0,0 +1,31 @@
Geocentric Solar Ecliptic (GSE) frame:
+X is parallel to the geometric earth-sun position vector.
+Y axis is the normalized component of the geometric earth-sun velocity
vector orthogonal to the GSE +X axis.
+Z axis is parallel to the cross product of the GSE +X axis
and the GSE +Y axis.
\begindata
FRAME_GSE = 2
FRAME_2_NAME = 'GSE'
FRAME_2_CLASS = 5
FRAME_2_CLASS_ID = 2
FRAME_2_CENTER = 399
FRAME_2_RELATIVE = 'J2000'
FRAME_2_DEF_STYLE = 'PARAMETERIZED'
FRAME_2_FAMILY = 'TWO-VECTOR'
FRAME_2_PRI_AXIS = 'X'
FRAME_2_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
FRAME_2_PRI_OBSERVER = 'EARTH'
FRAME_2_PRI_TARGET = 'SUN'
FRAME_2_PRI_ABCORR = 'NONE'
FRAME_2_SEC_AXIS = 'Y'
FRAME_2_SEC_VECTOR_DEF = 'OBSERVER_TARGET_VELOCITY'
FRAME_2_SEC_OBSERVER = 'EARTH'
FRAME_2_SEC_TARGET = 'SUN'
FRAME_2_SEC_ABCORR = 'NONE'
FRAME_2_SEC_FRAME = 'J2000'

View File

@@ -0,0 +1,31 @@
Geocentric Solar Magnetospheric (GSM) frame:
+X is parallel to the geometric earth-sun position vector.
+Z axis is normalized component of north centered geomagnetic dipole
vector orthogonal to GSM +X axis.
+Y completes the right-handed frame.
\begindata
FRAME_GSM = 1
FRAME_1_NAME = 'GSM'
FRAME_1_CLASS = 5
FRAME_1_CLASS_ID = 1
FRAME_1_CENTER = 399
FRAME_1_RELATIVE = 'GALACTIC'
FRAME_1_DEF_STYLE = 'PARAMETERIZED'
FRAME_1_FAMILY = 'TWO-VECTOR'
FRAME_1_PRI_AXIS = 'X'
FRAME_1_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
FRAME_1_PRI_OBSERVER = 'EARTH'
FRAME_1_PRI_TARGET = 'SUN'
FRAME_1_PRI_ABCORR = 'NONE'
FRAME_1_SEC_AXIS = 'Z'
FRAME_1_SEC_VECTOR_DEF = 'CONSTANT'
FRAME_1_SEC_FRAME = 'ECLIPJ2000'
FRAME_1_SEC_SPEC = 'LATITUDINAL'
FRAME_1_SEC_UNITS = 'DEGREES'
FRAME_1_SEC_LONGITUDE = 288.43
FRAME_1_SEC_LATITUDE = 79.54

View File

@@ -0,0 +1,264 @@
Dynamic Heliospheric Coordinate Frames developed for the NASA STEREO mission
The coordinate frames in this file all have ID values based on the pattern
18ccple, where
18 = Prefix to put in the allowed 1400000 to 2000000 range
cc = 03 for geocentric, 10 for heliocentric
p = Pole basis: 1=geographic, 2=geomagnetic, 3=ecliptic, 4=solar
l = Longitude basis: 1=Earth-Sun, 2=ecliptic
e = Ecliptic basis: 0=J2000, 1=mean, 2=true
Author: William Thompson
NASA Goddard Space Flight Center
Code 612.1
Greenbelt, MD 20771
William.T.Thompson.1@gsfc.nasa.gov
History
Version 1, 18-Feb-2005, WTT, initial release
GSE and ECLIPDATE definitions from examples in frames.req by C.H. Acton
HEE definition is based on the GSE example
Version 2, 22-Feb-2005, WTT
Modified HCI definition to tie to IAU_SUN frame
Use RECTANGULAR specification in HEEQ frame
Version 3, 23-Feb-2005, WTT
Correct GSE and HEE definitions to use ECLIPDATE axis
Version 4, 08-Aug-2008, WTT
Add GEORTN coordinate system (comment added 30-Aug-2010)
Mean Ecliptic of Date (ECLIPDATE) Frame
Definition of the Mean Ecliptic of Date frame:
All vectors are geometric: no aberration corrections are
used.
The X axis is the first point in Aries for the mean ecliptic of
date, and the Z axis points along the ecliptic north pole.
The Y axis is Z cross X, completing the right-handed
reference frame.
This reference frame can be used to realize the HAE coordinate
system by using the sun as the observing body.
\begindata
FRAME_ECLIPDATE = 1803321
FRAME_1803321_NAME = 'ECLIPDATE'
FRAME_1803321_CLASS = 5
FRAME_1803321_CLASS_ID = 1803321
FRAME_1803321_CENTER = 399
FRAME_1803321_RELATIVE = 'J2000'
FRAME_1803321_DEF_STYLE = 'PARAMETERIZED'
FRAME_1803321_FAMILY = 'MEAN_ECLIPTIC_AND_EQUINOX_OF_DATE'
FRAME_1803321_PREC_MODEL = 'EARTH_IAU_1976'
FRAME_1803321_OBLIQ_MODEL = 'EARTH_IAU_1980'
FRAME_1803321_ROTATION_STATE = 'ROTATING'
\begintext
Geocentric Solar Ecliptic (GSE) Frame
Definition of the Geocentric Solar Ecliptic frame:
All vectors are geometric: no aberration corrections are
used.
The position of the sun relative to the earth is the primary
vector: the X axis points from the earth to the sun.
The northern surface normal to the mean ecliptic of date is the
secondary vector: the Z axis is the component of this vector
orthogonal to the X axis.
The Y axis is Z cross X, completing the right-handed
reference frame.
\begindata
FRAME_GSE = 1803311
FRAME_1803311_NAME = 'GSE'
FRAME_1803311_CLASS = 5
FRAME_1803311_CLASS_ID = 1803311
FRAME_1803311_CENTER = 399
FRAME_1803311_RELATIVE = 'J2000'
FRAME_1803311_DEF_STYLE = 'PARAMETERIZED'
FRAME_1803311_FAMILY = 'TWO-VECTOR'
FRAME_1803311_PRI_AXIS = 'X'
FRAME_1803311_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
FRAME_1803311_PRI_OBSERVER = 'EARTH'
FRAME_1803311_PRI_TARGET = 'SUN'
FRAME_1803311_PRI_ABCORR = 'NONE'
FRAME_1803311_SEC_AXIS = 'Z'
FRAME_1803311_SEC_VECTOR_DEF = 'CONSTANT'
FRAME_1803311_SEC_FRAME = 'ECLIPDATE'
FRAME_1803311_SEC_SPEC = 'RECTANGULAR'
FRAME_1803311_SEC_VECTOR = ( 0, 0, 1 )
\begintext
Heliocentric Inertial (HCI) Frame
Definition of the Heliocentric Inertial frame:
All vectors are geometric: no aberration corrections are
used.
The solar rotation axis is the primary vector: the Z axis points
in the solar north direction.
The solar ascending node on the ecliptic of J2000 forms the X
axis.
The Y axis is Z cross X, completing the right-handed
reference frame.
\begindata
FRAME_HCI = 1810420
FRAME_1810420_NAME = 'HCI'
FRAME_1810420_CLASS = 5
FRAME_1810420_CLASS_ID = 1810420
FRAME_1810420_CENTER = 10
FRAME_1810420_RELATIVE = 'J2000'
FRAME_1810420_DEF_STYLE = 'PARAMETERIZED'
FRAME_1810420_FAMILY = 'TWO-VECTOR'
FRAME_1810420_PRI_AXIS = 'Z'
FRAME_1810420_PRI_VECTOR_DEF = 'CONSTANT'
FRAME_1810420_PRI_FRAME = 'IAU_SUN'
FRAME_1810420_PRI_SPEC = 'RECTANGULAR'
FRAME_1810420_PRI_VECTOR = ( 0, 0, 1 )
FRAME_1810420_SEC_AXIS = 'Y'
FRAME_1810420_SEC_VECTOR_DEF = 'CONSTANT'
FRAME_1810420_SEC_FRAME = 'ECLIPJ2000'
FRAME_1810420_SEC_SPEC = 'RECTANGULAR'
FRAME_1810420_SEC_VECTOR = ( 0, 0, 1 )
\begintext
Heliocentric Earth Ecliptic (HEE) Frame
Definition of the Heliocentric Earth Ecliptic frame:
All vectors are geometric: no aberration corrections are
used.
The position of the earth relative to the sun is the primary
vector: the X axis points from the sun to the earth.
The northern surface normal to the mean ecliptic of date is the
secondary vector: the Z axis is the component of this vector
orthogonal to the X axis.
The Y axis is Z cross X, completing the right-handed
reference frame.
\begindata
FRAME_HEE = 1810311
FRAME_1810311_NAME = 'HEE'
FRAME_1810311_CLASS = 5
FRAME_1810311_CLASS_ID = 1810311
FRAME_1810311_CENTER = 10
FRAME_1810311_RELATIVE = 'J2000'
FRAME_1810311_DEF_STYLE = 'PARAMETERIZED'
FRAME_1810311_FAMILY = 'TWO-VECTOR'
FRAME_1810311_PRI_AXIS = 'X'
FRAME_1810311_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
FRAME_1810311_PRI_OBSERVER = 'SUN'
FRAME_1810311_PRI_TARGET = 'EARTH'
FRAME_1810311_PRI_ABCORR = 'NONE'
FRAME_1810311_SEC_AXIS = 'Z'
FRAME_1810311_SEC_VECTOR_DEF = 'CONSTANT'
FRAME_1810311_SEC_FRAME = 'ECLIPDATE'
FRAME_1810311_SEC_SPEC = 'RECTANGULAR'
FRAME_1810311_SEC_VECTOR = ( 0, 0, 1 )
\begintext
Heliocentric Earth Equatorial (HEEQ) Frame
Definition of the Heliocentric Earth Equatorial frame:
All vectors are geometric: no aberration corrections are
used.
The solar rotation axis is the primary vector: the Z axis points
in the solar north direction.
The position of the sun relative to the earth is the secondary
vector: the X axis is the component of this position vector
orthogonal to the Z axis.
The Y axis is Z cross X, completing the right-handed
reference frame.
\begindata
FRAME_HEEQ = 1810411
FRAME_1810411_NAME = 'HEEQ'
FRAME_1810411_CLASS = 5
FRAME_1810411_CLASS_ID = 1810411
FRAME_1810411_CENTER = 10
FRAME_1810411_RELATIVE = 'J2000'
FRAME_1810411_DEF_STYLE = 'PARAMETERIZED'
FRAME_1810411_FAMILY = 'TWO-VECTOR'
FRAME_1810411_PRI_AXIS = 'Z'
FRAME_1810411_PRI_VECTOR_DEF = 'CONSTANT'
FRAME_1810411_PRI_FRAME = 'IAU_SUN'
FRAME_1810411_PRI_SPEC = 'RECTANGULAR'
FRAME_1810411_PRI_VECTOR = ( 0, 0, 1 )
FRAME_1810411_SEC_AXIS = 'X'
FRAME_1810411_SEC_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
FRAME_1810411_SEC_OBSERVER = 'SUN'
FRAME_1810411_SEC_TARGET = 'EARTH'
FRAME_1810411_SEC_ABCORR = 'NONE'
FRAME_1810411_SEC_FRAME = 'IAU_SUN'
\begintext
Geocentric Radial Tangential Normal (GEORTN) Frame
Definition of the Geocentric RTN Frame
All vectors are geometric: no aberration corrections are used.
The position of Earth relative to the Sun is the primary
vector: the X axis points from the Sun center to Earth
The solar rotation axis is the secondary vector: the Z axis is
the component of the solar north direction perpendicular to X.
The Y axis is Z cross X, completing the right-handed reference
frame.
\begindata
FRAME_GEORTN = 1803410
FRAME_1803410_NAME = 'GEORTN'
FRAME_1803410_CLASS = 5
FRAME_1803410_CLASS_ID = 1803410
FRAME_1803410_CENTER = 10
FRAME_1803410_RELATIVE = 'J2000'
FRAME_1803410_DEF_STYLE = 'PARAMETERIZED'
FRAME_1803410_FAMILY = 'TWO-VECTOR'
FRAME_1803410_PRI_AXIS = 'X'
FRAME_1803410_PRI_VECTOR_DEF = 'OBSERVER_TARGET_POSITION'
FRAME_1803410_PRI_OBSERVER = 'SUN'
FRAME_1803410_PRI_TARGET = 'EARTH'
FRAME_1803410_PRI_ABCORR = 'NONE'
FRAME_1803410_PRI_FRAME = 'IAU_SUN'
FRAME_1803410_SEC_AXIS = 'Z'
FRAME_1803410_SEC_VECTOR_DEF = 'CONSTANT'
FRAME_1803410_SEC_FRAME = 'IAU_SUN'
FRAME_1803410_SEC_SPEC = 'RECTANGULAR'
FRAME_1803410_SEC_VECTOR = ( 0, 0, 1 )
\begintext

BIN
data/test2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
data/test3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

8236
ext/json/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,7 @@
#include <memory>
#include <string>
#include <vector>
#include <future>
namespace openspace {
@@ -55,20 +56,37 @@ public:
bool isAborted;
std::string filePath;
std::string errorMessage;
std::string format;
// Values set by others to be consumed by the DownloadManager
bool abortDownload;
};
struct MemoryFile {
char* buffer;
size_t size;
std::string format;
bool corrupted;
};
using DownloadProgressCallback = std::function<void(const FileFuture&)>;
using DownloadFinishedCallback = std::function<void(const FileFuture&)>;
using SuccessCallback = std::function<void(const MemoryFile&)>;
using ErrorCallback = std::function<void(const std::string&)>;
using RequestFinishedCallback = std::function<void(std::string)>;
using AsyncDownloadFinishedCallback =
std::function<void(const std::vector<std::shared_ptr<FileFuture>>&)>;
//Just a helper function to check if a future is ready to ".get()". Not specific
// to DownloadManager but is useful for anyone using the DownloadManager
template<typename R>
static bool futureReady(std::future<R> const& f)
{ return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }
DownloadManager(std::string requestURL, int applicationVersion,
bool useMultithreadedDownload = true);
// callers responsibility to delete
// callbacks happen on a different thread
std::shared_ptr<FileFuture> downloadFile(const std::string& url, const ghoul::filesystem::File& file,
bool overrideFile = true,
@@ -76,6 +94,15 @@ public:
DownloadProgressCallback progressCallback = DownloadProgressCallback()
);
std::shared_ptr<FileFuture> downloadToMemory(
const std::string& url, std::string& memoryBuffer,
DownloadFinishedCallback finishedCallback = DownloadFinishedCallback()
);
std::future<MemoryFile> fetchFile(
const std::string& url,
SuccessCallback successCallback = SuccessCallback(), ErrorCallback errorCallback = ErrorCallback());
std::vector<std::shared_ptr<FileFuture>> downloadRequestFiles(const std::string& identifier,
const ghoul::filesystem::Directory& destination, int version,
bool overrideFiles = true,
@@ -88,6 +115,9 @@ public:
bool overrideFiles, AsyncDownloadFinishedCallback callback
);
void getFileExtension(const std::string& url,
RequestFinishedCallback finishedCallback = RequestFinishedCallback());
private:
std::vector<std::string> _requestURL;
int _applicationVersion;

View File

@@ -42,6 +42,7 @@ public:
SelectionProperty(std::string identifier, std::string guiName);
void addOption(Option option);
void removeOptions();
const std::vector<Option>& options() const;
private:

View File

@@ -35,6 +35,8 @@ namespace properties {
class Renderable;
class Scene;
class SceneGraphNode;
class IswaGroup;
class ScreenSpaceRenderable;
Scene* sceneGraph();
SceneGraphNode* sceneGraphNode(const std::string& name);

View File

@@ -83,8 +83,10 @@ public:
static void setPscUniforms(ghoul::opengl::ProgramObject& program, const Camera& camera, const PowerScaledCoordinate& position);
private:
protected:
properties::BoolProperty _enabled;
private:
PowerScaledScalar boundingSphere_;
std::string _startTime;
std::string _endTime;

View File

@@ -29,6 +29,7 @@
#include <openspace/properties/vectorproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/rendering/screenspacerenderable.h>
namespace ghoul {
@@ -51,6 +52,7 @@ class Scene;
class Renderer;
class RaycasterManager;
class ScreenLog;
class ScreenSpaceRenderable;
class RenderEngine {
public:
@@ -100,6 +102,11 @@ public:
void setDisableRenderingOnMaster(bool enabled);
void registerScreenSpaceRenderable(std::shared_ptr<ScreenSpaceRenderable> s);
void unregisterScreenSpaceRenderable(std::shared_ptr<ScreenSpaceRenderable> s);
void unregisterScreenSpaceRenderable(std::string name);
std::shared_ptr<ScreenSpaceRenderable> screenSpaceRenderable(std::string name);
std::unique_ptr<ghoul::opengl::ProgramObject> buildRenderProgram(
std::string name,
std::string vsPath,
@@ -135,13 +142,14 @@ public:
// Temporary fade functionality
void startFading(int direction, float fadeDuration);
void sortScreenspaceRenderables();
// This is temporary until a proper screenspace solution is found ---abock
struct {
glm::vec2 _position;
unsigned int _size;
int _node;
} _onScreenInformation;
private:
void setRenderer(std::unique_ptr<Renderer> renderer);
RendererImplementation rendererFromString(const std::string& method);
@@ -171,6 +179,7 @@ private:
int _fadeDirection;
std::vector<ghoul::opengl::ProgramObject*> _programs;
std::vector<std::shared_ptr<ScreenSpaceRenderable>> _screenSpaceRenderables;
std::shared_ptr<ghoul::fontrendering::Font> _fontInfo = nullptr;
std::shared_ptr<ghoul::fontrendering::Font> _fontDate = nullptr;

View File

@@ -0,0 +1,126 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __SCREENSPACERENDERABLE_H__
#define __SCREENSPACERENDERABLE_H__
#include <ghoul/opengl/programobject.h>
#include <openspace/engine/wrapper/windowwrapper.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/properties/scalarproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/triggerproperty.h>
#include <ghoul/opengl/texture.h>
#include <modules/onscreengui/include/gui.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/engine/openspaceengine.h>
#include <ghoul/opengl/textureunit.h>
#include <openspace/util/camera.h>
#ifdef WIN32
#define _USE_MATH_DEFINES
#include <math.h>
#endif
namespace openspace {
/**
* @brief The base class for screen scape images and screen space framebuffers
* @details This base class handles general functionality specific to planes that
* are rendered infront of the camera. It implements protected methods and properties for converting
* the planes from spherical to euclidean coordinates and back. It also specifies the interface
* that it's children needs to implement.
*/
class ScreenSpaceRenderable : public properties::PropertyOwner {
public:
static ScreenSpaceRenderable* createFromDictionary(const ghoul::Dictionary& dictionary);
ScreenSpaceRenderable(const ghoul::Dictionary& dictionary);
~ScreenSpaceRenderable();
virtual void render() = 0;
virtual bool initialize() = 0;
virtual bool deinitialize() = 0;
virtual void update() = 0;
virtual bool isReady() const = 0;
bool isEnabled() const;
glm::vec2 euclideanPosition() const {return _euclideanPosition.value();};
glm::vec2 sphericalPosition() const {return _sphericalPosition.value();};
float depth() const {return _depth.value();};
protected:
void createPlane();
void useEuclideanCoordinates(bool b);
/**
* @brief Converts vec2 polar coordinates to euclidean
*
* @param polar the coordinates theta and phi
* @param radius the radius position value of the plane
*
* @return glm::vec2 with the x and y position value of the plane
*/
glm::vec2 toEuclidean(glm::vec2 polar, float radius);
/**
* @brief Converts vec2 euclidean coordinates to sperical
*
* @param euclidean the coordinates x and y
* @return glm::vec2 with the spherical coordinates theta and phi.
*/
glm::vec2 toSpherical(glm::vec2 euclidean);
void registerProperties();
void unregisterProperties();
void createShaders();
glm::mat4 scaleMatrix();
glm::mat4 rotationMatrix();
glm::mat4 translationMatrix();
void draw(glm::mat4 modelTransform);
properties::BoolProperty _enabled;
properties::BoolProperty _useFlatScreen;
properties::Vec2Property _euclideanPosition;
properties::Vec2Property _sphericalPosition;
properties::FloatProperty _depth;
properties::FloatProperty _scale;
properties::FloatProperty _alpha;
properties::TriggerProperty _delete;
GLuint _quad;
GLuint _vertexPositionBuffer;
const std::string _rendererPath;
ghoul::Dictionary _rendererData;
const std::string _vertexPath;
const std::string _fragmentPath;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
bool _useEuclideanCoordinates;
const float _planeDepth = -2.0;
glm::vec2 _originalViewportSize;
float _radius;
};
} // namespace openspace
#endif // __SCREENSPACERENDERABLE_H__

View File

@@ -41,6 +41,7 @@ namespace openspace {
TransferFunction(const std::string& filepath, TfChangedCallback tfChangedCallback = TfChangedCallback());
void setPath(const std::string& filepath);
ghoul::opengl::Texture& getTexture();
void bind();
void update();
glm::vec4 sample(size_t t);
size_t width();

View File

@@ -97,6 +97,11 @@ public:
std::vector<SceneGraphNode*> allSceneGraphNodes();
SceneGraph& sceneGraph();
void addSceneGraphNode(SceneGraphNode* node){
_graph.addSceneGraphNode(node);
}
/**
* Returns the Lua library that contains all Lua functions available to change the
* scene graph. The functions contained are

View File

@@ -25,11 +25,8 @@
#ifndef __SCENEGRAPH_H__
#define __SCENEGRAPH_H__
#include <ghoul/misc/dictionary.h>
#include <unordered_map>
#include <vector>
#include <string>
namespace openspace {
class SceneGraphNode;

View File

@@ -33,19 +33,29 @@ class Histogram {
public:
Histogram();
Histogram(float minBin, float maxBin, int numBins);
Histogram(float minBin, float maxBin, int numBins, float *data);
Histogram(float minValue, float maxValue, int numBins);
Histogram(float minValue, float maxValue, int numBins, float *data);
Histogram(Histogram&& other);
~Histogram();
Histogram& operator=(Histogram&& other);
int numBins() const;
float minBin() const;
float maxBin() const;
float minValue() const;
float maxValue() const;
bool isValid() const;
bool add(float bin, float value);
/**
* Enter value into the histogram. The add method takes the given
* value, works out which bin this corresponds to, and increments
* this bin by 'repeat'.
*
* @param value The Value to insert into the histogram
* @param repeat How many times you want to insert it
*
* @return Returns true if succesful insertion, otherwise return false
*/
bool add(float value, float repeat = 1.0f);
bool add(const Histogram& histogram);
bool addRectangle(float lowBin, float highBin, float value);
@@ -56,13 +66,25 @@ public:
void normalize();
void print() const;
void generateEqualizer();
Histogram equalize();
float equalize (float);
float entropy();
float highestBinValue(bool equalized);
float binWidth();
void changeRange(float minValue, float maxValue);
private:
int _numBins;
float _minBin;
float _maxBin;
float _minValue;
float _maxValue;
float* _data;
std::vector<float> _equalizer;
int _numValues;
}; // class Histogram
} // namespace openspace

View File

@@ -0,0 +1,52 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __TRANSFORMATIONMANAGER__
#define __TRANSFORMATIONMANAGER__
#include <ghoul/designpattern/singleton.h>
#include <ghoul/glm.h>
#include <ccmc/Kameleon.h>
namespace openspace {
class ccmc::Kameleon;
class TransformationManager : public ghoul::Singleton<TransformationManager> {
friend class ghoul::Singleton<TransformationManager>;
public:
TransformationManager();
~TransformationManager();
glm::dmat3 frameTransformationMatrix(std::string from, std::string to, double ephemerisTime) const;
private:
std::shared_ptr<ccmc::Kameleon> _kameleon;
std::set<std::string> _kameleonFrames;
std::set<std::string> _dipoleFrames;
};
}
#endif //__TRANSFORMATIONMANAGER__

View File

@@ -38,6 +38,8 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablestars.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrail.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.h
${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/spiceephemeris.h
${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/staticephemeris.h
)
@@ -57,6 +59,8 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablestars.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrail.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/spiceephemeris.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/staticephemeris.cpp
)
@@ -85,6 +89,8 @@ set(SHADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/shaders/star_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/star_ge.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/star_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/screnspace_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/screnspace_vs.glsl
)
source_group("Shader Files" FILES ${SHADER_FILES})

View File

@@ -25,6 +25,7 @@
#include <modules/base/basemodule.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
@@ -42,6 +43,8 @@
#include <modules/base/rendering/simplespheregeometry.h>
#include <modules/base/rendering/modelgeometry.h>
#include <modules/base/rendering/multimodelgeometry.h>
#include <modules/base/rendering/screenspaceimage.h>
#include <modules/base/rendering/screenspaceframebuffer.h>
#include <modules/base/ephemeris/staticephemeris.h>
#include <modules/base/ephemeris/spiceephemeris.h>
@@ -57,6 +60,13 @@ BaseModule::BaseModule()
void BaseModule::internalInitialize() {
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<planetgeometry::PlanetGeometry>>());
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<modelgeometry::ModelGeometry>>());
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<ScreenSpaceRenderable>>());
auto fScreenSpaceRenderable = FactoryManager::ref().factory<ScreenSpaceRenderable>();
ghoul_assert(fScreenSpaceRenderable, "ScreenSpaceRenderable factory was not created");
fScreenSpaceRenderable->registerClass<ScreenSpaceImage>("ScreenSpaceImage");
fScreenSpaceRenderable->registerClass<ScreenSpaceFramebuffer>("ScreenSpaceFramebuffer");
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fRenderable, "Renderable factory was not created");

View File

@@ -0,0 +1,158 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/base/rendering/screenspaceframebuffer.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <modules/onscreengui/include/gui.h>
#include <openspace/util/camera.h>
#include <openspace/rendering/renderer.h>
#include <openspace/rendering/abufferrenderer.h>
#include <openspace/rendering/framebufferrenderer.h>
namespace openspace {
ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary)
:ScreenSpaceRenderable(dictionary)
,_size("size", "Size", glm::vec4(0), glm::vec4(0), glm::vec4(2000))
,_framebuffer(nullptr)
{
_id = id();
setName("ScreenSpaceFramebuffer" + std::to_string(_id));
registerProperties();
glm::vec2 resolution = OsEng.windowWrapper().currentWindowResolution();
addProperty(_size);
OsEng.gui()._screenSpaceProperty.registerProperty(&_size);
_size.set(glm::vec4(0, 0, resolution.x,resolution.y));
_scale.setValue(1.0f);
}
ScreenSpaceFramebuffer::~ScreenSpaceFramebuffer(){}
bool ScreenSpaceFramebuffer::initialize(){
_originalViewportSize = OsEng.windowWrapper().currentWindowResolution();
createPlane();
createShaders();
createFragmentbuffer();
return isReady();
}
bool ScreenSpaceFramebuffer::deinitialize(){
unregisterProperties();
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
_texture = nullptr;
RenderEngine& renderEngine = OsEng.renderEngine();
if (_shader) {
renderEngine.removeRenderProgram(_shader);
_shader = nullptr;
}
_framebuffer->detachAll();
removeAllRenderFunctions();
return true;
}
void ScreenSpaceFramebuffer::render(){
glm::vec2 resolution = OsEng.windowWrapper().currentWindowResolution();
glm::vec4 size = _size.value();
float xratio = _originalViewportSize.x / (size.z-size.x);
float yratio = _originalViewportSize.y / (size.w-size.y);;
if(!_renderFunctions.empty()){
glViewport (-size.x*xratio, -size.y*yratio, _originalViewportSize.x*xratio, _originalViewportSize.y*yratio);
GLint defaultFBO = _framebuffer->getActiveObject();
_framebuffer->activate();
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_ALPHA_TEST);
for(auto renderFunction : _renderFunctions){
(*renderFunction)();
}
_framebuffer->deactivate();
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport (0, 0, resolution.x, resolution.y);
glm::mat4 rotation = rotationMatrix();
glm::mat4 translation = translationMatrix();
glm::mat4 scale = scaleMatrix();
scale = glm::scale(scale, glm::vec3((1.0/xratio), -(1.0/yratio), 1.0f));
glm::mat4 modelTransform = rotation*translation*scale;
draw(modelTransform);
}
}
void ScreenSpaceFramebuffer::update(){}
bool ScreenSpaceFramebuffer::isReady() const{
bool ready = true;
if (!_shader)
ready &= false;
if(!_texture)
ready &= false;
return ready;
}
void ScreenSpaceFramebuffer::setSize(glm::vec4 size){
_size.set(size);
}
void ScreenSpaceFramebuffer::addRenderFunction(std::shared_ptr<std::function<void()>> renderFunction){
_renderFunctions.push_back(renderFunction);
}
void ScreenSpaceFramebuffer::removeAllRenderFunctions(){
_renderFunctions.clear();
}
void ScreenSpaceFramebuffer::createFragmentbuffer(){
_framebuffer = std::make_unique<ghoul::opengl::FramebufferObject>();
_framebuffer->activate();
_texture = std::make_unique<ghoul::opengl::Texture>(glm::uvec3(_originalViewportSize.x, _originalViewportSize.y, 1));
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_framebuffer->attachTexture(_texture.get(), GL_COLOR_ATTACHMENT0);
_framebuffer->deactivate();
}
int ScreenSpaceFramebuffer::id(){
static int id = 0;
return id++;
}
} //namespace openspace

View File

@@ -0,0 +1,67 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __SCREENSPACEFRAMEBUFFER_H__
#define __SCREENSPACEFRAMEBUFFER_H__
#include <openspace/rendering/screenspacerenderable.h>
#include <ghoul/opengl/framebufferobject.h>
#include <ghoul/opengl/textureunit.h>
#include <modules/base/rendering/screenspaceimage.h>
namespace openspace {
/**
* @brief Creates a texture by rendering to a framebuffer, this is then used on a screen space plane.
* @details This class lets you ass renderfunctions that should render to a framebuffer with an attached texture.
* The texture is then used on a screen space plane that works both in fisheye and flat screens.
*/
class ScreenSpaceFramebuffer : public ScreenSpaceRenderable {
public:
ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary = ghoul::Dictionary());
~ScreenSpaceFramebuffer();
bool initialize() override;
bool deinitialize() override;
void render() override;
void update() override;
bool isReady() const override;
void setSize(glm::vec4);
void addRenderFunction(std::shared_ptr<std::function<void()>> renderFunction);
void removeAllRenderFunctions();
private:
void createFragmentbuffer();
static int id();
properties::Vec4Property _size;
std::unique_ptr<ghoul::opengl::FramebufferObject> _framebuffer;
std::vector<std::shared_ptr<std::function<void()>>> _renderFunctions;
int _id;
};
} //namespace openspace
#endif //__SCREENSPACEFRAMEBUFFER_H__

View File

@@ -0,0 +1,201 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/base/rendering/screenspaceimage.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/filesystem/filesystem>
namespace {
const std::string _loggerCat = "ScreenSpaceImage";
}
namespace openspace {
ScreenSpaceImage::ScreenSpaceImage(const ghoul::Dictionary& dictionary)
:ScreenSpaceRenderable(dictionary)
,_texturePath("texturePath", "Texture path", "")
,_downloadImage(false)
{
std::string name;
if(dictionary.getValue("Name", name)){
setName(name);
}else{
_id = id();
setName("ScreenSpaceImage" + std::to_string(_id));
}
addProperty(_texturePath);
registerProperties();
std::string texturePath;
bool texturesucces = (dictionary.getValue("TexturePath", texturePath));
if(texturesucces){
_texturePath.set(texturePath);
OsEng.gui()._screenSpaceProperty.registerProperty(&_texturePath);
_texturePath.onChange([this](){ loadTexture(); });
}
bool urlsucces = dictionary.getValue("URL", _url);
if(urlsucces){
_downloadImage =true;
}
//screenspaceCygnet does not have url or texturePath
// if(!texturesucces && !urlsucces){
// LERROR("Must specify TexturePath or URL");
// }
}
ScreenSpaceImage::~ScreenSpaceImage(){}
bool ScreenSpaceImage::initialize(){
_originalViewportSize = OsEng.windowWrapper().currentWindowResolution();
createPlane();
createShaders();
updateTexture();
return isReady();
}
bool ScreenSpaceImage::deinitialize(){
unregisterProperties();
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
_texturePath = "";
_texture = nullptr;
RenderEngine& renderEngine = OsEng.renderEngine();
if (_shader) {
renderEngine.removeRenderProgram(_shader);
_shader = nullptr;
}
return true;
}
void ScreenSpaceImage::render(){
if(!isReady()) return;
if(!_enabled) return;
glm::mat4 rotation = rotationMatrix();
glm::mat4 translation = translationMatrix();
glm::mat4 scale = scaleMatrix();
glm::mat4 modelTransform = rotation*translation*scale;
draw(modelTransform);
}
void ScreenSpaceImage::update(){
if(_downloadImage && _futureImage.valid() && DownloadManager::futureReady(_futureImage)){
loadTexture();
}
}
bool ScreenSpaceImage::isReady() const{
bool ready = true;
if (!_shader)
ready &= false;
if(!_texture)
ready &= false;
return ready;
}
void ScreenSpaceImage::loadTexture() {
std::unique_ptr<ghoul::opengl::Texture> texture = nullptr;
if(!_downloadImage)
texture = std::move(loadFromDisk());
else
texture = std::move(loadFromMemory());
if (texture) {
// LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'");
texture->uploadTexture();
// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_texture = std::move(texture);
}
}
void ScreenSpaceImage::updateTexture(){
if(!_downloadImage){
loadTexture();
} else {
if(_futureImage.valid())
return;
std::future<DownloadManager::MemoryFile> future = downloadImageToMemory(_url);
if(future.valid()){
_futureImage = std::move(future);
}
}
}
std::unique_ptr<ghoul::opengl::Texture> ScreenSpaceImage::loadFromDisk(){
if (_texturePath.value() != "")
return (ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath.value())));
return nullptr;
}
std::unique_ptr<ghoul::opengl::Texture> ScreenSpaceImage::loadFromMemory(){
if(_futureImage.valid() && DownloadManager::futureReady(_futureImage) ){
DownloadManager::MemoryFile imageFile = _futureImage.get();
if(imageFile.corrupted)
return nullptr;
return (ghoul::io::TextureReader::ref().loadTexture(
(void*) imageFile.buffer,
imageFile.size,
imageFile.format));
}
}
std::future<DownloadManager::MemoryFile> ScreenSpaceImage::downloadImageToMemory(std::string url){
return std::move( DlManager.fetchFile(
url,
[url](const DownloadManager::MemoryFile& file){
LDEBUG("Download to memory finished for screen space image");
},
[url](const std::string& err){
LDEBUG("Download to memory failer for screen space image: " +err);
}
) );
}
int ScreenSpaceImage::id(){
static int id = 0;
return id++;
}
}

View File

@@ -0,0 +1,75 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __SCREENSPACEIMAGE_H__
#define __SCREENSPACEIMAGE_H__
#include <openspace/rendering/screenspacerenderable.h>
#include <ghoul/opengl/texture.h>
#include <openspace/engine/downloadmanager.h>
namespace openspace {
/**
* @brief Creates a textured plane rendered in screenspace
* @details The plane gets the same ratio as the texture. Implements
* the interface that ScreenSpaceImage speciefies.
*
* @param texturePath Path to the image that should be used as texture
*/
class ScreenSpaceImage : public ScreenSpaceRenderable {
public:
ScreenSpaceImage(std::string texturePath);
ScreenSpaceImage(const ghoul::Dictionary& dictionary);
~ScreenSpaceImage();
bool initialize() override;
bool deinitialize() override;
void render() override;
virtual void update() override;
bool isReady() const override;
protected:
std::string _url;
bool _downloadImage;
std::future<DownloadManager::MemoryFile> _futureImage;
void loadTexture();
void updateTexture();
private:
static int id();
std::future<DownloadManager::MemoryFile> downloadImageToMemory(std::string url);
std::unique_ptr<ghoul::opengl::Texture> loadFromDisk();
std::unique_ptr<ghoul::opengl::Texture> loadFromMemory();
properties::StringProperty _texturePath;
//std::string _memorybuffer;
int _id;
};
} //namespace openspace
#endif //__SCREENSPACEIMAGE_H__

View File

@@ -77,7 +77,6 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary)
}
else
_segments = static_cast<int>(segments);
// The shader need the radii values but they are not changeable runtime
// TODO: Possibly add a scaling property @AA
addProperty(_realRadius);

View File

@@ -0,0 +1,50 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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__
uniform sampler2D texture1;
uniform float OcclusionDepth;
uniform float Alpha;
in vec2 vs_st;
in vec4 vs_position;
#include "fragment.glsl"
#include "PowerScaling/powerScaling_fs.hglsl"
Fragment getFragment(){
Fragment frag;
// power scale coordinates for depth. w value is set to 1.0.
float depth = (1.0 + log(abs(OcclusionDepth) + 1/pow(k, 1.0))/log(k)) / 27.0;
frag.color = texture(texture1, vec2(vs_st.s, 1-vs_st.t));
frag.color.a = (frag.color.a != 0.0f) ? Alpha : frag.color.a;
if(frag.color.a == 0.0f){
discard;
}
frag.depth = denormalizeFloat(depth);
return frag;
}

View File

@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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__
uniform mat4 ModelTransform;
uniform mat4 ViewProjectionMatrix;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
out vec4 vs_position;
void main(){
vs_st = in_st;
vs_position = ViewProjectionMatrix*ModelTransform*in_position;
gl_Position = vec4(vs_position);
}

View File

@@ -24,6 +24,7 @@
#include <modules/fieldlines/rendering/renderablefieldlines.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/powerscaledcoordinate.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/scene/scenegraphnode.h>
@@ -94,9 +95,10 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary)
dictionary.hasKeyAndValue<std::string>(SceneGraphNode::KeyName),
"Renderable does not have a name"
);
std::string name;
dictionary.getValue(SceneGraphNode::KeyName, name);
setName(name);
_loggerCat = "RenderableFieldlines [" + name + "]";
@@ -144,6 +146,13 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary)
_seedPointSourceFile.onChange(dirtySeedpoints);
addProperty(_seedPointSourceFile);
// OsEng.gui()._property.registerProperty(&_enabled);
// OsEng.gui()._property.registerProperty(&_stepSize);
// OsEng.gui()._property.registerProperty(&_classification);
// OsEng.gui()._property.registerProperty(&_fieldlineColor);
// OsEng.gui()._property.registerProperty(&_seedPointSource);
// OsEng.gui()._property.registerProperty(&_seedPointSourceFile);
}
void RenderableFieldlines::initializeDefaultPropertyValues() {
@@ -200,12 +209,13 @@ bool RenderableFieldlines::initialize() {
return false;
}
_program = ghoul::opengl::ProgramObject::Build(
_program = OsEng.renderEngine().buildRenderProgram(
"Fieldline",
"${MODULE_FIELDLINES}/shaders/fieldline_vs.glsl",
"${MODULE_FIELDLINES}/shaders/fieldline_fs.glsl",
"${MODULE_FIELDLINES}/shaders/fieldline_gs.glsl"
);
if (!_program)
return false;
@@ -217,6 +227,13 @@ bool RenderableFieldlines::deinitialize() {
_fieldlineVAO = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
RenderEngine& renderEngine = OsEng.renderEngine();
if (_program) {
renderEngine.removeRenderProgram(_program);
_program = nullptr;
}
return true;
}
@@ -225,7 +242,7 @@ void RenderableFieldlines::render(const RenderData& data) {
_program->setUniform("modelViewProjection", data.camera.viewProjectionMatrix());
_program->setUniform("modelTransform", glm::mat4(1.0));
_program->setUniform("cameraViewDir", data.camera.viewDirection());
glDisable(GL_CULL_FACE);
setPscUniforms(*_program, data.camera, data.position);
_program->setUniform("classification", _classification);
@@ -240,7 +257,7 @@ void RenderableFieldlines::render(const RenderData& data) {
static_cast<GLsizei>(_lineStart.size())
);
glBindVertexArray(0);
glEnable(GL_CULL_FACE);
_program->deactivate();
}

View File

@@ -22,8 +22,6 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
in vec4 gs_color;
in vec4 gs_position;
in vec3 gs_normal;
@@ -31,11 +29,14 @@ in vec3 gs_normal;
uniform bool classification;
uniform vec4 fieldLineColor;
#include "ABuffer/abufferStruct.hglsl"
#include "ABuffer/abufferAddToBuffer.hglsl"
#include "fragment.glsl"
#include "PowerScaling/powerScaling_fs.hglsl"
void main() {
Fragment getFragment()
{
float alpha = 1-length(gs_normal)*length(gs_normal);
vec4 fragColor;
if (classification)
@@ -44,6 +45,28 @@ void main() {
fragColor = vec4(fieldLineColor.rgb, fieldLineColor.a * alpha);
float depth = pscDepth(gs_position);
ABufferStruct_t frag = createGeometryFragment(fragColor, gs_position, depth);
addToBuffer(frag);
}
Fragment frag;
frag.depth = depth;
frag.color = fragColor;
return frag;
}
// #include "ABuffer/abufferStruct.hglsl"
// #include "ABuffer/abufferAddToBuffer.hglsl"
// #include "PowerScaling/powerScaling_fs.hglsl"
// void main() {
// float alpha = 1-length(gs_normal)*length(gs_normal);
// vec4 fragColor;
// if (classification)
// fragColor = vec4(gs_color.rgb, alpha);
// else
// fragColor = vec4(fieldLineColor.rgb, fieldLineColor.a * alpha);
// float depth = pscDepth(gs_position);
// ABufferStruct_t frag = createGeometryFragment(fragColor, gs_position, depth);
// addToBuffer(frag);
// }

View File

@@ -49,7 +49,7 @@ void ABufferEmitVertex(vec4 pos) {
// project the position to view space
position = modelViewProjection*position;
gl_Position = position;
gl_Position = z_normalization(position);
EmitVertex();
}

View File

@@ -0,0 +1,72 @@
#########################################################################################
# #
# OpenSpace #
# #
# Copyright (c) 2014-2016 #
# #
# 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}/util/iswamanager.h
${CMAKE_CURRENT_SOURCE_DIR}/util/dataprocessor.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/cygnetplane.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/iswacygnet.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/dataplane.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/textureplane.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/kameleonplane.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/cygnetsphere.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/datasphere.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspacecygnet.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/iswagroup.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/texturecygnet.h
)
source_group("Header Files" FILES ${HEADER_FILES})
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/util/iswamanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/dataprocessor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/iswacygnet.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/cygnetplane.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/dataplane.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/textureplane.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/kameleonplane.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/cygnetsphere.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/datasphere.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspacecygnet.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/iswagroup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/texturecygnet.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
set(SHADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/shaders/cygnetplane_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/cygnetplane_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/dataplane_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/dataplane_vs.glsl
)
source_group("Shader Files" FILES ${SHADER_FILES})
create_new_module(
"Iswa"
iswa_module
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)

View File

@@ -0,0 +1,123 @@
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#include "base64.h"
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}

View File

@@ -0,0 +1,4 @@
#include <string>
std::string base64_encode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const& s);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
set (OPENSPACE_DEPENDENCIES
base
)

24
modules/iswa/info Normal file
View File

@@ -0,0 +1,24 @@
ScreenSpaceRenderable
-->ScreenSpaceCygnet
IswaCygnet
-->CygnetPlane
-->dataPlane
-->texturePlane
-->CygnetSphere
-->dataSphere
-->textureSphere
-->CygnetCylinder
-->dataCylinder
-->textureCylinder
Renderable
-->ISWAmanager:
create iSWA cygnets.
Reads the metadata from the cygnet and creates the appropriate class.
can be a IswaCygnet or a ScreenSpaceCygnet
keeps a list of IswaCygnets to update and render.
registers the ScreenSpaceCygnets with the renderengine.
change names in everyting in iswa folder

View File

@@ -0,0 +1,59 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/iswa/iswamodule.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
#include <modules/iswa/rendering/textureplane.h>
#include <modules/iswa/rendering/dataplane.h>
#include <modules/iswa/rendering/kameleonplane.h>
#include <modules/iswa/rendering/datasphere.h>
#include <modules/iswa/rendering/screenspacecygnet.h>
namespace openspace {
IswaModule::IswaModule()
: OpenSpaceModule("ISWA")
{}
void IswaModule::internalInitialize(){
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fRenderable, "No renderable factory existed");
fRenderable->registerClass<TexturePlane>("TexturePlane");
fRenderable->registerClass<DataPlane>("DataPlane");
fRenderable->registerClass<KameleonPlane>("KameleonPlane");
fRenderable->registerClass<DataSphere>("DataSphere");
auto fScreenSpaceRenderable = FactoryManager::ref().factory<ScreenSpaceRenderable>();
ghoul_assert(fScreenSpaceRenderable, "No fScreenSpaceRenderable factory existed");
fScreenSpaceRenderable->registerClass<ScreenSpaceCygnet>("ScreenSpaceCygnet");
}
}

42
modules/iswa/iswamodule.h Normal file
View File

@@ -0,0 +1,42 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __ISWAMODULE_H__
#define __ISWAMODULE_H__
#include <openspace/util/openspacemodule.h>
namespace openspace{
class IswaModule : public OpenSpaceModule {
public:
IswaModule();
protected:
void internalInitialize() override;
};
} // namespace openspace
#endif // __ISWAMODULE_H__

View File

@@ -0,0 +1,87 @@
// * 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/iswa/rendering/cygnetplane.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
namespace openspace{
CygnetPlane::CygnetPlane(const ghoul::Dictionary& dictionary)
:IswaCygnet(dictionary)
,_quad(0)
,_vertexPositionBuffer(0)
{}
CygnetPlane::~CygnetPlane(){}
bool CygnetPlane::createGeometry() {
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
// ============================
// GEOMETRY (quad)
// ============================
// GLfloat x,y, z;
float s = _data->spatialScale.x;
const GLfloat x = s*_data->scale.x/2.0;
const GLfloat y = s*_data->scale.y/2.0;
const GLfloat z = s*_data->scale.z/2.0;
const GLfloat w = _data->spatialScale.w;
const GLfloat vertex_data[] = { // square of two triangles (sigh)
// x y z w s t
-x, -y, -z, w, 0, 1,
x, y, z, w, 1, 0,
-x, ((x>0)?y:-y), z, w, 0, 0,
-x, -y, -z, w, 0, 1,
x, ((x>0)?-y:y), -z, w, 1, 1,
x, y, z, w, 1, 0,
};
glBindVertexArray(_quad); // bind array
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
return true;
}
bool CygnetPlane::destroyGeometry(){
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
return true;
}
void CygnetPlane::renderGeometry() const {
glBindVertexArray(_quad);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
} //namespace openspace

View File

@@ -0,0 +1,48 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __CYGNETPLANE_H__
#define __CYGNETPLANE_H__
#include <modules/iswa/rendering/iswacygnet.h>
#include <ghoul/opengl/texture.h>
#include <openspace/util/powerscaledcoordinate.h>
namespace openspace{
class CygnetPlane : public IswaCygnet {
public:
CygnetPlane(const ghoul::Dictionary& dictionary);
~CygnetPlane();
protected:
virtual bool createGeometry() override;
virtual bool destroyGeometry() override;
virtual void renderGeometry() const override;
GLuint _quad;
GLuint _vertexPositionBuffer;
};
} //namespace openspace
#endif //__CYGNETPLANE_H__

View File

@@ -0,0 +1,65 @@
// * 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/iswa/rendering/cygnetsphere.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <modules/base/rendering/planetgeometry.h>
#include <modules/base/rendering/simplespheregeometry.h>
#include <openspace/util/powerscaledsphere.h>
#include <openspace/util/powerscaledscalar.h>
namespace openspace{
CygnetSphere::CygnetSphere(const ghoul::Dictionary& dictionary)
:IswaCygnet(dictionary)
,_sphere(nullptr)
{
float radius;
dictionary.getValue("Radius", radius);
_radius = radius;
}
CygnetSphere::~CygnetSphere(){}
bool CygnetSphere::createGeometry(){
PowerScaledScalar radius = PowerScaledScalar(6.371f*_radius, 6.0);
int segments = 100;
_sphere = std::make_shared<PowerScaledSphere>(radius, segments);
_sphere->initialize();
return true;
}
bool CygnetSphere::destroyGeometry(){
_sphere = nullptr;
return true;
}
void CygnetSphere::renderGeometry() const {
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
_sphere->render();
}
} //namespace openspace

View File

@@ -0,0 +1,54 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __CYGNETSPHERE_H__
#define __CYGNETSPHERE_H__
#include <modules/iswa/rendering/iswacygnet.h>
namespace openspace{
class PowerScaledSphere;
namespace planetgeometry {
class PlanetGeometry;
}
class CygnetSphere : public IswaCygnet {
public:
CygnetSphere(const ghoul::Dictionary& dictionary);
~CygnetSphere();
protected:
std::shared_ptr<PowerScaledSphere> _sphere;
private:
virtual bool createGeometry() override;
virtual bool destroyGeometry() override;
virtual void renderGeometry() const override;
float _radius;
};
} //namespace openspace
#endif // __CYGNETSPHERE_H__

View File

@@ -0,0 +1,39 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/iswa/rendering/datacygnet.h>
namespace {
const std::string _loggerCat = "DataCygnet";
}
namespace openspace{
DataCygnet::DataCygnet(const ghoul::Dictionary& dictionary)
:IswaCygnet(dictionary)
{}
DataCygnet::~DataCygnet(){}
} //namespace openspace

View File

@@ -0,0 +1,40 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __DATACYGNET_H__
#define __DATACYGNET_H__
#include <modules/iswa/rendering/iswacygnet.h>
namespace openspace{
class DataCygnet : public IswaCygnet {
public:
DataCygnet(const ghoul::Dictionary& dictionary);
~DataCygnet();
protected:
};
} //namespace openspace
#endif //__DATACYGNET_H__

View File

@@ -0,0 +1,366 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/iswa/rendering/dataplane.h>
#include <fstream>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <modules/iswa/rendering/iswagroup.h>
namespace {
const std::string _loggerCat = "DataPlane";
const int MAX_TEXTURES = 6;
}
namespace openspace {
DataPlane::DataPlane(const ghoul::Dictionary& dictionary)
:CygnetPlane(dictionary)
,_useLog("useLog","Use Logarithm", false)
,_useHistogram("useHistogram", "Use Histogram", true)
,_autoFilter("autoFilter", "Auto Filter", true)
,_normValues("normValues", "Normalize Values", glm::vec2(1.0,1.0), glm::vec2(0), glm::vec2(5.0))
,_backgroundValues("backgroundValues", "Background Values", glm::vec2(0.0), glm::vec2(0), glm::vec2(1.0))
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
,_dataOptions("dataOptions", "Data Options")
,_dataProcessor(nullptr)
{
std::string name;
dictionary.getValue("Name", name);
setName(name);
registerProperties();
addProperty(_useLog);
addProperty(_useHistogram);
addProperty(_autoFilter);
addProperty(_normValues);
addProperty(_backgroundValues);
addProperty(_transferFunctionsFile);
addProperty(_dataOptions);
_type = IswaManager::CygnetType::Data;
_programName = "DataPlaneProgram";
_vsPath = "${MODULE_ISWA}/shaders/dataplane_vs.glsl";
_fsPath = "${MODULE_ISWA}/shaders/dataplane_fs.glsl";
}
DataPlane::~DataPlane(){}
bool DataPlane::initialize(){
IswaCygnet::initialize();
if(_group){
_dataProcessor = _group->dataProcessor();
_groupEvent->subscribe(name(), "useLogChanged", [&](const ghoul::Dictionary& dict){
LDEBUG(name() + " Event useLogChanged");
_useLog.setValue(dict.value<bool>("useLog"));
});
_groupEvent->subscribe(name(), "normValuesChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event normValuesChanged");
std::shared_ptr<glm::vec2> values;
bool success = dict.getValue("normValues", values);
if(success){
_normValues.setValue(*values);
}
});
_groupEvent->subscribe(name(), "useHistogramChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event useHistogramChanged");
_useHistogram.setValue(dict.value<bool>("useHistogram"));
});
_groupEvent->subscribe(name(), "dataOptionsChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event dataOptionsChanged");
std::shared_ptr<std::vector<int> > values;
bool success = dict.getValue("dataOptions", values);
if(success){
_dataOptions.setValue(*values);
}
});
_groupEvent->subscribe(name(), "transferFunctionsChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event transferFunctionsChanged");
_transferFunctionsFile.setValue(dict.value<std::string>("transferFunctions"));
});
_groupEvent->subscribe(name(), "backgroundValuesChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event backgroundValuesChanged");
std::shared_ptr<glm::vec2> values;
bool success = dict.getValue("backgroundValues", values);
if(success){
_backgroundValues.setValue(*values);
}
});
_groupEvent->subscribe(name(), "autoFilterChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event autoFilterChanged");
_autoFilter.setValue(dict.value<bool>("autoFilter"));
});
_groupEvent->subscribe(name(), "updateGroup", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event updateGroup");
loadTexture();
});
}else{
OsEng.gui()._iswa.registerProperty(&_useLog);
OsEng.gui()._iswa.registerProperty(&_useHistogram);
OsEng.gui()._iswa.registerProperty(&_autoFilter);
OsEng.gui()._iswa.registerProperty(&_normValues);
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
OsEng.gui()._iswa.registerProperty(&_dataOptions);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
}
setTransferFunctions(_transferFunctionsFile.value());
_normValues.onChange([this](){
_dataProcessor->normValues(_normValues.value());
loadTexture();
});
_useLog.onChange([this](){
_dataProcessor->useLog(_useLog.value());
loadTexture();
});
_useHistogram.onChange([this](){
_dataProcessor->useHistogram(_useHistogram.value());
loadTexture();
});
_dataOptions.onChange([this](){
if(_dataOptions.value().size() > MAX_TEXTURES)
LWARNING("Too many options chosen, max is " + std::to_string(MAX_TEXTURES));
loadTexture();
});
_transferFunctionsFile.onChange([this](){
setTransferFunctions(_transferFunctionsFile.value());
});
return true;
}
bool DataPlane::loadTexture() {
// if The future is done then get the new dataFile
if(_futureObject.valid() && DownloadManager::futureReady(_futureObject)){
DownloadManager::MemoryFile dataFile = _futureObject.get();
if(dataFile.corrupted)
return false;
_dataBuffer = "";
_dataBuffer.append(dataFile.buffer, dataFile.size);
delete[] dataFile.buffer;
}
// if the buffer in the datafile is empty, do not proceed
if(_dataBuffer.empty())
return false;
if(!_dataOptions.options().size()){ // load options for value selection
fillOptions();
_dataProcessor->addValues(_dataBuffer, _dataOptions);
if(_group)
_group->updateGroup();
}
std::vector<float*> data = _dataProcessor->readData2(_dataBuffer, _dataOptions);
if(data.empty())
return false;
if(_autoFilter.value())
_backgroundValues.setValue(_dataProcessor->filterValues());
bool texturesReady = false;
std::vector<int> selectedOptions = _dataOptions.value();
for(int option: selectedOptions){
float* values = data[option];
if(!values) continue;
if(!_textures[option]){
std::unique_ptr<ghoul::opengl::Texture> texture = std::make_unique<ghoul::opengl::Texture>(
values,
_dataProcessor->dimensions(),
ghoul::opengl::Texture::Format::Red,
GL_RED,
GL_FLOAT,
ghoul::opengl::Texture::FilterMode::Linear,
ghoul::opengl::Texture::WrappingMode::ClampToEdge
);
if(texture){
texture->uploadTexture();
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_textures[option] = std::move(texture);
}
}else{
_textures[option]->setPixelData(values);
_textures[option]->uploadTexture();
}
texturesReady = true;
}
return texturesReady;
}
bool DataPlane::updateTexture(){
if(_futureObject.valid())
return false;
std::future<DownloadManager::MemoryFile> future = IswaManager::ref().fetchDataCygnet(_data->id);
if(future.valid()){
_futureObject = std::move(future);
return true;
}
return false;
}
bool DataPlane::readyToRender() const {
return (!_textures.empty());
}
void DataPlane::setUniformAndTextures(){
std::vector<int> selectedOptions = _dataOptions.value();
int activeTextures = std::min((int)selectedOptions.size(), MAX_TEXTURES);
int activeTransferfunctions = std::min((int)_transferFunctions.size(), MAX_TEXTURES);
ghoul::opengl::TextureUnit txUnits[6];
int j = 0;
for(int option : selectedOptions){
if(_textures[option]){
txUnits[j].activate();
_textures[option]->bind();
_shader->setUniform(
"textures[" + std::to_string(j) + "]",
txUnits[j]
);
j++;
if(j >= MAX_TEXTURES) break;
}
}
if(activeTextures > 0){
if(selectedOptions.back()>=activeTransferfunctions)
activeTransferfunctions = 1;
}
ghoul::opengl::TextureUnit tfUnits[6];
j = 0;
if((activeTransferfunctions == 1)){
tfUnits[0].activate();
_transferFunctions[0]->bind();
_shader->setUniform(
"transferFunctions[0]",
tfUnits[0]
);
}else{
for(int option : selectedOptions){
// std::cout << option << std::endl;
// if(option >= activeTransferfunctions){
// // LWARNING("No transfer function for this value.");
// break;
// }
if(_transferFunctions[option]){
tfUnits[j].activate();
_transferFunctions[option]->bind();
_shader->setUniform(
"transferFunctions[" + std::to_string(j) + "]",
tfUnits[j]
);
j++;
if(j >= MAX_TEXTURES) break;
}
}
}
_shader->setUniform("numTextures", activeTextures);
_shader->setUniform("numTransferFunctions", activeTransferfunctions);
_shader->setUniform("backgroundValues", _backgroundValues.value());
_shader->setUniform("transparency", _alpha.value());
}
void DataPlane::setTransferFunctions(std::string tfPath){
std::string line;
std::ifstream tfFile(absPath(tfPath));
std::vector<std::shared_ptr<TransferFunction>> tfs;
if(tfFile.is_open()){
while(getline(tfFile, line)){
std::shared_ptr<TransferFunction> tf = std::make_shared<TransferFunction>(absPath(line));
if(tf){
tfs.push_back(tf);
}
}
tfFile.close();
}
if(!tfs.empty()){
_transferFunctions.clear();
_transferFunctions = tfs;
}
}
void DataPlane::fillOptions(){
std::vector<std::string> options = _dataProcessor->readHeader(_dataBuffer);
for(int i=0; i<options.size(); i++){
_dataOptions.addOption({i, options[i]});
_textures.push_back(nullptr);
}
_dataOptions.setValue(std::vector<int>(1,0));
if(_group)
_group->registerOptions(_dataOptions.options());
}
}// namespace openspace

View File

@@ -0,0 +1,73 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __DATAPLANE_H__
#define __DATAPLANE_H__
#include <modules/iswa/rendering/cygnetplane.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/properties/selectionproperty.h>
#include <modules/iswa/util/dataprocessor.h>
namespace openspace{
class IswaGroup;
class DataPlane : public CygnetPlane {
friend class IswaGroup;
public:
DataPlane(const ghoul::Dictionary& dictionary);
~DataPlane();
bool initialize() override;
private:
virtual bool loadTexture() override;
virtual bool updateTexture() override;
virtual bool readyToRender() const override;
virtual void setUniformAndTextures() override;
void setTransferFunctions(std::string tfPath);
void fillOptions();
properties::SelectionProperty _dataOptions;
properties::StringProperty _transferFunctionsFile;
properties::Vec2Property _backgroundValues;
properties::Vec2Property _normValues;
properties::BoolProperty _useLog;
properties::BoolProperty _useHistogram;
properties::BoolProperty _autoFilter;
std::string _dataBuffer;
std::shared_ptr<DataProcessor> _dataProcessor;
};
} // namespace openspace
#endif //__DATAPLANE_H__

View File

@@ -0,0 +1,385 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/iswa/rendering/datasphere.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/filesystem/filesystem.h>
#include <modules/base/rendering/planetgeometry.h>
#include <fstream>
#include <modules/iswa/rendering/iswagroup.h>
namespace {
const std::string _loggerCat = "DataSphere";
const int MAX_TEXTURES = 6;
}
namespace openspace {
DataSphere::DataSphere(const ghoul::Dictionary& dictionary)
:CygnetSphere(dictionary)
,_useLog("useLog","Use Logarithm", false)
,_useHistogram("useHistogram", "Use Histogram", true)
,_autoFilter("autoFilter", "Auto Filter", true)
,_normValues("normValues", "Normalize Values", glm::vec2(1.0,1.0), glm::vec2(0), glm::vec2(5.0))
,_backgroundValues("backgroundValues", "Background Values", glm::vec2(0.0), glm::vec2(0), glm::vec2(1.0))
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
,_dataOptions("dataOptions", "Data Options")
{
std::string name;
dictionary.getValue("Name", name);
setName(name);
registerProperties();
addProperty(_useLog);
addProperty(_useHistogram);
addProperty(_autoFilter);
addProperty(_normValues);
addProperty(_backgroundValues);
addProperty(_transferFunctionsFile);
addProperty(_dataOptions);
_type = IswaManager::CygnetType::Data;
_programName = "DataSphereProgram";
_vsPath = "${MODULE_ISWA}/shaders/datasphere_vs.glsl";
_fsPath = "${MODULE_ISWA}/shaders/datasphere_fs.glsl";
}
DataSphere::~DataSphere(){}
bool DataSphere::initialize(){
IswaCygnet::initialize();
if(_group){
_dataProcessor = _group->dataProcessor();
_groupEvent->subscribe(name(), "useLogChanged", [&](const ghoul::Dictionary& dict){
LDEBUG(name() + " Event useLogChanged");
_useLog.setValue(dict.value<bool>("useLog"));
});
_groupEvent->subscribe(name(), "normValuesChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event normValuesChanged");
std::shared_ptr<glm::vec2> values;
bool success = dict.getValue("normValues", values);
if(success){
_normValues.setValue(*values);
}
});
_groupEvent->subscribe(name(), "useHistogramChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event useHistogramChanged");
_useHistogram.setValue(dict.value<bool>("useHistogram"));
});
_groupEvent->subscribe(name(), "dataOptionsChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event dataOptionsChanged");
std::shared_ptr<std::vector<int> > values;
bool success = dict.getValue("dataOptions", values);
if(success){
_dataOptions.setValue(*values);
}
});
_groupEvent->subscribe(name(), "transferFunctionsChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event transferFunctionsChanged");
_transferFunctionsFile.setValue(dict.value<std::string>("transferFunctions"));
});
_groupEvent->subscribe(name(), "backgroundValuesChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event backgroundValuesChanged");
std::shared_ptr<glm::vec2> values;
bool success = dict.getValue("backgroundValues", values);
if(success){
_backgroundValues.setValue(*values);
}
});
_groupEvent->subscribe(name(), "autoFilterChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event autoFilterChanged");
_autoFilter.setValue(dict.value<bool>("autoFilter"));
});
_groupEvent->subscribe(name(), "updateGroup", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event updateGroup");
loadTexture();
});
}else{
OsEng.gui()._iswa.registerProperty(&_useLog);
OsEng.gui()._iswa.registerProperty(&_useHistogram);
OsEng.gui()._iswa.registerProperty(&_autoFilter);
OsEng.gui()._iswa.registerProperty(&_normValues);
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
OsEng.gui()._iswa.registerProperty(&_dataOptions);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
}
setTransferFunctions(_transferFunctionsFile.value());
_normValues.onChange([this](){
_dataProcessor->normValues(_normValues.value());
loadTexture();
});
_useLog.onChange([this](){
_dataProcessor->useLog(_useLog.value());
loadTexture();
});
_useHistogram.onChange([this](){
_dataProcessor->useHistogram(_useHistogram.value());
loadTexture();
});
_dataOptions.onChange([this](){
if(_dataOptions.value().size() > MAX_TEXTURES)
LWARNING("Too many options chosen, max is " + std::to_string(MAX_TEXTURES));
loadTexture();
});
_transferFunctionsFile.onChange([this](){
setTransferFunctions(_transferFunctionsFile.value());
});
return true;
}
bool DataSphere::loadTexture(){
// if The future is done then get the new dataFile
if(_futureObject.valid() && DownloadManager::futureReady(_futureObject)){
DownloadManager::MemoryFile dataFile = _futureObject.get();
if(dataFile.corrupted)
return false;
_dataBuffer = "";
_dataBuffer.append(dataFile.buffer, dataFile.size);
delete[] dataFile.buffer;
}
// if the buffer in the datafile is empty, do not proceed
if(_dataBuffer.empty())
return false;
if(!_dataOptions.options().size()){ // load options for value selection
fillOptions();
_dataProcessor->addValuesFromJSON(_dataBuffer, _dataOptions);
if(_group)
_group->updateGroup();
}
std::vector<float*> data = _dataProcessor->readJSONData2(_dataBuffer, _dataOptions);
if(data.empty())
return false;
if(_autoFilter.value())
_backgroundValues.setValue(_dataProcessor->filterValues());
bool texturesReady = false;
std::vector<int> selectedOptions = _dataOptions.value();
for(int option: selectedOptions){
float* values = data[option];
if(!values) continue;
if(!_textures[option]){
std::unique_ptr<ghoul::opengl::Texture> texture = std::make_unique<ghoul::opengl::Texture>(
values,
_dataProcessor->dimensions(),
ghoul::opengl::Texture::Format::Red,
GL_RED,
GL_FLOAT,
ghoul::opengl::Texture::FilterMode::Linear,
ghoul::opengl::Texture::WrappingMode::ClampToEdge
);
if(texture){
texture->uploadTexture();
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_textures[option] = std::move(texture);
}
}else{
_textures[option]->setPixelData(values);
_textures[option]->uploadTexture();
}
texturesReady = true;
}
// _dataBuffer = "";
return texturesReady;
}
bool DataSphere::updateTexture(){
if(_futureObject.valid())
return false;
std::future<DownloadManager::MemoryFile> future = IswaManager::ref().fetchDataCygnet(_data->id);
if(future.valid()){
_futureObject = std::move(future);
return true;
}
return false;
}
bool DataSphere::readyToRender() const {
return (!_textures.empty());
bool ready = isReady();
ready &= (!_textures.empty() && _textures[0]);
ready &= (_sphere != nullptr);
return ready;
}
void DataSphere::setUniformAndTextures(){
std::vector<int> selectedOptions = _dataOptions.value();
int activeTextures = std::min((int)selectedOptions.size(), MAX_TEXTURES);
int activeTransferfunctions = std::min((int)_transferFunctions.size(), MAX_TEXTURES);
ghoul::opengl::TextureUnit txUnits[10];
int j = 0;
for(int option : selectedOptions){
if(_textures[option]){
txUnits[j].activate();
_textures[option]->bind();
_shader->setUniform(
"textures[" + std::to_string(j) + "]",
txUnits[j]
);
j++;
if(j >= MAX_TEXTURES) break;
}
}
if(activeTextures > 0){
if(selectedOptions.back()>=activeTransferfunctions)
activeTransferfunctions = 1;
}
ghoul::opengl::TextureUnit tfUnits[10];
j = 0;
if((activeTransferfunctions == 1)){
tfUnits[0].activate();
_transferFunctions[0]->bind();
_shader->setUniform(
"transferFunctions[0]",
tfUnits[0]
);
}else{
for(int option : selectedOptions){
// std::cout << option << std::endl;
// if(option >= activeTransferfunctions){
// // LWARNING("No transfer function for this value.");
// break;
// }
if(_transferFunctions[option]){
tfUnits[j].activate();
_transferFunctions[option]->bind();
_shader->setUniform(
"transferFunctions[" + std::to_string(j) + "]",
tfUnits[j]
);
j++;
if(j >= MAX_TEXTURES) break;
}
}
}
_shader->setUniform("numTextures", activeTextures);
_shader->setUniform("numTransferFunctions", activeTransferfunctions);
_shader->setUniform("backgroundValues", _backgroundValues.value());
_shader->setUniform("transparency", _alpha.value());
}
// bool DataSphere::createShader(){
// if (_shader == nullptr) {
// // Plane Program
// RenderEngine& renderEngine = OsEng.renderEngine();
// _shader = renderEngine.buildRenderProgram(
// "DataSphereProgram",
// "${MODULE_ISWA}/shaders/datasphere_vs.glsl",
// "${MODULE_ISWA}/shaders/datasphere_fs.glsl");
// if (!_shader)
// return false;
// }
// return true;
// }
void DataSphere::setTransferFunctions(std::string tfPath){
std::string line;
std::ifstream tfFile(absPath(tfPath));
std::vector<std::shared_ptr<TransferFunction>> tfs;
if(tfFile.is_open()){
while(getline(tfFile, line)){
std::shared_ptr<TransferFunction> tf = std::make_shared<TransferFunction>(absPath(line));
if(tf){
tfs.push_back(tf);
}
}
tfFile.close();
}
if(!tfs.empty()){
_transferFunctions.clear();
_transferFunctions = tfs;
}
}
void DataSphere::fillOptions(){
std::vector<std::string> options = _dataProcessor->readJSONHeader(_dataBuffer);
for(int i=0; i<options.size(); i++){
_dataOptions.addOption({i, options[i]});
_textures.push_back(nullptr);
}
_dataOptions.setValue(std::vector<int>(1,0));
if(_group)
_group->registerOptions(_dataOptions.options());
// IswaManager::ref().registerOptionsToGroup(_data->groupName, _dataOptions.options());
}
} //namespace openspace

View File

@@ -0,0 +1,72 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __DATASPHERE_H__
#define __DATASPHERE_H__
#include <modules/iswa/rendering/cygnetsphere.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/properties/selectionproperty.h>
#include <modules/iswa/util/dataprocessor.h>
namespace openspace{
class PowerScaledSphere;
class DataSphere : public CygnetSphere {
friend class IswaGroup;
public:
DataSphere(const ghoul::Dictionary& dictionary);
~DataSphere();
bool initialize() override;
private:
virtual bool loadTexture() override;
virtual bool updateTexture() override;
virtual bool readyToRender() const override;
virtual void setUniformAndTextures() override;
void setTransferFunctions(std::string tfPath);
void fillOptions();
properties::SelectionProperty _dataOptions;
properties::StringProperty _transferFunctionsFile;
properties::Vec2Property _backgroundValues;
properties::Vec2Property _normValues;
properties::BoolProperty _useLog;
properties::BoolProperty _useHistogram;
properties::BoolProperty _autoFilter;
std::string _dataBuffer;
std::shared_ptr<DataProcessor> _dataProcessor;
};
} //namespace openspace
#endif //__DATASPHERE_H__

View File

@@ -0,0 +1,280 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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/iswa/rendering/iswacygnet.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/time.h>
#include <openspace/util/transformationmanager.h>
namespace {
const std::string _loggerCat = "IswaCygnet";
}
namespace openspace{
IswaCygnet::IswaCygnet(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _delete("delete", "Delete")
,_alpha("alpha", "Alpha", 0.9f, 0.0f, 1.0f)
, _shader(nullptr)
,_type(IswaManager::CygnetType::NoType)
,_groupEvent()
,_group(nullptr)
,_textureDirty(false)
{
_data = std::make_shared<Metadata>();
// dict.getValue can only set strings in _data directly
float renderableId;
float updateTime;
glm::vec3 min, max;
glm::vec4 spatialScale;
dictionary.getValue("Id", renderableId);
dictionary.getValue("UpdateTime", updateTime);
dictionary.getValue("SpatialScale", spatialScale);
dictionary.getValue("GridMin", min);
dictionary.getValue("GridMax", max);
dictionary.getValue("Frame",_data->frame);
dictionary.getValue("CoordinateType", _data->coordinateType);
_data->id = (int) renderableId;
_data->updateTime = (int) updateTime;
_data->spatialScale = spatialScale;
_data->gridMin = min;
_data->gridMax = max;
glm::vec3 scale;
glm::vec3 offset;
scale = glm::vec3(
(max.x - min.x),
(max.y - min.y),
(max.z - min.z)
);
offset = glm::vec3(
(min.x + (std::abs(min.x)+std::abs(max.x))/2.0f),
(min.y + (std::abs(min.y)+std::abs(max.y))/2.0f),
(min.z + (std::abs(min.z)+std::abs(max.z))/2.0f)
);
_data->scale = scale;
_data->offset = offset;
// std::cout << std::to_string(min) << std::endl;
// std::cout << std::to_string(max) << std::endl;
// std::cout << std::to_string(_data->scale) << std::endl;
// std::cout << std::to_string(_data->offset) << std::endl;
addProperty(_alpha);
addProperty(_delete);
// if(dictionary.hasValue<float>("Group")){
dictionary.getValue("Group", _data->groupName);
// }
// _data->groupId = groupId;
// std::cout << _data->id << std::endl;
// std::cout << _data->frame << std::endl;
// std::cout << std::to_string(_data->offset) << std::endl;
// std::cout << std::to_string(_data->scale) << std::endl;
// std::cout << std::to_string(_data->max) << std::endl;
// std::cout << std::to_string(_data->min) << std::endl;
// std::cout << std::to_string(_data->spatialScale) << std::endl;
// OsEng.gui()._iswa.registerProperty(&_enabled);
}
IswaCygnet::~IswaCygnet(){}
bool IswaCygnet::initialize(){
_textures.push_back(nullptr);
if(!_data->groupName.empty()){
initializeGroup();
}else{
OsEng.gui()._iswa.registerProperty(&_alpha);
OsEng.gui()._iswa.registerProperty(&_delete);
_delete.onChange([this](){
deinitialize();
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + name() + "')");
});
}
initializeTime();
createGeometry();
createShader();
updateTexture();
return true;
}
bool IswaCygnet::deinitialize(){
if(!_data->groupName.empty())
_groupEvent->unsubscribe(name());
// IswaManager::ref().unregisterFromGroup(_data->groupName, this);
unregisterProperties();
destroyGeometry();
destroyShader();
return true;
}
bool IswaCygnet::isReady() const{
bool ready = true;
if (!_shader)
ready &= false;
return ready;
}
void IswaCygnet::render(const RenderData& data){
if(!readyToRender()) return;
psc position = data.position;
glm::mat4 transform = glm::mat4(1.0);
glm::mat4 rot = glm::mat4(1.0);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
}
}
position += transform*glm::vec4(_data->spatialScale.x*_data->offset, _data->spatialScale.w);
// Activate shader
_shader->activate();
glEnable(GL_ALPHA_TEST);
glDisable(GL_CULL_FACE);
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
_shader->setUniform("ModelTransform", transform);
setPscUniforms(*_shader.get(), data.camera, position);
setUniformAndTextures();
renderGeometry();
glEnable(GL_CULL_FACE);
_shader->deactivate();
}
void IswaCygnet::update(const UpdateData& data){
_openSpaceTime = Time::ref().currentTime();
_realTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
_stateMatrix = TransformationManager::ref().frameTransformationMatrix(_data->frame, "GALACTIC", _openSpaceTime);
bool timeToUpdate = (fabs(_openSpaceTime-_lastUpdateOpenSpaceTime) >= _data->updateTime &&
(_realTime.count()-_lastUpdateRealTime.count()) > _minRealTimeUpdateInterval);
if( _data->updateTime != 0 && (Time::ref().timeJumped() || timeToUpdate )){
updateTexture();
_lastUpdateRealTime = _realTime;
_lastUpdateOpenSpaceTime = _openSpaceTime;
}
if(_futureObject.valid() && DownloadManager::futureReady(_futureObject)) {
_textureDirty = true;
}
if(_textureDirty) {
loadTexture();
_textureDirty = false;
}
if(!_transferFunctions.empty())
for(auto tf : _transferFunctions)
tf->update();
}
bool IswaCygnet::destroyShader(){
RenderEngine& renderEngine = OsEng.renderEngine();
if (_shader) {
renderEngine.removeRenderProgram(_shader);
_shader = nullptr;
}
return true;
}
void IswaCygnet::registerProperties(){
OsEng.gui()._iswa.registerProperty(&_enabled);
// OsEng.gui()._iswa.registerProperty(&_delete);
}
void IswaCygnet::unregisterProperties(){
OsEng.gui()._iswa.unregisterProperties(name());
}
void IswaCygnet::initializeTime(){
_openSpaceTime = Time::ref().currentTime();
_lastUpdateOpenSpaceTime = _openSpaceTime;
_realTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
_lastUpdateRealTime = _realTime;
_minRealTimeUpdateInterval = 100;
}
bool IswaCygnet::createShader(){
if (_shader == nullptr) {
// Plane Program
RenderEngine& renderEngine = OsEng.renderEngine();
_shader = renderEngine.buildRenderProgram(_programName,
_vsPath,
_fsPath
);
if (!_shader) return false;
}
return true;
}
void IswaCygnet::initializeGroup(){
_groupEvent = IswaManager::ref().groupEvent(_data->groupName, _type);
_group = IswaManager::ref().registerToGroup(_data->groupName, _type);
//Subscribe to enable propert and delete
_groupEvent->subscribe(name(), "enabledChanged", [&](const ghoul::Dictionary& dict){
LDEBUG(name() + " Event enabledChanged");
_enabled.setValue(dict.value<bool>("enabled"));
});
_groupEvent->subscribe(name(), "alphaChanged", [&](const ghoul::Dictionary& dict){
LDEBUG(name() + " Event alphaChanged");
_alpha.setValue(dict.value<float>("alpha"));
});
_groupEvent->subscribe(name(), "clearGroup", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event clearGroup");
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + name() + "')");
});
}
}//namespace openspac

View File

@@ -0,0 +1,137 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __ISWACYGNET_H__
#define __ISWACYGNET_H__
#define _USE_MATH_DEFINES
#include <math.h>
#include <memory>
#include <chrono>
#include <ghoul/designpattern/event.h>
#include <openspace/properties/propertyowner.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/properties/scalarproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/triggerproperty.h>
#include <openspace/scene/scenegraphnode.h>
#include <modules/onscreengui/include/gui.h>
#include <ghoul/opengl/texture.h>
#include <modules/iswa/util/iswamanager.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <modules/iswa/util/iswamanager.h>
#include <ghoul/misc/dictionary.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/transferfunction.h>
namespace openspace{
class IswaGroup;
struct Metadata {
int id;
int updateTime;
std::string groupName;
std::string path;
std::string parent;
std::string frame;
glm::vec3 gridMin;
glm::vec3 gridMax;
glm::vec3 offset;
glm::vec3 scale;
glm::vec4 spatialScale;
std::string scaleVariable;
std::string coordinateType;
};
class IswaCygnet : public Renderable, public std::enable_shared_from_this<IswaCygnet> {
friend class IswaGroup;
public:
IswaCygnet(const ghoul::Dictionary& dictionary);
~IswaCygnet();
virtual bool initialize();
virtual bool deinitialize();
virtual bool isReady() const;
void render(const RenderData& data);
void update(const UpdateData& data);
protected:
void enabled(bool enabled){_enabled.setValue(enabled);};
void registerProperties();
void unregisterProperties();
void initializeTime();
void initializeGroup();
bool destroyShader();
bool createShader();
virtual bool createGeometry() = 0;
virtual bool destroyGeometry() = 0;
virtual void renderGeometry() const = 0;
virtual bool loadTexture() = 0;
virtual bool updateTexture() = 0;
virtual bool readyToRender() const = 0;
virtual void setUniformAndTextures() = 0;
properties::FloatProperty _alpha;
properties::TriggerProperty _delete;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
std::vector<std::unique_ptr<ghoul::opengl::Texture>> _textures;
std::shared_ptr<Metadata> _data;
glm::dmat3 _stateMatrix;
double _openSpaceTime;
double _lastUpdateOpenSpaceTime;
std::chrono::milliseconds _realTime;
std::chrono::milliseconds _lastUpdateRealTime;
int _minRealTimeUpdateInterval;
std::vector<std::shared_ptr<TransferFunction>> _transferFunctions;
std::future<DownloadManager::MemoryFile> _futureObject;
std::shared_ptr<ghoul::Event<ghoul::Dictionary> > _groupEvent;
std::shared_ptr<IswaGroup> _group;
IswaManager::CygnetType _type;
bool _textureDirty;
std::string _vsPath;
std::string _fsPath;
std::string _programName;
};
}//namespace openspace
#endif

View File

@@ -0,0 +1,270 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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/iswa/rendering/iswagroup.h>
#include <modules/iswa/rendering/dataplane.h>
#include <fstream>
#include <modules/iswa/ext/json/json.hpp>
namespace {
const std::string _loggerCat = "IswaGroup";
using json = nlohmann::json;
}
namespace openspace {
IswaGroup::IswaGroup(std::string name, IswaManager::CygnetType type)
:_enabled("enabled", "Enabled", true)
,_alpha("alpha", "Alpha", 0.9f, 0.0f, 1.0f)
,_useLog("useLog","Use Logarithm", false)
,_useHistogram("useHistogram", "Use Histogram", false)
,_autoFilter("autoFilter", "Auto Filter", true)
,_normValues("normValues", "Normalize Values", glm::vec2(1.0,1.0), glm::vec2(0), glm::vec2(5.0))
,_backgroundValues("backgroundValues", "Background Values", glm::vec2(0.0), glm::vec2(0), glm::vec2(1.0))
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
,_delete("delete", "Delete")
,_dataOptions("dataOptions", "Data Options")
,_fieldlines("fieldlineSeedsIndexFile", "Fieldline Seedpoints")
,_fieldlineIndexFile("")
,_type(type)
,_registered(false)
{
setName(name);
addProperty(_enabled);
addProperty(_alpha);
addProperty(_useLog);
addProperty(_useHistogram);
addProperty(_autoFilter);
addProperty(_normValues);
addProperty(_backgroundValues);
addProperty(_transferFunctionsFile);
addProperty(_dataOptions);
addProperty(_fieldlines);
addProperty(_delete);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
_groupEvent = std::make_shared<ghoul::Event<ghoul::Dictionary> >();
registerProperties();
}
IswaGroup::~IswaGroup(){}
void IswaGroup::registerOptions(const std::vector<properties::SelectionProperty::Option>& options){
if(!_registered){
registerProperties(); }
if(_type == IswaManager::CygnetType::Data){
if(_dataOptions.options().empty()){
for(auto option : options){
_dataOptions.addOption({option.value, option.description});
}
_dataOptions.setValue(std::vector<int>(1,0));
}
}
}
void IswaGroup::setFieldlineInfo(std::string fieldlineIndexFile, std::string kameleonPath){
if(fieldlineIndexFile != _fieldlineIndexFile){
_fieldlineIndexFile = fieldlineIndexFile;
readFieldlinePaths(_fieldlineIndexFile);
}
if(kameleonPath != _kameleonPath){
_kameleonPath = kameleonPath;
clearFieldlines();
updateFieldlineSeeds();
}
}
bool IswaGroup::isType(IswaManager::CygnetType type){
if(_type == IswaManager::CygnetType::NoType) return true;
return (_type == type);
}
void IswaGroup::registerProperties(){
OsEng.gui()._iswa.registerProperty(&_enabled);
OsEng.gui()._iswa.registerProperty(&_alpha);
_enabled.onChange([this]{
LDEBUG("Group " + name() + " published enabledChanged");
_groupEvent->publish("enabledChanged", ghoul::Dictionary({{"enabled", _enabled.value()}}));
});
_alpha.onChange([this]{
LDEBUG("Group " + name() + " published alphaChanged");
_groupEvent->publish("alphaChanged", ghoul::Dictionary({{"alpha", _alpha.value()}}));
});
if(_type == IswaManager::CygnetType::Data){
OsEng.gui()._iswa.registerProperty(&_useLog);
OsEng.gui()._iswa.registerProperty(&_useHistogram);
OsEng.gui()._iswa.registerProperty(&_autoFilter);
OsEng.gui()._iswa.registerProperty(&_normValues);
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
OsEng.gui()._iswa.registerProperty(&_fieldlines);
OsEng.gui()._iswa.registerProperty(&_dataOptions);
_useLog.onChange([this]{
LDEBUG("Group " + name() + " published useLogChanged");
_groupEvent->publish("useLogChanged", ghoul::Dictionary({{"useLog", _useLog.value()}}));
});
_useHistogram.onChange([this]{
LDEBUG("Group " + name() + " published useHistogramChanged");
_groupEvent->publish("useHistogramChanged", ghoul::Dictionary({{"useHistogram", _useHistogram.value()}}));
});
_autoFilter.onChange([this]{
LDEBUG("Group " + name() + " published autoFilterChanged");
_groupEvent->publish("autoFilterChanged", ghoul::Dictionary({{"autoFilter", _autoFilter.value()}}));
});
_normValues.onChange([this]{
LDEBUG("Group " + name() + " published normValuesChanged");
_groupEvent->publish("normValuesChanged", ghoul::Dictionary({{"normValues", std::make_shared<glm::vec2>(_normValues.value())}}));
});
_backgroundValues.onChange([this]{
LDEBUG("Group " + name() + " published backgroundValuesChanged");
_groupEvent->publish("backgroundValuesChanged", ghoul::Dictionary({{"backgroundValues", std::make_shared<glm::vec2>(_backgroundValues.value())}}));
});
_transferFunctionsFile.onChange([this]{
LDEBUG("Group " + name() + " published transferFunctionsChanged");
_groupEvent->publish("transferFunctionsChanged", ghoul::Dictionary({{"transferFunctions", _transferFunctionsFile.value()}}));
});
_dataOptions.onChange([this]{
LDEBUG("Group " + name() + " published dataOptionsChanged");
_groupEvent->publish("dataOptionsChanged", ghoul::Dictionary({{"dataOptions", std::make_shared<std::vector<int> >(_dataOptions.value())}}));
});
_fieldlines.onChange([this]{
updateFieldlineSeeds();
// LDEBUG("Group " + name() + " published fieldlinesChanged");
// _groupEvent->publish("fieldlinesChanged", ghoul::Dictionary({{"fieldlines", std::make_shared<std::vector<int> >(_fieldlines.value())}}));
});
}
OsEng.gui()._iswa.registerProperty(&_delete);
_delete.onChange([this]{
clearGroup();
});
_registered = true;
}
void IswaGroup::unregisterProperties(){
OsEng.gui()._iswa.unregisterProperties(name());
_registered = false;
}
void IswaGroup::updateGroup(){
_groupEvent->publish("updateGroup", ghoul::Dictionary());
}
void IswaGroup::clearGroup(){
_groupEvent->publish("clearGroup", ghoul::Dictionary());
LDEBUG("Group " + name() + " published clearGroup");
unregisterProperties();
clearFieldlines();
}
std::shared_ptr<DataProcessor> IswaGroup::dataProcessor(){
return _dataProcessor;
}
void IswaGroup::updateFieldlineSeeds(){
std::vector<int> selectedOptions = _fieldlines.value();
// SeedPath == map<int selectionValue, tuple< string name, string path, bool active > >
for (auto& seedPath: _fieldlineState) {
// if this option was turned off
if( std::find(selectedOptions.begin(), selectedOptions.end(), seedPath.first)==selectedOptions.end() && std::get<2>(seedPath.second)){
LDEBUG("Removed fieldlines: " + std::get<0>(seedPath.second));
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + std::get<0>(seedPath.second) + "')");
std::get<2>(seedPath.second) = false;
// if this option was turned on
} else if( std::find(selectedOptions.begin(), selectedOptions.end(), seedPath.first)!=selectedOptions.end() && !std::get<2>(seedPath.second)) {
LDEBUG("Created fieldlines: " + std::get<0>(seedPath.second));
IswaManager::ref().createFieldline(std::get<0>(seedPath.second), _kameleonPath, std::get<1>(seedPath.second));
std::get<2>(seedPath.second) = true;
}
}
}
void IswaGroup::readFieldlinePaths(std::string indexFile){
LINFO("Reading seed points paths from file '" << indexFile << "'");
// Read the index file from disk
std::ifstream seedFile(indexFile);
if (!seedFile.good())
LERROR("Could not open seed points file '" << indexFile << "'");
else {
std::string line;
std::string fileContent;
while (std::getline(seedFile, line)) {
fileContent += line;
}
try{
//Parse and add each fieldline as an selection
json fieldlines = json::parse(fileContent);
int i = 0;
for (json::iterator it = fieldlines.begin(); it != fieldlines.end(); ++it) {
_fieldlines.addOption({i, name()+"/"+it.key()});
_fieldlineState[i] = std::make_tuple(name()+"/"+it.key(), it.value(), false);
i++;
}
} catch(const std::exception& e) {
LERROR("Error when reading json file with paths to seedpoints: " + std::string(e.what()));
}
}
}
void IswaGroup::clearFieldlines(){
// SeedPath == map<int selectionValue, tuple< string name, string path, bool active > >
for (auto& seedPath: _fieldlineState) {
if(std::get<2>(seedPath.second)){
LDEBUG("Removed fieldlines: " + std::get<0>(seedPath.second));
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + std::get<0>(seedPath.second) + "')");
std::get<2>(seedPath.second) = false;
}
}
}
} //namespace openspace

View File

@@ -0,0 +1,108 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __ISWAGROUP_H__
#define __ISWAGROUP_H__
#include <ghoul/designpattern/event.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/selectionproperty.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/engine/openspaceengine.h>
// #include <modules/iswa/rendering/iswacygnet.h>
#include <openspace/properties/triggerproperty.h>
#include <modules/iswa/util/iswamanager.h>
#include <modules/iswa/util/dataprocessor.h>
namespace openspace{
class IswaCygnet;
class IswaGroup : public properties::PropertyOwner{
public:
IswaGroup(std::string name, IswaManager::CygnetType type);
~IswaGroup();
//void registerCygnet(IswaCygnet* cygnet, IswaManager::CygnetType type);
//void unregisterCygnet(IswaCygnet* cygnet);
void registerOptions(const std::vector<properties::SelectionProperty::Option>& options);
void registerFieldLineOptions(const std::vector<properties::SelectionProperty::Option>& options);
bool isType(IswaManager::CygnetType type);
void clearGroup();
void updateGroup();
std::shared_ptr<ghoul::Event<ghoul::Dictionary> > groupEvent(){ return _groupEvent; };
std::shared_ptr<DataProcessor> dataProcessor();
std::vector<int> fieldlineValue() {return _fieldlines.value();}
std::vector<int> dataOptionsValue() {return _dataOptions.value();}
void setFieldlineInfo(std::string fieldlineIndexFile, std::string kameleonPath);
// bool useLog(){return _useLog.value();};
// glm::vec2 normValues(){return _normValues.value();};
// bool useHistogram(){return _useHistogram.value();};
// std::vector<int> dataOptions(){return _dataOptions.value();};
// std::string transferFunctionsFile(){return _transferFunctionsFile.value();};
// glm::vec2 backgroundValues(){return _backgroundValues.value();};
private:
void registerProperties();
void unregisterProperties();
void readFieldlinePaths(std::string indexFile);
void updateFieldlineSeeds();
void clearFieldlines();
properties::BoolProperty _enabled;
properties::FloatProperty _alpha;
properties::BoolProperty _useLog;
properties::BoolProperty _useHistogram;
properties::BoolProperty _autoFilter;
properties::Vec2Property _normValues;
properties::Vec2Property _backgroundValues;
properties::StringProperty _transferFunctionsFile;
properties::SelectionProperty _dataOptions;
properties::SelectionProperty _fieldlines;
properties::TriggerProperty _delete;
// properties::SelectionProperty _dataOptions;
// properties::StringProperty _transferFunctionsFile;
// properties::Vec2Property _normValues;
// properties::Vec2Property _backgroundValues;
// properties::BoolProperty _useLog;
// properties::BoolProperty _useHistogram;;
// int groupId;
// IswaCygnet cygnet;
int _id;
std::shared_ptr<ghoul::Event<ghoul::Dictionary> > _groupEvent;
std::shared_ptr<DataProcessor> _dataProcessor;
//std::vector<IswaCygnet* > _cygnets;
IswaManager::CygnetType _type;
bool _registered;
std::string _fieldlineIndexFile;
std::string _kameleonPath;
std::map<int, std::tuple<std::string, std::string, bool> > _fieldlineState;
};
} //namespace openspace
#endif

View File

@@ -0,0 +1,527 @@
// /*****************************************************************************************
// * *
// * OpenSpace *
// * *
// * Copyright (c) 2014-2016 *
// * *
// * 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/iswa/rendering/kameleonplane.h>
#include <ghoul/filesystem/filesystem>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <ghoul/filesystem/filesystem.h>
#include <fstream>
#include <modules/iswa/ext/json/json.hpp>
#include <modules/iswa/rendering/iswagroup.h>
namespace {
using json = nlohmann::json;
const std::string _loggerCat = "KameleonPlane";
const int MAX_TEXTURES = 6;
}
namespace openspace {
KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary)
:CygnetPlane(dictionary)
,_useLog("useLog","Use Logarithm", false)
,_useHistogram("useHistogram", "Use Histogram", false)
,_autoFilter("autoFilter", "Auto Filter", true)
,_normValues("normValues", "Normalize Values", glm::vec2(1.0,1.0), glm::vec2(0), glm::vec2(5.0))
,_backgroundValues("backgroundValues", "Background Values", glm::vec2(0.0), glm::vec2(0), glm::vec2(1.0))
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
,_dataOptions("dataOptions", "Data Options")
,_fieldlines("fieldlineSeedsIndexFile", "Fieldline Seedpoints")
,_resolution("resolution", "Resolutionx100", 1, 1, 5)
,_slice("slice", "Slice", 0.0, 0.0, 1.0)
{
std::string name;
dictionary.getValue("Name", name);
setName(name);
registerProperties();
addProperty(_useLog);
addProperty(_useHistogram);
addProperty(_autoFilter);
addProperty(_normValues);
addProperty(_backgroundValues);
addProperty(_resolution);
addProperty(_slice);
addProperty(_transferFunctionsFile);
addProperty(_dataOptions);
addProperty(_fieldlines);
_type = IswaManager::CygnetType::Data;
dictionary.getValue("kwPath", _kwPath);
std::string fieldlineIndexFile;
dictionary.getValue("fieldlineSeedsIndexFile", _fieldlineIndexFile);
std::string axis;
dictionary.getValue("axisCut", axis);
OsEng.gui()._iswa.registerProperty(&_slice);
if(axis == "x"){
_scale = _data->scale.x;
_data->scale.x = 0;
_data->offset.x = 0;
_slice.setValue(0.8);
}else if(axis == "y"){
_scale = _data->scale.y;
_data->scale.y = 0;
// _data->offset.y = 0;
_slice.setValue((_data->offset.y -_data->gridMin.y)/_scale);
}else{
_scale = _data->scale.z;
_data->scale.z = 0;
// _data->offset.z = 0;
_slice.setValue((_data->offset.z - _data->gridMin.z)/_scale);
}
_programName = "DataPlaneProgram";
_vsPath = "${MODULE_ISWA}/shaders/dataplane_vs.glsl";
_fsPath = "${MODULE_ISWA}/shaders/dataplane_fs.glsl";
}
KameleonPlane::~KameleonPlane(){}
bool KameleonPlane::deinitialize(){
IswaCygnet::deinitialize();
_fieldlines.set(std::vector<int>());
_kw = nullptr;
return true;
}
bool KameleonPlane::initialize(){
_kw = std::make_shared<KameleonWrapper>(absPath(_kwPath));
_textures.push_back(nullptr);
if(!_data->groupName.empty()){
initializeGroup();
}
initializeTime();
createGeometry();
createShader();
readFieldlinePaths(absPath(_fieldlineIndexFile));
if(_group){
_dataProcessor = _group->dataProcessor();
_groupEvent->subscribe(name(), "useLogChanged", [&](const ghoul::Dictionary& dict){
LDEBUG(name() + " Event useLogChanged");
_useLog.setValue(dict.value<bool>("useLog"));
});
_groupEvent->subscribe(name(), "normValuesChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event normValuesChanged");
std::shared_ptr<glm::vec2> values;
bool success = dict.getValue("normValues", values);
if(success){
_normValues.setValue(*values);
}
});
_groupEvent->subscribe(name(), "useHistogramChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event useHistogramChanged");
_useHistogram.setValue(dict.value<bool>("useHistogram"));
});
_groupEvent->subscribe(name(), "dataOptionsChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event dataOptionsChanged");
std::shared_ptr<std::vector<int> > values;
bool success = dict.getValue("dataOptions", values);
if(success){
_dataOptions.setValue(*values);
}
});
_groupEvent->subscribe(name(), "transferFunctionsChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event transferFunctionsChanged");
_transferFunctionsFile.setValue(dict.value<std::string>("transferFunctions"));
});
_groupEvent->subscribe(name(), "backgroundValuesChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event backgroundValuesChanged");
std::shared_ptr<glm::vec2> values;
bool success = dict.getValue("backgroundValues", values);
if(success){
_backgroundValues.setValue(*values);
}
});
_groupEvent->subscribe(name(), "autoFilterChanged", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event autoFilterChanged");
_autoFilter.setValue(dict.value<bool>("autoFilter"));
});
_groupEvent->subscribe(name(), "updateGroup", [&](ghoul::Dictionary dict){
LDEBUG(name() + " Event updateGroup");
loadTexture();
});
}else{
OsEng.gui()._iswa.registerProperty(&_useLog);
OsEng.gui()._iswa.registerProperty(&_useHistogram);
OsEng.gui()._iswa.registerProperty(&_autoFilter);
OsEng.gui()._iswa.registerProperty(&_normValues);
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
OsEng.gui()._iswa.registerProperty(&_resolution);
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
OsEng.gui()._iswa.registerProperty(&_fieldlines);
OsEng.gui()._iswa.registerProperty(&_dataOptions);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
}
setTransferFunctions(_transferFunctionsFile.value());
_normValues.onChange([this](){
_dataProcessor->normValues(_normValues.value());
loadTexture();
});
_useLog.onChange([this](){
_dataProcessor->useLog(_useLog.value());
loadTexture();
});
_useHistogram.onChange([this](){
_dataProcessor->useHistogram(_useHistogram.value());
loadTexture();
});
_transferFunctionsFile.onChange([this](){
setTransferFunctions(_transferFunctionsFile.value());
});
_resolution.onChange([this](){
for(int i=0; i<_textures.size(); i++){
_textures[i] = std::move(nullptr);
}
_dataProcessor->clear();
updateTexture();
});
_slice.onChange([this](){
updateTexture();
});
_fieldlines.onChange([this](){
updateFieldlineSeeds();
});
fillOptions();
updateTexture();
return true;
}
bool KameleonPlane::loadTexture() {
std::vector<int> selectedOptions = _dataOptions.value();
auto options = _dataOptions.options();
for(int option : selectedOptions){
if(!_dataSlices[option]){
std::string optionName = options[option].description;
_dataSlices[option] = _kw->getUniformSliceValues(optionName, _dimensions, _slice.value());
if(!_textures[option]){
_dataProcessor->addValuesFromKameleonData(_dataSlices[option], _dimensions, options.size(), option);
if(_group)
_group->updateGroup();
}
}
}
std::vector<float*> data = _dataProcessor->processKameleonData2(_dataSlices, _dimensions, _dataOptions);
if(data.empty())
return false;
if(_autoFilter.value())
_backgroundValues.setValue(_dataProcessor->filterValues());
bool texturesReady = false;
for(int option: selectedOptions){
float* values = data[option];
if(!values) continue;
if(!_textures[option]){
std::unique_ptr<ghoul::opengl::Texture> texture = std::make_unique<ghoul::opengl::Texture>(
values,
_textureDimensions,
ghoul::opengl::Texture::Format::Red,
GL_RED,
GL_FLOAT,
ghoul::opengl::Texture::FilterMode::Linear,
ghoul::opengl::Texture::WrappingMode::ClampToEdge
);
if(texture){
texture->uploadTexture();
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_textures[option] = std::move(texture);
}
}else{
_textures[option]->setPixelData(values);
_textures[option]->uploadTexture();
}
texturesReady = true;
}
return texturesReady;
}
bool KameleonPlane::updateTexture(){
_dimensions = glm::size3_t(_resolution.value()*100);
if(_data->scale.x == 0){
_dimensions.x = 1;
_dimensions.z = (int) _dimensions.y * (_data->scale.y/_data->scale.z);
_textureDimensions = glm::size3_t(_dimensions.y, _dimensions.z, 1);
_data->offset.x = _data->gridMin.x+_slice.value()*_scale;
}else if(_data->scale.y == 0){
_dimensions.y = 1;
_dimensions.z = (int) _dimensions.x * (_data->scale.x/_data->scale.z);
_textureDimensions = glm::size3_t(_dimensions.x, _dimensions.z, 1);
_data->offset.y = _data->gridMin.y+_slice.value()*_scale;
}else{
_dimensions.z = 1;
_dimensions.y = (int) _dimensions.x * (_data->scale.x/_data->scale.y);
_textureDimensions = glm::size3_t(_dimensions.x, _dimensions.y, 1);
_data->offset.z = _data->gridMin.z+_slice.value()*_scale;
}
for(int i=0; i<_dataSlices.size(); ++i){
float* slice = _dataSlices[i];
if(slice){
_dataSlices[i] = nullptr;
delete slice;
}
}
_textureDirty = true;
return true;
}
bool KameleonPlane::readyToRender() const {
return (!_textures.empty() && !_transferFunctions.empty());
}
void KameleonPlane::setUniformAndTextures(){
std::vector<int> selectedOptions = _dataOptions.value();
int activeTextures = std::min((int)selectedOptions.size(), MAX_TEXTURES);
int activeTransferfunctions = std::min((int)_transferFunctions.size(), MAX_TEXTURES);
ghoul::opengl::TextureUnit txUnits[6];
int j = 0;
for(int option : selectedOptions){
if(_textures[option]){
txUnits[j].activate();
_textures[option]->bind();
_shader->setUniform(
"textures[" + std::to_string(j) + "]",
txUnits[j]
);
j++;
if(j >= MAX_TEXTURES) break;
}
}
if(activeTextures > 0){
if(selectedOptions.back()>=activeTransferfunctions)
activeTransferfunctions = 1;
}
ghoul::opengl::TextureUnit tfUnits[6];
j = 0;
if((activeTransferfunctions == 1)){
tfUnits[0].activate();
_transferFunctions[0]->bind();
_shader->setUniform(
"transferFunctions[0]",
tfUnits[0]
);
}else{
for(int option : selectedOptions){
if(_transferFunctions[option]){
tfUnits[j].activate();
_transferFunctions[option]->bind();
_shader->setUniform(
"transferFunctions[" + std::to_string(j) + "]",
tfUnits[j]
);
j++;
if(j >= MAX_TEXTURES) break;
}
}
}
_shader->setUniform("numTextures", activeTextures);
_shader->setUniform("numTransferFunctions", activeTransferfunctions);
_shader->setUniform("backgroundValues", _backgroundValues.value());
_shader->setUniform("transparency", _alpha.value());
}
void KameleonPlane::setTransferFunctions(std::string tfPath){
std::string line;
std::ifstream tfFile(absPath(tfPath));
std::vector<std::shared_ptr<TransferFunction>> tfs;
if(tfFile.is_open()){
while(getline(tfFile, line)){
std::shared_ptr<TransferFunction> tf = std::make_shared<TransferFunction>(absPath(line));
if(tf){
tfs.push_back(tf);
}
}
tfFile.close();
}
if(!tfs.empty()){
_transferFunctions.clear();
_transferFunctions = tfs;
}
}
void KameleonPlane::fillOptions(){
std::vector<std::string> options = _kw->getVariables();
int numOptions = 0;
for(std::string option : options){
if(option.size() < 4 && option != "x" && option != "y" && option != "z"){
_dataOptions.addOption({numOptions, option});
_dataSlices.push_back(nullptr);
_textures.push_back(nullptr);
numOptions++;
}
}
if(_group){
_group->registerOptions(_dataOptions.options());
_dataOptions.setValue(_group->dataOptionsValue());
}else{
_dataOptions.setValue(std::vector<int>(1,0));
// IswaManager::ref().registerOptionsToGroup(_data->groupName, _dataOptions.options());
}
_dataOptions.onChange([this](){
if(_dataOptions.value().size() > MAX_TEXTURES)
LWARNING("Too many options chosen, max is " + std::to_string(MAX_TEXTURES));
loadTexture();
});
}
void KameleonPlane::updateFieldlineSeeds(){
std::vector<int> selectedOptions = _fieldlines.value();
// SeedPath == map<int selectionValue, tuple< string name, string path, bool active > >
for (auto& seedPath: _fieldlineState) {
// if this option was turned off
if( std::find(selectedOptions.begin(), selectedOptions.end(), seedPath.first)==selectedOptions.end() && std::get<2>(seedPath.second)){
if(OsEng.renderEngine().scene()->sceneGraphNode(std::get<0>(seedPath.second)) == nullptr) return;
LDEBUG("Removed fieldlines: " + std::get<0>(seedPath.second));
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + std::get<0>(seedPath.second) + "')");
std::get<2>(seedPath.second) = false;
// if this option was turned on
} else if( std::find(selectedOptions.begin(), selectedOptions.end(), seedPath.first)!=selectedOptions.end() && !std::get<2>(seedPath.second)) {
if(OsEng.renderEngine().scene()->sceneGraphNode(std::get<0>(seedPath.second)) != nullptr) return;
LDEBUG("Created fieldlines: " + std::get<0>(seedPath.second));
IswaManager::ref().createFieldline(std::get<0>(seedPath.second), _kwPath, std::get<1>(seedPath.second));
std::get<2>(seedPath.second) = true;
}
}
}
void KameleonPlane::readFieldlinePaths(std::string indexFile){
LINFO("Reading seed points paths from file '" << indexFile << "'");
if(_group){
_group->setFieldlineInfo(indexFile, _kwPath);
return;
}
// Read the index file from disk
std::ifstream seedFile(indexFile);
if (!seedFile.good())
LERROR("Could not open seed points file '" << indexFile << "'");
else {
std::string line;
std::string fileContent;
while (std::getline(seedFile, line)) {
fileContent += line;
}
try{
//Parse and add each fieldline as an selection
json fieldlines = json::parse(fileContent);
int i = 0;
std::string fullName = name();
std::string partName = fullName.substr(0,fullName.find_last_of("-"));
std::cout << fullName << std::endl;
std::cout << partName << std::endl;
for (json::iterator it = fieldlines.begin(); it != fieldlines.end(); ++it) {
_fieldlines.addOption({i, name()+"/"+it.key()});
_fieldlineState[i] = std::make_tuple(partName+"/"+it.key(), it.value(), false);
i++;
}
// if(_group)
// _group->registerFieldLineOptions(_fieldlines.options());
} catch(const std::exception& e) {
LERROR("Error when reading json file with paths to seedpoints: " + std::string(e.what()));
}
}
}
}// namespace openspace

View File

@@ -0,0 +1,108 @@
/****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __KAMELEONPLANE_H__
#define __KAMELEONPLANE_H__
#include <modules/iswa/rendering/cygnetplane.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <modules/iswa/util/dataprocessor.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/properties/selectionproperty.h>
namespace openspace{
class KameleonPlane : public CygnetPlane {
public:
KameleonPlane(const ghoul::Dictionary& dictionary);
~KameleonPlane();
bool initialize() override;
bool deinitialize() override;
private:
virtual bool loadTexture() override;
virtual bool updateTexture() override;
virtual bool readyToRender() const override;
virtual void setUniformAndTextures() override;
/**
* Given a path to the json index of seedpoints file, this
* method reads, parses and adds them as checkbox options
* in the _fieldlines SelectionProperty
*
* @param indexFile Path to json index file
*/
void readFieldlinePaths(std::string indexFile);
/**
* Updates the _fieldlineState map to match the _fieldlines
* SelectionProperty and creates or removes fieldlines in the scene.
*/
void updateFieldlineSeeds();
void setTransferFunctions(std::string tfPath);
void fillOptions();
static int id();
properties::IntProperty _resolution;
properties::FloatProperty _slice;
properties::SelectionProperty _dataOptions;
properties::SelectionProperty _fieldlines;
properties::StringProperty _transferFunctionsFile;
properties::Vec2Property _backgroundValues;
properties::Vec2Property _normValues;
properties::BoolProperty _useLog;
properties::BoolProperty _useHistogram;
properties::BoolProperty _autoFilter;
std::shared_ptr<KameleonWrapper> _kw;
std::string _kwPath;
glm::size3_t _dimensions;
glm::size3_t _textureDimensions;
float* _dataSlice;
std::string _var;
std::vector<float*> _dataSlices;
std::shared_ptr<DataProcessor> _dataProcessor;
float _scale;
/**
* _fieldlineState maps the checkbox value of each fieldline seedpoint file to a tuple
* containing information that is needed to either add or remove a fieldline from the scenegraph.
* this is the name, path to seedpoints file and a boolean to determine if it is active or inactive.
*/
std::map<int, std::tuple<std::string, std::string, bool> > _fieldlineState;
std::string _fieldlineIndexFile;
};
} // namespace openspace
#endif //__KAMELEONPLANE_H__

View File

@@ -0,0 +1,88 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/iswa/rendering/screenspacecygnet.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/filesystem/filesystem>
#include <openspace/util/time.h>
#include <modules/iswa/util/iswamanager.h>
namespace {
const std::string _loggerCat = "ScreenSpaceCygnet";
}
namespace openspace {
ScreenSpaceCygnet::ScreenSpaceCygnet(const ghoul::Dictionary& dictionary)
: ScreenSpaceImage(dictionary)
{
// hacky, have to first get as float and then cast to int.
float cygnetid;
dictionary.getValue("CygnetId", cygnetid);
_cygnetId = (int)cygnetid;
float interval;
dictionary.getValue("UpdateInterval", interval);
_updateTime = (int) interval;
_downloadImage = true;
_url = IswaManager::ref().iswaUrl(_cygnetId);
_openSpaceTime = Time::ref().currentTime();
_lastUpdateOpenSpaceTime = _openSpaceTime;
_realTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
_lastUpdateRealTime = _realTime;
_minRealTimeUpdateInterval = 100;
_delete.onChange([this](){
OsEng.scriptEngine().queueScript(
"openspace.iswa.removeScreenSpaceCygnet("+std::to_string(_cygnetId)+");"
);
});
// IswaManager::ref().deleteIswaCygnet(name());});
}
ScreenSpaceCygnet::~ScreenSpaceCygnet(){}
void ScreenSpaceCygnet::update(){
_openSpaceTime = Time::ref().currentTime();
_realTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
bool timeToUpdate = (fabs(_openSpaceTime-_lastUpdateOpenSpaceTime) >= _updateTime &&
(_realTime.count()-_lastUpdateRealTime.count()) > _minRealTimeUpdateInterval);
if((Time::ref().timeJumped() || timeToUpdate )){
_url = IswaManager::ref().iswaUrl(_cygnetId);
updateTexture();
_lastUpdateRealTime = _realTime;
_lastUpdateOpenSpaceTime = _openSpaceTime;
}
if(_futureImage.valid() && DownloadManager::futureReady(_futureImage)) {
loadTexture();
}
}
}

View File

@@ -0,0 +1,59 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __SCREENSPACECYGNET_H__
#define __SCREENSPACECYGNET_H__
#include <chrono>
#include <future>
#include <openspace/rendering/screenspacerenderable.h>
#include <modules/base/rendering/screenspaceimage.h>
#include <openspace/engine/downloadmanager.h>
#include <modules/iswa/util/iswamanager.h>
namespace openspace{
class ScreenSpaceCygnet : public ScreenSpaceImage {
public:
ScreenSpaceCygnet(const ghoul::Dictionary& dictionary);
~ScreenSpaceCygnet();
virtual void update() override;
private:
int _cygnetId;
int _updateTime;
double _openSpaceTime;
double _lastUpdateOpenSpaceTime;
std::chrono::milliseconds _realTime;
std::chrono::milliseconds _lastUpdateRealTime;
int _minRealTimeUpdateInterval;
};
} // namespace openspace
#endif //__SCREENSPACECYGNET_H__

View File

@@ -0,0 +1,95 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/iswa/rendering/texturecygnet.h>
#include <ghoul/io/texture/texturereader.h>
namespace {
const std::string _loggerCat = "TextureCygnet";
}
namespace openspace{
TextureCygnet::TextureCygnet(const ghoul::Dictionary& dictionary)
:IswaCygnet(dictionary)
{}
TextureCygnet::~TextureCygnet(){}
bool TextureCygnet::loadTexture() {
// if The future is done then get the new imageFile
DownloadManager::MemoryFile imageFile;
if(_futureObject.valid() && DownloadManager::futureReady(_futureObject)){
imageFile = _futureObject.get();
} else {
return false;
}
if(imageFile.corrupted)
return false;
std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::TextureReader::ref().loadTexture(
(void*) imageFile.buffer,
imageFile.size,
imageFile.format);
if (texture) {
LDEBUG("Loaded texture from image iswa cygnet with id: '" << _data->id << "'");
texture->uploadTexture();
// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_textures[0] = std::move(texture);
}
return false;
}
bool TextureCygnet::updateTexture(){
if(_textures.empty())
_textures.push_back(nullptr);
if(_futureObject.valid())
return false;
std::future<DownloadManager::MemoryFile> future = IswaManager::ref().fetchImageCygnet(_data->id);
if(future.valid()){
_futureObject = std::move(future);
return true;
}
return false;
}
bool TextureCygnet::readyToRender() const {
return (isReady() && ((!_textures.empty()) && (_textures[0] != nullptr)));
}
} //namespace openspace

View File

@@ -0,0 +1,57 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __TEXTURECYGNET_H__
#define __TEXTURECYGNET_H__
#include <modules/iswa/rendering/iswacygnet.h>
namespace openspace{
/**
* This class exist tp abstract away the loading of images
* from iSWA and updating of the textures for child geometries.
* The class specifies the minimum interface that child classes
* needs to implement.
*/
class TextureCygnet : public IswaCygnet {
public:
TextureCygnet(const ghoul::Dictionary& dictionary);
~TextureCygnet();
protected:
bool loadTexture() override;
bool updateTexture() override;
bool readyToRender() const override;
// Interface for concrete subclasses
virtual void setUniformAndTextures() = 0;
virtual bool createGeometry() = 0;
virtual bool destroyGeometry() = 0;
virtual void renderGeometry() const = 0;
};
} //namespace openspace
#endif //__TEXTURECYGNET_H__

View File

@@ -0,0 +1,112 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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/iswa/rendering/textureplane.h>
#include <openspace/engine/openspaceengine.h>
#include <ghoul/opengl/texture.h>
namespace {
const std::string _loggerCat = "TexturePlane";
}
namespace openspace {
TexturePlane::TexturePlane(const ghoul::Dictionary& dictionary)
:TextureCygnet(dictionary)
,_quad(0)
,_vertexPositionBuffer(0)
{
std::string name;
dictionary.getValue("Name", name);
setName(name);
registerProperties();
_type = IswaManager::CygnetType::Texture;
_programName = "PlaneProgram";
_vsPath = "${MODULE_ISWA}/shaders/cygnetplane_vs.glsl";
_fsPath = "${MODULE_ISWA}/shaders/cygnetplane_fs.glsl";
}
TexturePlane::~TexturePlane(){}
void TexturePlane::setUniformAndTextures(){
ghoul::opengl::TextureUnit unit;
unit.activate();
_textures[0]->bind();
_shader->setUniform("texture1", unit);
_shader->setUniform("transparency", _alpha.value());
}
bool TexturePlane::createGeometry() {
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
// ============================
// GEOMETRY (quad)
// ============================
float s = _data->spatialScale.x;
const GLfloat x = s*_data->scale.x/2.0;
const GLfloat y = s*_data->scale.y/2.0;
const GLfloat z = s*_data->scale.z/2.0;
const GLfloat w = _data->spatialScale.w;
const GLfloat vertex_data[] = { // square of two triangles (sigh)
// x y z w s t
-x, -y, -z, w, 0, 1,
x, y, z, w, 1, 0,
-x, ((x>0)?y:-y), z, w, 0, 0,
-x, -y, -z, w, 0, 1,
x, ((x>0)?-y:y), -z, w, 1, 1,
x, y, z, w, 1, 0,
};
glBindVertexArray(_quad); // bind array
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
return true;
}
bool TexturePlane::destroyGeometry(){
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
return true;
}
void TexturePlane::renderGeometry() const {
glBindVertexArray(_quad);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
}// namespace openspace

View File

@@ -0,0 +1,54 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __TEXTUREPLANE_H__
#define __TEXTUREPLANE_H__
#include <modules/iswa/rendering/texturecygnet.h>
namespace openspace{
/**
* TexturePlane is a "concrete" IswaCygnet. It handles the creation,
* destruction and rendering of a plane geometry. It also specifies
* which shaders to use and the uniforms that it needs.
*/
class TexturePlane : public TextureCygnet{
public:
TexturePlane(const ghoul::Dictionary& dictionary);
~TexturePlane();
private:
bool createGeometry() override;
void setUniformAndTextures() override;
bool destroyGeometry() override;
void renderGeometry() const override;
GLuint _quad;
GLuint _vertexPositionBuffer;
};
} // namespace openspace
#endif

View File

@@ -0,0 +1,60 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 time;
uniform sampler2D texture1;
uniform float transparency;
in vec2 vs_st;
in vec4 vs_position;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
vec4 position = vs_position;
float depth = pscDepth(position);
vec4 diffuse;
diffuse = texture(texture1, vec2(vs_st.s, 1-vs_st.t));
//vec4 diffuse = vec4(1,vs_st,1);
//vec4 diffuse = vec4(1,0,0,1);
// if(position.w > 9.0) {
// diffuse = vec4(1,0,0,1);
// }
//diffuse.a = diffuse.r;
float tot = diffuse.r + diffuse.g + diffuse.b;
tot /= 3.0;
if (tot >= 0.5 || tot <= 0.05)
discard;
diffuse.a *= transparency;
Fragment frag;
frag.color = diffuse;
frag.depth = depth;
return frag;
}

View File

@@ -0,0 +1,49 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
out vec4 vs_position;
out float s;
#include "PowerScaling/powerScaling_vs.hglsl"
void main()
{
vec4 tmp = in_position;
vec4 position = pscTransform(tmp, ModelTransform);
vs_position = tmp;
vs_st = in_st;
position = ViewProjection * position;
gl_Position = z_normalization(position);
}

View File

@@ -0,0 +1,88 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 time;
// uniform sampler2D texture1;
uniform sampler2D textures[6];
uniform sampler2D transferFunctions[6];
// uniform sampler2D tf;
// uniform sampler2D tfs[6];
uniform int numTextures;
uniform int numTransferFunctions;
uniform bool averageValues;
uniform vec2 backgroundValues;
uniform float transparency;
// uniform float background;
in vec2 vs_st;
in vec4 vs_position;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
vec4 position = vs_position;
float depth = pscDepth(position);
vec4 transparent = vec4(0.0f);
vec4 diffuse = transparent;
float v = 0;
float x = backgroundValues.x;
float y = backgroundValues.y;
if((numTransferFunctions == 1) || (numTextures > numTransferFunctions)){
for(int i=0; i<numTextures; i++){
v += texture(textures[i], vec2(vs_st.s, 1-vs_st.t)).r;
}
v /= numTextures;
vec4 color = texture(transferFunctions[0], vec2(v,0));
if((v<(x+y)) && v>(x-y))
color = mix(transparent, color, clamp(1,0,abs(v-x)));
diffuse = color;
}else{
for(int i=0; i<numTextures; i++){
v = texture(textures[i], vec2(vs_st.s, 1-vs_st.t)).r;
vec4 color = texture(transferFunctions[i], vec2(v,0));
if((v<(x+y)) && v>(x-y))
color = mix(transparent, color, clamp(1,0,abs(v-x)));
diffuse += color;
}
}
if(numTextures == 0) diffuse = transparent;
if (diffuse.a <= backgroundValues.y)
discard;
diffuse.a *= transparency;
Fragment frag;
frag.color = diffuse;
frag.depth = depth;
return frag;
}

View File

@@ -0,0 +1,49 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
out vec4 vs_position;
out float s;
#include "PowerScaling/powerScaling_vs.hglsl"
void main()
{
vec4 tmp = in_position;
vec4 position = pscTransform(tmp, ModelTransform);
vs_position = tmp;
vs_st = in_st;
position = ViewProjection * position;
gl_Position = z_normalization(position);
}

View File

@@ -0,0 +1,88 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 time;
// uniform sampler2D texture1;
uniform sampler2D textures[6];
uniform sampler2D transferFunctions[6];
// uniform sampler2D tf;
// uniform sampler2D tfs[6];
uniform int numTextures;
uniform int numTransferFunctions;
uniform bool averageValues;
uniform vec2 backgroundValues;
uniform float transparency;
// uniform float background;
in vec2 vs_st;
in vec4 vs_position;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
vec4 position = vs_position;
float depth = pscDepth(position);
vec4 transparent = vec4(0.0f);
vec4 diffuse = transparent;
float v = 0;
float x = backgroundValues.x;
float y = backgroundValues.y;
if((numTransferFunctions == 1) || (numTextures > numTransferFunctions)){
for(int i=0; i<numTextures; i++){
v += texture(textures[i], vec2(vs_st.t, vs_st.s)).r;
}
v /= numTextures;
vec4 color = texture(transferFunctions[0], vec2(v,0));
if((v<(x+y)) && v>(x-y))
color = mix(transparent, color, clamp(1,0,abs(v-x)));
diffuse = color;
}else{
for(int i=0; i<numTextures; i++){
v = texture(textures[i], vec2(vs_st.t, vs_st.s)).r;
vec4 color = texture(transferFunctions[i], vec2(v,0));
if((v<(x+y)) && v>(x-y))
color = mix(transparent, color, clamp(1,0,abs(v-x)));
diffuse += color;
}
}
if (diffuse.a <= backgroundValues.y)
discard;
diffuse.a *= transparency;
// diffuse = vec4(vs_st.s, 0,0,1);
Fragment frag;
frag.color = diffuse;
frag.depth = depth;
return frag;
}

View File

@@ -0,0 +1,53 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
#version __CONTEXT__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
out vec4 vs_position;
out float s;
#include "PowerScaling/powerScaling_vs.hglsl"
void main()
{
// set variables
vs_st = in_st;
vs_position = in_position;
vec4 tmp = in_position;
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
// vs_normal = normalize(ModelTransform * vec4(in_normal,0));
vec4 position = pscTransform(tmp, ModelTransform);
vs_position = tmp;
position = ViewProjection * position;
gl_Position = z_normalization(position);
}

View File

@@ -0,0 +1,843 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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/iswa/util/dataprocessor.h>
#include <openspace/util/histogram.h>
#include <fstream>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <modules/iswa/util/iswamanager.h>
#include <modules/iswa/ext/json/json.hpp>
namespace {
const std::string _loggerCat = "DataPlane";
using json = nlohmann::json;
}
namespace openspace {
DataProcessor::DataProcessor(bool useLog, bool useHistogram, glm::vec2 normValues)
:_useLog(useLog)
,_useHistogram(useHistogram)
,_normValues(normValues)
,_filterValues(glm::vec2(0))
,_numValues(0)
{
_coordinateVariables = {"x", "y", "z", "phi", "theta"};
};
DataProcessor::~DataProcessor(){};
std::vector<std::string> DataProcessor::readHeader(std::string& dataBuffer){
std::vector<std::string> options = std::vector<std::string>();
if(!dataBuffer.empty()){
std::stringstream memorystream(dataBuffer);
std::string line;
while(getline(memorystream,line)){
if(line.find("#") == 0){
if(line.find("# Output data:") == 0){
line = line.substr(26);
std::stringstream ss(line);
std::string token;
getline(ss, token, 'x');
int x = std::stoi(token);
getline(ss, token, '=');
int y = std::stoi(token);
_dimensions = glm::size3_t(x, y, 1);
getline(memorystream, line);
line = line.substr(1);
ss = std::stringstream(line);
std::string option;
while(ss >> option){
if(_coordinateVariables.find(option) == _coordinateVariables.end()){
options.push_back(option);
}
}
}
}else{
break;
}
}
}
return options;
}
std::vector<std::string> DataProcessor::readJSONHeader(std::string& dataBuffer){
std::vector<std::string> options = std::vector<std::string>();
if(!dataBuffer.empty()){
json j = json::parse(dataBuffer);
json var = j["variables"];
for (json::iterator it = var.begin(); it != var.end(); ++it) {
std::string option = it.key();
if(option == "x"){
json lon = it.value();
json lat = lon.at(0);
_dimensions = glm::size3_t(lat.size(), lon.size(), 1);
}
if(_coordinateVariables.find(option) == _coordinateVariables.end()){
options.push_back(option);
}
}
}
return options;
}
void DataProcessor::addValues(std::string& dataBuffer, properties::SelectionProperty dataOptions){
int numOptions = dataOptions.options().size();
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
if(_sum.empty()) _sum = std::vector<float>(numOptions, 0.0f);
if(_sd.empty()) _sd = std::vector<float>(numOptions, 0.0f);
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
if(!dataBuffer.empty()){
std::stringstream memorystream(dataBuffer);
std::string line;
std::vector<float> sum(numOptions, 0.0f);
std::vector<std::vector<float>> values(numOptions, std::vector<float>());
int numValues = 0;
while(getline(memorystream, line)){
if(line.find("#") == 0) continue;
std::stringstream ss(line);
std::vector<float> value;
float v;
while(ss >> v){
value.push_back(v);
}
if(value.size()){
for(int i=0; i<numOptions; i++){
float v = value[i+3];
values[i].push_back(v);
_min[i] = std::min(_min[i], v);
_max[i] = std::max(_max[i], v);
sum[i] += v;
}
numValues++;
}
}
for(int i=0; i<numOptions; i++){
if(!_histograms[i]){
_histograms[i] = std::make_shared<Histogram>(_min[i], _max[i], 512);
}else{
_histograms[i]->changeRange(_min[i], _max[i]);
}
int numValues = values[i].size();
float mean = (1.0/numValues)*sum[i];
float var = 0;
for(int j=0; j<numValues; j++){
var += pow(values[i][j] - mean, 2);
_histograms[i]->add(values[i][j], 1);
}
float sd = sqrt(var / numValues);
_sum[i] += sum[i];
_sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
_numValues[i] += numValues;
_histograms[i]->generateEqualizer();
}
}
}
std::vector<float*> DataProcessor::readData(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
std::stringstream memorystream(dataBuffer);
std::string line;
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<float> min(numSelected, std::numeric_limits<float>::max());
std::vector<float> max(numSelected, std::numeric_limits<float>::min());
std::vector<float> sum(numSelected, 0.0f);
std::vector<std::vector<float>> optionValues(numSelected, std::vector<float>());
std::vector<float*> data(dataOptions.options().size(), nullptr);
for(int option : selectedOptions){
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
}
int numValues = 0;
while(getline(memorystream, line)){
if(line.find("#") == 0){ //part of the header
continue;
}
std::stringstream ss(line);
std::vector<float> value;
float v;
while(ss >> v){
value.push_back(v);
}
if(value.size()){
for(int i=0; i<numSelected; i++){
float v = value[selectedOptions[i]+3]; //+3 because "options" x, y and z.
if(_useLog){
int sign = (v>0)? 1:-1;
v = sign*log(fabs(v) + 1);
}
optionValues[i].push_back(v);
min[i] = std::min(min[i], v);
max[i] = std::max(max[i], v);
sum[i] += v;
}
numValues++;
}
}
// std::cout << "Actual size: " << numValues << " Expected: " << _dimensions.x*_dimensions.y << std::endl;
if(numValues != _dimensions.x*_dimensions.y){
LWARNING("Number of values read and expected are not the same");
return std::vector<float*>();
}
// FOR TESTING
// ===========
// std::chrono::time_point<std::chrono::system_clock> start, end;
// start = std::chrono::system_clock::now();
// ===========
for(int i=0; i<numSelected; i++){
processData(data[ selectedOptions[i] ], optionValues[i], min[i], max[i], sum[i]);
}
// FOR TESTING
// ===========
// end = std::chrono::system_clock::now();
// _numOfBenchmarks++;
// std::chrono::duration<double> elapsed_seconds = end-start;
// _avgBenchmarkTime = ( (_avgBenchmarkTime * (_numOfBenchmarks-1)) + elapsed_seconds.count() ) / _numOfBenchmarks;
// std::cout << " readData():" << std::endl;
// std::cout << "avg elapsed time: " << _avgBenchmarkTime << "s\n";
// std::cout << "num Benchmarks: " << _numOfBenchmarks << "\n";
// ===========
return data;
}
else {
// LWARNING("Nothing in memory buffer, are you connected to the information super highway?");
return std::vector<float*>();
}
}
std::vector<float*> DataProcessor::readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
std::stringstream memorystream(dataBuffer);
std::string line;
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<std::vector<float>> values(selectedOptions.size(), std::vector<float>());
std::vector<float*> data(dataOptions.options().size(), nullptr);
for(int option : selectedOptions){
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
}
int numValues = 0;
while(getline(memorystream, line)){
if(line.find("#") == 0){ //part of the header
continue;
}
std::stringstream ss(line);
std::vector<float> value;
float v;
while(ss >> v){
value.push_back(v);
}
if(value.size()){
for(int option : selectedOptions){
float v = value[option+3]; //+3 because "options" x, y and z.
data[option][numValues] = processDataPoint(v, option);
}
}
numValues++;
}
if(numValues != _dimensions.x*_dimensions.y){
LWARNING("Number of values read and expected are not the same");
return std::vector<float*>();
}
_filterValues = glm::vec2(0.0f);
if(!_histograms.empty()){
for(int option : selectedOptions){
std::shared_ptr<Histogram> histogram = _histograms[option];
float mean = (1.0 / _numValues[option]) * _sum[option];
float sd = _sd[option];
float filterMid = histogram->highestBinValue(_useHistogram);
float filterWidth = mean+histogram->binWidth();
if(_useHistogram) {
sd = histogram->equalize(sd);
mean = histogram->equalize(mean);
filterWidth = mean+1.0;
}
filterMid = normalizeWithStandardScore(filterMid, mean, sd);
filterWidth = fabs(0.5-normalizeWithStandardScore(filterWidth, mean, sd));
_filterValues += glm::vec2(filterMid, filterWidth);
}
}
if(numSelected>0){
_filterValues.x /= numSelected;
_filterValues.y /= numSelected;
}else{
_filterValues = glm::vec2(0.0, 1.0);
}
return data;
}else{
return std::vector<float*>();
}
}
std::vector<float*> DataProcessor::readJSONData(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
json j = json::parse(dataBuffer);
json var = j["variables"];
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<float> min(numSelected, std::numeric_limits<float>::max());
std::vector<float> max(numSelected, std::numeric_limits<float>::min());
std::vector<float> sum(numSelected, 0.0f);
std::vector<std::vector<float>> optionValues(numSelected, std::vector<float>());
auto options = dataOptions.options();
std::vector<float*> data(options.size(), nullptr);
int i = 0;
for(int option : selectedOptions){
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
std::string optionName = options[option].description;
json valueArray = var[optionName];
int ySize = valueArray.size();
for(int y=0; y<valueArray.size(); y++){
json values = valueArray.at(y);
for(int x=0; x<values.size(); x++){
float v = values.at(x);
if(_useLog){
int sign = (v>0)? 1:-1;
if(v != 0){
v = sign*log(fabs(v));
}
}
optionValues[i].push_back(v);
min[i] = std::min(min[i], v);
max[i] = std::max(max[i], v);
sum[i] += v;
}
}
i++;
}
for(int i=0; i<numSelected; i++){
processData(data[ selectedOptions[i] ], optionValues[i], min[i], max[i], sum[i]);
}
return data;
}
else {
// LWARNING("Nothing in memory buffer, are you connected to the information super highway?");
return std::vector<float*>();
}
}
void DataProcessor::addValuesFromJSON(std::string& dataBuffer, properties::SelectionProperty dataOptions){
int numOptions = dataOptions.options().size();
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
if(_sum.empty()) _sum = std::vector<float>(numOptions, 0.0f);
if(_sd.empty()) _sd = std::vector<float>(numOptions, 0.0f);
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
if(!dataBuffer.empty()){
json j = json::parse(dataBuffer);
json var = j["variables"];
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<float> sum(numOptions, 0.0f);
std::vector<std::vector<float>> values(numOptions, std::vector<float>());
auto options = dataOptions.options();
std::vector<float*> data(options.size(), nullptr);
int i = 0;
for(int i=0; i<numOptions; i++){
// std::stringstream memorystream();
std::string optionName = options[i].description;
// getline(memorystream, optionName, '/');
// getline(memorystream, optionName, '/');
json valueArray = var[optionName];
int ySize = valueArray.size();
for(int y=0; y<valueArray.size(); y++){
json value = valueArray.at(y);
for(int x=0; x<value.size(); x++){
float v = value.at(x);
values[i].push_back(v);
_min[i] = std::min(_min[i],v);
_max[i] = std::max(_max[i],v);
sum[i] += v;
}
}
}
// // // for(int i=0; i<numOptions; i++){
// // // if(!_histograms[i]){
// // // _histograms[i] = std::make_shared<Histogram>(_min[i], _max[i], 512);
// // // }else{
// // // //_histogram[option]->changeRange();
// // // }
// // // int numValues = values[i].size();
// // // float mean = (1.0/numValues)*sum[i];
// // // float var = 0;
// // // for(int j=0; j<numValues; j++){
// // // var += pow(values[i][j] - mean, 2);
// // // _histograms[i]->add(values[i][j], 1);
// // // }
// // // float sd = sqrt(var / numValues);
// // // _sum[i] += sum[i];
// // // _sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
// // // _numValues[i] += numValues;
// // // _histograms[i]->generateEqualizer();
// // // }
for(int i=0; i<numOptions; i++){
if(!_histograms[i]){
_histograms[i] = std::make_shared<Histogram>(_min[i], _max[i], 512);
}else{
_histograms[i]->changeRange(_min[i], _max[i]);
}
int numValues = values[i].size();
float mean = (1.0/numValues)*sum[i];
float var = 0;
for(int j=0; j<numValues; j++){
var += pow(values[i][j] - mean, 2);
_histograms[i]->add(values[i][j], 1);
}
float sd = sqrt(var / numValues);
_sum[i] += sum[i];
_sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
_numValues[i] += numValues;
_histograms[i]->generateEqualizer();
}
}
}
std::vector<float*> DataProcessor::readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
json j = json::parse(dataBuffer);
json var = j["variables"];
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<float> sum(numSelected, 0.0f);
std::vector<std::vector<float>> values(numSelected, std::vector<float>());
auto options = dataOptions.options();
std::vector<float*> data(options.size(), nullptr);
_filterValues = glm::vec2(0.0f);
for(int option : selectedOptions){
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
// std::stringstream memorystream();
std::string optionName = options[option].description;
// getline(memorystream, optionName, '/');
// getline(memorystream, optionName, '/');
json yArray = var[optionName];
for(int y=0; y<yArray.size(); y++){
json xArray = yArray.at(y);
for(int x=0; x<xArray.size(); x++){
int i = x + y*xArray.size();
// std::cout << _dimensions.x*_dimensions.y << " " << i << std::endl;
float v = xArray.at(x);
data[option][i] = processDataPoint(v, option);
}
}
if(!_histograms.empty()){
float mean = (1.0 / _numValues[option]) * _sum[option];
float sd = _sd[option];
std::shared_ptr<Histogram> histogram = _histograms[option];
float filterMid = histogram->highestBinValue(_useHistogram);
float filterWidth = mean+histogram->binWidth();
if(_useHistogram) {
sd = histogram->equalize(sd);
mean = histogram->equalize(mean);
filterWidth = mean+1.0;
}
filterMid = normalizeWithStandardScore(filterMid, mean, sd);
filterWidth = fabs(0.5-normalizeWithStandardScore(filterWidth, mean, sd));
_filterValues += glm::vec2(filterMid, filterWidth);
}
}
if(numSelected>0){
_filterValues.x /= numSelected;
_filterValues.y /= numSelected;
}else{
_filterValues = glm::vec2(0.0, 1.0);
}
return data;
}
else {
// LWARNING("Nothing in memory buffer, are you connected to the information super highway?");
return std::vector<float*>();
}
}
void DataProcessor::addValuesFromKameleonData(float* kdata, glm::size3_t dimensions, int numOptions, int option){
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
if(_sum.empty()) _sum= std::vector<float>(numOptions, 0.0f);
if(_sd.empty()) _sd= std::vector<float>(numOptions, 0.0f);
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
int numValues = dimensions.x*dimensions.y*dimensions.z;
float sum = 0;
for(int i=0; i<numValues; i++){
float v = kdata[i];
_min[option] = std::min(_min[option],v);
_max[option] = std::max(_max[option],v);
sum += v;
}
int i = option;
// for(int i=0; i<numOptions; i++){
if(!_histograms[i]){
_histograms[i] = std::make_shared<Histogram>(_min[i], _max[i], 512);
}else{
_histograms[i]->changeRange(_min[i], _max[i]);
}
// int numValues = values[i].size();
float mean = (1.0/numValues)*sum;
float var = 0;
for(int j=0; j<numValues; j++){
var += pow(kdata[j] - mean, 2);
_histograms[i]->add(kdata[j], 1);
}
float sd = sqrt(var / numValues);
_sum[i] += sum;
_sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
_numValues[i] += numValues;
_histograms[i]->generateEqualizer();
}
std::vector<float*> DataProcessor::processKameleonData2(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<std::vector<float>> values(selectedOptions.size(), std::vector<float>());
std::vector<float*> data(dataOptions.options().size(), nullptr);
int numValues = dimensions.x*dimensions.y*dimensions.z;
_filterValues = glm::vec2(0.0f);
for(int option : selectedOptions){
data[option] = new float[numValues]{0.0f};
float mean = (1.0 / _numValues[option]) * _sum[option];
float sd = _sd[option];
for(int i=0; i<numValues; i++){
float v = kdata[option][i];
data[option][i] = processDataPoint(v, option);
}
std::shared_ptr<Histogram> histogram = _histograms[option];
float filterMid = histogram->highestBinValue(_useHistogram);
float filterWidth = mean+histogram->binWidth();
if(_useHistogram) {
sd = histogram->equalize(sd);
mean = histogram->equalize(mean);
filterWidth = mean+1.0;
}
filterMid = normalizeWithStandardScore(filterMid, mean, sd);
filterWidth = fabs(0.5-normalizeWithStandardScore(filterWidth, mean, sd));
_filterValues += glm::vec2(filterMid, filterWidth);
}
if(numSelected>0){
_filterValues.x /= numSelected;
_filterValues.y /= numSelected;
}else{
_filterValues = glm::vec2(0.0, 1.0);
}
return data;
}
std::vector<float*> DataProcessor::processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
auto options = dataOptions.options();
int numOptions = options.size();
if(_min.empty()){
_min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
}
if(_max.empty()){
_max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
}
if(_sum.empty()){
_sum= std::vector<float>(numOptions, 0.0f);
}
if(_sd.empty()){
_sd= std::vector<float>(numOptions, 0.0f);
}
if(_histograms.empty()){
_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
}
std::vector<float> min(numSelected, std::numeric_limits<float>::max());
std::vector<float> max(numSelected, std::numeric_limits<float>::min());
std::vector<float> sum(numSelected, 0.0f);
std::vector<std::vector<float>> optionValues(numSelected, std::vector<float>());
std::vector<float*> data(options.size(), nullptr);
int numValues = dimensions.x*dimensions.y*dimensions.z;
int i = 0;
for(int option : selectedOptions){
bool calculateMin = (_min[option] == std::numeric_limits<float>::max());
bool calculateMax = (_max[option] == std::numeric_limits<float>::min());
bool claculateSum = (_sum[option] == 0.0f);
data[option] = new float[numValues]{0.0f};
for(int j=0; j<numValues; j++){
float v = kdata[option][j];
if(_useLog){
int sign = (v>0)? 1:-1;
if(v != 0){
v = sign*log(fabs(v));
}
}
optionValues[i].push_back(v);
min[i] = std::min(min[i], v);
max[i] = std::max(max[i], v);
sum[i] += v;
if(calculateMin)
_min[option] = std::min(_min[option],v);
if(calculateMax)
_max[option] = std::max(_max[option],v);
if(claculateSum)
_sum[option] += v;
}
i++;
// if(calculateMin)
// std::cout << _min[option] << std::endl;
}
for(int i=0; i<numSelected; i++){
int selected = selectedOptions[i];
processData(data[ selected ], optionValues[i], _min[selected], _max[selected], _sum[selected], selected);
}
return data;
}
void DataProcessor::processData(float* outputData, std::vector<float>& inputData, float min, float max,float sum, int selected){
const int numValues = inputData.size();
Histogram histogram(min, max, 512);
//Calculate the mean
float mean = (1.0 / numValues) * sum;
//Calculate the Standard Deviation
float var = 0;
for(auto dataValue : inputData){
var += pow(dataValue - mean, 2);
}
float standardDeviation = sqrt ( var / numValues );
// Histogram functionality
if(_useHistogram){
for(auto dataValue : inputData){
histogram.add(dataValue, 1);
}
histogram.generateEqualizer();
standardDeviation = histogram.equalize(standardDeviation);
mean = histogram.equalize(mean);
}
// Normalize and equalize
for(int i=0; i < numValues; i++){
float v = inputData[i];
if(_useHistogram){
v = histogram.equalize(v);
}
v = normalizeWithStandardScore(v, mean, standardDeviation);
outputData[i] += v;
}
if(_useHistogram){
float val = histogram.highestBinValue(_useHistogram);
val = normalizeWithStandardScore(val, mean, standardDeviation);
float width = normalizeWithStandardScore(1, mean, standardDeviation);
_filterValues = glm::vec2( val, width);
}
// Histogram equalized = histogram.equalize();
// histogram.print();
// equalized.print();
}
float DataProcessor::processDataPoint(float value, int option){
if(_numValues.empty()) return 0.0f;
std::shared_ptr<Histogram> histogram = _histograms[option];
float mean = (1.0 / _numValues[option]) * _sum[option];
float sd = _sd[option];
if(_useHistogram){
// std::cout << sd << " " <<
sd = histogram->equalize(sd);
mean = histogram->equalize(mean);
value = histogram->equalize(value);
}
float v = normalizeWithStandardScore(value, mean, sd);
return v;
}
float DataProcessor::normalizeWithStandardScore(float value, float mean, float sd){
float zScoreMin = _normValues.x;
float zScoreMax = _normValues.y;
float standardScore = ( value - mean ) / sd;
// Clamp intresting values
standardScore = glm::clamp(standardScore, -zScoreMin, zScoreMax);
//return and normalize
return ( standardScore + zScoreMin )/(zScoreMin + zScoreMax );
}
glm::vec2 DataProcessor::filterValues(){
return _filterValues;
}
void DataProcessor::clear(){
_min.clear();
_max.clear();
_sum.clear();
_sd.clear();
_histograms.clear();
_numValues.clear();
}
}

View File

@@ -0,0 +1,107 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __DATAPROCESSOR_H__
#define __DATAPROCESSOR_H__
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/scalarproperty.h>
#include <openspace/properties/selectionproperty.h>
#include <ghoul/glm.h>
#include <ghoul/opengl/texture.h>
#include <set>
#include <openspace/util/histogram.h>
namespace openspace{
class DataProcessor{
friend class IswaGroup;
public:
DataProcessor(bool useLog, bool useHistogram, glm::vec2 normValues);
~DataProcessor();
void useLog(bool useLog){
_useLog = useLog;
}
void useHistogram(bool useHistogram){
_useHistogram = useHistogram;
}
void normValues(glm::vec2 normValues){
_normValues = normValues;
}
glm::size3_t dimensions(){
return _dimensions;
}
std::vector<std::string> readHeader(std::string& dataBuffer);
std::vector<float*> readData(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<float*> readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions);
void addValues(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<std::string> readJSONHeader(std::string& dataBuffer);
std::vector<float*> readJSONData(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<float*> readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions);
void addValuesFromJSON(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<float*> processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions);
std::vector<float*> processKameleonData2(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions);
void addValuesFromKameleonData(float* kdata, glm::size3_t dimensions, int numOptions, int option);
void clear();
glm::vec2 filterValues();
private:
void processData(
float* outputData, // Where you want your processed data to go
std::vector<float>& inputData, //data that needs processing
float min, // min value of the input data
float max, // max valye of the input data
float sum, // sum of the input data
int selected = 0
);
float processDataPoint(float value, int option);
float normalizeWithStandardScore(float value, float mean, float sd);
glm::size3_t _dimensions;
bool _useLog;
bool _useHistogram;
glm::vec2 _normValues;
glm::vec2 _filterValues;
std::vector<float> _min;
std::vector<float> _max;
std::vector<float> _sum;
std::vector<float> _sd;
std::vector<float> _numValues;
std::vector<std::shared_ptr<Histogram>> _histograms;
// int _numValues;
std::set<std::string> _coordinateVariables;
};
} // namespace openspace
#endif //__DATAPROCESSOR_H__

View File

@@ -0,0 +1,683 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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/iswa/util/iswamanager.h>
#include <modules/iswa/rendering/dataplane.h>
#include <modules/iswa/rendering/textureplane.h>
#include <modules/iswa/rendering/datasphere.h>
#include <modules/iswa/rendering/screenspacecygnet.h>
#include <modules/iswa/rendering/iswacygnet.h>
#include <modules/iswa/rendering/iswagroup.h>
#include <fstream>
#include <algorithm>
#include <ghoul/filesystem/filesystem>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/util/time.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scripting/script_helper.h>
#include <ghoul/lua/ghoul_lua.h>
#include <ghoul/lua/lua_helper.h>
#include "iswamanager_lua.inl";
namespace {
using json = nlohmann::json;
const std::string _loggerCat = "IswaManager";
}
namespace openspace{
IswaManager::IswaManager()
: _iswaEvent()
{
_month["JAN"] = "01";
_month["FEB"] = "02";
_month["MAR"] = "03";
_month["APR"] = "04";
_month["MAY"] = "05";
_month["JUN"] = "06";
_month["JUL"] = "07";
_month["AUG"] = "08";
_month["SEP"] = "09";
_month["OCT"] = "10";
_month["NOV"] = "11";
_month["DEC"] = "12";
_type[CygnetType::Texture] = "Texture";
_type[CygnetType::Data] = "Data";
_type[CygnetType::Kameleon] = "Kameleon";
_geom[CygnetGeometry::Plane] = "Plane";
_geom[CygnetGeometry::Sphere] = "Sphere";
DlManager.fetchFile(
"http://iswa2.ccmc.gsfc.nasa.gov/IswaSystemWebApp/CygnetHealthServlet",
[this](const DownloadManager::MemoryFile& file){
fillCygnetInfo(std::string(file.buffer));
},
[](const std::string& err){
LWARNING("Download to memory was aborted: " + err);
}
);
}
IswaManager::~IswaManager(){
_groups.clear();
_cygnetInformation.clear();
}
void IswaManager::addIswaCygnet(int id, std::string type, std::string group){
if(id > 0){
createScreenSpace(id);
}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]){
metaFuture->type = CygnetType::Texture;
} else if (type == _type[CygnetType::Data]) {
metaFuture->type = CygnetType::Data;
} else {
LERROR("\""+ type + "\" is not a valid type");
return;
}
// This callback determines what geometry should be used and creates the right cygbet
auto metadataCallback =
[this, metaFuture](const DownloadManager::MemoryFile& file){
//Create a string from downloaded file
std::string res;
res.append(file.buffer, file.size);
//add it to the metafuture object
metaFuture->json = res;
//convert to json
json j = json::parse(res);
// Check what kind of geometry here
if(j["Coordinate Type"].is_null()){
metaFuture->geom = CygnetGeometry::Sphere;
createSphere(metaFuture);
} else if (j["Coordinate Type"] == "Cartesian"){
metaFuture->geom = CygnetGeometry::Plane;
createPlane(metaFuture);
}
LDEBUG("Download to memory finished");
};
// Download metadata
DlManager.fetchFile(
"http://128.183.168.116:3000/" + std::to_string(-id),
// "http://10.0.0.76:3000/" + std::to_string(-id),
metadataCallback,
[id](const std::string& err){
LDEBUG("Download to memory was aborted for data cygnet with id "+ std::to_string(id)+": " + err);
}
);
}
// else{
// // Kameleonplane?
// // LERROR("No cygnet with id 0");
// std::string kwPath = "${OPENSPACE_DATA}/BATSRUS.cdf";
// if(type == "x" || type == "y" || type == "z")
// createKameleonPlane(kwPath, type, group);
// else
// createKameleonPlane(kwPath, "z", group);
// }
}
void IswaManager::addKameleonCdf(std::string group, int pos){
// auto info = _cdfInformation[group][pos];
// std::cout << group << " " << pos << std::endl;
createKameleonPlane(_cdfInformation[group][pos], "z");
createKameleonPlane(_cdfInformation[group][pos], "y");
createKameleonPlane(_cdfInformation[group][pos], "x");
}
std::future<DownloadManager::MemoryFile> IswaManager::fetchImageCygnet(int id){
return std::move( DlManager.fetchFile(
iswaUrl(id, "image"),
[id](const DownloadManager::MemoryFile& file){
LDEBUG("Download to memory finished for image cygnet with id: " + std::to_string(id));
},
[id](const std::string& err){
LDEBUG("Download to memory was aborted for image cygnet with id "+ std::to_string(id)+": " + err);
}
) );
}
std::future<DownloadManager::MemoryFile> IswaManager::fetchDataCygnet(int id){
return std::move( DlManager.fetchFile(
iswaUrl(id, "data"),
[id](const DownloadManager::MemoryFile& file){
LDEBUG("Download to memory finished for data cygnet with id: " + std::to_string(id));
},
[id](const std::string& err){
LDEBUG("Download to memory was aborted for data cygnet with id "+ std::to_string(id)+": " + err);
}
) );
}
std::string IswaManager::iswaUrl(int id, std::string type){
std::string url;
if(id < 0){
url = "http://128.183.168.116:3000/"+type+"/" + std::to_string(-id) + "/";
// url = "http://10.0.0.76:3000/"+type+"/" + std::to_string(-id) + "/";
} else{
url = "http://iswa2.ccmc.gsfc.nasa.gov/IswaSystemWebApp/iSWACygnetStreamer?window=-1&cygnetId="+ std::to_string(id) +"&timestamp=";
}
std::string t = Time::ref().currentTimeUTC();
std::stringstream ss(t);
std::string token;
std::getline(ss, token, ' ');
url += token + "-";
std::getline(ss, token, ' ');
url += _month[token] + "-";
std::getline(ss, token, 'T');
url += token + "%20";
std::getline(ss, token, '.');
url += token;
return url;
}
std::shared_ptr<ghoul::Event<ghoul::Dictionary> > IswaManager::groupEvent(std::string groupName, CygnetType type){
// Do some type checking and get the groupEvent
if(_groups.find(groupName) == _groups.end()){
_groups.insert(std::pair<std::string, std::shared_ptr<IswaGroup>>(groupName, std::make_shared<IswaGroup>(groupName, type)));
} else if(!_groups[groupName]->isType(type)){
LWARNING("Can't subscribe to Events from groups with diffent type");
return nullptr;
}
return _groups[groupName]->groupEvent();
}
std::shared_ptr<IswaGroup> IswaManager::registerToGroup(std::string groupName, CygnetType type){
if(_groups.find(groupName) == _groups.end()){
_groups.insert(std::pair<std::string, std::shared_ptr<IswaGroup>>(groupName, std::make_shared<IswaGroup>(groupName, type)));
} else if(!_groups[groupName]->isType(type)){
LWARNING("Can't subscribe to Events from groups with diffent type");
return nullptr;
}
return _groups[groupName];
}
// void IswaManager::unregisterFromGroup(std::string name, IswaCygnet* cygnet){
// if(_groups.find(name) != _groups.end()){
// _groups[name]->unregisterCygnet(cygnet);
// }
// }
// void IswaManager::registerOptionsToGroup(std::string name, const std::vector<properties::SelectionProperty::Option>& options){
// if(_groups.find(name) != _groups.end()){
// _groups[name]->registerOptions(options);
// }
// }
std::shared_ptr<IswaGroup> IswaManager::iswaGroup(std::string name){
if(_groups.find(name) != _groups.end()){
return _groups[name];
}
return nullptr;
}
std::map<int, std::shared_ptr<CygnetInfo>>& IswaManager::cygnetInformation(){
return _cygnetInformation;
}
std::map<std::string, std::shared_ptr<IswaGroup>>& IswaManager::groups(){
return _groups;
}
std::map<std::string, std::vector<CdfInfo>>& IswaManager::cdfInformation(){
return _cdfInformation;
}
std::shared_ptr<MetadataFuture> IswaManager::downloadMetadata(int id){
std::shared_ptr<MetadataFuture> metaFuture = std::make_shared<MetadataFuture>();
metaFuture->id = id;
DlManager.downloadToMemory(
"http://128.183.168.116:3000/" + std::to_string(-id),
// "http://10.0.0.76:3000/" + std::to_string(-id),
metaFuture->json,
[metaFuture](const DownloadManager::FileFuture& f){
if(f.isFinished){
metaFuture->isFinished;
LDEBUG("Download to memory finished");
} else if (f.isAborted){
LWARNING("Download to memory was aborted: " + f.errorMessage);
}
}
);
return metaFuture;
}
std::string IswaManager::jsonPlaneToLuaTable(std::shared_ptr<MetadataFuture> data){
if(data->json != ""){
json j = json::parse(data->json);
std::string parent = j["Central Body"];
std::string frame = j["Coordinates"];
std::string coordinateType = j["Coordinate Type"];
int updateTime = j["ISWA_UPDATE_SECONDS"];
glm::vec3 max(
j["Plot XMAX"],
j["Plot YMAX"],
j["Plot ZMAX"]
);
glm::vec3 min(
j["Plot XMIN"],
j["Plot YMIN"],
j["Plot ZMIN"]
);
glm::vec4 spatialScale(1, 1, 1, 10);
std::string spatial = j["Spatial Scale (Custom)"];
if(spatial == "R_E"){
spatialScale.x = 6.371f;
spatialScale.y = 6.371f;
spatialScale.z = 6.371f;
spatialScale.w = 6;
}
std::string table = "{"
"Name = '" + data->name +"' , "
"Parent = '" + parent + "', "
"Renderable = {"
"Type = '" + _type[data->type] + _geom[data->geom] + "', "
"Id = " + std::to_string(data->id) + ", "
"Frame = '" + frame + "' , "
"GridMin = " + std::to_string(min) + ", "
"GridMax = " + std::to_string(max) + ", "
"SpatialScale = " + std::to_string(spatialScale) + ", "
"UpdateTime = " + std::to_string(updateTime) + ", "
"CoordinateType = '" + coordinateType + "', "
"Group = '"+ data->group + "',"
"}"
"}";
return table;
}
return "";
}
std::string IswaManager::parseKWToLuaTable(CdfInfo info, std::string cut){
if(info.path != ""){
const std::string& extension = ghoul::filesystem::File(absPath(info.path)).fileExtension();
if(extension == "cdf"){
KameleonWrapper kw = KameleonWrapper(absPath(info.path));
std::string parent = kw.getParent();
std::string frame = kw.getFrame();
glm::vec3 min = kw.getGridMin();
glm::vec3 max = kw.getGridMax();
glm::vec4 spatialScale;
std::string coordinateType;
std::tuple < std::string, std::string, std::string > gridUnits = kw.getGridUnits();
if (std::get<0>(gridUnits) == "R" && std::get<1>(gridUnits) == "R" && std::get<2>(gridUnits) == "R") {
spatialScale.x = 6.371f;
spatialScale.y = 6.371f;
spatialScale.z = 6.371f;
spatialScale.w = 6;
coordinateType = "Cartesian";
}else{
spatialScale = glm::vec4(1.0);
spatialScale.w = 1; //-log10(1.0f/max.x);
coordinateType = "Polar";
}
std::string table = "{"
"Name = '" +info.group+"_"+info.name+"-"+cut+"',"
"Parent = '" + parent + "', "
"Renderable = {"
"Type = 'KameleonPlane', "
"Id = 0 ,"
"Frame = '" + frame + "' , "
"GridMin = " + std::to_string(min) + ", "
"GridMax = " + std::to_string(max) + ", "
"SpatialScale = " + std::to_string(spatialScale) + ", "
"UpdateTime = 0, "
"kwPath = '" + info.path + "' ,"
"axisCut = '"+cut+"',"
"CoordinateType = '" + coordinateType + "', "
"Group = '"+ info.group + "',"
"fieldlineSeedsIndexFile = '"+info.fieldlineSeedsIndexFile+"'"
"}"
"}"
;
// std::cout << table << std::endl;
return table;
}
}
return "";
}
std::string IswaManager::jsonSphereToLuaTable(std::shared_ptr<MetadataFuture> data){
if(data->json == ""){
LWARNING("jsonSphereToLuaTable: no content in metadata json");
return "";
}
json j = json::parse(data->json);
j = j["metadata"];
std::string parent = j["central_body"];
parent[0] = toupper(parent[0]);
std::string frame = j["standard_grid_target"];
std::string coordinateType = j["grid_1_type"];
std::string updateTime = j["output_time_interval"];
float radius = j["radius"];
glm::vec4 spatialScale(6.371f, 6.371f, 6.371f, 6);
glm::vec3 max(
j["x"]["actual_max"],
j["y"]["actual_max"],
j["z"]["actual_max"]
);
glm::vec3 min(
j["x"]["actual_min"],
j["y"]["actual_min"],
j["z"]["actual_min"]
);
std::string table = "{"
"Name = '" + data->name +"' , "
"Parent = '" + parent + "', "
"Renderable = {"
"Type = '" + _type[data->type] + _geom[data->geom] + "', "
"Id = " + std::to_string(data->id) + ", "
"Frame = '" + frame + "' , "
"GridMin = " + std::to_string(min) + ", "
"GridMax = " + std::to_string(max) + ", "
"UpdateTime = " + updateTime + ", "
"Radius = " + std::to_string(radius) + ", "
"CoordinateType = '" + coordinateType + "', "
"Group = '"+ data->group + "',"
"}"
"}";
return table;
}
void IswaManager::createScreenSpace(int id){
std::string script = "openspace.iswa.addScreenSpaceCygnet("
"{CygnetId =" + std::to_string(id) + "});";
OsEng.scriptEngine().queueScript(script);
}
void IswaManager::createPlane(std::shared_ptr<MetadataFuture> data){
// check if this plane already exist
std::string name = _type[data->type] + _geom[data->geom] + std::to_string(data->id);
if(!data->group.empty()){
auto it = _groups.find(data->group);
if(it == _groups.end() || (*it).second->isType((CygnetType) data->type))
name = data->group +"_"+ name;
}
data->name = name;
if( OsEng.renderEngine().scene()->sceneGraphNode(name) ){
LERROR("A node with name \"" + name +"\" already exist");
return;
}
std::string luaTable = jsonPlaneToLuaTable(data);
if(luaTable != ""){
std::string script = "openspace.addSceneGraphNode(" + luaTable + ");";
OsEng.scriptEngine().queueScript(script);
}
}
void IswaManager::createSphere(std::shared_ptr<MetadataFuture> data){
// check if this sphere already exist
std::string name = _type[data->type] + _geom[data->geom] + std::to_string(data->id);
if(!data->group.empty()){
auto it = _groups.find(data->group);
if(it == _groups.end() || (*it).second->isType((CygnetType) data->type))
name = data->group +"_"+name;
}
data->name = name;
if( OsEng.renderEngine().scene()->sceneGraphNode(name) ){
LERROR("A node with name \"" + name +"\" already exist");
return;
}
std::string luaTable = jsonSphereToLuaTable(data);
if(luaTable != ""){
std::string script = "openspace.addSceneGraphNode(" + luaTable + ");";
OsEng.scriptEngine().queueScript(script);
}
}
void IswaManager::createKameleonPlane(CdfInfo info, std::string cut){
std::cout << info.name << " " << cut << std::endl;
const std::string& extension = ghoul::filesystem::File(absPath(info.path)).fileExtension();
if(FileSys.fileExists(absPath(info.path)) && extension == "cdf"){
std::string luaTable = parseKWToLuaTable(info, cut);
if(!luaTable.empty()){
// // std::cout << luaTable << std::endl;
std::string script = "openspace.addSceneGraphNode(" + luaTable + ");";
OsEng.scriptEngine().queueScript(script);
}
}else{
LWARNING( absPath(info.path) + " is not a cdf file or can't be found.");
}
}
void IswaManager::createFieldline(std::string name, std::string cdfPath, std::string seedPath){
const std::string& extension = ghoul::filesystem::File(absPath(cdfPath)).fileExtension();
if(FileSys.fileExists(absPath(cdfPath)) && extension == "cdf"){
std::string luaTable = "{"
"Name = '" + name + "',"
"Parent = 'Earth',"
"Renderable = {"
"Type = 'RenderableFieldlines',"
"VectorField = {"
"Type = 'VolumeKameleon',"
"File = '" + cdfPath + "',"
"Model = 'BATSRUS',"
"Variables = {'bx', 'by', 'bz'}"
"},"
"Fieldlines = {"
"Stepsize = 1,"
"Classification = true"
"},"
"SeedPoints = {"
"Type = 'File',"
"File = '" + seedPath + "'"
"}"
"}"
"}";
if(!luaTable.empty()){
std::string script = "openspace.addSceneGraphNode(" + luaTable + ");";
OsEng.scriptEngine().queueScript(script);
}
}else{
LWARNING( cdfPath + " is not a cdf file or can't be found.");
}
}
void IswaManager::fillCygnetInfo(std::string jsonString){
if(jsonString != ""){
json j = json::parse(jsonString);
std::set<std::string> lists = {"listOfPriorityCygnets", "listOfOKCygnets"
// ,"listOfStaleCygnets", "listOfInactiveCygnets",
};
for(auto list : lists){
json jsonList = j[list];
for(int i=0; i<jsonList.size(); i++){
json jCygnet = jsonList.at(i);
std::string name = jCygnet["cygnetDisplayTitle"];
std::replace(name.begin(), name.end(),'.', ',');
CygnetInfo info = {
name,
jCygnet["cygnetDescription"],
jCygnet["cygnetUpdateInterval"],
false
};
_cygnetInformation[jCygnet["cygnetID"]] = std::make_shared<CygnetInfo>(info);
}
}
}
}
void IswaManager::addCdfFiles(std::string path){
path = absPath(path);
if(FileSys.fileExists(path)){
//std::string basePath = path.substr(0, path.find_last_of("/\\"));
std::ifstream jsonFile(path);
if (jsonFile.is_open()){
json cdfGroups = json::parse(jsonFile);
for(int i=0; i<cdfGroups.size(); i++){
json cdfGroup = cdfGroups.at(i);
std::string groupName = cdfGroup["group"];
std::string fieldlineSeedsIndexFile = cdfGroup["fieldlinefile"];
if(_cdfInformation.find(groupName) != _cdfInformation.end()){
LWARNING("CdfGroup with name" + groupName + " already exists.");
return;
}
_cdfInformation[groupName] = std::vector<CdfInfo>();
json cdfs = cdfGroup["cdfs"];
for(int j=0; j<cdfs.size(); j++){
json cdf = cdfs.at(j);
std::string name = cdf["name"];
std::string path = cdf["path"];
std::string date = cdf["date"];
_cdfInformation[groupName].push_back({name, path, groupName, date, fieldlineSeedsIndexFile});
}
}
jsonFile.close();
}
}else{
LWARNING( path + " is not a cdf file or can't be found.");
}
}
scripting::ScriptEngine::LuaLibrary IswaManager::luaLibrary() {
return {
"iswa",
{
{
"addCygnet",
&luascriptfunctions::iswa_addCygnet,
"int, string, string",
"Adds a IswaCygnet",
true
},
{
"addScreenSpaceCygnet",
&luascriptfunctions::iswa_addScreenSpaceCygnet,
"int, string, string",
"Adds a Screen Space Cygnets",
true
},
{
"addKameleonPlanes",
&luascriptfunctions::iswa_addKameleonPlanes,
"string, int",
"Adds KameleonPlanes from cdf file.",
true
},
// {
// "addKameleonPlane",
// &luascriptfunctions::iswa_addKameleonPlane,
// "string, string, string",
// "Adds a KameleonPlane from cdf file.",
// true
// },
{
"addCdfFiles",
&luascriptfunctions::iswa_addCdfFiles,
"string",
"Adds a cdf files to choose from.",
true
},
{
"removeCygnet",
&luascriptfunctions::iswa_removeCygnet,
"string",
"Remove a Cygnets",
true
},
{
"removeScreenSpaceCygnet",
&luascriptfunctions::iswa_removeScrenSpaceCygnet,
"int",
"Remove a Screen Space Cygnets",
true
},
{
"removeGroup",
&luascriptfunctions::iswa_removeGroup,
"int",
"Remove a group of Cygnets",
true
}
}
};
}
}// namsepace openspace

View File

@@ -0,0 +1,144 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2015 *
* *
* 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 __ISWAMANAGER_H__
#define __ISWAMANAGER_H__
#include <ghoul/designpattern/singleton.h>
#include <ghoul/designpattern/event.h>
#include <memory>
#include <map>
#include <future>
#include <ghoul/glm.h>
#include <ccmc/Kameleon.h>
#include <openspace/engine/downloadmanager.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <openspace/rendering/renderable.h>
#include <openspace/properties/selectionproperty.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/spicemanager.h>
#include <openspace/properties/selectionproperty.h>
#include <modules/iswa/ext/json/json.hpp>
// #include <modules/iswa/rendering/iswacygnet.h>
// #include <modules/iswa/rendering/iswagroup.h>
namespace openspace {
class IswaGroup;
class IswaCygnet;
struct CdfInfo {
std::string name;
std::string path;
std::string group;
std::string date;
std::string fieldlineSeedsIndexFile;
};
struct CygnetInfo {
std::string name;
std::string description;
int updateInterval;
bool selected;
};
struct MetadataFuture {
int id;
std::string group;
std::string name;
std::string json;
int type;
int geom;
bool isFinished;
};
class IswaManager : public ghoul::Singleton<IswaManager>, public properties::PropertyOwner {
friend class ghoul::Singleton<IswaManager>;
public:
enum CygnetType {Texture, Data, Kameleon, NoType};
enum CygnetGeometry {Plane, Sphere};
IswaManager();
~IswaManager();
void addIswaCygnet(int id, std::string type = "Texture", std::string group = "");
void addKameleonCdf(std::string group, int pos);
void createFieldline(std::string name, std::string cdfPath, std::string seedPath);
std::future<DownloadManager::MemoryFile> fetchImageCygnet(int id);
std::future<DownloadManager::MemoryFile> fetchDataCygnet(int id);
std::string iswaUrl(int id, std::string type = "image");
std::shared_ptr<ghoul::Event<ghoul::Dictionary> > groupEvent(std::string name, CygnetType type);
std::shared_ptr<IswaGroup> registerToGroup(std::string name, CygnetType type);
void unregisterFromGroup(std::string name, IswaCygnet* cygnet);
// void registerOptionsToGroup(std::string name, const std::vector<properties::SelectionProperty::Option>& options);
std::shared_ptr<IswaGroup> iswaGroup(std::string name);
std::map<int, std::shared_ptr<CygnetInfo>>& cygnetInformation();
std::map<std::string, std::shared_ptr<IswaGroup>>& groups();
// std::vector<CdfInfo>& cdfInformation();
std::map<std::string, std::vector<CdfInfo>>& cdfInformation();
static scripting::ScriptEngine::LuaLibrary luaLibrary();
ghoul::Event<>& iswaEvent(){
return _iswaEvent;
}
void addCdfFiles(std::string path);
private:
std::shared_ptr<MetadataFuture> downloadMetadata(int id);
std::string jsonPlaneToLuaTable(std::shared_ptr<MetadataFuture> data);
std::string jsonSphereToLuaTable(std::shared_ptr<MetadataFuture> data);
std::string parseKWToLuaTable(CdfInfo info, std::string cut="z");
void createScreenSpace(int id);
void createPlane(std::shared_ptr<MetadataFuture> data);
void createSphere(std::shared_ptr<MetadataFuture> data);
void createKameleonPlane(CdfInfo info, std::string cut);
void fillCygnetInfo(std::string jsonString);
std::map<std::string, std::string> _month;
std::map<int, std::string> _type;
std::map<int, std::string> _geom;
std::shared_ptr<ccmc::Kameleon> _kameleon;
std::set<std::string> _kameleonFrames;
std::map<std::string, std::shared_ptr<IswaGroup>> _groups;
std::map<int, std::shared_ptr<CygnetInfo>> _cygnetInformation;
// std::vector<CdfInfo> _cdfInformation;
std::map<std::string, std::vector<CdfInfo>> _cdfInformation;
ghoul::Event<> _iswaEvent;
};
} //namespace openspace
#endif //__ISWAMANAGER_H__

View File

@@ -0,0 +1,169 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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. *
****************************************************************************************/
namespace openspace {
namespace luascriptfunctions {
int iswa_addCygnet(lua_State* L) {
int nArguments = lua_gettop(L);
int id = -1;
std::string type = "Texture";
std::string group = "";
if(nArguments > 0)
id = lua_tonumber(L, 1);
if(nArguments > 1)
type = luaL_checkstring(L, 2);
if(nArguments > 2)
group = luaL_checkstring(L, 3);
IswaManager::ref().addIswaCygnet(id, type, group);
return 0;
}
int iswa_addScreenSpaceCygnet(lua_State* L){
static const std::string _loggerCat = "addScreenSpaceCygnet";
using ghoul::lua::errorLocation;
int nArguments = lua_gettop(L);
if (nArguments != 1)
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
ghoul::Dictionary d;
try {
ghoul::lua::luaDictionaryFromState(L, d);
}
catch (const ghoul::lua::LuaFormatException& e) {
LERROR(e.what());
return 0;
}
float id;
d.getValue("CygnetId", id);
auto cygnetInformation = IswaManager::ref().cygnetInformation();
if(cygnetInformation.find((int)id) == cygnetInformation.end()){
LWARNING("Could not find Cygnet with id = " + std::to_string(id));
return 0;
}
auto info = cygnetInformation[(int)id];
std::string name = info->name;
int updateInterval = info->updateInterval;
info->selected = true;
if(OsEng.renderEngine().screenSpaceRenderable(name)){
LERROR("A cygnet with the name \"" + name +"\" already exist");
return 0;
}else{
d.setValue("Name", name);
d.setValue("Type", "ScreenSpaceCygnet");
d.setValue("UpdateInterval", (float) updateInterval);
std::shared_ptr<ScreenSpaceRenderable> s( ScreenSpaceRenderable::createFromDictionary(d) );
OsEng.renderEngine().registerScreenSpaceRenderable(s);
}
return 0;
}
// int iswa_addKameleonPlane(lua_State* L){
// int nArguments = lua_gettop(L);
// std::string kwPath = "";
// std::string type = "x";
// std::string group = "";
// if(nArguments > 0)
// kwPath = luaL_checkstring(L, 1);
// if(nArguments > 1)
// type = luaL_checkstring(L, 2);
// if(nArguments > 2)
// group = luaL_checkstring(L, 3);
// IswaManager::ref().createKameleonPlane(kwPath, type, group);
// return 0;
// }
int iswa_removeCygnet(lua_State* L){
std::string name = luaL_checkstring(L, -1);
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + name + "')");
// IswaManager::ref().deleteIswaCygnet(s);
return 0;
}
int iswa_removeScrenSpaceCygnet(lua_State* L){
static const std::string _loggerCat = "removeScreenSpaceCygnet";
int id = lua_tonumber(L, 1);
auto cygnetInformation = IswaManager::ref().cygnetInformation();
if(cygnetInformation.find(id) == cygnetInformation.end()){
LWARNING("Could not find Cygnet with id = " + std::to_string(id));
return 0;
}
auto info = cygnetInformation[id];
info->selected = false;
std::string script = "openspace.unregisterScreenSpaceRenderable('" + cygnetInformation[id]->name + "');";
OsEng.scriptEngine().queueScript(script);
return 0;
}
int iswa_removeGroup(lua_State* L){
std::string name = luaL_checkstring(L, -1);
// IswaManager::ref().unregisterGroup(id);
auto groups = IswaManager::ref().groups();
if(groups.find(name) != groups.end())
groups[name]->clearGroup();
return 0;
}
int iswa_addCdfFiles(lua_State* L){
std::string path = luaL_checkstring(L, 1);
IswaManager::ref().addCdfFiles(path);
return 0;
}
int iswa_addKameleonPlanes(lua_State* L){
std::string group = luaL_checkstring(L, 1);
int pos = lua_tonumber(L, 2);
IswaManager::ref().addKameleonCdf(group, pos);
// auto cdfInfo =
return 0;
}
}// namespace luascriptfunctions
}// namespace openspace

View File

@@ -93,6 +93,11 @@ public:
const std::string& var,
const glm::size3_t& outDimensions);
float* getUniformSliceValues(
const std::string& var,
const glm::size3_t& outDimensions,
const float& zSlice);
float* getUniformSampledVectorValues(
const std::string& xVar,
const std::string& yVar,
@@ -120,7 +125,9 @@ public:
float stepsize);
glm::vec3 getModelBarycenterOffset();
glm::vec4 getModelBarycenterOffsetScaled();
glm::vec3 getModelScale();
glm::vec4 getModelScaleScaled();
glm::vec3 getGridMax();
glm::vec3 getGridMin();
std::string getVariableUnit(const std::string& variable);
@@ -129,6 +136,9 @@ public:
Model model();
GridType gridType();
std::string getParent();
std::string getFrame();
std::vector<std::string> getVariables();
private:
typedef std::vector<glm::vec3> TraceLine;

View File

@@ -33,6 +33,7 @@
#include <ccmc/Interpolator.h>
#include <ccmc/BATSRUS.h>
#include <ccmc/ENLIL.h>
#include <ccmc/CCMCTime.h>
#define _USE_MATH_DEFINES
#include <math.h>
@@ -154,6 +155,7 @@ bool KameleonWrapper::open(const std::string& filename) {
LDEBUG("_yValidMax: " << _yValidMax);
LDEBUG("_zValidMin: " << _zValidMin);
LDEBUG("_zValidMax: " << _zValidMax);
return true;
}
return false;
@@ -240,7 +242,7 @@ float* KameleonWrapper::getUniformSampledValues(
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";
LWARNING("Warning: There might be a gap in the data");
}
// Leave values at zero if outside domain
} else { // if inside
@@ -352,6 +354,140 @@ float* KameleonWrapper::getUniformSampledValues(
return data;
}
float* KameleonWrapper::getUniformSliceValues(
const std::string& var,
const glm::size3_t& outDimensions,
const float& slice)
{
assert(_model && _interpolator);
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
LINFO("Loading variable " << var << " from CDF data with a uniform sampling");
unsigned int size = static_cast<unsigned int>(outDimensions.x*outDimensions.y*outDimensions.z);
float* data = new float[size];
double* doubleData = new double[size];
_model->loadVariable(var);
double varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat();
double varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat();
double stepX = (_xMax-_xMin)/(static_cast<double>(outDimensions.x));
double stepY = (_yMax-_yMin)/(static_cast<double>(outDimensions.y));
double stepZ = (_zMax-_zMin)/(static_cast<double>(outDimensions.z));
bool xSlice = (outDimensions.x <= 1);
bool ySlice = (outDimensions.y <= 1);
bool zSlice = (outDimensions.z <= 1);
double xDim = (!xSlice)? outDimensions.x-1 : 1.0;
double yDim = (!ySlice)? outDimensions.y-1 : 1.0;
double zDim = (!zSlice)? outDimensions.z-1 : 1.0;
LDEBUG(var << "Min: " << varMin);
LDEBUG(var << "Max: " << varMax);
double maxValue = 0.0;
double minValue = std::numeric_limits<double>::max();
float missingValue = _model->getMissingValue();
for (int x = 0; x < outDimensions.x; ++x) {
for (int y = 0; y < outDimensions.y; ++y) {
for(int z = 0; z < outDimensions.z; ++z){
float xi = (!xSlice)? x : slice;
float yi = (!ySlice)? y : slice;
float zi = (!zSlice)? z : slice;
double value = 0;
unsigned int index = static_cast<unsigned int>(x + y*outDimensions.x + z*outDimensions.x*outDimensions.y);
if(_gridType == GridType::Spherical) {
// int z = zSlice;
// Put r in the [0..sqrt(3)] range
double rNorm = sqrt(3.0)*(double)xi/(double)(xDim);
// Put theta in the [0..PI] range
double thetaNorm = M_PI*(double)yi/(double)(yDim);
// Put phi in the [0..2PI] range
double phiNorm = 2.0*M_PI*(double)zi/(double)(zDim);
// Go to physical coordinates before sampling
double rPh = _xMin + rNorm*(_xMax-_xMin);
double 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.
double phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001);
// See if sample point is inside domain
if (rPh < _xMin || rPh > _xMax || thetaPh < _yMin ||
thetaPh > _yMax || phiPh < _zMin || phiPh > _zMax) {
if (phiPh > _zMax) {
LWARNING("Warning: There might be a gap in the data");
}
// 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
value = _interpolator->interpolate(
var,
static_cast<float>(rPh),
static_cast<float>(phiPh),
static_cast<float>(thetaPh));
// value = _interpolator->interpolate(var, rPh, phiPh, thetaPh);
}
}else{
double xPos = _xMin + stepX*xi;
double yPos = _yMin + stepY*yi;
double zPos = _zMin + stepZ*zi;
// std::cout << zPos << ", " << zpos << std::endl;
// Should y and z be flipped?
value = _interpolator->interpolate(
var,
static_cast<float>(xPos),
static_cast<float>(zPos),
static_cast<float>(yPos));
}
if(value != missingValue){
doubleData[index] = value;
data[index] = value;
if(value > maxValue){
maxValue = value;
}
if(value < minValue){
minValue = value;
}
}else{
// std::cout << "value missing" << std::endl;
doubleData[index] = 0;
}
}
}
}
for(size_t i = 0; i < size; ++i) {
// double normalizedVal = (doubleData[i]-minValue)/(maxValue-minValue);
// data[i] = glm::clamp(normalizedVal, 0.0, 1.0);
// data[i] = 1;
// std::cout << minValue << ", " << maxValue << ", " << doubleData[i] << ", " << normalizedVal << ", " << data[i] << std::endl;
}
delete[] doubleData;
return data;
}
float* KameleonWrapper::getUniformSampledVectorValues(
const std::string& xVar,
const std::string& yVar,
@@ -542,6 +678,19 @@ glm::vec3 KameleonWrapper::getModelBarycenterOffset() {
return offset;
}
glm::vec4 KameleonWrapper::getModelBarycenterOffsetScaled(){
std::tuple < std::string, std::string, std::string > gridUnits = getGridUnits();
glm::vec4 offset = glm::vec4(getModelBarycenterOffset(), 1.0);
if(std::get<0>(gridUnits) == "R" && std::get<1>(gridUnits) == "R" && std::get<2>(gridUnits) == "R"){
offset.x *= 6.371f;
offset.y *= 6.371f;
offset.z *= 6.371f;
offset.w = 6;
}
// else if(std::get<0>(t) == "m" && std::get<1>(t) == "radian" && std::get<2>(t) == "radian"){}
return offset;
}
glm::vec3 KameleonWrapper::getModelScale() {
if (_type == Model::ENLIL)
return glm::vec3(1.0f, 1.0f, 1.0f);
@@ -553,6 +702,24 @@ glm::vec3 KameleonWrapper::getModelScale() {
return scale;
}
glm::vec4 KameleonWrapper::getModelScaleScaled(){
std::tuple < std::string, std::string, std::string > gridUnits = getGridUnits();
glm::vec4 scale = glm::vec4(getModelScale(), 1.0);
if (std::get<0>(gridUnits) == "R" && std::get<1>(gridUnits) == "R" && std::get<2>(gridUnits) == "R") {
// Earth radius
scale.x *= 6.371f;
scale.y *= 6.371f;
scale.z *= 6.371f;
scale.w = 6;
}
else if (std::get<0>(gridUnits) == "m" && std::get<1>(gridUnits) == "radian" && std::get<2>(gridUnits) == "radian") {
// For spherical coordinate systems the radius is in meter
scale.w = -log10(1.0f/_xMax);
}
return scale;
}
glm::vec3 KameleonWrapper::getGridMax() {
return glm::vec3(_xMax, _yMax, _zMax);
}
@@ -841,4 +1008,53 @@ 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)
{
return "Earth";
}else if(
_type == KameleonWrapper::Model::ENLIL ||
_type == KameleonWrapper::Model::MAS ||
_type == KameleonWrapper::Model::Adapt3D ||
_type == KameleonWrapper::Model::SWMF)
{
return "Sun";
}else{
return "";
}
}
std::string KameleonWrapper::getFrame(){
if( _type == KameleonWrapper::Model::BATSRUS ||
_type == KameleonWrapper::Model::OpenGGCM ||
_type == KameleonWrapper::Model::LFM)
{
return "GSM";
}else if(
_type == KameleonWrapper::Model::ENLIL ||
_type == KameleonWrapper::Model::MAS ||
_type == KameleonWrapper::Model::Adapt3D ||
_type == KameleonWrapper::Model::SWMF)
{
return "HEEQ";
}else{
return "";
}
}
std::vector<std::string> KameleonWrapper::getVariables(){
std::vector<std::string> variableNames;
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;
}
} // namespace openspace

View File

@@ -52,7 +52,7 @@ vec4 uvToModel(vec2 uv, vec4 radius, float segments){
float x = radius[0] * sin(phi) * sin(theta); //
float y = radius[1] * cos(theta); // up
float z = radius[2] * cos(phi) * sin(theta); //
return vec4(x, y, z, radius[3]);
return vec4(0.0);

View File

@@ -32,6 +32,8 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/include/guiperformancecomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guipropertycomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guitimecomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guiiswacomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/renderproperties.cpp
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -43,6 +45,9 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/src/guiperformancecomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guipropertycomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guitimecomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guiiswacomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/renderproperties.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})

View File

@@ -30,6 +30,7 @@
#include <modules/onscreengui/include/guipropertycomponent.h>
#include <modules/onscreengui/include/guiorigincomponent.h>
#include <modules/onscreengui/include/guitimecomponent.h>
#include <modules/onscreengui/include/guiiswacomponent.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/keys.h>
@@ -71,7 +72,10 @@ public:
GuiOriginComponent _origin;
GuiPerformanceComponent _performance;
GuiPropertyComponent _property;
// GuiPropertyComponent _iSWAproperty;
GuiPropertyComponent _screenSpaceProperty;
GuiTimeComponent _time;
GuiIswaComponent _iswa;
bool _isEnabled;

View File

@@ -0,0 +1,58 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __GUIISWACOMPONENT_H__
#define __GUIISWACOMPONENT_H__
#include <modules/onscreengui/include/guicomponent.h>
#include <modules/onscreengui/include/guipropertycomponent.h>
namespace openspace {
namespace gui {
struct RadioOption {
int value;
std::string path;
std::string date;
};
class GuiIswaComponent : public GuiPropertyComponent {
public:
GuiIswaComponent();
virtual void render() override;
private:
bool _gmdata;
bool _gmimage;
bool _iondata;
std::vector<int> _cdfOptions;
std::map<std::string, int> _cdfOptionsMap;
};
} // namespace gui
} // namespace openspace
#endif // __GUIISWACOMPONENT_H__

View File

@@ -43,7 +43,9 @@ namespace gui {
class GuiPropertyComponent : public GuiComponent {
public:
//void registerProperty(const std::string& propertyDescription);
void registerProperty(properties::Property* prop);
void registerProperty(properties::Property* prop, properties::Property* sibling = nullptr);
void unregisterProperty(properties::Property* prop);
void unregisterProperties(std::string owner);
void render();
protected:

View File

@@ -0,0 +1,46 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __RENDERPROPERTIES_H__
#define __RENDERPROPERTIES_H__
#include <openspace/engine/openspaceengine.h>
#include <openspace/properties/property.h>
using namespace openspace::properties;
void executeScript(const std::string& id, const std::string& value);
void renderBoolProperty(Property* prop, const std::string& ownerName);
void renderOptionProperty(Property* prop, const std::string& ownerName);
void renderSelectionProperty(Property* prop, const std::string& ownerName);
void renderStringProperty(Property* prop, const std::string& ownerName);
void renderIntProperty(Property* prop, const std::string& ownerName);
void renderFloatProperty(Property* prop, const std::string& ownerName);
void renderVec2Property(Property* prop, const std::string& ownerName);
void renderVec3Property(Property* prop, const std::string& ownerName);
void renderVec4Property(Property* prop, const std::string& ownerName);
void renderTriggerProperty(Property* prop, const std::string& ownerName);
#endif __RENDERPROPERTIES_H__

View File

@@ -34,6 +34,9 @@
#include <ghoul/filesystem/cachemanager.h>
#include <openspace/properties/property.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <modules/base/rendering/screenspaceimage.h>
// #include <modules/iswa/util/iswamanager.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/programobject.h>
@@ -129,6 +132,18 @@ namespace {
}
namespace openspace {
void addScreenSpaceRenderable(std::string texturePath){
std::string filepath ="${OPENSPACE_DATA}/"+texturePath;
if( ! FileSys.fileExists(filepath)) {
LWARNING("Could not find image '" << filepath << "'");
return;
}
std::string luaTable = "{Type = 'ScreenSpaceImage', TexturePath = '+" + filepath + " ' }";
std::string script = "openspace.registerScreenSpaceRenderable(" + luaTable + ");";
OsEng.scriptEngine().queueScript(script);
// OsEng.renderEngine().registerScreenSpaceRenderable(std::make_shared<ScreenSpaceImage>(filepath));
}
namespace gui {
GUI::GUI()
@@ -190,8 +205,10 @@ void GUI::initialize() {
//io.GetClipboardTextFn = ImImpl_GetClipboardTextFn; // @TODO implement? ---abock
_property.initialize();
_screenSpaceProperty.initialize();
_performance.initialize();
_help.initialize();
_iswa.initialize();
}
void GUI::initializeGL() {
@@ -236,8 +253,10 @@ void GUI::initializeGL() {
_property.initializeGL();
_screenSpaceProperty.initializeGL();
_performance.initializeGL();
_help.initializeGL();
_iswa.initializeGL();
}
void GUI::deinitializeGL() {
@@ -247,8 +266,10 @@ void GUI::deinitializeGL() {
glDeleteBuffers(1, &vbo);
_property.deinitializeGL();
_screenSpaceProperty.deinitializeGL();
_performance.deinitializeGL();
_help.deinitializeGL();
_iswa.deinitializeGL();
}
void GUI::startFrame(float deltaTime, const glm::vec2& windowSize,
@@ -275,10 +296,14 @@ void GUI::endFrame() {
if (_property.isEnabled())
_property.render();
if (_screenSpaceProperty.isEnabled())
_screenSpaceProperty.render();
if (_performance.isEnabled())
_performance.render();
if (_help.isEnabled())
_help.render();
if (_iswa.isEnabled())
_iswa.render();
ImGui::Render();
}
@@ -373,7 +398,11 @@ bool GUI::charCallback(unsigned int character, KeyModifier modifier) {
void GUI::renderMainWindow() {
ImGui::Begin("OpenSpace GUI", nullptr);
ImGui::Checkbox("Properties", &_property._isEnabled);
ImGui::Checkbox("Scene Graph Properties", &_property._isEnabled);
ImGui::Checkbox("ScreenSpace Properties", &_screenSpaceProperty._isEnabled);
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
ImGui::Checkbox("iSWA", &_iswa._isEnabled);
#endif
ImGui::Checkbox("Performance", &_performance._isEnabled);
_origin.render();
_time.render();
@@ -395,6 +424,24 @@ void GUI::renderMainWindow() {
ImGui::Checkbox("Help", &_help._isEnabled);
static const int addImageBufferSize = 256;
static char addImageBuffer[addImageBufferSize];
ImGui::InputText("addImage", addImageBuffer, addImageBufferSize);
if(ImGui::SmallButton("Add Image")){
addScreenSpaceRenderable(std::string(addImageBuffer));
}
// #ifdef OPENSPACE_MODULE_ISWA_ENABLED
// static const int addCygnetBufferSize = 256;
// static char addCygnetBuffer[addCygnetBufferSize];
// ImGui::InputText("addCynget", addCygnetBuffer, addCygnetBufferSize);
// if(ImGui::SmallButton("Add Cygnet"))
// OsEng.scriptEngine().queueScript("openspace.iswa.addCygnet('"+std::string(addCygnetBuffer)+"');");
// #endif
ImGui::End();
}

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