├── .github └── workflows │ ├── ci-windows-minimal.yml │ └── doxygen-gh-pages.yml ├── CMakeLists.txt ├── Doxyfile ├── LICENSE ├── README.md ├── bootstrap-vcpkg.bat ├── cmake ├── FindImGui.cmake └── install-export-files.cmake ├── data ├── bing.map.json ├── crop.map.json ├── fonts │ └── times.vsgb ├── geotiff.map.json ├── imagery │ └── world.tif ├── openmaptiles.map.json ├── openstreetmap.map.json ├── openstreetmap_slippy.map.json ├── readymap.map.json └── wmts.map.json ├── src ├── CMakeLists.txt ├── apps │ ├── CMakeLists.txt │ ├── rocky_demo │ │ ├── CMakeLists.txt │ │ ├── Demo_Decluttering.h │ │ ├── Demo_Environment.h │ │ ├── Demo_Geocoder.h │ │ ├── Demo_Icon.h │ │ ├── Demo_Label.h │ │ ├── Demo_LabelFeatures.h │ │ ├── Demo_Line.h │ │ ├── Demo_LineFeatures.h │ │ ├── Demo_Map.h │ │ ├── Demo_MapManipulator.h │ │ ├── Demo_Mesh.h │ │ ├── Demo_Model.h │ │ ├── Demo_PolygonFeatures.h │ │ ├── Demo_RTT.h │ │ ├── Demo_Registry.h │ │ ├── Demo_Rendering.h │ │ ├── Demo_Serialization.h │ │ ├── Demo_Simulation.h │ │ ├── Demo_Stats.h │ │ ├── Demo_Tethering.h │ │ ├── Demo_TrackHistory.h │ │ ├── Demo_Views.h │ │ ├── Demo_Widget.h │ │ ├── helpers.h │ │ └── rocky_demo.cpp │ ├── rocky_demo_qt │ │ ├── CMakeLists.txt │ │ └── rocky_demo_qt.cpp │ ├── rocky_engine │ │ ├── CMakeLists.txt │ │ └── rocky_engine.cpp │ └── rocky_simple │ │ ├── CMakeLists.txt │ │ └── rocky_simple.cpp ├── rocky │ ├── Azure.cpp │ ├── Azure.h │ ├── AzureImageLayer.cpp │ ├── AzureImageLayer.h │ ├── CMakeLists.txt │ ├── Callbacks.h │ ├── Color.cpp │ ├── Color.h │ ├── Common.h │ ├── Context.cpp │ ├── Context.h │ ├── DateTime.cpp │ ├── DateTime.h │ ├── ElevationLayer.cpp │ ├── ElevationLayer.h │ ├── Ellipsoid.cpp │ ├── Ellipsoid.h │ ├── Ephemeris.cpp │ ├── Ephemeris.h │ ├── Feature.cpp │ ├── Feature.h │ ├── GDAL.cpp │ ├── GDAL.h │ ├── GDALElevationLayer.cpp │ ├── GDALElevationLayer.h │ ├── GDALImageLayer.cpp │ ├── GDALImageLayer.h │ ├── GeoCircle.cpp │ ├── GeoCircle.h │ ├── GeoCommon.h │ ├── GeoExtent.cpp │ ├── GeoExtent.h │ ├── GeoHeightfield.cpp │ ├── GeoHeightfield.h │ ├── GeoImage.cpp │ ├── GeoImage.h │ ├── GeoPoint.cpp │ ├── GeoPoint.h │ ├── Geocoder.cpp │ ├── Geocoder.h │ ├── Geoid.cpp │ ├── Geoid.h │ ├── Heightfield.cpp │ ├── Heightfield.h │ ├── Horizon.cpp │ ├── Horizon.h │ ├── IOTypes.cpp │ ├── IOTypes.h │ ├── Image.cpp │ ├── Image.h │ ├── ImageLayer.cpp │ ├── ImageLayer.h │ ├── LRUCache.h │ ├── Layer.cpp │ ├── Layer.h │ ├── LayerCollection.cpp │ ├── LayerCollection.h │ ├── LayerReference.h │ ├── Log.cpp │ ├── Log.h │ ├── MBTiles.cpp │ ├── MBTiles.h │ ├── MBTilesElevationLayer.cpp │ ├── MBTilesElevationLayer.h │ ├── MBTilesImageLayer.cpp │ ├── MBTilesImageLayer.h │ ├── Map.cpp │ ├── Map.h │ ├── Math.cpp │ ├── Math.h │ ├── Memory.cpp │ ├── Memory.h │ ├── Profile.cpp │ ├── Profile.h │ ├── SRS.cpp │ ├── SRS.h │ ├── SentryTracker.h │ ├── Status.cpp │ ├── Status.h │ ├── TMS.cpp │ ├── TMS.h │ ├── TMSElevationLayer.cpp │ ├── TMSElevationLayer.h │ ├── TMSImageLayer.cpp │ ├── TMSImageLayer.h │ ├── TerrainTileModel.cpp │ ├── TerrainTileModel.h │ ├── TerrainTileModelFactory.cpp │ ├── TerrainTileModelFactory.h │ ├── TerrainTileNode │ ├── Threading.cpp │ ├── Threading.h │ ├── TileKey.cpp │ ├── TileKey.h │ ├── TileLayer.cpp │ ├── TileLayer.h │ ├── URI.cpp │ ├── URI.h │ ├── Units.cpp │ ├── Units.h │ ├── Utils.cpp │ ├── Utils.h │ ├── Version.h.in │ ├── Viewpoint.cpp │ ├── Viewpoint.h │ ├── VisibleLayer.cpp │ ├── VisibleLayer.h │ ├── contrib │ │ ├── EarthFileImporter.cpp │ │ └── EarthFileImporter.h │ ├── json.h │ ├── option.h │ ├── rocky-config.cmake.in │ ├── rocky.h │ ├── rtree.h │ ├── sha1.h │ ├── static.cpp │ ├── tinyxml │ │ ├── tinyxml.cpp │ │ ├── tinyxml.h │ │ ├── tinyxmlerror.cpp │ │ └── tinyxmlparser.cpp │ ├── vsg │ │ ├── Application.cpp │ │ ├── Application.h │ │ ├── Common.h │ │ ├── DisplayManager.cpp │ │ ├── DisplayManager.h │ │ ├── GeoTransform.cpp │ │ ├── GeoTransform.h │ │ ├── MapManipulator.cpp │ │ ├── MapManipulator.h │ │ ├── MapNode.cpp │ │ ├── MapNode.h │ │ ├── PipelineState.cpp │ │ ├── PipelineState.h │ │ ├── PixelScaleTransform.h │ │ ├── RTT.cpp │ │ ├── RTT.h │ │ ├── SkyNode.cpp │ │ ├── SkyNode.h │ │ ├── Utils.h │ │ ├── VSGContext.cpp │ │ ├── VSGContext.h │ │ ├── ViewLocal.h │ │ ├── ecs.h │ │ ├── ecs │ │ │ ├── Component.h │ │ │ ├── Declutter.h │ │ │ ├── ECSNode.cpp │ │ │ ├── ECSNode.h │ │ │ ├── FeatureView.cpp │ │ │ ├── FeatureView.h │ │ │ ├── Icon.h │ │ │ ├── IconSystem.cpp │ │ │ ├── IconSystem.h │ │ │ ├── IconSystem2.cpp │ │ │ ├── IconSystem2.h │ │ │ ├── Label.h │ │ │ ├── LabelSystem.cpp │ │ │ ├── LabelSystem.h │ │ │ ├── Line.h │ │ │ ├── LineSystem.cpp │ │ │ ├── LineSystem.h │ │ │ ├── Mesh.h │ │ │ ├── MeshSystem.cpp │ │ │ ├── MeshSystem.h │ │ │ ├── Motion.h │ │ │ ├── MotionSystem.h │ │ │ ├── Registry.cpp │ │ │ ├── Registry.h │ │ │ ├── Transform.h │ │ │ ├── TransformDetail.cpp │ │ │ ├── TransformDetail.h │ │ │ ├── TransformSystem.cpp │ │ │ ├── TransformSystem.h │ │ │ ├── Visibility.h │ │ │ ├── Widget.h │ │ │ ├── WidgetSystem.cpp │ │ │ └── WidgetSystem.h │ │ ├── imgui │ │ │ ├── ImGuiIntegration.cpp │ │ │ ├── ImGuiIntegration.h │ │ │ ├── RenderImGui.cpp │ │ │ ├── RenderImGui.h │ │ │ ├── SendEventsToImGui.cpp │ │ │ └── SendEventsToImGui.h │ │ ├── json.h │ │ ├── shaders │ │ │ ├── rocky.atmo.ground.frag │ │ │ ├── rocky.atmo.ground.vert.glsl │ │ │ ├── rocky.atmo.sky.frag │ │ │ ├── rocky.atmo.sky.vert │ │ │ ├── rocky.icon.frag │ │ │ ├── rocky.icon.indirect.cull.comp │ │ │ ├── rocky.icon.indirect.frag │ │ │ ├── rocky.icon.indirect.vert │ │ │ ├── rocky.icon.vert │ │ │ ├── rocky.lighting.frag.glsl │ │ │ ├── rocky.line.frag │ │ │ ├── rocky.line.vert │ │ │ ├── rocky.mesh.frag │ │ │ ├── rocky.mesh.vert │ │ │ ├── rocky.terrain.frag │ │ │ └── rocky.terrain.vert │ │ ├── terrain-dbpager │ │ │ ├── GeometryPool.cpp │ │ │ ├── GeometryPool.h │ │ │ ├── SurfaceNode.cpp │ │ │ ├── SurfaceNode.h │ │ │ ├── TerrainEngine.cpp │ │ │ ├── TerrainEngine.h │ │ │ ├── TerrainNode.cpp │ │ │ ├── TerrainNode.h │ │ │ ├── TerrainSettings.cpp │ │ │ ├── TerrainSettings.h │ │ │ ├── TerrainState.cpp │ │ │ ├── TerrainState.h │ │ │ ├── TerrainTileNode.cpp │ │ │ └── TerrainTileNode.h │ │ └── terrain │ │ │ ├── GeometryPool.cpp │ │ │ ├── GeometryPool.h │ │ │ ├── SurfaceNode.cpp │ │ │ ├── SurfaceNode.h │ │ │ ├── TerrainEngine.cpp │ │ │ ├── TerrainEngine.h │ │ │ ├── TerrainNode.cpp │ │ │ ├── TerrainNode.h │ │ │ ├── TerrainSettings.cpp │ │ │ ├── TerrainSettings.h │ │ │ ├── TerrainState.cpp │ │ │ ├── TerrainState.h │ │ │ ├── TerrainTileHost.h │ │ │ ├── TerrainTileNode.cpp │ │ │ ├── TerrainTileNode.h │ │ │ ├── TerrainTilePager.cpp │ │ │ └── TerrainTilePager.h │ ├── weejobs.h │ └── weemesh.h └── tests │ ├── CMakeLists.txt │ ├── catch.hpp │ └── tests.cpp └── vcpkg ├── ports ├── _archive │ ├── vsg │ │ ├── devendor-glslang.patch │ │ ├── portfile.cmake │ │ └── vcpkg.json │ ├── vsgimgui │ │ ├── portfile.cmake │ │ ├── vcpkg.json │ │ └── vsgImGui.patch │ └── vsgxchange │ │ ├── portfile.cmake │ │ ├── require-features.patch │ │ ├── vcpkg.json │ │ └── vsgXchange.patch └── vsgqt │ ├── portfile.cmake │ └── vcpkg.json └── vcpkg.json /.github/workflows/ci-windows-minimal.yml: -------------------------------------------------------------------------------- 1 | name: windows-x64-Release-minimal 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | env: 6 | VCPKG_BINARY_SOURCES : 'clear;x-gha,readwrite' 7 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 8 | BUILD_TYPE: Release 9 | VCPKG_VERSION: 'master' 10 | 11 | jobs: 12 | 13 | build: 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | matrix: 18 | os: ['windows-latest'] 19 | include: 20 | - os: 'windows-latest' 21 | triplet: 'x64-windows' 22 | mono: '' 23 | VCPKG_WORKSPACE: 'c:/vcpkg_own' 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | with: 28 | submodules: recursive 29 | 30 | - name: Export GitHub Actions cache environment variables 31 | uses: actions/github-script@v7 32 | with: 33 | script: | 34 | core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); 35 | core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); 36 | 37 | - name: Install Vulkan SDK 38 | uses: pelicanmapping/setup-vulkan-sdk@v1.2.1 39 | with: 40 | vulkan-query-version: 1.3.231.1 41 | vulkan-components: Vulkan-Headers, Vulkan-Loader 42 | vulkan-use-cache: true 43 | 44 | - name: Installing vcpkg (windows) 45 | shell: 'bash' 46 | run: | 47 | cmake -E make_directory ${{ matrix.VCPKG_WORKSPACE }} 48 | cd ${{ matrix.VCPKG_WORKSPACE }} 49 | # git clone --depth 1 --branch ${{env.VCPKG_VERSION}} https://github.com/microsoft/vcpkg 50 | git clone https://github.com/microsoft/vcpkg 51 | cd vcpkg 52 | git checkout ${{env.VCPKG_VERSION}} 53 | cd .. 54 | ./vcpkg/bootstrap-vcpkg.bat -disableMetrics 55 | echo "set(VCPKG_BUILD_TYPE release)" >> ./vcpkg/triplets/x64-windows.cmake 56 | ${{ matrix.VCPKG_WORKSPACE }}/vcpkg/vcpkg version 57 | 58 | - name: Create Build Environment 59 | run: | 60 | cmake -E make_directory ${{runner.workspace}}/build 61 | 62 | - name: Configure CMake 63 | shell: bash 64 | working-directory: ${{ runner.workspace }}/build 65 | run: cmake $GITHUB_WORKSPACE -DWIN32_USE_MP=ON -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DROCKY_SUPPORTS_GDAL=OFF -DROCKY_SUPPORTS_MBTILES=OFF -DROCKY_SUPPORTS_AZURE=OFF -DROCKY_SUPPORTS_BING=OFF -DCMAKE_TOOLCHAIN_FILE=${{ matrix.VCPKG_WORKSPACE }}/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_BUILD_TYPE=$BUILD_TYPE -DVCPKG_MANIFEST_DIR=$GITHUB_WORKSPACE/vcpkg 66 | 67 | - name: 'Upload cmake configure log artifact' 68 | uses: actions/upload-artifact@v4 69 | if: ${{ failure() }} 70 | with: 71 | name: cmake-log 72 | path: ${{ runner.workspace }}/build/CMakeCache.txt 73 | retention-days: 1 74 | 75 | - name: Build 76 | working-directory: ${{ runner.workspace }}/build 77 | shell: bash 78 | run: cmake --build . --config $BUILD_TYPE 79 | -------------------------------------------------------------------------------- /.github/workflows/doxygen-gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Doxygen GitHub Pages Deploy Action 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v3 15 | with: 16 | submodules: "false" 17 | 18 | - name: Install Doxygen 19 | run: sudo apt-get install doxygen graphviz -y 20 | shell: bash 21 | 22 | - name: Generate Doxygen Documentation 23 | run: doxygen Doxyfile 24 | shell: bash 25 | 26 | - name: Create .nojekyll (ensures pages with underscores work on gh pages) 27 | run: touch docs/html/.nojekyll 28 | shell: bash 29 | 30 | - name: Deploy to GitHub Pages 31 | uses: JamesIves/github-pages-deploy-action@v4 32 | with: 33 | token: ${{ secrets.GITHUB_TOKEN }} 34 | branch: gh-pages 35 | folder: docs/html 36 | target-folder: doxygen 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Pelican Mapping 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cmake/FindImGui.cmake: -------------------------------------------------------------------------------- 1 | # Finds the ImGui library and creates the target imgui::imgui 2 | # 3 | # Inputs: 4 | # IMGUI_DIR : Set this to compile imgui from source found in the folder 5 | # 6 | # Outputs: 7 | # ImGui_FOUND : True if everything worked out and imgui::imgui is available. 8 | # 9 | 10 | if (NOT TARGET imgui::imgui) 11 | 12 | # Check for a CONFIG file first (vcpkg uses one): 13 | # vcpkg names the library "imgui::imgui" so we'll follow that pattern here. 14 | if(NOT IMGUI_DIR) 15 | 16 | find_package(imgui CONFIG QUIET) 17 | if (TARGET imgui::imgui) 18 | set(ImGui_FOUND TRUE) 19 | endif() 20 | 21 | else() 22 | 23 | message(STATUS "Since you set IMGUI_DIR, I will try to build ImGui from source.") 24 | message(STATUS "IMGUI_DIR = ${IMGUI_DIR}") 25 | 26 | set(IMGUI_SOURCES "") 27 | 28 | # find the imgui sources based on the IMGUI_DIR variable the user passed in: 29 | find_path(IMGUI_INCLUDE_DIR NAMES imgui.h 30 | HINTS ${IMGUI_DIR} 31 | NO_CACHE NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) 32 | mark_as_advanced(IMGUI_INCLUDE_DIR) 33 | 34 | if (IMGUI_INCLUDE_DIR) 35 | set(IMGUI_ALL_SOURCES_FOUND TRUE) 36 | 37 | add_library(imgui::imgui INTERFACE IMPORTED) 38 | 39 | set_property(TARGET imgui::imgui APPEND PROPERTY 40 | INTERFACE_INCLUDE_DIRECTORIES ${IMGUI_INCLUDE_DIR} "${IMGUI_INCLUDE_DIR}/backends") 41 | 42 | foreach(_file imgui.cpp imgui_widgets.cpp imgui_draw.cpp imgui_tables.cpp backends/imgui_impl_vulkan.cpp) 43 | find_file(_source_${_file} NAMES ${_file} 44 | HINTS ${IMGUI_DIR} 45 | NO_CACHE NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) 46 | 47 | if(NOT _source_${_file}) 48 | set(IMGUI_ALL_SOURCES_FOUND FALSE) 49 | message(WARNING "Failed to find ${_source_${_file}} in ${IMGUI_DIR}") 50 | break() 51 | endif() 52 | 53 | list(APPEND IMGUI_SOURCES ${_source_${_file}}) 54 | 55 | unset(_source_${_file}) 56 | endforeach() 57 | 58 | if(IMGUI_ALL_SOURCES_FOUND) 59 | add_library(imgui::sources INTERFACE IMPORTED) 60 | 61 | set_property(TARGET imgui::sources APPEND PROPERTY 62 | INTERFACE_SOURCES "${IMGUI_SOURCES}") 63 | 64 | # make imgui depend on sources: 65 | set_property(TARGET imgui::imgui APPEND PROPERTY 66 | INTERFACE_LINK_LIBRARIES imgui::sources) 67 | endif() 68 | else() 69 | message(WARNING "Could not find any ImGui source code at ${IMGUI_DIR}") 70 | endif() 71 | 72 | if(IMGUI_ALL_SOURCES_FOUND) 73 | set(ImGui_FOUND TRUE) 74 | endif() 75 | 76 | unset(IMGUI_SOURCES) 77 | unset(IMGUI_ALL_SOURCES_FOUND) 78 | endif() 79 | endif() 80 | 81 | if(NOT ImGui_FOUND) 82 | message(WARNING "ImGui wasn't found. You may want to try setting IMGUI_DIR to automatically build it from source.") 83 | endif() 84 | -------------------------------------------------------------------------------- /cmake/install-export-files.cmake: -------------------------------------------------------------------------------- 1 | function(rocky_install_export_files TARGET) 2 | 3 | include(CMakePackageConfigHelpers) 4 | 5 | #set(PACKAGE_INSTALL_DIR share/rocky) 6 | set(ROCKY_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) 7 | set(ROCKY_LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) 8 | set(ROCKY_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/rocky") 9 | 10 | configure_package_config_file( 11 | "${TARGET}-config.cmake.in" 12 | "${TARGET}-config.cmake" 13 | INSTALL_DESTINATION ${ROCKY_CMAKE_INSTALL_DIR} 14 | PATH_VARS ROCKY_INCLUDE_INSTALL_DIR ROCKY_LIBRARY_INSTALL_DIR) 15 | 16 | write_basic_package_version_file( 17 | "${TARGET}-config-version.cmake" 18 | VERSION ${PROJECT_VERSION} 19 | COMPATIBILITY AnyNewerVersion) 20 | 21 | install( 22 | EXPORT ${TARGET}Targets 23 | FILE ${TARGET}-targets.cmake 24 | NAMESPACE rocky:: 25 | DESTINATION ${ROCKY_CMAKE_INSTALL_DIR} ) 26 | 27 | install( 28 | FILES 29 | "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-config.cmake" 30 | "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-config-version.cmake" 31 | DESTINATION 32 | ${ROCKY_CMAKE_INSTALL_DIR} ) 33 | 34 | endfunction() 35 | -------------------------------------------------------------------------------- /data/bing.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "map" : { 3 | "name" : "Bing Maps Example", 4 | "layers": [ 5 | { 6 | "name": "Bing Maps imagery", 7 | "type": "BingImage", 8 | "imagery_set": "Aerial", 9 | "key": "", 10 | "attribution" : { 11 | "text" :"\u00a9 Microsoft Corporation, \u00a9 TomTom", 12 | "href" :"https://www.microsoft.com/en-us/maps/bing-maps/product" 13 | } 14 | }, 15 | { 16 | "name" :"Bing Maps elevation", 17 | "type" :"BingElevation", 18 | "attribution" : { 19 | "text" :"\u00a9 Microsoft Corporation", 20 | "href" :"https://www.microsoft.com/en-us/maps/bing-maps/product" 21 | } 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /data/crop.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "map" : { 3 | "name" : "Cropping demo", 4 | "layers": [ 5 | { 6 | "name": "Local GeoTIFF", 7 | "type": "GDALImage", 8 | "uri": "imagery/world.tif" 9 | }, 10 | { 11 | "name": "OpenStreetMap Imagery - cropped", 12 | "profile": "spherical-mercator", 13 | "crop" : { 14 | "srs" : "spherical-mercator", 15 | "xmin" : 250000, 16 | "ymin" : 250000, 17 | "xmax" : 1750000, 18 | "ymax" : 1750000 19 | }, 20 | "uri" : "https://[abc].tile.openstreetmap.org/{z}/{x}/{y}.png", 21 | "type": "TMSImage", 22 | "opacity": 0.5, 23 | "attribution": { 24 | "text": "Copyright OpenStreetMap contributers", 25 | "href": "https://openstreetmap.org/copyright" 26 | } 27 | } 28 | ] 29 | } 30 | } -------------------------------------------------------------------------------- /data/fonts/times.vsgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pelicanmapping/rocky/4881c10c4694613d5d4ac6fd3e068952e248bc75/data/fonts/times.vsgb -------------------------------------------------------------------------------- /data/geotiff.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "map" : { 3 | "name" : "Local GeoTIFF Map", 4 | "layers": [ 5 | { 6 | "name": "Local GeoTIFF", 7 | "type": "GDALImage", 8 | "uri": "imagery/world.tif" 9 | } 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /data/imagery/world.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pelicanmapping/rocky/4881c10c4694613d5d4ac6fd3e068952e248bc75/data/imagery/world.tif -------------------------------------------------------------------------------- /data/openmaptiles.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "terrain" : { 3 | "screen_space_error" : 0.0 4 | }, 5 | "map" : { 6 | "name" : "OpenMapTiles Example", 7 | "layers": [ 8 | { 9 | "name": "ReadyMap OpenMapTiles Street Map", 10 | "profile": "spherical-mercator", 11 | "uri" : "https://openmaptiles.readymap.org/styles/basic/{z}/{x}/{y}.png", 12 | "type": "TMSImage", 13 | "attribution": { 14 | "text": "\u00a9 MapTiler \u00a9 OpenStreetMap contributors", 15 | "href": "https://openstreetmap.org/copyright" 16 | } 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /data/openstreetmap.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "terrain" : { 3 | "screen_space_error" : 0.0 4 | }, 5 | "map" : { 6 | "name" : "OpenStreetMap Example", 7 | "layers": [ 8 | { 9 | "name": "OpenStreetMap Imagery", 10 | "profile": "spherical-mercator", 11 | "uri": "https://[abc].tile.openstreetmap.org/{z}/{x}/{y}.png", 12 | "type": "TMSImage", 13 | "attribution": { 14 | "text": "\u00a9 OpenStreetMap contributors", 15 | "href": "https://openstreetmap.org/copyright" 16 | } 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /data/openstreetmap_slippy.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "profile" : "spherical-mercator", 3 | "terrain" : { 4 | "screen_space_error" : 128 5 | }, 6 | "map" : { 7 | "name" : "OpenStreetMap Slippy Map", 8 | "layers": [ 9 | { 10 | "name": "OpenStreetMap Imagery", 11 | "profile": "spherical-mercator", 12 | "uri": "https://[abc].tile.openstreetmap.org/{z}/{x}/{y}.png", 13 | "type": "TMSImage", 14 | "attribution": { 15 | "text": "\u00a9 OpenStreetMap contributors", 16 | "href": "https://openstreetmap.org/copyright" 17 | } 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /data/readymap.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "map" : { 3 | "name" : "ReadyMap(R) Tiles", 4 | "layers": [ 5 | { 6 | "name": "ReadyMap 15m Base Imagery", 7 | "type": "TMSImage", 8 | "uri": "https://readymap.org/readymap/tiles/1.0.0/7", 9 | "attribution": { 10 | "text": "\u00a9 Pelican Mapping", 11 | "href": "https://www.pelicanmapping.com/readymap-data" 12 | } 13 | }, 14 | { 15 | "name": "ReadyMap 90m Elevation", 16 | "type": "TMSElevation", 17 | "uri": "https://readymap.org/readymap/tiles/1.0.0/116/", 18 | "attribution": { 19 | "text": "\u00a9 Pelican Mapping", 20 | "href": "https://www.pelicanmapping.com/readymap-data" 21 | } 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /data/wmts.map.json: -------------------------------------------------------------------------------- 1 | { 2 | "map" : { 3 | "name" : "WMTS Map", 4 | "comment" : "See https://gdal.org/drivers/raster/wmts.html", 5 | "layers": [ 6 | { 7 | "name": "Global Imagery", 8 | "type": "GDALImage", 9 | "connection": " https://services.sentinel-hub.com/ogc/wmts/MODIS/1.0.0/Capabilities.xml s2cloudless-2020 " 10 | } 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 2 | 3 | # sort into group folders to help IDEs present the files in a logical manner 4 | function(assign_source_groups GROUP_NAME ROOT_FOLDER) 5 | foreach(FILE IN ITEMS ${ARGN}) 6 | if (IS_ABSOLUTE "${FILE}") 7 | file(RELATIVE_PATH RELATIVE_SOURCE "${ROOT_FOLDER}" "${FILE}") 8 | else() 9 | set(RELATIVE_SOURCE "${FILE}") 10 | endif() 11 | get_filename_component(SOURCE_PATH "${RELATIVE_SOURCE}" PATH) 12 | string(REPLACE "/" "\\" SOURCE_PATH_MSVC "${SOURCE_PATH}") 13 | source_group("${GROUP_NAME}\\${SOURCE_PATH_MSVC}" FILES "${FILE}") 14 | endforeach() 15 | endfunction() 16 | 17 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 18 | 19 | add_subdirectory(rocky) 20 | add_subdirectory(apps) 21 | add_subdirectory(tests) 22 | -------------------------------------------------------------------------------- /src/apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(ROCKY_RENDERER_VSG) 2 | add_subdirectory(rocky_simple) 3 | add_subdirectory(rocky_engine) 4 | 5 | if(ROCKY_SUPPORTS_IMGUI) 6 | add_subdirectory(rocky_demo) 7 | endif() 8 | 9 | if(ROCKY_SUPPORTS_QT) 10 | add_subdirectory(rocky_demo_qt) 11 | endif() 12 | endif() 13 | -------------------------------------------------------------------------------- /src/apps/rocky_demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(APP_NAME rocky_demo) 2 | 3 | find_package(ImGui REQUIRED) 4 | 5 | file(GLOB SOURCES *.cpp vsgImGui/*.cpp) 6 | file(GLOB HEADERS *.h vsgImGui/*.h) 7 | 8 | # enable folders for IDEs 9 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 10 | assign_source_groups("Source Files" "${CMAKE_CURRENT_SOURCE_DIR}" ${SOURCES}) 11 | assign_source_groups("Header Files" "${CMAKE_CURRENT_SOURCE_DIR}" ${HEADERS}) 12 | 13 | add_executable(${APP_NAME} ${SOURCES} ${HEADERS}) 14 | 15 | target_link_libraries(${APP_NAME} rocky imgui::imgui) 16 | 17 | install(TARGETS ${APP_NAME} RUNTIME DESTINATION bin) 18 | 19 | set_target_properties(${APP_NAME} PROPERTIES FOLDER "apps") 20 | -------------------------------------------------------------------------------- /src/apps/rocky_demo/Demo_Environment.h: -------------------------------------------------------------------------------- 1 | /** 2 | * rocky c++ 3 | * Copyright 2023 Pelican Mapping 4 | * MIT License 5 | */ 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "helpers.h" 11 | using namespace ROCKY_NAMESPACE; 12 | 13 | auto Demo_Environment = [](Application& app) 14 | { 15 | if (app.skyNode == nullptr) 16 | { 17 | ImGui::TextColored(ImVec4(1, 0, 0, 1), "Sky is not installed"); 18 | 19 | if (ImGui::Button("Install sky")) 20 | { 21 | app.context->onNextUpdate([&app]() 22 | { 23 | app.skyNode = SkyNode::create(app.context); 24 | app.mainScene->children.insert(app.mainScene->children.begin(), app.skyNode); 25 | app.context->compile(app.skyNode); 26 | }); 27 | } 28 | 29 | return; 30 | } 31 | 32 | static DateTime dt; 33 | 34 | if (ImGuiLTable::Begin("environment")) 35 | { 36 | float hours = (float)dt.hours(); 37 | if (ImGuiLTable::SliderFloat("Time of day (UTC)", &hours, 0.0f, 23.999f, "%.1f")) 38 | { 39 | dt = DateTime(dt.year(), dt.month(), dt.day(), hours); 40 | app.skyNode->setDateTime(dt); 41 | } 42 | 43 | float ambient = app.skyNode->ambient->color.r; 44 | if (ImGuiLTable::SliderFloat("Ambient level", &ambient, 0.0f, 1.0f, "%.3f", ImGuiSliderFlags_Logarithmic)) 45 | { 46 | app.skyNode->ambient->color = { ambient, ambient, ambient }; 47 | } 48 | 49 | ImGuiLTable::End(); 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /src/apps/rocky_demo/Demo_Icon.h: -------------------------------------------------------------------------------- 1 | /** 2 | * rocky c++ 3 | * Copyright 2023 Pelican Mapping 4 | * MIT License 5 | */ 6 | #pragma once 7 | #include 8 | #include "helpers.h" 9 | 10 | using namespace ROCKY_NAMESPACE; 11 | 12 | auto Demo_Icon = [](Application& app) 13 | { 14 | static entt::entity entity = entt::null; 15 | static Status status; 16 | 17 | if (status.failed()) 18 | { 19 | ImGui::TextColored(ImVec4(1, 0, 0, 1), "Image load failed"); 20 | ImGui::TextColored(ImVec4(1, 0, 0, 1), status.message.c_str()); 21 | return; 22 | } 23 | 24 | if (entity == entt::null) 25 | { 26 | auto [lock, registry] = app.registry.write(); 27 | 28 | // Load an icon image 29 | auto io = app.context->io; 30 | auto image = io.services.readImageFromURI("https://readymap.org/readymap/filemanager/download/public/icons/BENDER.png", io); 31 | if (image.status.failed()) 32 | { 33 | status = image.status; 34 | return; 35 | } 36 | 37 | // Make an entity to host our icon: 38 | entity = registry.create(); 39 | 40 | // Attach the new Icon and set up its properties: 41 | auto& icon = registry.emplace(entity); 42 | icon.image = image.value; 43 | icon.style = IconStyle{ 75, 0.0f }; // pixel size, rotation(radians) 44 | 45 | // Transform to place the icon: 46 | auto& transform = registry.emplace(entity); 47 | transform.position = GeoPoint(SRS::WGS84, 0, 0, 50000); 48 | transform.topocentric = false; // optimization for billboards :) 49 | } 50 | 51 | if (ImGuiLTable::Begin("icon")) 52 | { 53 | auto [lock, registry] = app.registry.read(); 54 | 55 | bool visible = ecs::visible(registry, entity); 56 | if (ImGuiLTable::Checkbox("Show", &visible)) 57 | ecs::setVisible(registry, entity, visible); 58 | 59 | auto& icon = registry.get(entity); 60 | 61 | if (ImGuiLTable::SliderFloat("Pixel size", &icon.style.size_pixels, 1.0f, 1024.0f)) 62 | icon.revision++; 63 | 64 | if (ImGuiLTable::SliderFloat("Rotation", &icon.style.rotation_radians, 0.0f, 6.28f)) 65 | icon.revision++; 66 | 67 | ImGuiLTable::End(); 68 | } 69 | }; 70 | -------------------------------------------------------------------------------- /src/apps/rocky_demo/Demo_Label.h: -------------------------------------------------------------------------------- 1 | /** 2 | * rocky c++ 3 | * Copyright 2023 Pelican Mapping 4 | * MIT License 5 | */ 6 | #pragma once 7 | #include "helpers.h" 8 | using namespace ROCKY_NAMESPACE; 9 | 10 | auto Demo_Label = [](Application& app) 11 | { 12 | static entt::entity entity = entt::null; 13 | static Status status; 14 | 15 | auto& font = app.context->defaultFont; 16 | if (!font) 17 | { 18 | ImGui::TextWrapped(status.message.c_str()); 19 | status = Status(Status::ResourceUnavailable, 20 | "No font available - did you set the ROCKY_DEFAULT_FONT environment variable?"); 21 | return; 22 | } 23 | 24 | if (entity == entt::null) 25 | { 26 | auto [lock, registry] = app.registry.write(); 27 | 28 | // Create a host entity 29 | entity = registry.create(); 30 | 31 | // Attach a label to the host and configure it 32 | auto& label = registry.emplace