Merge remote-tracking branch 'origin/feature/iSWA' into develop
Conflicts: data/scene/default.scene scripts/bind_keys.lua
2
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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"}
|
||||
},
|
||||
|
||||
7
data/scene/iswa/cdf/fieldlines.json
Normal 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"
|
||||
}
|
||||
1
data/scene/iswa/tfs/autumn.tf
Normal file
@@ -0,0 +1 @@
|
||||
${SCENE}/iswa/tfs/colormap_autumn.png
|
||||
BIN
data/scene/iswa/tfs/blue.jpg
Normal file
|
After Width: | Height: | Size: 726 B |
BIN
data/scene/iswa/tfs/colormap_autumn.png
Normal file
|
After Width: | Height: | Size: 565 B |
BIN
data/scene/iswa/tfs/colormap_hot.jpg
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
data/scene/iswa/tfs/colormap_hot.png
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
data/scene/iswa/tfs/colormap_parula.jpg
Normal file
|
After Width: | Height: | Size: 953 B |
BIN
data/scene/iswa/tfs/colormap_parula.png
Normal file
|
After Width: | Height: | Size: 846 B |
BIN
data/scene/iswa/tfs/green.jpg
Normal file
|
After Width: | Height: | Size: 799 B |
1
data/scene/iswa/tfs/hot.tf
Normal file
@@ -0,0 +1 @@
|
||||
${SCENE}/iswa/tfs/colormap_hot.jpg
|
||||
1
data/scene/iswa/tfs/parula.tf
Normal file
@@ -0,0 +1 @@
|
||||
${SCENE}/iswa/tfs/colormap_parula.jpg
|
||||
BIN
data/scene/iswa/tfs/red.jpg
Normal file
|
After Width: | Height: | Size: 772 B |
3
data/scene/iswa/tfs/rgb.tf
Normal file
@@ -0,0 +1,3 @@
|
||||
${SCENE}/iswa/tfs/red.jpg
|
||||
${SCENE}/iswa/tfs/green.jpg
|
||||
${SCENE}/iswa/tfs/blue.jpg
|
||||
@@ -208,7 +208,7 @@ return {
|
||||
Size = {1.0, 6.4},
|
||||
Origin = "Center",
|
||||
Billboard = true,
|
||||
ProjectionListener = true,
|
||||
ProjectionListener = false,
|
||||
Texture = "textures/Pluto-Text.png"
|
||||
},
|
||||
Ephemeris = {
|
||||
|
||||
31
data/spice/iSWAKernels/GSE.ti
Normal 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'
|
||||
31
data/spice/iSWAKernels/GSM.ti
Normal 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
|
||||
264
data/spice/iSWAKernels/heliospheric.tf
Normal 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
|
After Width: | Height: | Size: 133 KiB |
BIN
data/test3.jpg
Normal file
|
After Width: | Height: | Size: 186 KiB |
8236
ext/json/json.hpp
Normal 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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace properties {
|
||||
class Renderable;
|
||||
class Scene;
|
||||
class SceneGraphNode;
|
||||
class IswaGroup;
|
||||
class ScreenSpaceRenderable;
|
||||
|
||||
Scene* sceneGraph();
|
||||
SceneGraphNode* sceneGraphNode(const std::string& name);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
126
include/openspace/rendering/screenspacerenderable.h
Normal 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__
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
52
include/openspace/util/transformationmanager.h
Normal 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__
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
158
modules/base/rendering/screenspaceframebuffer.cpp
Normal 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
|
||||
67
modules/base/rendering/screenspaceframebuffer.h
Normal 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__
|
||||
201
modules/base/rendering/screenspaceimage.cpp
Normal 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++;
|
||||
}
|
||||
}
|
||||
75
modules/base/rendering/screenspaceimage.h
Normal 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__
|
||||
@@ -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);
|
||||
|
||||
50
modules/base/shaders/screnspace_fs.glsl
Normal 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;
|
||||
}
|
||||
41
modules/base/shaders/screnspace_vs.glsl
Normal 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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
// }
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
72
modules/iswa/CMakeLists.txt
Normal 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}
|
||||
)
|
||||
123
modules/iswa/ext/base64/base64.cpp
Normal 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;
|
||||
}
|
||||
4
modules/iswa/ext/base64/base64.h
Normal 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);
|
||||
8236
modules/iswa/ext/json/json.hpp
Normal file
3
modules/iswa/include.cmake
Normal file
@@ -0,0 +1,3 @@
|
||||
set (OPENSPACE_DEPENDENCIES
|
||||
base
|
||||
)
|
||||
24
modules/iswa/info
Normal 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
|
||||
59
modules/iswa/iswamodule.cpp
Normal 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
@@ -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__
|
||||
87
modules/iswa/rendering/cygnetplane.cpp
Normal 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
|
||||
48
modules/iswa/rendering/cygnetplane.h
Normal 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__
|
||||
65
modules/iswa/rendering/cygnetsphere.cpp
Normal 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
|
||||
54
modules/iswa/rendering/cygnetsphere.h
Normal 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__
|
||||
39
modules/iswa/rendering/datacygnet.cpp
Normal 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
|
||||
40
modules/iswa/rendering/datacygnet.h
Normal 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__
|
||||
366
modules/iswa/rendering/dataplane.cpp
Normal 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
|
||||
73
modules/iswa/rendering/dataplane.h
Normal 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__
|
||||
385
modules/iswa/rendering/datasphere.cpp
Normal 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
|
||||
72
modules/iswa/rendering/datasphere.h
Normal 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__
|
||||
280
modules/iswa/rendering/iswacygnet.cpp
Normal 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
|
||||
137
modules/iswa/rendering/iswacygnet.h
Normal 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
|
||||
270
modules/iswa/rendering/iswagroup.cpp
Normal 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
|
||||
108
modules/iswa/rendering/iswagroup.h
Normal 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
|
||||
527
modules/iswa/rendering/kameleonplane.cpp
Normal 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
|
||||
108
modules/iswa/rendering/kameleonplane.h
Normal 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__
|
||||
88
modules/iswa/rendering/screenspacecygnet.cpp
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
59
modules/iswa/rendering/screenspacecygnet.h
Normal 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__
|
||||
95
modules/iswa/rendering/texturecygnet.cpp
Normal 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
|
||||
57
modules/iswa/rendering/texturecygnet.h
Normal 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__
|
||||
112
modules/iswa/rendering/textureplane.cpp
Normal 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
|
||||
54
modules/iswa/rendering/textureplane.h
Normal 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
|
||||
60
modules/iswa/shaders/cygnetplane_fs.glsl
Normal 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;
|
||||
|
||||
}
|
||||
49
modules/iswa/shaders/cygnetplane_vs.glsl
Normal 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);
|
||||
}
|
||||
88
modules/iswa/shaders/dataplane_fs.glsl
Normal 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;
|
||||
|
||||
}
|
||||
49
modules/iswa/shaders/dataplane_vs.glsl
Normal 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);
|
||||
}
|
||||
88
modules/iswa/shaders/datasphere_fs.glsl
Normal 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;
|
||||
|
||||
}
|
||||
53
modules/iswa/shaders/datasphere_vs.glsl
Normal 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);
|
||||
}
|
||||
843
modules/iswa/util/dataprocessor.cpp
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
107
modules/iswa/util/dataprocessor.h
Normal 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__
|
||||
683
modules/iswa/util/iswamanager.cpp
Normal 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) +"×tamp=";
|
||||
}
|
||||
|
||||
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
|
||||
144
modules/iswa/util/iswamanager.h
Normal 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__
|
||||
169
modules/iswa/util/iswamanager_lua.inl
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
58
modules/onscreengui/include/guiiswacomponent.h
Normal 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__
|
||||
@@ -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:
|
||||
|
||||
46
modules/onscreengui/include/renderproperties.h
Normal 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__
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||