Merge branch 'develop' into feature/multitouch

This commit is contained in:
Jonathan Bosson
2017-04-11 11:25:59 -06:00
153 changed files with 2310 additions and 2130 deletions

View File

@@ -33,38 +33,38 @@ endif ()
option(OPENSPACE_OPENVR_SUPPORT "Build OpenSpace application with OpenVR support" OFF)
if(OPENSPACE_OPENVR_SUPPORT)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OPENSPACE_EXT_DIR}/sgct/cmake/modules/")
find_package(OpenVR REQUIRED)
set(SGCT_OPENVR_DEFINITIONS OPENVR_SUPPORT)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OPENSPACE_EXT_DIR}/sgct/cmake/modules/")
find_package(OpenVR REQUIRED)
set(SGCT_OPENVR_DEFINITIONS OPENVR_SUPPORT)
if(NOT SGCT_OPENVR_INCLUDE_DIRECTORY)
if( WIN32 )
find_path(SGCT_OPENVR_INCLUDE_DIRECTORY
NAMES SGCTOpenVR.h
PATHS $ENV{SGCT_ROOT_DIR}/additional_includes/openvr ${OPENSPACE_EXT_DIR}/sgct/additional_includes/openvr NO_DEFAULT_PATH
REQUIRED)
else()
find_path(SGCT_OPENVR_INCLUDE_DIRECTORY
NAMES SGCTOpenVR.h
PATH_SUFFIXES SGCTOpenVR
PATHS $ENV{SGCT_ROOT_DIR}/additional_includes/openvr ${OPENSPACE_EXT_DIR}/sgct/additional_includes/openvr
REQUIRED)
endif()
else()
set(SGCT_OPENVR_FILES ${SGCT_OPENVR_INCLUDE_DIRECTORY}/SGCTOpenVR.h ${SGCT_OPENVR_INCLUDE_DIRECTORY}/SGCTOpenVR.cpp)
endif()
if(NOT SGCT_OPENVR_INCLUDE_DIRECTORY)
if( WIN32 )
find_path(SGCT_OPENVR_INCLUDE_DIRECTORY
NAMES SGCTOpenVR.h
PATHS $ENV{SGCT_ROOT_DIR}/additional_includes/openvr ${OPENSPACE_EXT_DIR}/sgct/additional_includes/openvr NO_DEFAULT_PATH
REQUIRED)
else()
find_path(SGCT_OPENVR_INCLUDE_DIRECTORY
NAMES SGCTOpenVR.h
PATH_SUFFIXES SGCTOpenVR
PATHS $ENV{SGCT_ROOT_DIR}/additional_includes/openvr ${OPENSPACE_EXT_DIR}/sgct/additional_includes/openvr
REQUIRED)
endif()
else()
set(SGCT_OPENVR_FILES ${SGCT_OPENVR_INCLUDE_DIRECTORY}/SGCTOpenVR.h ${SGCT_OPENVR_INCLUDE_DIRECTORY}/SGCTOpenVR.cpp)
endif()
else()
set(OPENVR_INCLUDE_DIRS "")
set(SGCT_OPENVR_INCLUDE_DIRECTORY "")
set(OPENVR_LIBRARY "")
set(SGCT_OPENVR_DEFINITIONS "")
set(OPENVR_INCLUDE_DIRS "")
set(SGCT_OPENVR_INCLUDE_DIRECTORY "")
set(OPENVR_LIBRARY "")
set(SGCT_OPENVR_DEFINITIONS "")
endif()
##OpenVR section end####################
add_executable(${APPLICATION_NAME}
${SGCT_OPENVR_FILES}
${SGCT_OPENVR_FILES}
${OPENSPACE_APPS_DIR}/OpenSpace/main.cpp
${RESOURCE_FILE}
)
@@ -72,6 +72,7 @@ target_include_directories(${APPLICATION_NAME} PUBLIC ${OPENSPACE_BASE_DIR}/incl
target_link_libraries(${APPLICATION_NAME} libOpenSpace ${OPENVR_LIBRARY})
target_compile_definitions(${APPLICATION_NAME} PUBLIC ${SGCT_OPENVR_DEFINITIONS})
if (MSVC)
set_target_properties(${APPLICATION_NAME} PROPERTIES LINK_FLAGS
"/NODEFAULTLIB:LIBCMTD.lib /NODEFAULTLIB:LIBCMT.lib"

View File

@@ -102,7 +102,7 @@ void mainInitFunc() {
// If we have an OpenVRWindow, initialize OpenVR.
sgct::SGCTOpenVR::initialize(
SgctEngine->getNearClippingPlane(), _sgctEngine->getFarClippingPlane()
SgctEngine->getNearClippingPlane(), SgctEngine->getFarClippingPlane()
);
#else
LWARNING(
@@ -167,10 +167,10 @@ void mainRenderFunc() {
glm::mat4 projectionMatrix = SgctEngine->getCurrentProjectionMatrix();
#ifdef OPENVR_SUPPORT
bool currentWindowIsHMD = FirstOpenVRWindow == _sgctEngine->getCurrentWindowPtr();
bool currentWindowIsHMD = FirstOpenVRWindow == SgctEngine->getCurrentWindowPtr();
if (sgct::SGCTOpenVR::isHMDActive() && currentWindowIsHMD) {
projectionMatrix = sgct::SGCTOpenVR::getHMDCurrentViewProjectionMatrix(
_sgctEngine->getCurrentFrustumMode()
SgctEngine->getCurrentFrustumMode()
);
}
#endif

View File

@@ -75,6 +75,10 @@ return {
FilePath = "map_service_configs/ESRI/ESRI_Imagery_World_2D.wms",
Name = "ESRI",
},
{
Name = "ESRI Imagery World",
FilePath = "map_service_configs/ESRI/ESRI_Imagery_World_2D.wms"
},
{
Type = "Temporal",
Name = "Temporal VIIRS SNPP",
@@ -108,6 +112,11 @@ return {
FilePath = "map_service_configs/GIBS/VIIRS_CityLights_2012.xml",
Enabled = true,
},
{
Type = "Temporal",
Name = "Temporal Earth at Night",
FilePath = "map_service_configs/GIBS/Temporal_VIIRS_CityLights.xml"
}
},
WaterMasks = {
{

View File

@@ -14,8 +14,8 @@
<BandsCount>3</BandsCount>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache_ESRI_Imagery_World_2d</Path>
<Depth>10</Depth>
<Path>./GDAL_Cache/ESRI_Imagery_World_2d</Path>
<Depth>4</Depth>
<Extension>.jpg</Extension>
</Cache>
<OfflineMode>false</OfflineMode>

View File

@@ -1,14 +1,21 @@
<GDAL_WMS>
<Service name="TiledWMS">
<ServerUrl>http://198.102.45.23/arcgis/rest/services/worldelevation3d/terrain3d?</ServerUrl>
<TiledGroupName>GCS_Elevation</TiledGroupName>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<YOrigin>bottom</YOrigin>
</DataWindow>
<Timeout>2</Timeout>
<Service name="TiledWMS">
<ServerUrl>http://198.102.45.23/arcgis/rest/services/worldelevation3d/terrain3d?</ServerUrl>
<TiledGroupName>GCS_Elevation</TiledGroupName>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90.0</UpperLeftY>
<LowerRightX>180.0</LowerRightX>
<LowerRightY>-90.0</LowerRightY>
<YOrigin>bottom</YOrigin>
</DataWindow>
<Timeout>2</Timeout>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/TERRAIN</Path>
<Depth>4</Depth>
<Extension>.jpg</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/Coastlines/default/2013-08-21/EPSG4326_250m/${z}/${y}/${x}.png</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/Coastlines/default/2013-08-21/250m/${z}/${y}/${x}.png</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>4</BandsCount>
</GDAL_WMS>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/Coastlines</Path>
<Depth>4</Depth>
<Extension>.png</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/MODIS_Aqua_CorrectedReflectance_TrueColor/default/2013-08-21/EPSG4326_250m/${z}/${y}/${x}.jpg</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Aqua_CorrectedReflectance_TrueColor/default/2013-08-21/250m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
</GDAL_WMS>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/GIBS_Aqua_MODIS_true</Path>
<Depth>4</Depth>
<Extension>.jpg</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/MODIS_Terra_Brightness_Temp_Band31_Day/default/2013-08-21/EPSG4326_1km/${z}/${y}/${x}.png</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Terra_Brightness_Temp_Band31_Day/default/2013-08-21/1km/${z}/${y}/${x}.png</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>4</BandsCount>
</GDAL_WMS>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/MODIS_Terra_Brightness_Temp_Band31_Day</Path>
<Depth>4</Depth>
<Extension>.png</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/MODIS_Terra_CorrectedReflectance_TrueColor/default/2016-05-16/EPSG4326_250m/${z}/${y}/${x}.jpg</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Terra_CorrectedReflectance_TrueColor/default/2013-08-21/250m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
</GDAL_WMS>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/MODIS_Terra_CorrectedReflectance_TrueColor</Path>
<Depth>4</Depth>
<Extension>.jpg</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,19 +0,0 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/MODIS_Terra_CorrectedReflectance_TrueColor/default/${t}/EPSG4326_250m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90</UpperLeftY>
<LowerRightX>396.0</LowerRightX>
<LowerRightY>-198</LowerRightY>
<TileLevel>8</TileLevel>
<TileCountX>2</TileCountX>
<TileCountY>1</TileCountY>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>EPSG:4326</Projection>
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/MODIS_Water_Mask/default/2013-08-21/EPSG4326_250m/${z}/${y}/${x}.png</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Water_Mask/default/2013-08-21/250m/${z}/${y}/${x}.png</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>4</BandsCount>
</GDAL_WMS>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/MODIS_Water_Mask</Path>
<Depth>4</Depth>
<Extension>.png</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/Reference_Features/default/2013-08-21/EPSG4326_250m/${z}/${y}/${x}.png</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/Reference_Features/default/2013-08-21/250m/${z}/${y}/${x}.png</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>4</BandsCount>
</GDAL_WMS>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/Reference_Features</Path>
<Depth>4</Depth>
<Extension>.png</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/Reference_Labels/default/2013-08-21/EPSG4326_250m/${z}/${y}/${x}.png</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/Reference_Labels/default/2013-08-21/250m/${z}/${y}/${x}.png</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>4</BandsCount>
</GDAL_WMS>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/Reference_Labels</Path>
<Depth>4</Depth>
<Extension>.png</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TiledWMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/twms-geo/twms.cgi?</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/twms/twms.cgi?</ServerUrl>
<TiledGroupName>MODIS TERRA tileset</TiledGroupName>
<Change key="${time}">2016-04-12</Change>
</Service>

View File

@@ -6,7 +6,7 @@
<GDAL_WMS>
<Service name="WMS">
<Version>1.1.1</Version>
<ServerUrl>http://map2.vis.earthdata.nasa.gov/wms/wms.php?TIME=${OpenSpaceTimeId}</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wms/wms.php?TIME=${OpenSpaceTimeId}</ServerUrl>
<SRS>EPSG:4326</SRS>
<ImageFormat>image/png</ImageFormat>
<Transparent>TRUE</Transparent>
@@ -26,11 +26,8 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>
</OpenSpaceTemporalGDALDataset>
<!--
https://map2.vis.earthdata.nasa.gov/wms/wms.php?TIME=2014-07-17&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=Aqua_Orbit_Asc&WIDTH=512&HEIGHT=512&SRS=EPSG%3A4326&STYLES=&BBOX=46.125%2C48.375%2C46.6875%2C48.9375
https://map2.vis.earthdata.nasa.gov/wms/wms.php?TIME=2015-11-23&service=WMS&request=GetMap&version=1.1.1&layers=Aqua_Orbit_Asc&styles=&srs=EPSG:4326&transparent=FALSE&format=image/png&width=512&height=512&bbox=-180.00000000,18.00000000,-108.00000000,90.00000000
-->

View File

@@ -5,7 +5,7 @@
<OpenSpaceTimeIdFormat>YYYY-MM-DD</OpenSpaceTimeIdFormat>
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/GHRSST_L4_MUR_Sea_Surface_Temperature/default/${OpenSpaceTimeId}/EPSG4326_1km/${z}/${y}/${x}.png</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/GHRSST_L4_MUR_Sea_Surface_Temperature/default/${OpenSpaceTimeId}/250m/${z}/${y}/${x}.png</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -21,5 +21,8 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>4</BandsCount>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>
</OpenSpaceTemporalGDALDataset>
</OpenSpaceTemporalGDALDataset>

View File

@@ -5,7 +5,7 @@
<OpenSpaceTimeIdFormat>YYYY-MM-DD</OpenSpaceTimeIdFormat>
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/MODIS_Aqua_CorrectedReflectance_TrueColor/default/${OpenSpaceTimeId}/EPSG4326_250m/${z}/${y}/${x}.jpg</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Aqua_CorrectedReflectance_TrueColor/default/${OpenSpaceTimeId}/250m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -21,5 +21,8 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>
</OpenSpaceTemporalGDALDataset>
</OpenSpaceTemporalGDALDataset>

View File

@@ -0,0 +1,28 @@
<OpenSpaceTemporalGDALDataset>
<OpenSpaceTimeStart>2012-05-08</OpenSpaceTimeStart>
<OpenSpaceTimeEnd></OpenSpaceTimeEnd>
<OpenSpaceTimeResolution>1d</OpenSpaceTimeResolution>
<OpenSpaceTimeIdFormat>YYYY-MM-DD</OpenSpaceTimeIdFormat>
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Terra_CorrectedReflectance_TrueColor/default/${OpenSpaceTimeId}/250m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90</UpperLeftY>
<LowerRightX>396.0</LowerRightX>
<LowerRightY>-198</LowerRightY>
<TileLevel>8</TileLevel>
<TileCountX>2</TileCountX>
<TileCountY>1</TileCountY>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>EPSG:4326</Projection>
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>
</OpenSpaceTemporalGDALDataset>

View File

@@ -5,7 +5,7 @@
<OpenSpaceTimeIdFormat>YYYY-MM-DD</OpenSpaceTimeIdFormat>
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/VIIRS_SNPP_CorrectedReflectance_TrueColor/default/${OpenSpaceTimeId}/EPSG4326_250m/${z}/${y}/${x}.jpg</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/VIIRS_SNPP_CorrectedReflectance_TrueColor/default/${OpenSpaceTimeId}/250m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -21,5 +21,8 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>
</OpenSpaceTemporalGDALDataset>
</OpenSpaceTemporalGDALDataset>

View File

@@ -0,0 +1,28 @@
<OpenSpaceTemporalGDALDataset>
<OpenSpaceTimeStart>2012-05-08</OpenSpaceTimeStart>
<OpenSpaceTimeEnd></OpenSpaceTimeEnd>
<OpenSpaceTimeResolution>1d</OpenSpaceTimeResolution>
<OpenSpaceTimeIdFormat>YYYY-MM-DD</OpenSpaceTimeIdFormat>
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/VIIRS_SNPP_DayNightBand_ENCC/default/${OpenSpaceTimeId}/500m/${z}/${y}/${x}.png</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
<UpperLeftY>90</UpperLeftY>
<LowerRightX>396.0</LowerRightX>
<LowerRightY>-198</LowerRightY>
<TileLevel>8</TileLevel>
<TileCountX>2</TileCountX>
<TileCountY>1</TileCountY>
<YOrigin>top</YOrigin>
</DataWindow>
<Projection>EPSG:4326</Projection>
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>
</OpenSpaceTemporalGDALDataset>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/VIIRS_CityLights_2012/default/2012-01-01/EPSG4326_500m/${z}/${y}/${x}.jpg</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/VIIRS_CityLights_2012/default/2013-08-21/500m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>4</BandsCount>
</GDAL_WMS>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/VIIRS_CityLights_2012</Path>
<Depth>4</Depth>
<Extension>.jpg</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,6 +1,6 @@
<GDAL_WMS>
<Service name="TMS">
<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-geo/VIIRS_SNPP_CorrectedReflectance_TrueColor/default/2016-10-01/EPSG4326_250m/${z}/${y}/${x}.jpg</ServerUrl>
<ServerUrl>https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/VIIRS_SNPP_CorrectedReflectance_TrueColor/default/2016-08-21/250m/${z}/${y}/${x}.jpg</ServerUrl>
</Service>
<DataWindow>
<UpperLeftX>-180.0</UpperLeftX>
@@ -16,4 +16,14 @@
<BlockSizeX>512</BlockSizeX>
<BlockSizeY>512</BlockSizeY>
<BandsCount>3</BandsCount>
<MaxConnections>5</MaxConnections>
<Cache>
<Path>./GDAL_Cache/VIIRS_SNPP_CorrectedReflectance_TrueColor</Path>
<Depth>4</Depth>
<Extension>.jpg</Extension>
</Cache>
<OfflineMode>false</OfflineMode>
<UnsafeSSL>true</UnsafeSSL>
<ZeroBlockHttpCodes>400</ZeroBlockHttpCodes>
<ZeroBlockOnServerException>true</ZeroBlockOnServerException>
</GDAL_WMS>

View File

@@ -1,4 +1,9 @@
return {
-- Solar system module
{
Name = "SolarSystem",
Parent = "Root"
},
-- Sun barycenter module
{
Name = "SolarSystemBarycenter",

Binary file not shown.

Binary file not shown.

BIN
ext/curl/lib/libeay32.dll Normal file

Binary file not shown.

BIN
ext/curl/lib/ssleay32.dll Normal file

Binary file not shown.

View File

@@ -55,6 +55,8 @@ class NetworkEngine;
class ParallelConnection;
class RenderEngine;
class SettingsEngine;
class SceneManager;
class SyncEngine;
class TimeManager;
class WindowWrapper;
@@ -95,7 +97,9 @@ public:
void externalControlCallback(const char* receivedChars, int size, int clientId);
void encode();
void decode();
void scheduleLoadScene(std::string scenePath);
void enableBarrier();
void disableBarrier();
@@ -167,6 +171,7 @@ private:
std::unique_ptr<WindowWrapper> windowWrapper);
~OpenSpaceEngine() = default;
void loadScene(const std::string& scenePath);
void gatherCommandlineArguments();
void loadFonts();
void runPreInitializationScripts(const std::string& sceneDescription);
@@ -174,6 +179,7 @@ private:
// Components
std::unique_ptr<ConfigurationManager> _configurationManager;
std::unique_ptr<SceneManager> _sceneManager;
std::unique_ptr<DownloadManager> _downloadManager;
std::unique_ptr<LuaConsole> _console;
std::unique_ptr<ModuleEngine> _moduleEngine;
@@ -193,6 +199,9 @@ private:
// Others
std::unique_ptr<properties::PropertyOwner> _globalPropertyNamespace;
bool _scheduledSceneSwitch;
std::string _scenePath;
struct {
std::vector<std::function<void()>> initialize;
std::vector<std::function<void()>> deinitialize;

View File

@@ -89,6 +89,11 @@ public:
*/
void removeSyncable(Syncable* syncable);
/**
* Remove multiple Syncables from being synchronized over the SGCT cluster
*/
void removeSyncables(const std::vector<Syncable*>& syncables);
private:
/**
* Vector of Syncables. The vectors ensures consistent encode/decode order

View File

@@ -25,13 +25,18 @@
#ifndef __OPENSPACE_CORE___RENDERENGINE___H__
#define __OPENSPACE_CORE___RENDERENGINE___H__
#include <openspace/scripting/scriptengine.h>
#include <openspace/performance/performancemanager.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/triggerproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/intproperty.h>
#include <openspace/properties/triggerproperty.h>
#include <openspace/rendering/raycastermanager.h>
#include <openspace/rendering/renderer.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/syncdata.h>
@@ -48,17 +53,11 @@ class SharedMemory;
namespace openspace {
namespace performance {
class PerformanceManager;
}
// Forward declare to minimize dependencies
class Camera;
class SyncBuffer;
class Scene;
class Renderer;
class RaycasterManager;
class SceneManager;
class ScreenLog;
class ScreenSpaceRenderable;
@@ -77,14 +76,15 @@ public:
};
RenderEngine();
~RenderEngine();
~RenderEngine() = default;
void initialize();
void initializeGL();
void deinitialize();
void setSceneGraph(Scene* sceneGraph);
void setScene(Scene* scene);
Scene* scene();
void updateScene();
Camera* camera() const;
Renderer* renderer() const;
@@ -93,7 +93,7 @@ public:
// sgct wrapped functions
void updateSceneGraph();
void updateShaderPrograms();
void updateFade();
void updateRenderer();
@@ -144,6 +144,11 @@ public:
*/
void postRaycast(ghoul::opengl::ProgramObject& programObject);
/**
* Set the camera to use for rendering
*/
void setCamera(Camera* camera);
void setRendererFromString(const std::string& method);
@@ -181,9 +186,9 @@ private:
void renderInformation();
Camera* _mainCamera;
Scene* _sceneGraph;
RaycasterManager* _raycasterManager;
Camera* _camera;
Scene* _scene;
std::unique_ptr<RaycasterManager> _raycasterManager;
properties::BoolProperty _performanceMeasurements;
std::unique_ptr<performance::PerformanceManager> _performanceManager;

View File

@@ -33,8 +33,6 @@
#include <openspace/util/camera.h>
#include <openspace/util/updatestructures.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scene/scenegraph.h>
#include <ghoul/opengl/programobject.h>
namespace ghoul { class Dictionary; }
@@ -49,61 +47,104 @@ class SceneGraphNode;
// SceneGraphFinishedLoading
class Scene {
public:
using UpdateDependencies = ghoul::Boolean;
struct InvalidSceneError : ghoul::RuntimeError {
/**
* \param message The reason that caused this exception to be thrown
* \param component The optional compoment that caused this exception to be thrown
* \pre message may not be empty
*/
explicit InvalidSceneError(const std::string& message, const std::string& component = "");
};
// constructors & destructor
Scene();
~Scene();
/**
* Initalizes the SceneGraph by loading modules from the ${SCENEPATH} directory
* Initalizes the SceneGraph
*/
bool initialize();
void initialize();
/*
* Clean up everything
/**
* Clear the scene graph,
* i.e. set the root node to nullptr and deallocate all scene graph nodes.
*/
bool deinitialize();
void clear();
/*
* Load the scenegraph from the provided folder
/**
* Set the root node of the scene
*/
void scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath);
void clearSceneGraph();
void setRoot(std::unique_ptr<SceneGraphNode> root);
void loadModule(const std::string& modulePath);
/**
* Set the camera of the scene
*/
void setCamera(std::unique_ptr<Camera> camera);
/*
/**
* Return the camera
*/
Camera* camera() const;
/**
* Updates all SceneGraphNodes relative positions
*/
void update(const UpdateData& data);
/*
* Evaluates if the SceneGraphNodes are visible to the provided camera
/**
* Evaluate if the SceneGraphNodes are visible to the provided camera.
*/
void evaluate(Camera* camera);
/*
* Render visible SceneGraphNodes using the provided camera
/**
* Render visible SceneGraphNodes using the provided camera.
*/
void render(const RenderData& data, RendererTasks& tasks);
/*
* Returns the root SceneGraphNode
/**
* Return the root SceneGraphNode.
*/
SceneGraphNode* root() const;
/**
* Return the scenegraph node with the specified name or <code>nullptr</code> if that
* name does not exist
* name does not exist.
*/
SceneGraphNode* sceneGraphNode(const std::string& name) const;
std::vector<SceneGraphNode*> allSceneGraphNodes() const;
/**
* Add a node and all its children to the scene.
*/
void addNode(SceneGraphNode* node, UpdateDependencies updateDeps = UpdateDependencies::Yes);
SceneGraph& sceneGraph();
/**
* Remove a node and all its children from the scene.
*/
void removeNode(SceneGraphNode* node, UpdateDependencies updateDeps = UpdateDependencies::Yes);
/**
* Update dependencies.
*/
void updateDependencies();
/**
* Return a vector of all scene graph nodes in the scene.
*/
const std::vector<SceneGraphNode*>& allSceneGraphNodes() const;
/**
* Return a a map from name to scene graph node.
*/
const std::map<std::string, SceneGraphNode*>& nodesByName() const;
/**
* Output property documentation to a file.
*/
void writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename);
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
@@ -116,39 +157,18 @@ public:
static documentation::Documentation Documentation();
private:
bool loadSceneInternal(const std::string& sceneDescriptionFilePath);
private:
void sortTopologically();
void writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename);
std::string _focus;
// actual scenegraph
SceneGraph _graph;
//SceneGraphNode* _root;
//std::vector<SceneGraphNode*> _nodes;
//std::map<std::string, SceneGraphNode*> _allNodes;
std::string _sceneGraphToLoad;
std::unique_ptr<SceneGraphNode> _root;
std::unique_ptr<Camera> _camera;
std::vector<SceneGraphNode*> _topologicallySortedNodes;
std::vector<SceneGraphNode*> _circularNodes;
std::map<std::string, SceneGraphNode*> _nodesByName;
std::mutex _programUpdateLock;
std::set<ghoul::opengl::ProgramObject*> _programsToUpdate;
std::vector<std::unique_ptr<ghoul::opengl::ProgramObject>> _programs;
typedef std::map<std::string, ghoul::Dictionary> NodeMap;
typedef std::multimap<std::string, std::string> DependencyMap;
typedef std::vector<std::string> LoadedList;
struct LoadMaps {
NodeMap nodes;
DependencyMap dependencies;
LoadedList loadedNodes;
};
void loadModules(const std::string& directory, const ghoul::Dictionary& dictionary);
void loadModule(LoadMaps& m,const std::string& modulePath, lua_State* state);
void loadNodes(const std::string& parentName, LoadMaps& m);
void loadNode(const ghoul::Dictionary& dictionary);
};
} // namespace openspace

View File

@@ -47,6 +47,8 @@ namespace documentation { struct Documentation; }
class SceneGraphNode : public properties::PropertyOwner {
public:
using UpdateScene = ghoul::Boolean;
struct PerformanceRecord {
long long renderTime; // time in ns
long long updateTimeRenderable; // time in ns
@@ -63,21 +65,32 @@ public:
SceneGraphNode();
~SceneGraphNode();
static SceneGraphNode* createFromDictionary(const ghoul::Dictionary& dictionary);
static std::unique_ptr<SceneGraphNode> createFromDictionary(const ghoul::Dictionary& dictionary);
bool initialize();
bool deinitialize();
void traversePreOrder(std::function<void(SceneGraphNode*)> fn);
void traversePostOrder(std::function<void(SceneGraphNode*)> fn);
void update(const UpdateData& data);
void evaluate(const Camera* camera, const psc& parentPosition = psc());
void render(const RenderData& data, RendererTasks& tasks);
void updateCamera(Camera* camera) const;
//void addNode(SceneGraphNode* child);
void attachChild(std::unique_ptr<SceneGraphNode> child, UpdateScene updateScene = UpdateScene::Yes);
std::unique_ptr<SceneGraphNode> detachChild(SceneGraphNode& child, UpdateScene updateScene = UpdateScene::Yes);
void setParent(SceneGraphNode& parent, UpdateScene updateScene = UpdateScene::Yes);
void addChild(SceneGraphNode* child);
void setParent(SceneGraphNode* parent);
//bool abandonChild(SceneGraphNode* child);
void addDependency(SceneGraphNode& dependency, UpdateScene updateScene = UpdateScene::Yes);
void removeDependency(SceneGraphNode& dependency, UpdateScene updateScene = UpdateScene::Yes);
void clearDependencies(UpdateScene updateScene = UpdateScene::Yes);
void setDependencies(const std::vector<SceneGraphNode*>& dependencies, UpdateScene updateScene = UpdateScene::Yes);
const std::vector<SceneGraphNode*>& dependencies() const;
const std::vector<SceneGraphNode*>& dependentNodes() const;
Scene* scene();
void setScene(Scene* scene);
glm::dvec3 position() const;
const glm::dmat3& rotationMatrix() const;
@@ -88,7 +101,7 @@ public:
double worldScale() const;
SceneGraphNode* parent() const;
const std::vector<SceneGraphNode*>& children() const;
std::vector<SceneGraphNode*> children() const;
PowerScaledScalar calculateBoundingSphere();
PowerScaledScalar boundingSphere() const;
@@ -104,14 +117,15 @@ public:
static documentation::Documentation Documentation();
private:
bool sphereInsideFrustum(const psc& s_pos, const PowerScaledScalar& s_rad, const Camera* camera);
glm::dvec3 calculateWorldPosition() const;
glm::dmat3 calculateWorldRotation() const;
double calculateWorldScale() const;
std::vector<SceneGraphNode*> _children;
std::vector<std::unique_ptr<SceneGraphNode>> _children;
SceneGraphNode* _parent;
std::vector<SceneGraphNode*> _dependencies;
std::vector<SceneGraphNode*> _dependentNodes;
Scene* _scene;
PerformanceRecord _performanceRecord;

View File

@@ -0,0 +1,119 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___SCENELOADER___H__
#define __OPENSPACE_CORE___SCENELOADER___H__
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/camera.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/lua/ghoul_lua.h>
#include <memory>
#include <string>
namespace openspace {
class Scene;
class SceneLoader {
public:
SceneLoader() = default;
~SceneLoader() = default;
/**
* Load a scene file.
*/
std::unique_ptr<Scene> loadScene(const std::string& path);
/**
* Import a directory of scene contents into an existing scene.
*/
std::vector<SceneGraphNode*> importDirectory(Scene& scene, const std::string& directory);
/**
* Import a scene graph node from a dictionary into an existing scene.
*/
SceneGraphNode* importNodeDictionary(Scene& scene, const ghoul::Dictionary& dictionary);
private:
struct LoadedNode {
LoadedNode(
const std::string& nodeName,
const std::string& parentName,
const std::vector<std::string>& deps,
std::unique_ptr<SceneGraphNode> n
)
: name(nodeName)
, parent(parentName)
, dependencies(deps)
, node(std::move(n)) {}
std::string name;
std::string parent;
std::vector<std::string> dependencies;
std::unique_ptr<SceneGraphNode> node;
};
struct LoadedCamera {
LoadedCamera(
const std::string& parentName,
std::unique_ptr<Camera> c
)
: parent(parentName)
, camera(std::move(c)) {}
std::string parent;
std::unique_ptr<Camera> camera;
};
/**
* Load a scene graph node from a dictionary
*/
SceneLoader::LoadedNode loadNode(const ghoul::Dictionary& dictionary);
/**
* Load a mod file.
*/
std::vector<SceneLoader::LoadedNode> loadModule(const std::string& path, lua_State* luaState);
/**
* Load a directory.
*/
std::vector<SceneLoader::LoadedNode> loadDirectory(const std::string& path, lua_State* luaState);
/**
* Load a camera from a dictionary
*/
SceneLoader::LoadedCamera loadCamera(const ghoul::Dictionary& dictionary);
/**
* Add loaded nodes to an existing scene
*/
std::vector<SceneGraphNode*> addLoadedNodes(Scene& scene, std::vector<SceneLoader::LoadedNode>&& nodes);
};
}
#endif // __OPENSPACE_CORE___SCENELOADER___H__

View File

@@ -21,55 +21,28 @@
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___SCENEGRAPH___H__
#define __OPENSPACE_CORE___SCENEGRAPH___H__
#ifndef __OPENSPACE_CORE___SCENEMANAGER___H__
#define __OPENSPACE_CORE___SCENEMANAGER___H__
#include <vector>
#include <string>
#include <memory>
namespace openspace {
class SceneGraphNode;
class Scene;
class SceneGraph {
class SceneManager {
public:
SceneGraph();
~SceneGraph();
void clear();
bool loadFromFile(const std::string& sceneDescription);
// Returns if addition was successful
bool addSceneGraphNode(SceneGraphNode* node);
bool removeSceneGraphNode(SceneGraphNode* node);
const std::vector<SceneGraphNode*>& nodes() const;
SceneGraphNode* rootNode() const;
SceneGraphNode* sceneGraphNode(const std::string& name) const;
SceneManager() = default;
~SceneManager() = default;
Scene* loadScene(const std::string& path);
void unloadScene(Scene& scene);
void unloadAll();
private:
struct SceneGraphNodeInternal {
~SceneGraphNodeInternal();
SceneGraphNode* node = nullptr;
// From nodes that are dependent on this one
std::vector<SceneGraphNodeInternal*> incomingEdges;
// To nodes that this node depends on
std::vector<SceneGraphNodeInternal*> outgoingEdges;
};
bool nodeIsDependentOnRoot(SceneGraphNodeInternal* node);
bool sortTopologically();
SceneGraphNodeInternal* nodeByName(const std::string& name);
SceneGraphNode* _rootNode;
std::vector<SceneGraphNodeInternal*> _nodes;
std::vector<SceneGraphNode*> _topologicalSortedNodes;
std::vector<std::unique_ptr<Scene>> _scenes;
};
} // namespace openspace
}
#endif // __OPENSPACE_CORE___SCENEGRAPH___H__
#endif // __OPENSPACE_CORE___SCENEMANAGER___H__

View File

@@ -39,6 +39,7 @@
namespace openspace {
class SyncBuffer;
class SceneGraphNode;
/**
* This class still needs some more love. Suggested improvements:
@@ -92,6 +93,7 @@ public:
void setRotation(Quat rotation);
void setScaling(glm::vec2 scaling);
void setMaxFov(float fov);
void setParent(SceneGraphNode* parent);
// Relative mutators
void rotate(Quat rotation);
@@ -109,6 +111,7 @@ public:
const Quat& rotationQuaternion() const;
float maxFov() const;
float sinMaxFov() const;
SceneGraphNode* parent() const;
// @TODO this should simply be called viewMatrix!
// Or it needs to be changed so that it actually is combined. Right now it is
@@ -181,6 +184,7 @@ private:
SyncData<Vec3> _position;
SyncData<Quat> _rotation;
SyncData<glm::vec2> _scaling;
SceneGraphNode* _parent;
// _focusPosition to be removed

View File

@@ -66,7 +66,7 @@ int Distance::getDesiredLevel(const Chunk& chunk, const RenderData& data) const
double scaleFactor =
globe.generalProperties().lodScaleFactor * ellipsoid.minimumRadius();
double projectedScaleFactor = scaleFactor / distance;
int desiredLevel = ceil(log2(projectedScaleFactor));
int desiredLevel = static_cast<int>(ceil(log2(projectedScaleFactor)));
return desiredLevel;
}

View File

@@ -27,6 +27,8 @@
#include <modules/globebrowsing/geometry/angle.h>
#include <modules/globebrowsing/tile/tileindex.h>
#include <ghoul/misc/assert.h>
namespace openspace {
namespace globebrowsing {
@@ -90,6 +92,7 @@ Geodetic2 GeodeticPatch::getCorner(Quad q) const {
case NORTH_EAST: return Geodetic2(maxLat(), maxLon());// northEastCorner();
case SOUTH_WEST: return Geodetic2(minLat(), minLon());// southWestCorner();
case SOUTH_EAST: return Geodetic2(minLat(), maxLon());// southEastCorner();
default: ghoul_assert(false, "Missing case label");
}
}

View File

@@ -241,6 +241,8 @@ int PixelRegion::edge(Side side) const {
return start.x + numPixels.x;
case Side::BOTTOM:
return start.y + numPixels.y;
default:
ghoul_assert(false, "Missing case label");
}
}

View File

@@ -26,9 +26,11 @@
#include <modules/globebrowsing/tile/tileprovider/cachingtileprovider.h>
#include <ghoul/filesystem/filesystem>
#include <ghoul/logging/logmanager.h>
#include "cpl_minixml.h"
#include <fmt/format.h>
#include <fstream>
namespace {
@@ -72,7 +74,9 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
(std::istreambuf_iterator<char>())
);
_gdalXmlTemplate = consumeTemporalMetaData(xml);
_defaultTile = getTileProvider()->getDefaultTile();
std::shared_ptr<TileProvider> tileProvider = getTileProvider();
ghoul_assert(tileProvider, "No tile provider found");
_defaultTile = tileProvider->getDefaultTile();
}
std::string TemporalTileProvider::consumeTemporalMetaData(const std::string& xml) {
@@ -227,6 +231,33 @@ std::shared_ptr<TileProvider> TemporalTileProvider::getTileProvider(TimeKey time
std::shared_ptr<TileProvider> TemporalTileProvider::initTileProvider(TimeKey timekey) {
std::string gdalDatasetXml = getGdalDatasetXML(timekey);
try {
gdalDatasetXml = absPath(gdalDatasetXml);
}
catch (ghoul::filesystem::FileSystem::ResolveTokenException& e) {
const std::vector<std::string> AllowedToken = {
// From: http://www.gdal.org/frmt_wms.html
// @FRAGILE: What happens if a user specifies one of these as path tokens?
// ---abock
"${x}",
"${y}",
"${z}",
"${version}",
"${format}",
"${layer}"
};
auto it = std::find(AllowedToken.begin(), AllowedToken.end(), e.token);
if (it == AllowedToken.end()) {
throw;
}
LINFOC(
"TemporalTileProvider",
fmt::format("Ignoring '{}' in absolute path resolve", e.token)
);
}
_initDict.setValue<std::string>(KeyFilePath, gdalDatasetXml);
auto tileProvider = std::make_shared<CachingTileProvider>(_initDict);
return tileProvider;
@@ -243,6 +274,8 @@ std::string TemporalTileProvider::getGdalDatasetXML(TimeKey timeKey) {
//size_t numChars = std::string(URL_TIME_PLACEHOLDER).length();
size_t numChars = strlen(URL_TIME_PLACEHOLDER);
ghoul_assert(pos != std::string::npos, "Invalid dataset file");
// @FRAGILE: This will only find the first instance. Dangerous if that instance is
// commented out ---abock
std::string timeSpecifiedXml = xmlTemplate.replace(pos, numChars, timeKey);
return timeSpecifiedXml;
}

View File

@@ -37,7 +37,7 @@ class DataProcessor{
friend class IswaBaseGroup;
public:
DataProcessor();
~DataProcessor();
virtual ~DataProcessor();
virtual std::vector<std::string> readMetadata(std::string data, glm::size3_t& dimensions) = 0;
virtual void addDataValues(std::string data, properties::SelectionProperty& dataOptions) = 0;
@@ -50,6 +50,7 @@ public:
glm::vec2 filterValues();
void clear();
protected:
float processDataPoint(float value, int option);
float normalizeWithStandardScore(float value, float mean, float sd, glm::vec2 normalizationValues = glm::vec2(1.0f, 1.0f));

View File

@@ -32,7 +32,7 @@ namespace openspace {
class DataProcessorJson : public DataProcessor {
public:
DataProcessorJson();
~DataProcessorJson();
virtual ~DataProcessorJson();
virtual std::vector<std::string> readMetadata(std::string data, glm::size3_t& dimensions) override;
virtual void addDataValues(std::string data, properties::SelectionProperty& dataOptions) override;

View File

@@ -53,21 +53,22 @@ create_new_module(
add_subdirectory(${KAMELEON_ROOT_DIR})
target_include_directories(${kameleon_module} SYSTEM PUBLIC ${KAMELEON_INCLUDES})
target_link_libraries(${kameleon_module} ccmc)
if (OPENSPACE_DISABLE_EXTERNAL_WARNINGS)
if (GHOUL_DISABLE_EXTERNAL_WARNINGS)
if (MSVC)
target_compile_options(ccmc PUBLIC "/W0" "/MP")
target_compile_options(ccmc PRIVATE "/W0" "/MP")
target_compile_definitions(ccmc PRIVATE "_SCL_SECURE_NO_WARNINGS")
else ()
target_compile_options(ccmc PUBLIC "-w")
target_compile_options(ccmc PRIVATE "-w")
endif ()
target_compile_definitions(ccmc PUBLIC "_SCL_SECURE_NO_WARNINGS")
endif ()
set_property(TARGET ccmc PROPERTY FOLDER "External")
if (TARGET cdf)
if (GHOUL_DISABLE_EXTERNAL_WARNINGS)
if (MSVC)
target_compile_options(cdf PUBLIC "/W0" "/MP")
target_compile_options(cdf PRIVATE "/W0" "/MP")
target_compile_definitions(cdf PRIVATE "_SCL_SECURE_NO_WARNINGS")
else ()
target_compile_options(cdf PUBLIC "-w")
target_compile_options(cdf PRIVATE "-w")
endif ()
endif ()
set_property(TARGET cdf PROPERTY FOLDER "External")

View File

@@ -288,7 +288,12 @@ std::string RenderableKameleonVolume::cacheSuffix() {
void RenderableKameleonVolume::loadFromPath(const std::string& path) {
ghoul::filesystem::File file(path);
std::string extension = file.fileExtension();
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
std::transform(
extension.begin(),
extension.end(),
extension.begin(),
[](char v) { return static_cast<char>(tolower(v)); }
);
if (extension == "cdf") {
loadCdf(path);
} else {

View File

@@ -492,7 +492,6 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string&
// An early out for when the target is not in field of view
if (!isInFov) {
for (size_t i = 0; i < _instrument.bounds.size(); ++i) {
const glm::dvec3& bound = _instrument.bounds[i];
// If none of the points are able to intersect with the target, we can just
// copy the values from the field-of-view boundary. So we take each second
// item (the first one is (0,0,0)) and replicate it 'InterpolationSteps' times

View File

@@ -379,7 +379,7 @@ void RenderableModelProjection::attitudeParameters(double time) {
try {
SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_projectionComponent.instrumentId());
boresight = std::move(res.boresightVector);
} catch (const SpiceManager::SpiceException& e) {
} catch (const SpiceManager::SpiceException&) {
return;
}

View File

@@ -265,8 +265,9 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime
if (!_moving) {
SceneGraphNode* thisNode = OsEng.renderEngine().scene()->sceneGraphNode(_name);
SceneGraphNode* newParent = OsEng.renderEngine().scene()->sceneGraphNode(_target.node);
if (thisNode != nullptr && newParent != nullptr)
thisNode->setParent(newParent);
if (thisNode && newParent) {
thisNode->setParent(*newParent);
}
}
const GLfloat vertex_data[] = { // square of two triangles drawn within fov in target coordinates
@@ -312,9 +313,6 @@ void RenderablePlaneProjection::setTarget(std::string body) {
return;
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine().scene()->allSceneGraphNodes();
Renderable* possibleTarget;
bool hasBody, found = false;
std::string targetBody;
_target.body = body;
_target.frame = openspace::SpiceManager::ref().frameFromBody(body);
@@ -325,15 +323,11 @@ std::string RenderablePlaneProjection::findClosestTarget(double currentTime) {
std::vector<std::string> targets;
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine().scene()->allSceneGraphNodes();
Renderable* possibleTarget;
std::string targetBody;
bool hasBody, found = false;
PowerScaledScalar min = PowerScaledScalar::CreatePSS(REALLY_FAR);
PowerScaledScalar distance = PowerScaledScalar::CreatePSS(0.0);
return targetBody;
}

View File

@@ -137,7 +137,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"RenderablePlanetProject"
"RenderablePlanetProjection"
);
std::string name;

View File

@@ -82,7 +82,12 @@ HongKangParser::HongKangParser(std::string name, std::string fileName,
void HongKangParser::findPlaybookSpecifiedTarget(std::string line, std::string& target) {
//remembto add this lua later...
std::transform(line.begin(), line.end(), line.begin(), toupper);
std::transform(
line.begin(),
line.end(),
line.begin(),
[](char v) { return static_cast<char>(toupper(v)); }
);
std::vector<std::string> ptarg = _potentialTargets;
for (const auto& p : ptarg) {
// loop over all targets and determine from 4th col which target this instrument points to
@@ -313,6 +318,7 @@ double HongKangParser::getETfromMet(double met) {
} else if (met < _metRef) {
return referenceET - diff;
}
return 0.0;
}
double HongKangParser::getMetFromET(double et) {
@@ -321,7 +327,7 @@ double HongKangParser::getMetFromET(double et) {
if (et >= referenceET) {
return _metRef + (et - referenceET);
}else {
} else {
return _metRef - (referenceET - et);
}
}

View File

@@ -52,6 +52,7 @@ struct ImageSubset {
class SequenceParser {
public:
virtual ~SequenceParser() = default;
virtual bool create() = 0;
virtual std::map<std::string, ImageSubset> getSubsetMap() final;
virtual std::vector<std::pair<std::string, TimeRange>> getInstrumentTimes() final;

View File

@@ -206,29 +206,44 @@ function generateScene(arg)
if scene == nil then
return ""
else
local offset = ""
local offset = nil
if scene["offset"] then
local o = scene["offset"]
offset = [[<Offset x="]]..o["x"]..[[" y="]]..o["y"]..[[" z="]]..o["z"]..[[" />]]
end
local orientation = ""
local orientation = nil
if scene["orientation"] then
local o = scene["orientation"]
orientation = [[<Orientation yaw="]]..o["yaw"]..[[" pitch="]]..o["pitch"]..[[" roll="]]..o["roll"]..[[" />]]
end
local scale = ""
local scale = nil
if scene["scale"] then
scale = [[<Scale value="]] .. scene["scale"] .. [[" />]]
end
return [[
<Scene>
]]..offset..[[
]]..orientation..[[
]]..scale..[[
</Scale]]
local sceneString = " <Scene>"
if offset then
sceneString = sceneString .. "\n " .. offset .. "\n"
end
if orientation then
sceneString = sceneString .. "\n " .. orientation .. "\n"
end
if scale then
sceneString = sceneString .. "\n " .. scale .. "\n"
end
sceneString = sceneString .. " </Scene>\n"
return sceneString
-- return [[
-- <Scene>
-- ]]..offset..[[
-- ]]..orientation..[[
-- ]]..scale..[[
-- </Scene>]]
end
end

View File

@@ -124,7 +124,8 @@ set(OPENSPACE_SOURCE
${OPENSPACE_BASE_DIR}/src/scene/scene.cpp
${OPENSPACE_BASE_DIR}/src/scene/scene_doc.inl
${OPENSPACE_BASE_DIR}/src/scene/scene_lua.inl
${OPENSPACE_BASE_DIR}/src/scene/scenegraph.cpp
${OPENSPACE_BASE_DIR}/src/scene/sceneloader.cpp
${OPENSPACE_BASE_DIR}/src/scene/scenemanager.cpp
${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode.cpp
${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode_doc.inl
${OPENSPACE_BASE_DIR}/src/scripting/lualibrary.cpp
@@ -267,7 +268,8 @@ set(OPENSPACE_HEADER
${OPENSPACE_BASE_DIR}/include/openspace/scene/rotation.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/scale.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/scene.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraph.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/sceneloader.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenemanager.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraphnode.h
${OPENSPACE_BASE_DIR}/include/openspace/scripting/lualibrary.h
${OPENSPACE_BASE_DIR}/include/openspace/scripting/script_helper.h

View File

@@ -163,10 +163,19 @@ std::shared_ptr<DownloadManager::FileFuture> DownloadManager::downloadFile(
std::shared_ptr<FileFuture> future = std::make_shared<FileFuture>(file.filename());
errno = 0;
#ifdef WIN32
FILE* fp;
errno_t error = fopen_s(&fp, file.path().c_str(), "wb");
ghoul_assert(
error == 0,
"Could not open/create file:" + file.path() + ". Errno: " + std::to_string(errno)
);
#else
FILE* fp = fopen(file.path().c_str(), "wb"); // write binary
#endif // WIN32
ghoul_assert(
fp != nullptr,
"Could not open/create file:\n" + file.path() + " \nerrno: " + std::to_string(errno)
"Could not open/create file:" + file.path() + ". Errno: " + std::to_string(errno)
);
//LDEBUG("Start downloading file: '" << url << "' into file '" << file.path() << "'");

View File

@@ -40,10 +40,14 @@
#include <openspace/network/networkengine.h>
#include <openspace/rendering/renderable.h>
#include <openspace/scripting/scriptscheduler.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/rotation.h>
#include <openspace/scene/scale.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/translation.h>
#include <openspace/scene/scenemanager.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/task.h>
#include <openspace/util/openspacemodule.h>
@@ -53,6 +57,7 @@
#include <openspace/util/transformationmanager.h>
#include <ghoul/ghoul.h>
#include <ghoul/misc/onscopeexit.h>
#include <ghoul/cmdparser/commandlineparser.h>
#include <ghoul/cmdparser/singlecommand.h>
#include <ghoul/filesystem/filesystem.h>
@@ -103,14 +108,18 @@ namespace openspace {
namespace properties {
class Property;
}
class Scene;
OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr;
OpenSpaceEngine::OpenSpaceEngine(std::string programName,
std::unique_ptr<WindowWrapper> windowWrapper)
OpenSpaceEngine::OpenSpaceEngine(
std::string programName,
std::unique_ptr<WindowWrapper> windowWrapper)
: _configurationManager(new ConfigurationManager)
, _interactionHandler(new interaction::InteractionHandler)
, _renderEngine(new RenderEngine)
, _sceneManager(new SceneManager)
, _scriptEngine(new scripting::ScriptEngine)
, _scriptScheduler(new scripting::ScriptScheduler)
, _networkEngine(new NetworkEngine)
@@ -126,6 +135,8 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
, _parallelConnection(new ParallelConnection)
, _windowWrapper(std::move(windowWrapper))
, _globalPropertyNamespace(new properties::PropertyOwner(""))
, _scheduledSceneSwitch(false)
, _scenePath("")
, _runTime(0.0)
, _shutdown({false, 0.f, 0.f})
, _isFirstRenderingFirstFrame(true)
@@ -165,22 +176,6 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
TransformationManager::initialize();
}
//OpenSpaceEngine::~OpenSpaceEngine() {
// _globalPropertyNamespace = nullptr;
// _windowWrapper = nullptr;
// _parallelConnection = nullptr;
// _configurationManager = nullptr;
// _interactionHandler = nullptr;
// _renderEngine = nullptr;
// _scriptEngine = nullptr;
// _networkEngine = nullptr;
// _syncEngine = nullptr;
// _commandlineParser = nullptr;
// _console = nullptr;
// _moduleEngine = nullptr;
// _settingsEngine = nullptr;
//}
OpenSpaceEngine& OpenSpaceEngine::ref() {
ghoul_assert(_engine, "OpenSpaceEngine not created");
return *_engine;
@@ -194,7 +189,7 @@ void OpenSpaceEngine::create(int argc, char** argv,
ghoul_assert(windowWrapper != nullptr, "No Window Wrapper was provided");
requestClose = false;
ghoul::initialize();
// Initialize the LogManager and add the console log as this will be used every time
@@ -315,7 +310,7 @@ void OpenSpaceEngine::create(int argc, char** argv,
// Initialize the requested logs from the configuration file
_engine->configureLogging();
LINFOC("OpenSpace Version",
LINFOC("OpenSpace Version",
OPENSPACE_VERSION_MAJOR << "." <<
OPENSPACE_VERSION_MINOR << "." <<
OPENSPACE_VERSION_PATCH <<
@@ -381,15 +376,22 @@ void OpenSpaceEngine::destroy() {
func();
}
_engine->_syncEngine->removeSyncables(Time::ref().getSyncables());
_engine->_syncEngine->removeSyncables(_engine->_renderEngine->getSyncables());
_engine->_syncEngine->removeSyncable(_engine->_scriptEngine.get());
_engine->_moduleEngine->deinitialize();
_engine->_console->deinitialize();
_engine->_scriptEngine->deinitialize();
_engine->_sceneManager->unloadAll();
delete _engine;
FactoryManager::deinitialize();
Time::deinitialize();
SpiceManager::deinitialize();
ghoul::fontrendering::FontRenderer::deinitialize();
LogManager::deinitialize();
@@ -497,35 +499,132 @@ void OpenSpaceEngine::initialize() {
// Load a light and a monospaced font
loadFonts();
// Initialize the Scene
// @CLEANUP: This should become a unique_ptr that is either created inside the
// renderengine or moved into it ---abock
Scene* sceneGraph = new Scene;
sceneGraph->initialize();
std::string scenePath = "";
configurationManager().getValue(ConfigurationManager::KeyConfigScene, scenePath);
sceneGraph->scheduleLoadSceneFile(scenePath);
// Initialize the RenderEngine
_renderEngine->setSceneGraph(sceneGraph);
_renderEngine->initialize();
_renderEngine->setGlobalBlackOutFactor(0.0);
_renderEngine->startFading(1, 3.0);
for (const auto& func : _moduleCallbacks.initialize) {
func();
}
scheduleLoadScene(scenePath);
LTRACE("OpenSpaceEngine::initialize(end)");
}
void OpenSpaceEngine::scheduleLoadScene(std::string scenePath) {
_scheduledSceneSwitch = true;
_scenePath = std::move(scenePath);
}
void OpenSpaceEngine::loadScene(const std::string& scenePath) {
LTRACE("OpenSpaceEngine::loadScene(begin)");
windowWrapper().setBarrier(false);
windowWrapper().setSynchronization(false);
OnExit(
[this]() {
windowWrapper().setSynchronization(true);
windowWrapper().setBarrier(true);
}
);
// Run start up scripts
runPreInitializationScripts(scenePath);
try {
runPreInitializationScripts(scenePath);
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
}
Scene* scene;
try {
scene = _sceneManager->loadScene(scenePath);
} catch (const ghoul::FileNotFoundError& e) {
LERRORC(e.component, e.message);
return;
} catch (const Scene::InvalidSceneError& e) {
LERRORC(e.component, e.message);
return;
} catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
return;
}
Scene* previousScene = _renderEngine->scene();
if (previousScene) {
_syncEngine->removeSyncables(Time::ref().getSyncables());
_syncEngine->removeSyncables(_renderEngine->getSyncables());
_syncEngine->removeSyncable(_scriptEngine.get());
_renderEngine->setScene(nullptr);
_renderEngine->setCamera(nullptr);
_sceneManager->unloadScene(*previousScene);
}
// Initialize the RenderEngine
_renderEngine->setScene(scene);
_renderEngine->setCamera(scene->camera());
_renderEngine->setGlobalBlackOutFactor(0.0);
_renderEngine->startFading(1, 3.0);
scene->initialize();
_interactionHandler->setCamera(scene->camera());
try {
runPostInitializationScripts(scenePath);
}
catch (const ghoul::RuntimeError& e) {
LFATALC(e.component, e.message);
}
// Write keyboard documentation.
{
const std::string KeyboardShortcutsType =
ConfigurationManager::KeyKeyboardShortcuts + "." +
ConfigurationManager::PartType;
const std::string KeyboardShortcutsFile =
ConfigurationManager::KeyKeyboardShortcuts + "." +
ConfigurationManager::PartFile;
std::string type, file;
const bool hasType = configurationManager().getValue(KeyboardShortcutsType, type);
const bool hasFile = configurationManager().getValue(KeyboardShortcutsFile, file);
if (hasType && hasFile) {
file = absPath(file);
interactionHandler().writeKeyboardDocumentation(type, file);
}
}
// If a PropertyDocumentationFile was specified, generate it now.
{
const std::string KeyPropertyDocumentationType =
ConfigurationManager::KeyPropertyDocumentation + '.' +
ConfigurationManager::PartType;
const std::string KeyPropertyDocumentationFile =
ConfigurationManager::KeyPropertyDocumentation + '.' +
ConfigurationManager::PartFile;
std::string type, file;
const bool hasType = configurationManager().getValue(KeyPropertyDocumentationType, type);
const bool hasFile = configurationManager().getValue(KeyPropertyDocumentationFile, file);
if (hasType && hasFile) {
file = absPath(file);
scene->writePropertyDocumentation(file, type, scenePath);
}
}
_syncEngine->addSyncables(Time::ref().getSyncables());
_syncEngine->addSyncables(_renderEngine->getSyncables());
_syncEngine->addSyncable(_scriptEngine.get());
LINFO("Finished initializing");
LTRACE("OpenSpaceEngine::initialize(end)");
LTRACE("OpenSpaceEngine::loadScene(end)");
}
void OpenSpaceEngine::deinitialize() {
@@ -830,6 +929,11 @@ void OpenSpaceEngine::preSynchronization() {
LTRACE("OpenSpaceEngine::preSynchronization(begin)");
FileSys.triggerFilesystemEvents();
if (_scheduledSceneSwitch) {
loadScene(_scenePath);
_scheduledSceneSwitch = false;
}
if (_isFirstRenderingFirstFrame) {
_windowWrapper->setSynchronization(false);
}
@@ -850,7 +954,7 @@ void OpenSpaceEngine::preSynchronization() {
_interactionHandler->updateInputStates(dt);
_renderEngine->updateSceneGraph();
_renderEngine->updateScene();
_interactionHandler->updateCamera(dt);
@@ -880,7 +984,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() {
_shutdown.timer -= static_cast<float>(_windowWrapper->averageDeltaTime());
}
_renderEngine->updateSceneGraph();
_renderEngine->updateScene();
_renderEngine->updateFade();
_renderEngine->updateRenderer();
_renderEngine->updateScreenSpaceRenderables();

View File

@@ -70,8 +70,9 @@ SettingsEngine::SettingsEngine()
void SettingsEngine::initialize() {
// Load all matching files in the Scene
// TODO: match regex with either with new ghoul readFiles or local code
std::string sceneDir = "${SCENE}";
std::vector<std::string> scenes = ghoul::filesystem::Directory(sceneDir).readFiles();
const std::string sceneDir = "${SCENE}";
const std::vector<std::string> scenes = ghoul::filesystem::Directory(sceneDir).readFiles();
for (std::size_t i = 0; i < scenes.size(); ++i) {
std::size_t found = scenes[i].find_last_of("/\\");
_scenes.addOption(static_cast<int>(i), scenes[i].substr(found + 1));
@@ -79,11 +80,11 @@ void SettingsEngine::initialize() {
// Set interaction to change ConfigurationManager and schedule the load
_scenes.onChange(
[this]() {
[this, sceneDir]() {
std::string sceneFile = _scenes.getDescriptionByValue(_scenes);
OsEng.configurationManager().setValue(
ConfigurationManager::KeyConfigScene, sceneFile);
OsEng.renderEngine().scene()->scheduleLoadSceneFile(sceneFile);
OsEng.scheduleLoadScene(sceneDir + "/" + sceneFile);
}
);
}
@@ -106,4 +107,4 @@ bool SettingsEngine::useDoubleBuffering() {
return _useDoubleBuffering.value();
}
} // namespace openspace
} // namespace openspace

View File

@@ -86,4 +86,10 @@ void SyncEngine::removeSyncable(Syncable* syncable) {
);
}
void SyncEngine::removeSyncables(const std::vector<Syncable*>& syncables) {
for (const auto& syncable : syncables) {
removeSyncable(syncable);
}
}
} // namespace openspace

View File

@@ -169,6 +169,7 @@ void InteractionHandler::setFocusNode(SceneGraphNode* node) {
void InteractionHandler::setCamera(Camera* camera) {
_camera = camera;
setFocusNode(_camera->parent());
}
void InteractionHandler::resetCameraDirection() {
@@ -500,6 +501,11 @@ void InteractionHandler::writeKeyboardDocumentation(const std::string& type,
}
}
std::string generationTime;
try {
generationTime = Time::now().ISO8601();
}
catch (...) {}
std::stringstream html;
html << "<!DOCTYPE html>\n"
@@ -514,7 +520,7 @@ void InteractionHandler::writeKeyboardDocumentation(const std::string& type,
<< "\t<script>\n"
<< "var keybindings = JSON.parse('" << jsonString << "');\n"
<< "var version = [" << OPENSPACE_VERSION_MAJOR << ", " << OPENSPACE_VERSION_MINOR << ", " << OPENSPACE_VERSION_PATCH << "];\n"
<< "var generationTime = '" << Time::now().ISO8601() << "';\n"
<< "var generationTime = '" << generationTime << "';\n"
<< jsContent << "\n"
<< "\t</script>\n"
<< "\t<style type=\"text/css\">\n"

View File

@@ -258,7 +258,6 @@ int saveCameraStateToFile(lua_State* L) {
int resetCameraDirection(lua_State* L) {
using ghoul::lua::luaTypeToString;
const std::string _loggerCat = "lua.resetCameraDirection";
int nArguments = lua_gettop(L);
if (nArguments != 0) {

View File

@@ -42,6 +42,13 @@ namespace {
const int NoAutoComplete = -1;
// A high number is chosen since we didn't have a version number before
// any small number might also be equal to the console history length
// @CPP17
//const uint64_t CurrentVersion = 0xFEEE'FEEE'0000'0001;
const uint64_t CurrentVersion = 0xFEEEFEEE00000001;
const openspace::Key CommandInputButton = openspace::Key::GraveAccent;
} // namespace
@@ -71,27 +78,43 @@ void LuaConsole::initialize() {
"",
ghoul::filesystem::CacheManager::Persistent::Yes
);
try {
if (FileSys.fileExists(filename)) {
std::ifstream file;
file.exceptions(std::ofstream::badbit);
file.open(filename, std::ios::binary | std::ios::in);
if (FileSys.fileExists(filename)) {
std::ifstream file;
file.exceptions(std::ofstream::badbit);
file.open(filename, std::ios::binary | std::ios::in);
// Read the number of commands from the history
uint64_t version;
file.read(reinterpret_cast<char*>(&version), sizeof(uint64_t));
// Read the number of commands from the history
int64_t nCommands;
file.read(reinterpret_cast<char*>(&nCommands), sizeof(int64_t));
if (version != CurrentVersion) {
LWARNINGC(
"LuaConsole",
"Outdated console history version: " << version
);
}
else {
int64_t nCommands;
file.read(reinterpret_cast<char*>(&nCommands), sizeof(int64_t));
for (int64_t i = 0; i < nCommands; ++i) {
int64_t length;
file.read(reinterpret_cast<char*>(&length), sizeof(int64_t));
// @TODO: Add an upper limit on the number of commands so that the history
// can't grow without bounds
for (int64_t i = 0; i < nCommands; ++i) {
int64_t length;
file.read(reinterpret_cast<char*>(&length), sizeof(int64_t));
std::vector<char> tmp(length);
file.read(tmp.data(), length);
//tmp[length] = '\0';
_commandsHistory.emplace_back(std::string(tmp.begin(), tmp.end()));
std::vector<char> tmp(length);
file.read(tmp.data(), length);
_commandsHistory.emplace_back(std::string(tmp.begin(), tmp.end()));
}
}
file.close();
}
file.close();
}
catch (std::exception& e) {
LERRORC("LuaConsole", e.what());
}
_commands = _commandsHistory;
@@ -117,6 +140,9 @@ void LuaConsole::deinitialize() {
std::ofstream file(filename);
uint64_t version = CurrentVersion;
file.write(reinterpret_cast<const char*>(&version), sizeof(uint64_t));
int64_t nCommands = _commandsHistory.size();
file.write(reinterpret_cast<const char*>(&nCommands), sizeof(int64_t));
@@ -297,7 +323,7 @@ bool LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction actio
std::transform(
command.begin(), command.end(),
std::back_inserter(commandLowerCase),
::tolower
[](char v) { return static_cast<char>(tolower(v)); }
);
std::string initialValueLowerCase;
@@ -305,7 +331,7 @@ bool LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction actio
_autoCompleteInfo.initialValue.begin(),
_autoCompleteInfo.initialValue.end(),
std::back_inserter(initialValueLowerCase),
::tolower
[](char v) { return static_cast<char>(tolower(v)); }
);
bool correctCommand =

View File

@@ -621,11 +621,23 @@ void ParallelConnection::sendFunc(){
reinterpret_cast<const char*>(&messageSizeOut),
reinterpret_cast<const char*>(&messageSizeOut) + sizeof(uint32_t));
result = send(_clientSocket, header.data(), header.size(), 0);
result = send(_clientSocket, message.content.data(), message.content.size(), 0);
result = send(
_clientSocket,
header.data(),
static_cast<int>(header.size()),
0
);
result = send(
_clientSocket,
message.content.data(),
static_cast<int>(message.content.size()),
0
);
if (result == SOCKET_ERROR) {
LERROR("Failed to send message.\nError: " << _ERRNO << " detected in connection, disconnecting.");
LERROR("Failed to send message.\nError: " <<
_ERRNO << " detected in connection, disconnecting."
);
signalDisconnect();
}
@@ -826,7 +838,12 @@ void ParallelConnection::listenCommunication() {
// receive the payload
messageBuffer.resize(messageSize);
nBytesRead = receiveData(_clientSocket, messageBuffer, messageSize, 0);
nBytesRead = receiveData(
_clientSocket,
messageBuffer,
static_cast<int>(messageSize),
0
);
if (nBytesRead <= 0) {
if (!_disconnect) {
@@ -964,7 +981,7 @@ void ParallelConnection::setNConnections(size_t nConnections) {
}
int ParallelConnection::nConnections() {
return _nConnections;
return static_cast<int>(_nConnections);
}
bool ParallelConnection::isHost() {

View File

@@ -54,6 +54,9 @@ REGISTER_TEMPLATEPROPERTY_SOURCE(BoolProperty, bool, false,
if (success) {
return v;
}
else {
throw ghoul::RuntimeError("Conversion error for string: " + value);
}
},
[](std::string& outValue, bool inValue) -> bool {
outValue = inValue ? "true" : "false";

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -37,10 +37,12 @@ namespace properties {
#define DEFAULT_FROM_LUA_LAMBDA(TYPE, DEFAULT_VALUE) \
[](lua_State* state, bool& success) -> TYPE { \
success = (lua_isnumber(state, -1) == 1); \
if (success) \
if (success) { \
return static_cast<TYPE>(lua_tonumber(state, -1)); \
else \
} \
else { \
return DEFAULT_VALUE; \
} \
}
#define DEFAULT_TO_LUA_LAMBDA(TYPE) \
@@ -55,8 +57,12 @@ namespace properties {
TYPE v; \
s >> v; \
success = !s.fail(); \
if (success) \
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -37,10 +37,12 @@ namespace properties {
#define DEFAULT_FROM_LUA_LAMBDA(TYPE, DEFAULT_VALUE) \
[](lua_State* state, bool& success) -> TYPE { \
success = (lua_isnumber(state, -1) == 1); \
if (success) \
if (success) { \
return static_cast<TYPE>(lua_tonumber(state, -1)); \
else \
} \
else { \
return DEFAULT_VALUE; \
} \
}
#define DEFAULT_TO_LUA_LAMBDA(TYPE) \
@@ -55,8 +57,12 @@ namespace properties {
TYPE v; \
s >> v; \
success = !s.fail(); \
if (success) \
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -60,6 +60,9 @@ namespace properties {
if (success) { \
return v; \
} \
else { \
throw ghoul::RuntimeError("Conversion error for string: " + value); \
} \
}
#define DEFAULT_TO_STRING_LAMBDA(TYPE) \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -40,8 +40,8 @@ namespace properties {
__TYPE__ result; \
lua_pushnil(state); \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
int success = lua_next(state, -2); \
if (success != 1) { \
int hasNext = lua_next(state, -2); \
if (hasNext != 1) { \
success = false; \
return __TYPE__(0); \
} \
@@ -85,8 +85,9 @@ namespace properties {
success = false; \
return result; \
} \
else \
else { \
result[i] = v; \
} \
} \
success = true; \
return result; \
@@ -95,8 +96,9 @@ namespace properties {
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
[](std::string& outValue, __TYPE__ inValue) -> bool { \
outValue = "{"; \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
outValue += std::to_string(inValue[i]) + ","; \
} \
outValue.pop_back(); \
outValue += "}"; \
return true; \

View File

@@ -99,7 +99,8 @@ properties::Property* property(const std::string& uri) {
std::vector<properties::Property*> allProperties() {
std::vector<properties::Property*> properties;
auto p = OsEng.globalPropertyOwner().propertiesRecursive();
std::vector<properties::Property*> p =
OsEng.globalPropertyOwner().propertiesRecursive();
properties.insert(
properties.end(),
@@ -111,7 +112,7 @@ std::vector<properties::Property*> allProperties() {
std::vector<SceneGraphNode*> nodes = graph->allSceneGraphNodes();
for (SceneGraphNode* n : nodes) {
auto p = n->propertiesRecursive();
std::vector<properties::Property*> props = n->propertiesRecursive();
properties.insert(
properties.end(),
p.begin(),

View File

@@ -298,14 +298,14 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
float gamma = 1.0;
glm::vec3 cameraPos = data.camera.position().vec3();
float maxComponent = std::max(std::max(std::abs(cameraPos.x), std::abs(cameraPos.y)), std::abs(cameraPos.z));
float logDistance = std::log(glm::length(cameraPos / maxComponent) * maxComponent) / std::log(10);
float logDistance = std::log(glm::length(cameraPos / maxComponent) * maxComponent) / std::log(10.f);
float minLogDist = 15;
float maxLogDist = 20;
float t = (logDistance - minLogDist) / (maxLogDist - minLogDist);
t = glm::clamp(t, 0.0f, 1.0f);
gamma = 1.0 * (1 - t) + 2.2 * t;
gamma = 1.f * (1.f - t) + 2.2f * t;
_resolveProgram->setUniform("gamma", gamma);
@@ -503,7 +503,7 @@ void ABufferRenderer::updateRaycastData() {
for (auto &raycaster : raycasters) {
if (nextId > MaxRaycasters) {
int nIgnored = MaxRaycasters - raycasters.size();
int nIgnored = MaxRaycasters - static_cast<int>(raycasters.size());
LWARNING("ABufferRenderer does not support more than 32 raycasters. Ignoring " << nIgnored << " raycasters");
break;
}

View File

@@ -37,9 +37,8 @@
#include <openspace/rendering/abufferrenderer.h>
#include <openspace/rendering/framebufferrenderer.h>
#include <openspace/rendering/raycastermanager.h>
#include <openspace/rendering/renderer.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scene/scene.h>
#include <openspace/util/camera.h>
#include <openspace/util/time.h>
#include <openspace/util/screenlog.h>
@@ -93,7 +92,7 @@ namespace openspace {
RenderEngine::RenderEngine()
: properties::PropertyOwner("RenderEngine")
, _mainCamera(nullptr)
, _camera(nullptr)
, _raycasterManager(nullptr)
, _performanceMeasurements("performanceMeasurements", "Performance Measurements")
, _frametimeType(
@@ -101,6 +100,7 @@ RenderEngine::RenderEngine()
"Type of the frametime display",
properties::OptionProperty::DisplayType::Dropdown
)
, _scene(nullptr)
, _showInfo("showInfo", "Show Render Information", true)
, _showLog("showLog", "Show the OnScreen log", true)
, _nAaSamples("nAaSamples", "Number of Antialiasing samples", 8, 1, 16)
@@ -109,7 +109,6 @@ RenderEngine::RenderEngine()
, _showFrameNumber("showFrameNumber", "Show Frame Number", false)
, _disableMasterRendering("disableMasterRendering", "Disable Master Rendering", false)
, _shouldTakeScreenshot(false)
, _sceneGraph(nullptr)
, _renderer(nullptr)
, _rendererImplementation(RendererImplementation::Invalid)
, _performanceManager(nullptr)
@@ -168,12 +167,23 @@ RenderEngine::RenderEngine()
addProperty(_disableMasterRendering);
}
RenderEngine::~RenderEngine() {
delete _sceneGraph;
_sceneGraph = nullptr;
void RenderEngine::setRendererFromString(const std::string& renderingMethod) {
_rendererImplementation = rendererFromString(renderingMethod);
delete _mainCamera;
delete _raycasterManager;
std::unique_ptr<Renderer> newRenderer = nullptr;
switch (_rendererImplementation) {
case RendererImplementation::Framebuffer:
newRenderer = std::make_unique<FramebufferRenderer>();
break;
case RendererImplementation::ABuffer:
newRenderer = std::make_unique<ABufferRenderer>();
break;
case RendererImplementation::Invalid:
LFATAL("Rendering method '" << renderingMethod << "' not among the available "
<< "rendering methods");
}
setRenderer(std::move(newRenderer));
}
void RenderEngine::initialize() {
@@ -201,20 +211,12 @@ void RenderEngine::initialize() {
);
}
_raycasterManager = new RaycasterManager();
_raycasterManager = std::make_unique<RaycasterManager>();
_nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples();
LINFO("Seting renderer from string: " << renderingMethod);
setRendererFromString(renderingMethod);
// init camera and set temporary position and scaling
_mainCamera = new Camera();
OsEng.interactionHandler().setCamera(_mainCamera);
if (_renderer) {
_renderer->setCamera(_mainCamera);
}
#ifdef GHOUL_USE_DEVIL
ghoul::io::TextureReader::ref().addReader(std::make_shared<ghoul::io::TextureReaderDevIL>());
#endif // GHOUL_USE_DEVIL
@@ -253,79 +255,6 @@ void RenderEngine::initializeGL() {
throw;
}
// ALL OF THIS HAS TO BE CHECKED
// ---abock
// sgct::Engine::instance()->setNearAndFarClippingPlanes(0.001f, 1000.0f);
// sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f, 30.0f);
// calculating the maximum field of view for the camera, used to
// determine visibility of objects in the scene graph
/* if (sgct::Engine::instance()->getCurrentRenderTarget() == sgct::Engine::NonLinearBuffer) {
// fisheye mode, looking upwards to the "dome"
glm::vec4 upDirection(0, 1, 0, 0);
// get the tilt and rotate the view
const float tilt = wPtr->getFisheyeTilt();
glm::mat4 tiltMatrix
= glm::rotate(glm::mat4(1.0f), tilt, glm::vec3(1.0f, 0.0f, 0.0f));
const glm::vec4 viewdir = tiltMatrix * upDirection;
// set the tilted view and the FOV
_mainCamera->setCameraDirection(glm::vec3(viewdir[0], viewdir[1], viewdir[2]));
_mainCamera->setMaxFov(wPtr->getFisheyeFOV());
_mainCamera->setLookUpVector(glm::vec3(0.0, 1.0, 0.0));
}
else {*/
// get corner positions, calculating the forth to easily calculate center
// glm::vec3 corners[4];
// sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getWindowPtr(0);
// sgct_core::BaseViewport* vp = wPtr->getViewport(0);
// sgct_core::SGCTProjectionPlane* projectionPlane = vp->getProjectionPlane();
// corners[0] = *(projectionPlane->getCoordinatePtr(sgct_core::SGCTProjectionPlane::LowerLeft));
// corners[1] = *(projectionPlane->getCoordinatePtr(sgct_core::SGCTProjectionPlane::UpperLeft));
// corners[2] = *(projectionPlane->getCoordinatePtr(sgct_core::SGCTProjectionPlane::UpperRight));
// corners[3] = glm::vec3(corners[2][0], corners[0][1], corners[2][2]);
//
// const glm::vec3 center = (corners[0] + corners[1] + corners[2] + corners[3]);
////
//const glm::vec3 eyePosition = sgct_core::ClusterManager::instance()->getDefaultUserPtr()->getPos();
////// get viewdirection, stores the direction in the camera, used for culling
//const glm::vec3 viewdir = glm::normalize(eyePosition - center);
//const glm::vec3 upVector = corners[0] - corners[1];
//_mainCamera->setCameraDirection(glm::normalize(-viewdir));
//_mainCamera->setCameraDirection(glm::vec3(0.f, 0.f, -1.f));
//_mainCamera->setLookUpVector(glm::normalize(upVector));
//_mainCamera->setLookUpVector(glm::vec3(0.f, 1.f, 0.f));
// set the initial fov to be 0.0 which means everything will be culled
//float maxFov = 0.0f;
float maxFov = std::numeric_limits<float>::max();
//// for each corner
//for (int i = 0; i < 4; ++i) {
// // calculate radians to corner
// glm::vec3 dir = glm::normalize(eyePosition - corners[i]);
// float radsbetween = acos(glm::dot(viewdir, dir))
// / (glm::length(viewdir) * glm::length(dir));
// // the angle to a corner is larger than the current maxima
// if (radsbetween > maxFov) {
// maxFov = radsbetween;
// }
//}
_mainCamera->setMaxFov(maxFov);
//}
LINFO("Initializing Log");
std::unique_ptr<ScreenLog> log = std::make_unique<ScreenLog>(ScreenLogTimeToLive);
_log = log.get();
@@ -340,32 +269,10 @@ void RenderEngine::deinitialize() {
}
MissionManager::deinitialize();
_sceneGraph->clearSceneGraph();
}
void RenderEngine::setRendererFromString(const std::string& renderingMethod) {
_rendererImplementation = rendererFromString(renderingMethod);
std::unique_ptr<Renderer> newRenderer = nullptr;
switch (_rendererImplementation) {
case RendererImplementation::Framebuffer:
newRenderer = std::make_unique<FramebufferRenderer>();
break;
case RendererImplementation::ABuffer:
newRenderer = std::make_unique<ABufferRenderer>();
break;
case RendererImplementation::Invalid:
LFATAL("Rendering method '" << renderingMethod << "' not among the available "
<< "rendering methods");
}
setRenderer(std::move(newRenderer));
}
void RenderEngine::updateSceneGraph() {
LTRACE("RenderEngine::updateSceneGraph(begin)");
_sceneGraph->update({
void RenderEngine::updateScene() {
_scene->update({
glm::dvec3(0),
glm::dmat3(1),
1,
@@ -376,13 +283,7 @@ void RenderEngine::updateSceneGraph() {
_performanceManager != nullptr
});
_sceneGraph->evaluate(_mainCamera);
//Allow focus node to update camera (enables camera-following)
//FIX LATER: THIS CAUSES MASTER NODE TO BE ONE FRAME AHEAD OF SLAVES
//if (const SceneGraphNode* node = OsEng.ref().interactionHandler().focusNode()){
//node->updateCamera(_mainCamera);
//}
_scene->evaluate(_camera);
LTRACE("RenderEngine::updateSceneGraph(end)");
}
@@ -468,8 +369,7 @@ void RenderEngine::updateFade() {
0.f,
_currentFadeTime / _fadeDuration
);
}
else {
} else {
_globalBlackOutFactor = glm::smoothstep(
0.f,
1.f,
@@ -483,11 +383,12 @@ void RenderEngine::updateFade() {
}
}
void RenderEngine::render(const glm::mat4& viewMatrix, const glm::mat4& projectionMatrix)
{
void RenderEngine::render(const glm::mat4& viewMatrix, const glm::mat4& projectionMatrix) {
LTRACE("RenderEngine::render(begin)");
_mainCamera->sgctInternal.setViewMatrix(viewMatrix);
_mainCamera->sgctInternal.setProjectionMatrix(projectionMatrix);
_camera->sgctInternal.setViewMatrix(viewMatrix);
_camera->sgctInternal.setProjectionMatrix(projectionMatrix);
WindowWrapper& wrapper = OsEng.windowWrapper();
@@ -562,20 +463,29 @@ void RenderEngine::postDraw() {
}
Scene* RenderEngine::scene() {
ghoul_assert(_sceneGraph, "Scenegraph not initialized");
return _sceneGraph;
return _scene;
}
RaycasterManager& RenderEngine::raycasterManager() {
return *_raycasterManager;
}
void RenderEngine::setSceneGraph(Scene* sceneGraph) {
_sceneGraph = sceneGraph;
void RenderEngine::setScene(Scene* scene) {
_scene = scene;
if (_renderer) {
_renderer->setScene(scene);
}
}
void RenderEngine::setCamera(Camera* camera) {
_camera = camera;
if (_renderer) {
_renderer->setCamera(camera);
}
}
Camera* RenderEngine::camera() const {
return _mainCamera;
return _camera;
}
Renderer* RenderEngine::renderer() const {
@@ -735,8 +645,8 @@ void RenderEngine::setRenderer(std::unique_ptr<Renderer> renderer) {
_renderer->setResolution(renderingResolution());
_renderer->setNAaSamples(_nAaSamples);
_renderer->initialize();
_renderer->setCamera(_mainCamera);
_renderer->setScene(_sceneGraph);
_renderer->setCamera(_camera);
_renderer->setScene(_scene);
}
scripting::LuaLibrary RenderEngine::luaLibrary() {
@@ -943,7 +853,7 @@ void RenderEngine::renderInformation() {
const std::string& hostName = OsEng.parallelConnection().hostName();
std::string connectionInfo = "";
int nClients = nConnections;
int nClients = static_cast<int>(nConnections);
if (status == ParallelConnection::Status::Host) {
nClients--;
if (nClients == 1) {
@@ -983,21 +893,12 @@ void RenderEngine::renderInformation() {
#ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED
//<<<<<<< HEAD
bool hasNewHorizons = scene()->sceneGraphNode("NewHorizons");
double currentTime = Time::ref().j2000Seconds();
if (MissionManager::ref().hasCurrentMission()) {
const Mission& mission = MissionManager::ref().currentMission();
//=======
// bool hasNewHorizons = scene()->sceneGraphNode("NewHorizons");
// double currentTime = Time::ref().currentTime();
//>>>>>>> develop
//
// if (MissionManager::ref().hasCurrentMission()) {
//
// const Mission& mission = MissionManager::ref().currentMission();
if (mission.phases().size() > 0) {
static const glm::vec4 nextMissionColor(0.7, 0.3, 0.3, 1);
@@ -1062,7 +963,7 @@ void RenderEngine::renderInformation() {
if (isCurrentPhase || showAllPhases) {
// phases are sorted increasingly by start time, and will be popped
// last-in-first-out from the stack, so add them in reversed order.
int indexLastPhase = phase->phases().size() - 1;
int indexLastPhase = static_cast<int>(phase->phases().size()) - 1;
for (int i = indexLastPhase; 0 <= i; --i) {
S.push({ &phase->phases()[i], depth + 1 });
}
@@ -1084,11 +985,11 @@ void RenderEngine::renderInformation() {
glm::dvec3 p =
SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", {}, currentTime, lt);
psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z);
float a, b, c;
float a, b;
glm::dvec3 radii;
SpiceManager::ref().getValue("PLUTO", "RADII", radii);
a = radii.x;
b = radii.y;
a = static_cast<float>(radii.x);
b = static_cast<float>(radii.y);
float radius = (a + b) / 2.f;
float distToSurf = glm::length(nhPos.vec3()) - radius;
@@ -1353,7 +1254,11 @@ void RenderEngine::renderScreenLog() {
}
std::vector<Syncable*> RenderEngine::getSyncables(){
return _mainCamera->getSyncables();
if (_camera) {
return _camera->getSyncables();
} else {
return std::vector<Syncable*>();
}
}
void RenderEngine::sortScreenspaceRenderables() {

View File

@@ -110,9 +110,9 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary
, _sphericalPosition(
"sphericalPosition",
"Spherical coordinates",
glm::vec2(0.f, M_PI_2),
glm::vec2(-M_PI),
glm::vec2(M_PI)
glm::vec2(0.f, static_cast<float>(M_PI_2)),
glm::vec2(-static_cast<float>(M_PI)),
glm::vec2(static_cast<float>(M_PI))
)
, _depth("depth", "Depth", 0.f, 0.f, 1.f)
, _scale("scale", "Scale", 0.25f, 0.f, 2.f)
@@ -241,7 +241,7 @@ glm::vec2 ScreenSpaceRenderable::toEuclidean(const glm::vec2& spherical, float r
glm::vec2 ScreenSpaceRenderable::toSpherical(const glm::vec2& euclidean) {
_radius = -sqrt(pow(euclidean[0],2)+pow(euclidean[1],2)+pow(PlaneDepth,2));
float theta = atan2(-PlaneDepth,euclidean[0])-M_PI/2.0;
float theta = atan2(-PlaneDepth, euclidean[0]) - static_cast<float>(M_PI_2);
float phi = acos(euclidean[1]/_radius);
return glm::vec2(theta, phi);

View File

@@ -32,6 +32,7 @@
#include <openspace/query/query.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scene/sceneloader.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scripting/script_helper.h>
#include <openspace/util/time.h>
@@ -54,6 +55,8 @@
#include <numeric>
#include <fstream>
#include <string>
#include <stack>
#include <unordered_map>
#include "scene_doc.inl"
#include "scene_lua.inl"
@@ -79,69 +82,141 @@ namespace {
namespace openspace {
Scene::Scene()
: _focus(SceneGraphNode::RootNodeName)
{}
Scene::Scene() {}
Scene::~Scene() {
deinitialize();
Scene::~Scene() {}
void Scene::setRoot(std::unique_ptr<SceneGraphNode> root) {
if (_root) {
removeNode(_root.get());
}
_root = std::move(root);
_root->setScene(this);
addNode(_root.get());
}
bool Scene::initialize() {
LDEBUG("Initializing SceneGraph");
return true;
void Scene::setCamera(std::unique_ptr<Camera> camera) {
_camera = std::move(camera);
}
bool Scene::deinitialize() {
clearSceneGraph();
return true;
Camera* Scene::camera() const {
return _camera.get();
}
void Scene::update(const UpdateData& data) {
if (!_sceneGraphToLoad.empty()) {
OsEng.renderEngine().scene()->clearSceneGraph();
try {
loadSceneInternal(_sceneGraphToLoad);
void Scene::addNode(SceneGraphNode* node, UpdateDependencies updateDeps) {
// Add the node and all its children.
node->traversePreOrder([this](SceneGraphNode* n) {
_topologicallySortedNodes.push_back(n);
_nodesByName[n->name()] = n;
});
if (updateDeps) {
updateDependencies();
}
}
// Reset the InteractionManager to Orbital/default mode
// TODO: Decide if it belongs in the scene and/or how it gets reloaded
//OsEng.interactionHandler().setInteractionMode("Orbital");
void Scene::removeNode(SceneGraphNode* node, UpdateDependencies updateDeps) {
// Remove the node and all its children.
node->traversePostOrder([this](SceneGraphNode* node) {
_topologicallySortedNodes.erase(
std::remove(_topologicallySortedNodes.begin(), _topologicallySortedNodes.end(), node),
_topologicallySortedNodes.end()
);
_nodesByName.erase(node->name());
});
if (updateDeps) {
updateDependencies();
}
}
// After loading the scene, the keyboard bindings have been set
const std::string KeyboardShortcutsType =
ConfigurationManager::KeyKeyboardShortcuts + "." +
ConfigurationManager::PartType;
void Scene::updateDependencies() {
sortTopologically();
}
const std::string KeyboardShortcutsFile =
ConfigurationManager::KeyKeyboardShortcuts + "." +
ConfigurationManager::PartFile;
void Scene::sortTopologically() {
_topologicallySortedNodes.insert(
_topologicallySortedNodes.end(),
std::make_move_iterator(_circularNodes.begin()),
std::make_move_iterator(_circularNodes.end())
);
_circularNodes.clear();
ghoul_assert(_topologicallySortedNodes.size() == _nodesByName.size(), "Number of scene graph nodes is inconsistent");
if (_topologicallySortedNodes.empty())
return;
std::string type;
std::string file;
bool hasType = OsEng.configurationManager().getValue(
KeyboardShortcutsType, type
);
bool hasFile = OsEng.configurationManager().getValue(
KeyboardShortcutsFile, file
);
if (hasType && hasFile) {
OsEng.interactionHandler().writeKeyboardDocumentation(type, file);
}
LINFO("Loaded " << _sceneGraphToLoad);
_sceneGraphToLoad = "";
}
catch (const ghoul::RuntimeError& e) {
LERROR(e.what());
_sceneGraphToLoad = "";
return;
// Only the Root node can have an in-degree of 0
SceneGraphNode* root = _nodesByName[SceneGraphNode::RootNodeName];
if (!root) {
throw Scene::InvalidSceneError("No root node found");
}
std::unordered_map<SceneGraphNode*, size_t> inDegrees;
for (SceneGraphNode* node : _topologicallySortedNodes) {
size_t inDegree = node->dependencies().size();
if (node->parent() != nullptr) {
inDegree++;
inDegrees[node] = inDegree;
}
}
for (SceneGraphNode* node : _graph.nodes()) {
std::stack<SceneGraphNode*> zeroInDegreeNodes;
zeroInDegreeNodes.push(root);
std::vector<SceneGraphNode*> nodes;
nodes.reserve(_topologicallySortedNodes.size());
while (!zeroInDegreeNodes.empty()) {
SceneGraphNode* node = zeroInDegreeNodes.top();
nodes.push_back(node);
zeroInDegreeNodes.pop();
for (SceneGraphNode* n : node->dependentNodes()) {
auto it = inDegrees.find(n);
it->second -= 1;
if (it->second == 0) {
zeroInDegreeNodes.push(n);
inDegrees.erase(it);
}
}
for (SceneGraphNode* n : node->children()) {
auto it = inDegrees.find(n);
it->second -= 1;
if (it->second == 0) {
zeroInDegreeNodes.push(n);
inDegrees.erase(it);
}
}
}
if (inDegrees.size() > 0) {
LERROR("The scene contains circular dependencies. " << inDegrees.size() << " nodes will be disabled.");
}
for (auto it : inDegrees) {
_circularNodes.push_back(it.first);
}
_topologicallySortedNodes = nodes;
}
void Scene::initialize() {
for (SceneGraphNode* node : _topologicallySortedNodes) {
try {
bool success = node->initialize();
if (success)
LDEBUG(node->name() << " initialized successfully!");
else
LWARNING(node->name() << " not initialized.");
}
catch (const ghoul::RuntimeError& e) {
LERRORC(std::string(_loggerCat) + "(" + e.component + ")", e.what());
}
}
}
void Scene::update(const UpdateData& data) {
for (SceneGraphNode* node : _topologicallySortedNodes) {
try {
LTRACE("Scene::update(begin '" + node->name() + "')");
node->update(data);
@@ -154,299 +229,54 @@ void Scene::update(const UpdateData& data) {
}
void Scene::evaluate(Camera* camera) {
for (SceneGraphNode* node : _graph.nodes())
node->evaluate(camera);
//_root->evaluate(camera);
for (SceneGraphNode* node : _topologicallySortedNodes) {
try {
LTRACE("Scene::evaluate(begin '" + node->name() + "')");
node->evaluate(camera);
LTRACE("Scene::evaluate(end '" + node->name() + "')");
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.what());
}
}
}
void Scene::render(const RenderData& data, RendererTasks& tasks) {
for (SceneGraphNode* node : _graph.nodes()) {
LTRACE("Scene::render(begin '" + node->name() + "')");
node->render(data, tasks);
LTRACE("Scene::render(end '" + node->name() + "')");
for (SceneGraphNode* node : _topologicallySortedNodes) {
try {
LTRACE("Scene::render(begin '" + node->name() + "')");
node->render(data, tasks);
LTRACE("Scene::render(end '" + node->name() + "')");
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.what());
}
}
}
void Scene::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath) {
_sceneGraphToLoad = sceneDescriptionFilePath;
}
void Scene::clearSceneGraph() {
void Scene::clear() {
LINFO("Clearing current scene graph");
// deallocate the scene graph. Recursive deallocation will occur
_graph.clear();
//if (_root) {
// _root->deinitialize();
// delete _root;
// _root = nullptr;
//}
// _nodes.erase(_nodes.begin(), _nodes.end());
// _allNodes.erase(_allNodes.begin(), _allNodes.end());
_focus.clear();
_root = nullptr;
}
bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
ghoul::Dictionary dictionary;
OsEng.windowWrapper().setSynchronization(false);
OnExit(
[](){ OsEng.windowWrapper().setSynchronization(true); }
);
lua_State* state = ghoul::lua::createNewLuaState();
OnExit(
// Delete the Lua state at the end of the scope, no matter what
[state](){ ghoul::lua::destroyLuaState(state); }
);
OsEng.scriptEngine().initializeLuaState(state);
ghoul::lua::loadDictionaryFromFile(
sceneDescriptionFilePath,
dictionary,
state
);
// Perform testing against the documentation/specification
openspace::documentation::testSpecificationAndThrow(
Scene::Documentation(),
dictionary,
"Scene"
);
_graph.loadFromFile(sceneDescriptionFilePath);
// Initialize all nodes
for (SceneGraphNode* node : _graph.nodes()) {
try {
bool success = node->initialize();
if (success)
LDEBUG(node->name() << " initialized successfully!");
else
LWARNING(node->name() << " not initialized.");
}
catch (const ghoul::RuntimeError& e) {
LERRORC(std::string(_loggerCat) + "(" + e.component + ")", e.what());
}
}
// update the position of all nodes
// TODO need to check this; unnecessary? (ab)
for (SceneGraphNode* node : _graph.nodes()) {
try {
node->update({
glm::dvec3(0),
glm::dmat3(1),
1,
Time::ref().j2000Seconds() });
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
}
}
for (auto it = _graph.nodes().rbegin(); it != _graph.nodes().rend(); ++it)
(*it)->calculateBoundingSphere();
// Read the camera dictionary and set the camera state
ghoul::Dictionary cameraDictionary;
if (dictionary.getValue(KeyCamera, cameraDictionary)) {
OsEng.interactionHandler().setCameraStateFromDictionary(cameraDictionary);
}
// If a PropertyDocumentationFile was specified, generate it now
const std::string KeyPropertyDocumentationType =
ConfigurationManager::KeyPropertyDocumentation + '.' +
ConfigurationManager::PartType;
const std::string KeyPropertyDocumentationFile =
ConfigurationManager::KeyPropertyDocumentation + '.' +
ConfigurationManager::PartFile;
const bool hasType = OsEng.configurationManager().hasKey(KeyPropertyDocumentationType);
const bool hasFile = OsEng.configurationManager().hasKey(KeyPropertyDocumentationFile);
if (hasType && hasFile) {
std::string propertyDocumentationType;
OsEng.configurationManager().getValue(KeyPropertyDocumentationType, propertyDocumentationType);
std::string propertyDocumentationFile;
OsEng.configurationManager().getValue(KeyPropertyDocumentationFile, propertyDocumentationFile);
propertyDocumentationFile = absPath(propertyDocumentationFile);
writePropertyDocumentation(propertyDocumentationFile, propertyDocumentationType, sceneDescriptionFilePath);
}
OsEng.runPostInitializationScripts(sceneDescriptionFilePath);
OsEng.enableBarrier();
return true;
const std::map<std::string, SceneGraphNode*>& Scene::nodesByName() const {
return _nodesByName;
}
//void Scene::loadModules(
// const std::string& directory,
// const ghoul::Dictionary& dictionary)
//{
// // Struct containing dependencies and nodes
// LoadMaps m;
//
// // Get the common directory
// std::string commonDirectory(_defaultCommonDirectory);
// dictionary.getValue(constants::scenegraph::keyCommonFolder, commonDirectory);
// FileSys.registerPathToken(_commonModuleToken, commonDirectory);
//
// lua_State* state = ghoul::lua::createNewLuaState();
// OsEng.scriptEngine()->initializeLuaState(state);
//
// LDEBUG("Loading common module folder '" << commonDirectory << "'");
// // Load common modules into LoadMaps struct
// loadModule(m, FileSys.pathByAppendingComponent(directory, commonDirectory), state);
//
// // Load the rest of the modules into LoadMaps struct
// ghoul::Dictionary moduleDictionary;
// if (dictionary.getValue(constants::scenegraph::keyModules, moduleDictionary)) {
// std::vector<std::string> keys = moduleDictionary.keys();
// std::sort(keys.begin(), keys.end());
// for (const std::string& key : keys) {
// std::string moduleFolder;
// if (moduleDictionary.getValue(key, moduleFolder)) {
// loadModule(m, FileSys.pathByAppendingComponent(directory, moduleFolder), state);
// }
// }
// }
//
// // Load and construct scenegraphnodes from LoadMaps struct
// loadNodes(SceneGraphNode::RootNodeName, m);
//
// // Remove loaded nodes from dependency list
// for(const auto& name: m.loadedNodes) {
// m.dependencies.erase(name);
// }
//
// // Check to see what dependencies are not resolved.
// for(auto& node: m.dependencies) {
// LWARNING(
// "'" << node.second << "'' not loaded, parent '"
// << node.first << "' not defined!");
// }
//}
//void Scene::loadModule(LoadMaps& m,const std::string& modulePath, lua_State* state) {
// auto pos = modulePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator);
// if (pos == modulePath.npos) {
// LERROR("Bad format for module path: " << modulePath);
// return;
// }
//
// std::string fullModule = modulePath + modulePath.substr(pos) + _moduleExtension;
// LDEBUG("Loading nodes from: " << fullModule);
//
// ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
// FileSys.setCurrentDirectory(modulePath);
//
// ghoul::Dictionary moduleDictionary;
// ghoul::lua::loadDictionaryFromFile(fullModule, moduleDictionary, state);
// std::vector<std::string> keys = moduleDictionary.keys();
// for (const std::string& key : keys) {
// if (!moduleDictionary.hasValue<ghoul::Dictionary>(key)) {
// LERROR("SceneGraphElement '" << key << "' is not a table in module '"
// << fullModule << "'");
// continue;
// }
//
// ghoul::Dictionary element;
// std::string nodeName;
// std::string parentName;
//
// moduleDictionary.getValue(key, element);
// element.setValue(constants::scenegraph::keyPathModule, modulePath);
//
// element.getValue(constants::scenegraphnode::keyName, nodeName);
// element.getValue(constants::scenegraphnode::keyParentName, parentName);
//
// m.nodes[nodeName] = element;
// m.dependencies.emplace(parentName,nodeName);
// }
//
// FileSys.setCurrentDirectory(oldDirectory);
//}
//void Scene::loadNodes(const std::string& parentName, LoadMaps& m) {
// auto eqRange = m.dependencies.equal_range(parentName);
// for (auto it = eqRange.first; it != eqRange.second; ++it) {
// auto node = m.nodes.find((*it).second);
// loadNode(node->second);
// loadNodes((*it).second, m);
// }
// m.loadedNodes.emplace_back(parentName);
//}
//
//void Scene::loadNode(const ghoul::Dictionary& dictionary) {
// SceneGraphNode* node = SceneGraphNode::createFromDictionary(dictionary);
// if(node) {
// _allNodes.emplace(node->name(), node);
// _nodes.push_back(node);
// }
//}
//void SceneGraph::loadModule(const std::string& modulePath) {
// auto pos = modulePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator);
// if (pos == modulePath.npos) {
// LERROR("Bad format for module path: " << modulePath);
// return;
// }
//
// std::string fullModule = modulePath + modulePath.substr(pos) + _moduleExtension;
// LDEBUG("Loading modules from: " << fullModule);
//
// ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
// FileSys.setCurrentDirectory(modulePath);
//
// ghoul::Dictionary moduleDictionary;
// ghoul::lua::loadDictionaryFromFile(fullModule, moduleDictionary);
// std::vector<std::string> keys = moduleDictionary.keys();
// for (const std::string& key : keys) {
// if (!moduleDictionary.hasValue<ghoul::Dictionary>(key)) {
// LERROR("SceneGraphElement '" << key << "' is not a table in module '"
// << fullModule << "'");
// continue;
// }
//
// ghoul::Dictionary element;
// moduleDictionary.getValue(key, element);
//
// element.setValue(constants::scenegraph::keyPathModule, modulePath);
//
// //each element in this new dictionary becomes a scenegraph node.
// SceneGraphNode* node = SceneGraphNode::createFromDictionary(element);
//
// _allNodes.emplace(node->name(), node);
// _nodes.push_back(node);
// }
//
// FileSys.setCurrentDirectory(oldDirectory);
//
// // Print the tree
// //printTree(_root);
//}
SceneGraphNode* Scene::root() const {
return _graph.rootNode();
return _root.get();
}
SceneGraphNode* Scene::sceneGraphNode(const std::string& name) const {
return _graph.sceneGraphNode(name);
auto it = _nodesByName.find(name);
if (it != _nodesByName.end()) {
return it->second;
}
return nullptr;
}
std::vector<SceneGraphNode*> Scene::allSceneGraphNodes() const {
return _graph.nodes();
}
SceneGraph& Scene::sceneGraph() {
return _graph;
const std::vector<SceneGraphNode*>& Scene::allSceneGraphNodes() const {
return _topologicallySortedNodes;
}
void Scene::writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename) {
@@ -457,7 +287,7 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
file.open(filename);
using properties::Property;
for (SceneGraphNode* node : _graph.nodes()) {
for (SceneGraphNode* node : allSceneGraphNodes()) {
std::vector<Property*> properties = node->propertiesRecursive();
if (!properties.empty()) {
file << node->name() << std::endl;
@@ -547,7 +377,7 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
std::stringstream json;
json << "[";
std::vector<SceneGraphNode*> nodes = _graph.nodes();
std::vector<SceneGraphNode*> nodes = allSceneGraphNodes();
if (!nodes.empty()) {
json << std::accumulate(
std::next(nodes.begin()),
@@ -570,6 +400,12 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
}
}
std::string generationTime;
try {
generationTime = Time::now().ISO8601();
}
catch (...) {}
std::stringstream html;
html << "<!DOCTYPE html>\n"
<< "<html>\n"
@@ -587,7 +423,7 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
<< "var propertyOwners = JSON.parse('" << jsonString << "');\n"
<< "var version = [" << OPENSPACE_VERSION_MAJOR << ", " << OPENSPACE_VERSION_MINOR << ", " << OPENSPACE_VERSION_PATCH << "];\n"
<< "var sceneFilename = '" << sceneFilename << "';\n"
<< "var generationTime = '" << Time::now().ISO8601() << "';\n"
<< "var generationTime = '" << generationTime << "';\n"
<< jsContent << "\n"
<< "\t</script>\n"
<< "\t<style type=\"text/css\">\n"
@@ -598,45 +434,6 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
<< "\t<body>\n"
<< "\t<body>\n"
<< "</html>\n";
/*
html << "<html>\n"
<< "\t<head>\n"
<< "\t\t<title>Properties</title>\n"
<< "\t</head>\n"
<< "<body>\n"
<< "<table cellpadding=3 cellspacing=0 border=1>\n"
<< "\t<caption>Properties</caption>\n\n"
<< "\t<thead>\n"
<< "\t\t<tr>\n"
<< "\t\t\t<th>ID</th>\n"
<< "\t\t\t<th>Type</th>\n"
<< "\t\t\t<th>Description</th>\n"
<< "\t\t</tr>\n"
<< "\t</thead>\n"
<< "\t<tbody>\n";
for (SceneGraphNode* node : _graph.nodes()) {
for (properties::Property* p : node->propertiesRecursive()) {
html << "\t\t<tr>\n"
<< "\t\t\t<td>" << p->fullyQualifiedIdentifier() << "</td>\n"
<< "\t\t\t<td>" << p->className() << "</td>\n"
<< "\t\t\t<td>" << p->guiName() << "</td>\n"
<< "\t\t</tr>\n";
}
if (!node->propertiesRecursive().empty()) {
html << "\t<tr><td style=\"line-height: 10px;\" colspan=3></td></tr>\n";
}
}
html << "\t</tbody>\n"
<< "</table>\n"
<< "</html>;";
*/
file << html.str();
}
else
@@ -703,4 +500,8 @@ scripting::LuaLibrary Scene::luaLibrary() {
};
}
Scene::InvalidSceneError::InvalidSceneError(const std::string& error, const std::string& comp)
: ghoul::RuntimeError(error, comp)
{}
} // namespace openspace

View File

@@ -130,8 +130,11 @@ int property_setValueRegex(lua_State* L) {
lua_type(L, -1)
);
}
catch (const std::regex_error& e) {
LERRORC("property_setValueRegex", "Malformed regular expression: '" << regex << "'");
catch (const std::regex_error&) {
LERRORC(
"property_setValueRegex",
"Malformed regular expression: '" << regex << "'"
);
}
return 0;
@@ -213,9 +216,8 @@ int loadScene(lua_State* L) {
SCRIPT_CHECK_ARGUMENTS("loadScene", L, 1, nArguments);
std::string sceneFile = luaL_checkstring(L, -1);
OsEng.renderEngine().scene()->scheduleLoadSceneFile(sceneFile);
OsEng.scheduleLoadScene(sceneFile);
return 0;
}
@@ -234,22 +236,11 @@ int addSceneGraphNode(lua_State* L) {
return 0;
}
SceneGraphNode* node = SceneGraphNode::createFromDictionary(d);
std::string parent = d.value<std::string>(SceneGraphNode::KeyParentName);
SceneGraphNode* parentNode = OsEng.renderEngine().scene()->sceneGraphNode(parent);
if (!parentNode) {
LERRORC(
"addSceneGraphNode",
errorLocation(L) << "Could not find parent node '" << parent << "'"
);
return 0;
}
node->setParent(parentNode);
node->initialize();
OsEng.renderEngine().scene()->sceneGraph().addSceneGraphNode(node);
SceneLoader loader;
SceneGraphNode* importedNode = loader.importNodeDictionary(*OsEng.renderEngine().scene(), d);
importedNode->initialize();
return 0;
return 1;
}
int removeSceneGraphNode(lua_State* L) {
@@ -257,21 +248,25 @@ int removeSceneGraphNode(lua_State* L) {
int nArguments = lua_gettop(L);
SCRIPT_CHECK_ARGUMENTS("removeSceneGraphNode", L, 1, nArguments);
std::string nodeName = luaL_checkstring(L, -1);
SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(nodeName);
if (!node) {
LERRORC(
"removeSceneGraphNode",
errorLocation(L) << "Could not find node '" << nodeName << "'"
);
);
return 0;
}
OsEng.renderEngine().scene()->sceneGraph().removeSceneGraphNode(node);
node->deinitialize();
delete node;
SceneGraphNode* parent = node->parent();
if (!parent) {
LERRORC(
"removeSceneGraphNode",
errorLocation(L) << "Cannot remove root node"
);
return 0;
}
parent->detachChild(*node);
return 1;
}

View File

@@ -1,580 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <openspace/scene/scenegraph.h>
#include <openspace/documentation/documentation.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/interaction/interactionhandler.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/lua/lua_helper.h>
#include <ghoul/misc/onscopeexit.h>
#include <stack>
#include <unordered_map>
#ifdef _MSC_VER
#ifdef OPENSPACE_ENABLE_VLD
#include <vld.h>
#endif
#endif
namespace {
const std::string _loggerCat = "SceneGraph";
const std::string _moduleExtension = ".mod";
const std::string _defaultCommonDirectory = "common";
const std::string _commonModuleToken = "${COMMON_MODULE}";
const std::string KeyPathScene = "ScenePath";
const std::string KeyModules = "Modules";
const std::string KeyCommonFolder = "CommonFolder";
const std::string KeyPathModule = "ModulePath";
}
namespace openspace {
SceneGraph::SceneGraphNodeInternal::~SceneGraphNodeInternal() {
delete node;
}
SceneGraph::SceneGraph()
: _rootNode(nullptr)
{}
SceneGraph::~SceneGraph() {
clear();
}
void SceneGraph::clear() {
// Untested ---abock
for (SceneGraphNodeInternal* n : _nodes)
delete n;
_nodes.clear();
_rootNode = nullptr;
}
bool SceneGraph::loadFromFile(const std::string& sceneDescription) {
clear(); // Move this to a later stage to retain a proper scenegraph when the loading fails ---abock
std::string absSceneFile = absPath(sceneDescription);
// See if scene file exists
using RawPath = ghoul::filesystem::FileSystem::RawPath;
if (!FileSys.fileExists(absSceneFile, RawPath::Yes)) {
LERROR("Could not load scene file '" << absSceneFile << "'. " <<
"File not found");
return false;
}
LINFO("Loading SceneGraph from file '" << absSceneFile << "'");
lua_State* state = ghoul::lua::createNewLuaState();
OnExit(
// Delete the Lua state at the end of the scope, no matter what
[state](){ghoul::lua::destroyLuaState(state);}
);
OsEng.scriptEngine().initializeLuaState(state);
// Load dictionary
ghoul::Dictionary sceneDictionary;
try {
ghoul::lua::loadDictionaryFromFile(
absSceneFile,
sceneDictionary,
state
);
}
catch (...) {
// @CLEANUP: This is bad to just catch all exceptions! ---abock
return false;
}
std::string sceneDescriptionDirectory = ghoul::filesystem::File(
absSceneFile,
ghoul::filesystem::File::RawPath::Yes
).directoryName();
std::string sceneDirectory(".");
sceneDictionary.getValue(KeyPathScene, sceneDirectory);
// The scene path could either be an absolute or relative path to the description
// paths directory
std::string relativeCandidate = sceneDescriptionDirectory +
ghoul::filesystem::FileSystem::PathSeparator + sceneDirectory;
std::string absoluteCandidate = absPath(sceneDirectory);
if (FileSys.directoryExists(relativeCandidate))
sceneDirectory = relativeCandidate;
else if (FileSys.directoryExists(absoluteCandidate))
sceneDirectory = absoluteCandidate;
else {
LERROR("The '" << KeyPathScene << "' pointed to a "
"path '" << sceneDirectory << "' that did not exist");
return false;
}
ghoul::Dictionary moduleDictionary;
bool success = sceneDictionary.getValue(KeyModules, moduleDictionary);
if (!success)
// There are no modules that are loaded
return true;
// lua_State* state = ghoul::lua::createNewLuaState();
// OsEng.scriptEngine().initializeLuaState(state);
// Above we generated a ghoul::Dictionary from the scene file; now we run the scene
// file again to load any variables defined inside into the state that is passed to
// the modules. This allows us to specify global variables that can then be used
// inside the modules to toggle settings
ghoul::lua::runScriptFile(state, absSceneFile);
// Get the common directory
bool commonFolderSpecified = sceneDictionary.hasKey(KeyCommonFolder);
bool commonFolderCorrectType = sceneDictionary.hasKeyAndValue<std::string>(KeyCommonFolder);
if (commonFolderSpecified) {
if (commonFolderCorrectType) {
std::string commonFolder = sceneDictionary.value<std::string>(KeyCommonFolder);
std::string fullCommonFolder = FileSys.pathByAppendingComponent(
sceneDirectory,
commonFolder
);
if (!FileSys.directoryExists(fullCommonFolder))
LERROR("Specified common folder '" << fullCommonFolder << "' did not exist");
else {
if (!commonFolder.empty()) {
FileSys.registerPathToken(
_commonModuleToken, commonFolder,
ghoul::filesystem::FileSystem::Override::Yes
);
size_t nKeys = moduleDictionary.size();
moduleDictionary.setValue(
std::to_string(nKeys + 1),
commonFolder
);
}
}
}
else
LERROR("Specification for 'common' folder has invalid type");
}
std::vector<std::string> keys = moduleDictionary.keys();
std::map<std::string, std::vector<std::string>> dependencies;
std::map<std::string, std::string> parents;
_rootNode = new SceneGraphNode;
_rootNode->setName(SceneGraphNode::RootNodeName);
SceneGraphNodeInternal* internalRoot = new SceneGraphNodeInternal;
internalRoot->node = _rootNode;
_nodes.push_back(internalRoot);
std::sort(keys.begin(), keys.end());
ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
for (const std::string& key : keys) {
std::string fullModuleName = moduleDictionary.value<std::string>(key);
std::replace(fullModuleName.begin(), fullModuleName.end(), '/', FileSys.PathSeparator);
std::string modulePath = FileSys.pathByAppendingComponent(sceneDirectory, fullModuleName);
std::string moduleName = fullModuleName;
std::string::size_type pos = fullModuleName.find_last_of(FileSys.PathSeparator);
if (pos != std::string::npos)
moduleName = fullModuleName.substr(pos + 1);
if (!FileSys.directoryExists(modulePath)) {
LERROR("Could not load module '" << moduleName << "'. Directory did not exist");
continue;
}
std::string moduleFile = FileSys.pathByAppendingComponent(
modulePath,
moduleName + _moduleExtension
);
struct ModuleInformation {
ghoul::Dictionary dictionary;
std::string moduleFile;
std::string modulePath;
std::string moduleName;
};
std::vector<ModuleInformation> moduleDictionaries;
if (FileSys.fileExists(moduleFile)) {
// We have a module file, so it is a direct include
try {
ghoul::Dictionary moduleDictionary;
ghoul::lua::loadDictionaryFromFile(moduleFile, moduleDictionary, state);
moduleDictionaries.push_back({
moduleDictionary,
moduleFile,
modulePath,
moduleName
});
}
catch (const ghoul::lua::LuaRuntimeException& e) {
LERRORC(e.component, e.message);
continue;
}
}
else {
// If we do not have a module file, we have to include all subdirectories
using ghoul::filesystem::Directory;
using std::string;
std::vector<string> directories = Directory(modulePath).readDirectories();
for (const string& s : directories) {
std::string::size_type pos = s.find_last_of(FileSys.PathSeparator);
if (pos == std::string::npos) {
LERROR("Error parsing subdirectory name '" << s << "'");
continue;
}
string moduleName = s.substr(pos+1);
string submodulePath = s;
string moduleFile = FileSys.pathByAppendingComponent(submodulePath, moduleName) + _moduleExtension;
// string moduleName = s;
if (!FileSys.fileExists(moduleFile)) {
continue;
}
// We have a module file, so it is a direct include
try {
ghoul::Dictionary moduleDictionary;
ghoul::lua::loadDictionaryFromFile(moduleFile, moduleDictionary, state);
moduleDictionaries.push_back({
moduleDictionary,
moduleFile,
submodulePath,
moduleName
});
}
catch (const ghoul::lua::LuaRuntimeException& e) {
LERRORC(e.component, e.message);
continue;
}
}
}
auto addModule = [this, &dependencies, &parents](const ModuleInformation& moduleInformation) {
const ghoul::Dictionary& moduleDictionary = moduleInformation.dictionary;
const std::string& moduleFile = moduleInformation.moduleFile;
const std::string& modulePath = moduleInformation.modulePath;
const std::string& moduleName = moduleInformation.moduleName;
std::vector<std::string> keys = moduleDictionary.keys();
for (const std::string& key : keys) {
if (!moduleDictionary.hasValue<ghoul::Dictionary>(key)) {
LERROR("SceneGraphNode '" << key << "' is not a table in module '"
<< moduleFile << "'");
continue;
}
ghoul::Dictionary element;
std::string nodeName;
std::string parentName;
moduleDictionary.getValue(key, element);
element.setValue(KeyPathModule, modulePath);
element.getValue(SceneGraphNode::KeyName, nodeName);
element.getValue(SceneGraphNode::KeyParentName, parentName);
FileSys.setCurrentDirectory(modulePath);
LDEBUGC("Create from dictionary", "Node name: " << nodeName << " Parent name:" << parentName << " Path: " << modulePath);
SceneGraphNode* node = SceneGraphNode::createFromDictionary(element);
if (node == nullptr) {
LERROR("Error loading SceneGraphNode '" << nodeName << "' in module '" << moduleName << "'");
continue;
}
dependencies[nodeName].push_back(parentName);
parents[nodeName] = parentName;
// Also include loaded dependencies
if (element.hasKey(SceneGraphNode::KeyDependencies)) {
if (element.hasValue<ghoul::Dictionary>(SceneGraphNode::KeyDependencies)) {
ghoul::Dictionary nodeDependencies;
element.getValue(SceneGraphNode::KeyDependencies, nodeDependencies);
std::vector<std::string> keys = nodeDependencies.keys();
for (const std::string& key : keys) {
std::string value = nodeDependencies.value<std::string>(key);
dependencies[nodeName].push_back(value);
}
}
else {
LERROR("Dependencies did not have the corrent type");
}
}
SceneGraphNodeInternal* internalNode = new SceneGraphNodeInternal;
internalNode->node = node;
_nodes.push_back(internalNode);
}
};
for (const ModuleInformation& i : moduleDictionaries) {
try {
LINFO("Adding module: " << i.moduleName);
addModule(i);
}
catch (const documentation::SpecificationError& specError) {
LERROR("Error loading module: " << i.moduleName);
LERRORC(specError.component, specError.message);
for (const auto& offense : specError.result.offenses) {
LERRORC(offense.offender, std::to_string(offense.reason));
}
}
}
}
// ghoul::lua::destroyLuaState(state);
FileSys.setCurrentDirectory(oldDirectory);
for (SceneGraphNodeInternal* node : _nodes) {
if (node->node == _rootNode)
continue;
std::string parent = parents[node->node->name()];
SceneGraphNode* parentNode = sceneGraphNode(parent);
if (parentNode == nullptr) {
LERROR("Could not find parent '" << parent << "' for '" << node->node->name() << "'");
continue;
}
node->node->setParent(parentNode);
parentNode->addChild(node->node);
}
// Setup dependencies
for (SceneGraphNodeInternal* node : _nodes) {
std::vector<std::string> nodeDependencies = dependencies[node->node->name()];
for (const std::string& dep : nodeDependencies) {
SceneGraphNodeInternal* n = nodeByName(dep);
if (n == nullptr) {
LERROR("Dependent node '" << dep << "' was not loaded for '" <<node->node->name() << "'");
continue;
}
node->outgoingEdges.push_back(n);
n->incomingEdges.push_back(node);
}
}
std::vector<SceneGraphNodeInternal*> nodesToDelete;
for (SceneGraphNodeInternal* node : _nodes) {
if (!nodeIsDependentOnRoot(node)) {
LERROR("Node '" << node->node->name() << "' has no direct connection to Root.");
nodesToDelete.push_back(node);
}
}
for (SceneGraphNodeInternal* node : nodesToDelete) {
_nodes.erase(std::find(_nodes.begin(), _nodes.end(), node));
delete node;
}
bool s = sortTopologically();
if (!s) {
LERROR("Topological sort failed");
return false;
}
return true;
}
bool SceneGraph::nodeIsDependentOnRoot(SceneGraphNodeInternal* node) {
if (node->node->name() == SceneGraphNode::RootNodeName)
return true;
else {
for (SceneGraphNodeInternal* n : node->outgoingEdges) {
bool dep = nodeIsDependentOnRoot(n);
if (dep)
return true;
}
return false;
}
}
bool SceneGraph::sortTopologically() {
if (_nodes.empty())
return true;
// Only the Root node can have an in-degree of 0
SceneGraphNodeInternal* root = nodeByName(SceneGraphNode::RootNodeName);
ghoul_assert(root != nullptr, "Could not find Root node");
std::stack<SceneGraphNodeInternal*> zeroInDegreeNodes;
zeroInDegreeNodes.push(root);
std::unordered_map<SceneGraphNodeInternal*, size_t> inDegrees;
for (SceneGraphNodeInternal* node : _nodes)
inDegrees[node] = node->outgoingEdges.size();
//inDegrees[node] = node->incomingEdges.size();
_topologicalSortedNodes.clear();
_topologicalSortedNodes.reserve(_nodes.size());
while (!zeroInDegreeNodes.empty()) {
SceneGraphNodeInternal* node = zeroInDegreeNodes.top();
_topologicalSortedNodes.push_back(node->node);
zeroInDegreeNodes.pop();
//for (SceneGraphNodeInternal* n : node->outgoingEdges) {
for (SceneGraphNodeInternal* n : node->incomingEdges) {
inDegrees[n] -= 1;
if (inDegrees[n] == 0)
zeroInDegreeNodes.push(n);
}
}
return true;
}
bool SceneGraph::addSceneGraphNode(SceneGraphNode* node) {
// @TODO rework this ---abock
ghoul_assert(node, "Node must not be nullptr");
SceneGraphNodeInternal* internalNode = new SceneGraphNodeInternal;
internalNode->node = node;
auto it = std::find_if(
_nodes.begin(),
_nodes.end(),
[node](SceneGraphNodeInternal* i) {
return i->node == node->parent();
}
);
if (it == _nodes.end()) {
LERROR("Parent node was not found");
delete internalNode;
return false;
}
(*it)->incomingEdges.push_back(internalNode);
internalNode->outgoingEdges.push_back(*it);
_nodes.push_back(internalNode);
sortTopologically();
return true;
}
bool SceneGraph::removeSceneGraphNode(SceneGraphNode* node) {
// @TODO rework this ---abock
ghoul_assert(node, "Node must not be nullptr");
auto it = std::find_if(
_nodes.begin(),
_nodes.end(),
[node](SceneGraphNodeInternal* i) {
return i->node == node;
}
);
if (it == _nodes.end()) {
LERROR("The node '" << node->name() << "' did not exist in the scenegraph");
return false;
}
// Remove internal node from the list of nodes
//SceneGraphNodeInternal* internalNode = *it;
_nodes.erase(it);
if (OsEng.interactionHandler().focusNode() == node)
OsEng.interactionHandler().setFocusNode(node->parent());
sortTopologically();
#if 0
SceneGraphNodeInternal* parentInternalNode = nodeByName(node->parent()->name());
ghoul_assert(parentInternalNode, "Could not find internal parent node");
// Reparent its children to its parent
for (SceneGraphNode* c : node->children())
c->setParent(node->parent());
// Reset the dependencies accordingly
// VERY untested ---abock
for (SceneGraphNodeInternal* c : internalNode->incomingEdges) {
parentInternalNode->outgoingEdges.insert(parentInternalNode->outgoingEdges.end(), c->outgoingEdges.begin(), c->outgoingEdges.end());
parentInternalNode->incomingEdges.insert(parentInternalNode->incomingEdges.end(), c->incomingEdges.begin(), c->incomingEdges.end());
}
#endif
return true;
}
SceneGraph::SceneGraphNodeInternal* SceneGraph::nodeByName(const std::string& name) {
auto it = std::find_if(
_nodes.begin(),
_nodes.end(),
[name](SceneGraphNodeInternal* node) {
return node->node->name() == name;
}
);
if (it == _nodes.end())
return nullptr;
else
return *it;
}
const std::vector<SceneGraphNode*>& SceneGraph::nodes() const {
return _topologicalSortedNodes;
}
SceneGraphNode* SceneGraph::rootNode() const {
return _rootNode;
}
SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const {
auto it = std::find_if(
_nodes.begin(),
_nodes.end(),
[name](SceneGraphNodeInternal* node) {
return node->node->name() == name;
}
);
if (it != _nodes.end())
return (*it)->node;
else
return nullptr;
}
} // namespace openspace

View File

@@ -65,14 +65,14 @@ const std::string SceneGraphNode::KeyName = "Name";
const std::string SceneGraphNode::KeyParentName = "Parent";
const std::string SceneGraphNode::KeyDependencies = "Dependencies";
SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& dictionary){
std::unique_ptr<SceneGraphNode> SceneGraphNode::createFromDictionary(const ghoul::Dictionary& dictionary){
openspace::documentation::testSpecificationAndThrow(
SceneGraphNode::Documentation(),
dictionary,
"SceneGraphNode"
);
SceneGraphNode* result = new SceneGraphNode;
std::unique_ptr<SceneGraphNode> result = std::make_unique<SceneGraphNode>();
std::string name = dictionary.value<std::string>(KeyName);
result->setName(name);
@@ -87,7 +87,6 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
if (result->_renderable == nullptr) {
LERROR("Failed to create renderable for SceneGraphNode '"
<< result->name() << "'");
delete result;
return nullptr;
}
result->addPropertySubOwner(result->_renderable.get());
@@ -102,7 +101,6 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
if (result->_transform.translation == nullptr) {
LERROR("Failed to create ephemeris for SceneGraphNode '"
<< result->name() << "'");
delete result;
return nullptr;
}
result->addPropertySubOwner(result->_transform.translation.get());
@@ -117,7 +115,6 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
if (result->_transform.rotation == nullptr) {
LERROR("Failed to create rotation for SceneGraphNode '"
<< result->name() << "'");
delete result;
return nullptr;
}
result->addPropertySubOwner(result->_transform.rotation.get());
@@ -132,7 +129,6 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
if (result->_transform.scale == nullptr) {
LERROR("Failed to create scale for SceneGraphNode '"
<< result->name() << "'");
delete result;
return nullptr;
}
result->addPropertySubOwner(result->_transform.scale.get());
@@ -141,12 +137,13 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
LDEBUG("Successfully created SceneGraphNode '"
<< result->name() << "'");
return result;
return std::move(result);
}
SceneGraphNode::SceneGraphNode()
: properties::PropertyOwner("")
, _parent(nullptr)
, _scene(nullptr)
, _transform {
std::make_unique<StaticTranslation>(),
std::make_unique<StaticRotation>(),
@@ -200,6 +197,20 @@ bool SceneGraphNode::deinitialize() {
return true;
}
void SceneGraphNode::traversePreOrder(std::function<void(SceneGraphNode*)> fn) {
fn(this);
for (std::unique_ptr<SceneGraphNode>& child : _children) {
child->traversePreOrder(fn);
}
}
void SceneGraphNode::traversePostOrder(std::function<void(SceneGraphNode*)> fn) {
for (std::unique_ptr<SceneGraphNode>& child : _children) {
child->traversePostOrder(fn);
}
fn(this);
}
void SceneGraphNode::update(const UpdateData& data) {
if (_transform.translation) {
if (data.doPerformanceMeasurement) {
@@ -356,35 +367,134 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
// child->render(newData);
}
void SceneGraphNode::setParent(SceneGraphNode& parent, UpdateScene updateScene) {
ghoul_assert(_parent != nullptr, "Node must be attached to a parent");
ghoul_assert(
!updateScene || _scene == parent._scene,
"For the scene to be updated, this object must belong to the same scene as the parent"
);
ghoul_assert(
!updateScene || _parent->_scene == parent._scene,
"Old and new parent cannot belong to separate scenes"
);
// not used anymore @AA
//void SceneGraphNode::addNode(SceneGraphNode* child)
//{
// // add a child node and set this node to be the parent
// child->setParent(this);
// _children.push_back(child);
//}
parent.attachChild(_parent->detachChild(*this, UpdateScene::No), UpdateScene::No);
void SceneGraphNode::setParent(SceneGraphNode* parent) {
_parent = parent;
if (_scene && updateScene) {
_scene->updateDependencies();
}
}
void SceneGraphNode::addChild(SceneGraphNode* child) {
_children.push_back(child);
void SceneGraphNode::attachChild(std::unique_ptr<SceneGraphNode> child, UpdateScene updateScene) {
ghoul_assert(child->parent() == nullptr, "Child may not already have a parent");
child->_parent = this;
if (_scene) {
child->setScene(_scene);
}
_children.push_back(std::move(child));
if (_scene && updateScene) {
_scene->addNode(child.get());
}
}
std::unique_ptr<SceneGraphNode> SceneGraphNode::detachChild(SceneGraphNode& child, UpdateScene updateScene) {
ghoul_assert(child._dependentNodes.empty(), "Nodes cannot depend on a node being detached");
ghoul_assert(child._parent != nullptr, "Node must be attached to a parent");
// Update of deps is deffered to the removal of the node from the scene
clearDependencies(UpdateScene::No);
//not used anymore @AA
//bool SceneGraphNode::abandonChild(SceneGraphNode* child) {
// std::vector < SceneGraphNode* >::iterator it = std::find(_children.begin(), _children.end(), child);
//
// if (it != _children.end()){
// _children.erase(it);
// return true;
// }
//
// return false;
//}
auto iter = std::find_if(
_children.begin(),
_children.end(),
[&child] (const auto& c) {
return &child == c.get();
}
);
std::unique_ptr<SceneGraphNode> c = std::move(*iter);
_children.erase(iter);
if (_scene && updateScene) {
_scene->removeNode(&child);
}
if (_scene) {
setScene(nullptr);
}
return std::move(c);
}
void SceneGraphNode::addDependency(SceneGraphNode& dependency, UpdateScene updateScene) {
dependency._dependentNodes.push_back(this);
_dependencies.push_back(&dependency);
if (_scene && updateScene) {
_scene->updateDependencies();
}
}
void SceneGraphNode::removeDependency(SceneGraphNode& dependency, UpdateScene updateScene) {
dependency._dependentNodes.erase(std::remove_if(
dependency._dependentNodes.begin(),
dependency._dependentNodes.end(),
[this](const auto& d) {
return this == d;
}
), dependency._dependentNodes.end());
_dependencies.erase(std::remove_if(
_dependencies.begin(),
_dependencies.end(),
[&dependency](const auto& d) {
return &dependency == d;
}
), _dependencies.end());
if (_scene && updateScene) {
_scene->updateDependencies();
}
}
void SceneGraphNode::clearDependencies(UpdateScene updateScene) {
for (auto dependency : _dependencies) {
dependency->_dependentNodes.erase(std::remove_if(
dependency->_dependentNodes.begin(),
dependency->_dependentNodes.end(),
[this](const auto& d) {
return this == d;
}
), dependency->_dependentNodes.end());
}
_dependencies.clear();
if (_scene && updateScene) {
_scene->updateDependencies();
}
}
void SceneGraphNode::setDependencies(const std::vector<SceneGraphNode*>& dependencies, UpdateScene updateScene) {
clearDependencies(UpdateScene::No);
_dependencies = dependencies;
for (auto dependency : dependencies) {
dependency->_dependentNodes.push_back(this);
}
if (_scene && updateScene) {
_scene->updateDependencies();
}
}
const std::vector<SceneGraphNode*>& SceneGraphNode::dependencies() const {
return _dependencies;
}
const std::vector<SceneGraphNode*>& SceneGraphNode::dependentNodes() const {
return _dependentNodes;
}
glm::dvec3 SceneGraphNode::position() const
{
@@ -450,15 +560,28 @@ double SceneGraphNode::calculateWorldScale() const {
}
}
SceneGraphNode* SceneGraphNode::parent() const
{
SceneGraphNode* SceneGraphNode::parent() const {
return _parent;
}
const std::vector<SceneGraphNode*>& SceneGraphNode::children() const{
return _children;
Scene* SceneGraphNode::scene() {
return _scene;
}
void SceneGraphNode::setScene(Scene* scene) {
traversePreOrder([scene](SceneGraphNode* node) {
node->_scene = scene;
});
}
std::vector<SceneGraphNode*> SceneGraphNode::children() const {
std::vector<SceneGraphNode*> nodes;
for (auto& child : _children) {
nodes.push_back(child.get());
}
return nodes;
}
// bounding sphere
PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){
// set the bounding sphere to 0.0
_boundingSphere = 0.0;
@@ -489,7 +612,6 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){
if(renderableBS > _boundingSphere)
_boundingSphere = renderableBS;
}
//LINFO("Bounding Sphere of '" << name() << "': " << _boundingSphere);
return _boundingSphere;
}
@@ -512,7 +634,7 @@ Renderable* SceneGraphNode::renderable() {
return _renderable.get();
}
// private helper methods
/*
bool SceneGraphNode::sphereInsideFrustum(const psc& s_pos, const PowerScaledScalar& s_rad,
const Camera* camera)
{
@@ -543,15 +665,16 @@ bool SceneGraphNode::sphereInsideFrustum(const psc& s_pos, const PowerScaledScal
return false;
}
}
*/
SceneGraphNode* SceneGraphNode::childNode(const std::string& name)
{
if (this->name() == name)
return this;
else
for (SceneGraphNode* it : _children) {
for (std::unique_ptr<SceneGraphNode>& it : _children) {
SceneGraphNode* tmp = it->childNode(name);
if (tmp != nullptr)
if (tmp)
return tmp;
}
return nullptr;

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