mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-27 23:39:01 -06:00
Merge branch 'develop' into feature/multitouch
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
-->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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
BIN
ext/curl/lib/libeay32.dll
Normal file
Binary file not shown.
BIN
ext/curl/lib/ssleay32.dll
Normal file
BIN
ext/curl/lib/ssleay32.dll
Normal file
Binary file not shown.
Submodule ext/ghoul updated: 143d50aa65...c37ff8beb5
2
ext/sgct
2
ext/sgct
Submodule ext/sgct updated: bdff5552b4...1eb6bcfa78
Submodule ext/spice updated: 1c9bb9e4dd...63e382ac76
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
119
include/openspace/scene/sceneloader.h
Normal file
119
include/openspace/scene/sceneloader.h
Normal 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__
|
||||
@@ -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__
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderablePlanetProject"
|
||||
"RenderablePlanetProjection"
|
||||
);
|
||||
|
||||
std::string name;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() << "'");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user