├── src
├── CMakeLists.txt
└── vsgPoints
│ ├── vsgPointsConfig.cmake.in
│ ├── CMakeLists.txt
│ ├── Bricks.cpp
│ ├── AsciiPoints.cpp
│ ├── BIN.cpp
│ ├── shaders
│ ├── brick_flat_shaded_frag.cpp
│ ├── brick_vert.cpp
│ └── brick_phong_frag.cpp
│ ├── Brick.cpp
│ ├── BrickShaderSet.cpp
│ └── create.cpp
├── applications
├── CMakeLists.txt
└── vsgpoints_example
│ ├── CMakeLists.txt
│ ├── ConvertMeshToPoints.h
│ ├── ConvertMeshToPoints.cpp
│ └── vsgpoints_example.cpp
├── LICENSE.md
├── .gitignore
├── CMakeLists.txt
├── data
└── shaders
│ ├── brick_flat_shaded.frag
│ ├── brick.vert
│ └── brick_phong.frag
├── include
└── vsgPoints
│ ├── Export.h
│ ├── BIN.h
│ ├── AsciiPoints.h
│ ├── BrickShaderSet.h
│ ├── Brick.h
│ ├── create.h
│ ├── Settings.h
│ └── Bricks.h
├── .clang-format
└── README.md
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(vsgPoints)
2 |
--------------------------------------------------------------------------------
/applications/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(vsgpoints_example)
2 |
--------------------------------------------------------------------------------
/src/vsgPoints/vsgPointsConfig.cmake.in:
--------------------------------------------------------------------------------
1 | include(CMakeFindDependencyMacro)
2 |
3 | find_dependency(vsg)
4 |
5 | include("${CMAKE_CURRENT_LIST_DIR}/vsgPointsTargets.cmake")
6 |
--------------------------------------------------------------------------------
/applications/vsgpoints_example/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(SOURCES
2 | ConvertMeshToPoints.cpp
3 | vsgpoints_example.cpp
4 | )
5 |
6 | add_executable(vsgpoints_example ${SOURCES})
7 |
8 | target_link_libraries(vsgpoints_example vsg::vsg vsgPoints::vsgPoints)
9 |
10 | if (vsgXchange_FOUND)
11 | target_compile_definitions(vsgpoints_example PRIVATE vsgXchange_FOUND)
12 | target_link_libraries(vsgpoints_example vsgXchange::vsgXchange)
13 | endif()
14 |
15 | install(TARGETS vsgpoints_example RUNTIME DESTINATION bin)
16 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Robert Osfield
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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | cmake_uninstall.cmake
3 |
4 | lib/
5 | bin/
6 |
7 | # Autogenerated files
8 | # include/vsgPoints/Version.h
9 |
10 | *.pc
11 | *.conf
12 | *.backup
13 | CMakeCache.txt
14 | CMakeFiles
15 | CMakeScripts
16 | Makefile
17 | cmake_install.cmake
18 | install_manifest.txt
19 | CMakeDoxyfile.in
20 | CMakeDoxygenDefaults.cmake
21 | Doxyfile.docs
22 | Doxyfile.docs-vsgPoints
23 | vsgPointsConfig.cmake
24 | vsgPointsConfigVersion.cmake
25 |
26 |
27 | # Compiled Object files
28 | *.slo
29 | *.lo
30 | *.o
31 | *.obj
32 |
33 | # Precompiled Headers
34 | *.gch
35 | *.pch
36 |
37 | # Compiled Dynamic libraries
38 | *.so
39 | *.dylib
40 | *.dll
41 |
42 | # Fortran module files
43 | *.mod
44 |
45 | # Compiled Static libraries
46 | *.lai
47 | *.la
48 | *.a
49 | *.lib
50 |
51 | # Executables
52 | *.exe
53 | *.out
54 | *.app
55 |
56 | # Visual Studio files
57 | *.sln
58 | *.vcxproj
59 | *.vcxproj.filters
60 | *.vcxproj.user
61 | .vs/
62 | x64/
63 | src/vsgPoints/vsgPoints.dir/
64 | *.pdb
65 | *.tlog
66 | *.log
67 |
68 | # Xcode
69 | DerivedData/
70 | *.build
71 | *.xcodeproj
72 |
73 | # Gradle
74 | .gradle/
75 | .idea/
76 | .externalNativeBuild/
77 | *.iml
78 | build/
79 | local.properties
80 |
81 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.12)
2 |
3 | project(vsgPoints
4 | VERSION 0.7.0
5 | DESCRIPTION "VulkanSceneGraph Point Cloud rendering."
6 | LANGUAGES CXX
7 | )
8 | set(VSGPOINTS_SOVERSION 0)
9 | SET(VSGPOINTS_RELEASE_CANDIDATE 0)
10 |
11 | set(VSGPOINTS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Root source directory of vsgPoints")
12 | set(VSGPOINTS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "Root binary directory of vsgPoints")
13 |
14 |
15 | # Find Vulkan and the VSG
16 | if (VULKAN_SDK)
17 | set(ENV{VULKAN_SDK} ${VULKAN_SDK})
18 | endif()
19 |
20 | find_package(vsg 1.1.13 REQUIRED)
21 | find_package(vsgXchange 1.1.9 REQUIRED)
22 |
23 | vsg_setup_build_vars()
24 | vsg_setup_dir_vars()
25 |
26 | vsg_add_target_clang_format(
27 | FILES
28 | include/vsgPoints/*.h
29 | src/vsgPoints/*.cpp
30 | )
31 | vsg_add_target_clobber()
32 | vsg_add_target_cppcheck(
33 | FILES
34 | ${CMAKE_SOURCE_DIR}/src/vsgPoints/*.cpp
35 | ${CMAKE_SOURCE_DIR}/include/vsgPoints/*.h
36 | )
37 | vsg_add_target_docs(
38 | FILES
39 | include
40 | )
41 | vsg_add_target_uninstall()
42 |
43 | if (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR})
44 |
45 | vsg_add_option_maintainer(
46 | PREFIX v
47 | RCLEVEL ${VSGPOINTS_RELEASE_CANDIDATE}
48 | )
49 |
50 | endif()
51 |
52 | # source directories for vsgPoints library
53 | add_subdirectory(src)
54 | add_subdirectory(applications)
55 |
56 | vsg_add_feature_summary()
57 |
--------------------------------------------------------------------------------
/data/shaders/brick_flat_shaded.frag:
--------------------------------------------------------------------------------
1 | #version 450
2 | #extension GL_ARB_separate_shader_objects : enable
3 | #pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP)
4 |
5 | #define VIEW_DESCRIPTOR_SET 0
6 | #define MATERIAL_DESCRIPTOR_SET 1
7 |
8 | #ifdef VSG_DIFFUSE_MAP
9 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap;
10 | #endif
11 |
12 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform MaterialData
13 | {
14 | vec4 ambientColor;
15 | vec4 diffuseColor;
16 | vec4 specularColor;
17 | vec4 emissiveColor;
18 | float shininess;
19 | float alphaMask;
20 | float alphaMaskCutoff;
21 | } material;
22 |
23 | layout(location = 2) in vec4 vertexColor;
24 |
25 | #ifndef VSG_POINT_SPRITE
26 | layout(location = 3) in vec2 texCoord0;
27 | #endif
28 |
29 | layout(location = 0) out vec4 outColor;
30 |
31 | void main()
32 | {
33 | #ifdef VSG_POINT_SPRITE
34 | vec2 texCoord0 = gl_PointCoord.xy;
35 | #endif
36 |
37 | vec4 diffuseColor = vertexColor * material.diffuseColor;
38 |
39 | #ifdef VSG_DIFFUSE_MAP
40 | #ifdef VSG_GREYSCALE_DIFFUSE_MAP
41 | float v = texture(diffuseMap, texCoord0.st).s;
42 | diffuseColor *= vec4(v, v, v, 1.0);
43 | #else
44 | diffuseColor *= texture(diffuseMap, texCoord0.st);
45 | #endif
46 | #endif
47 |
48 | if (material.alphaMask == 1.0f)
49 | {
50 | if (diffuseColor.a < material.alphaMaskCutoff)
51 | discard;
52 | }
53 |
54 | outColor = diffuseColor;
55 | }
56 |
--------------------------------------------------------------------------------
/include/vsgPoints/Export.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2022 Robert Osfield
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | this software and associated documentation files (the "Software"), to deal in
9 | the Software without restriction, including without limitation the rights to
10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 | the Software, and to permit persons to whom the Software is furnished to do so,
12 | subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | */
25 |
26 | #if (defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__))
27 | # if defined(vsgPoints_EXPORTS)
28 | # define VSGPOINTS_DECLSPEC __declspec(dllexport)
29 | # elif defined(VSGPOINTS_SHARED_LIBRARY)
30 | # define VSGPOINTS_DECLSPEC __declspec(dllimport)
31 | # else
32 | # define VSGPOINTS_DECLSPEC
33 | # endif
34 | #else
35 | # define VSGPOINTS_DECLSPEC
36 | #endif
37 |
--------------------------------------------------------------------------------
/include/vsgPoints/BIN.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2023 Robert Osfield
6 |
7 | 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:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | 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.
12 |
13 | */
14 |
15 | #include
16 |
17 | #include
18 |
19 | namespace vsgPoints
20 | {
21 |
22 | class VSGPOINTS_DECLSPEC BIN : public vsg::Inherit
23 | {
24 | public:
25 | BIN();
26 |
27 | vsg::ref_ptr read(const vsg::Path& filename, vsg::ref_ptr options) const override;
28 |
29 | std::set supportedExtensions;
30 | };
31 |
32 | } // namespace vsgPoints
33 |
--------------------------------------------------------------------------------
/include/vsgPoints/AsciiPoints.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2023 Robert Osfield
6 |
7 | 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:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | 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.
12 |
13 | */
14 |
15 | #include
16 |
17 | #include
18 |
19 | namespace vsgPoints
20 | {
21 |
22 | class VSGPOINTS_DECLSPEC AsciiPoints : public vsg::Inherit
23 | {
24 | public:
25 | AsciiPoints();
26 |
27 | vsg::ref_ptr read(const vsg::Path& filename, vsg::ref_ptr options) const override;
28 |
29 | std::set supportedExtensions;
30 | };
31 |
32 | } // namespace vsgPoints
33 |
--------------------------------------------------------------------------------
/include/vsgPoints/BrickShaderSet.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2022 Robert Osfield
6 |
7 | 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:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | 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.
12 |
13 | */
14 |
15 | #include
16 |
17 | #include
18 |
19 | namespace vsgPoints
20 | {
21 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createParticleImage(uint32_t dim);
22 |
23 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createPointsFlatShadedShaderSet(vsg::ref_ptr options);
24 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createPointsPhongShaderSet(vsg::ref_ptr options);
25 | } // namespace vsgPoints
26 |
--------------------------------------------------------------------------------
/data/shaders/brick.vert:
--------------------------------------------------------------------------------
1 | #version 450
2 | #extension GL_ARB_separate_shader_objects : enable
3 | #pragma import_defines (VSG_POSITION_SCALE)
4 |
5 | #define VIEW_DESCRIPTOR_SET 0
6 | #define MATERIAL_DESCRIPTOR_SET 1
7 |
8 | layout(push_constant) uniform PushConstants {
9 | mat4 projection;
10 | mat4 modelView;
11 | } pc;
12 |
13 |
14 | layout(location = 0) in vec3 vsg_Vertex;
15 | layout(location = 1) in vec3 vsg_Normal;
16 | layout(location = 2) in vec4 vsg_Color;
17 |
18 | #ifdef VSG_POSITION_SCALE
19 | layout(location = 3) in vec4 vsg_PositionScale;
20 | #endif
21 |
22 | layout(location = 4) in vec2 vsg_PointSize;
23 |
24 | layout(location = 0) out vec3 eyePos;
25 | layout(location = 1) out vec3 normalDir;
26 | layout(location = 2) out vec4 vertexColor;
27 |
28 | layout(location = 5) out vec3 viewDir;
29 |
30 | layout(set = VIEW_DESCRIPTOR_SET, binding = 1) buffer ViewportData
31 | {
32 | vec4 values[];
33 | } viewportData;
34 |
35 | out gl_PerVertex{
36 | vec4 gl_Position;
37 | float gl_PointSize;
38 | };
39 |
40 | void main()
41 | {
42 |
43 | #ifdef VSG_POSITION_SCALE
44 | vec4 vertex = vec4(vsg_PositionScale.xyz + vsg_Vertex * vsg_PositionScale.w, 1.0);
45 | #else
46 | vec4 vertex = vec4(vsg_Vertex, 1.0);
47 | #endif
48 |
49 | vec4 normal = vec4(vsg_Normal, 0.0);
50 |
51 | gl_Position = (pc.projection * pc.modelView) * vertex;
52 |
53 | eyePos = vec4(pc.modelView * vertex).xyz;
54 | viewDir = -eyePos;//normalize(-eyePos);
55 | normalDir = (pc.modelView * normal).xyz;
56 | vertexColor = vsg_Color;
57 |
58 | float dist = max(vsg_PointSize[1], abs(eyePos.z));
59 | vec4 viewport = viewportData.values[0];
60 | gl_PointSize = viewport[3] * (vsg_PointSize[0] / dist);
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/include/vsgPoints/Brick.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2023 Robert Osfield
6 |
7 | 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:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | 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.
12 |
13 | */
14 |
15 | #include
16 |
17 | namespace vsgPoints
18 | {
19 | #pragma pack(1)
20 |
21 | struct PackedPoint
22 | {
23 | vsg::usvec3 v;
24 | vsg::ubvec4 c;
25 | };
26 |
27 | #pragma pack()
28 |
29 | using Key = vsg::ivec4;
30 |
31 | class VSGPOINTS_DECLSPEC Brick : public vsg::Inherit
32 | {
33 | public:
34 | Brick();
35 |
36 | std::vector points;
37 |
38 | vsg::ref_ptr createRendering(const Settings& settings, const vsg::vec4& positionScale, const vsg::vec2& pointSize);
39 | vsg::ref_ptr createRendering(const Settings& settings, Key key, vsg::dbox& bound);
40 |
41 | protected:
42 | virtual ~Brick();
43 | };
44 |
45 | } // namespace vsgPoints
46 |
47 | EVSG_type_name(vsgPoints::Brick)
48 |
--------------------------------------------------------------------------------
/applications/vsgpoints_example/ConvertMeshToPoints.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | class ConvertMeshToPoints : public vsg::Inherit
6 | {
7 | public:
8 |
9 | ConvertMeshToPoints(vsg::ref_ptr settings);
10 |
11 | vsg::ref_ptr bricks = vsgPoints::Bricks::create();
12 |
13 | using ArrayStateStack = std::vector>;
14 | ArrayStateStack arrayStateStack;
15 | vsg::ref_ptr ushort_indices;
16 | vsg::ref_ptr uint_indices;
17 |
18 | /// get the current local to world matrix stack
19 | std::vector& localToWorldStack() { return arrayStateStack.back()->localToWorldStack; }
20 | vsg::dmat4 localToWorld() const { auto matrixStack = arrayStateStack.back()->localToWorldStack; return matrixStack.empty() ? vsg::dmat4{} : matrixStack.back(); }
21 |
22 | void applyDraw(uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount);
23 | void applyDrawIndexed(uint32_t firstIndex, uint32_t indexCount, uint32_t firstInstance, uint32_t instanceCount);
24 |
25 | void apply(const vsg::Node& node) override;
26 | void apply(const vsg::StateGroup& stategroup) override;
27 | void apply(const vsg::Transform& transform) override;
28 | void apply(const vsg::LOD& lod) override;
29 | void apply(const vsg::PagedLOD& plod) override;
30 | void apply(const vsg::VertexDraw& vid) override;
31 | void apply(const vsg::VertexIndexDraw& vid) override;
32 | void apply(const vsg::Geometry& geometry) override;
33 | void apply(const vsg::BindVertexBuffers& bvb) override;
34 | void apply(const vsg::BindIndexBuffer& bib) override;
35 | void apply(const vsg::BufferInfo& bufferInfo) override;
36 | void apply(const vsg::ushortArray& array) override;
37 | void apply(const vsg::uintArray& array) override;
38 | void apply(const vsg::Draw& draw) override;
39 | void apply(const vsg::DrawIndexed& drawIndexed) override;
40 | };
41 |
--------------------------------------------------------------------------------
/include/vsgPoints/create.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2023 Robert Osfield
6 |
7 | 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:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | 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.
12 |
13 | */
14 |
15 | #include
16 |
17 | #include
18 |
19 | namespace vsgPoints
20 | {
21 |
22 | /// create a scene graph from Bricks using the Setttings as a guide to the type of scene graph to create.
23 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createSceneGraph(vsg::ref_ptr bricks, vsg::ref_ptr settings);
24 |
25 | extern VSGPOINTS_DECLSPEC bool generateLevel(vsgPoints::Bricks& source, vsgPoints::Bricks& destination, const vsgPoints::Settings& settings);
26 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createStateGroup(const vsgPoints::Settings& settings);
27 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr subtile(vsgPoints::Settings& settings, vsgPoints::Levels::reverse_iterator level_itr, vsgPoints::Levels::reverse_iterator end_itr, vsgPoints::Key key, vsg::dbox& bound, bool root = false);
28 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createPagedLOD(vsgPoints::Levels& levels, vsgPoints::Settings& settings);
29 |
30 | } // namespace vsgPoints
31 |
--------------------------------------------------------------------------------
/src/vsgPoints/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
2 | # vars used to enable subdirectories to extend the build of the vsgPoints library in a loosely coupled way
3 | set(EXTRA_DEFINES)
4 | set(EXTRA_INCLUDES)
5 |
6 | SET(HEADER_PATH ${VSGPOINTS_SOURCE_DIR}/include/vsgPoints)
7 |
8 | set(HEADERS
9 | ${HEADER_PATH}/Export.h
10 | ${HEADER_PATH}/AsciiPoints.h
11 | ${HEADER_PATH}/BIN.h
12 | ${HEADER_PATH}/Brick.h
13 | ${HEADER_PATH}/Bricks.h
14 | ${HEADER_PATH}/BrickShaderSet.h
15 | ${HEADER_PATH}/Settings.h
16 | ${HEADER_PATH}/create.h
17 | )
18 |
19 | set(SOURCES
20 | AsciiPoints.cpp
21 | BIN.cpp
22 | Brick.cpp
23 | Bricks.cpp
24 | BrickShaderSet.cpp
25 | create.cpp
26 | )
27 |
28 | add_library(vsgPoints ${HEADERS} ${SOURCES})
29 |
30 | # add definitions to enable building vsgPoints as part of submodule
31 | add_library(vsgPoints::vsgPoints ALIAS vsgPoints)
32 | set(vsgPoints_FOUND TRUE CACHE INTERNAL "vsgPoints found.")
33 | set(CMAKE_DISABLE_FIND_PACKAGE_vsgPoints TRUE CACHE INTERNAL "Disable find_package(vsgPoints) as it's not necessary.")
34 |
35 | set_property(TARGET vsgPoints PROPERTY VERSION ${VSGPOINTS_VERSION_MAJOR}.${VSGPOINTS_VERSION_MINOR}.${VSGPOINTS_VERSION_PATCH})
36 | set_property(TARGET vsgPoints PROPERTY SOVERSION ${VSGPOINTS_SOVERSION})
37 | set_property(TARGET vsgPoints PROPERTY POSITION_INDEPENDENT_CODE ON)
38 | set_property(TARGET vsgPoints PROPERTY CXX_STANDARD 17)
39 |
40 | target_compile_definitions(vsgPoints PRIVATE ${EXTRA_DEFINES})
41 |
42 | target_include_directories(vsgPoints PUBLIC
43 | $
44 | $
45 | $
46 | ${EXTRA_INCLUDES}
47 | )
48 |
49 | target_link_libraries(vsgPoints
50 | PUBLIC
51 | vsg::vsg
52 | PRIVATE
53 | ${EXTRA_LIBRARIES}
54 | )
55 |
56 | install(TARGETS vsgPoints ${INSTALL_TARGETS_DEFAULT_FLAGS})
57 |
58 | if (BUILD_SHARED_LIBS)
59 | target_compile_definitions(vsgPoints INTERFACE VSGPOINTS_SHARED_LIBRARY)
60 | endif()
61 |
62 |
63 | install(DIRECTORY ${VSGPOINTS_SOURCE_DIR}/include/vsgPoints DESTINATION include)
64 |
65 | vsg_add_cmake_support_files(
66 | CONFIG_TEMPLATE
67 | vsgPointsConfig.cmake.in
68 | )
69 |
--------------------------------------------------------------------------------
/include/vsgPoints/Settings.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2023 Robert Osfield
6 |
7 | 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:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | 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.
12 |
13 | */
14 |
15 | #include
16 |
17 | #include
18 |
19 | namespace vsgPoints
20 | {
21 |
22 | enum CreateType
23 | {
24 | CREATE_FLAT, /// generate a flat scene graph with no LOD/PagedLOD, only suitable for small datasets
25 | CREATE_LOD, /// generate a hierarchical LOD scene graph, suitable for small to moderate sized datasets that can entirely fit in GPU memory
26 | CREATE_PAGEDLOD, /// generate a PagedLOD scene graph, suitable for large datasets that can't fit entirely in GPU memory
27 | };
28 |
29 | struct Settings : public vsg::Inherit
30 | {
31 | size_t numPointsPerBlock = 10000;
32 | double precision = 0.001;
33 | uint32_t bits = 10;
34 | float pointSize = 4.0f;
35 | float transition = 0.125f;
36 |
37 | CreateType createType = CREATE_LOD;
38 |
39 | vsg::Path path;
40 | vsg::Path extension = ".vsgb";
41 | vsg::ref_ptr options;
42 | vsg::dvec3 offset;
43 | vsg::dbox bound;
44 | };
45 |
46 | } // namespace vsgPoints
47 |
48 | EVSG_type_name(vsgPoints::Settings)
49 |
--------------------------------------------------------------------------------
/include/vsgPoints/Bricks.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 |
5 | Copyright(c) 2023 Robert Osfield
6 |
7 | 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:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | 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.
12 |
13 | */
14 |
15 | #include
16 |
17 | #include
18 |
19 | #include
20 |
21 | namespace vsgPoints
22 | {
23 | class VSGPOINTS_DECLSPEC Bricks : public vsg::Inherit
24 | {
25 | public:
26 | Bricks(vsg::ref_ptr in_settings = {});
27 |
28 | using BrickMap = std::map>;
29 | using key_type = BrickMap::key_type;
30 | using mapped_type = BrickMap::mapped_type;
31 | using value_type = BrickMap::value_type;
32 | using iterator = BrickMap::iterator;
33 | using const_iterator = BrickMap::const_iterator;
34 |
35 | vsg::ref_ptr settings;
36 | BrickMap bricks;
37 |
38 | void add(const vsg::dvec3& v, const vsg::ubvec4& c);
39 |
40 | iterator find(Key key) { return bricks.find(key); }
41 | const_iterator find(Key key) const { return bricks.find(key); }
42 |
43 | mapped_type& operator[](Key key) { return bricks[key]; }
44 |
45 | iterator begin() { return bricks.begin(); }
46 | iterator end() { return bricks.end(); }
47 |
48 | const_iterator begin() const { return bricks.begin(); }
49 | const_iterator end() const { return bricks.end(); }
50 |
51 | bool empty() const { return bricks.empty(); }
52 |
53 | size_t size() const { return bricks.size(); }
54 |
55 | // number of points
56 | size_t count() const;
57 | };
58 |
59 | using Levels = std::list>;
60 |
61 | } // namespace vsgPoints
62 |
63 | EVSG_type_name(vsgPoints::Bricks)
64 |
--------------------------------------------------------------------------------
/src/vsgPoints/Bricks.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright(c) 2023 Robert Osfield
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
10 |
11 | */
12 |
13 | #include
14 |
15 | #include
16 |
17 | #include
18 |
19 | using namespace vsgPoints;
20 |
21 | Bricks::Bricks(vsg::ref_ptr in_settings) :
22 | settings(in_settings)
23 | {
24 | }
25 |
26 | void Bricks::add(const vsg::dvec3& v, const vsg::ubvec4& c)
27 | {
28 | settings->bound.add(v);
29 |
30 | auto divide_round = [](int64_t value, int64_t divisor) -> int64_t {
31 | if (value < 0)
32 | return -1 - (-value / divisor);
33 | else
34 | return value / divisor;
35 | };
36 |
37 | double multiplier = 1.0 / settings->precision;
38 | int64_t divisor = 1 << settings->bits;
39 |
40 | vsg::dvec3 scaled_v = v * multiplier;
41 | vsg::dvec3 rounded_v = {std::round(scaled_v.x), std::round(scaled_v.y), std::round(scaled_v.z)};
42 | vsg::t_vec3 int64_v = {static_cast(rounded_v.x), static_cast(rounded_v.y), static_cast(rounded_v.z)};
43 | vsg::t_vec3 int64_key = {divide_round(int64_v.x, divisor), divide_round(int64_v.y, divisor), divide_round(int64_v.z, divisor)};
44 | Key key = {static_cast(int64_key.x), static_cast(int64_key.y), static_cast(int64_key.z), 1};
45 |
46 | PackedPoint packedPoint;
47 | packedPoint.v.set(int64_v.x - key.x * divisor, int64_v.y - key.y * divisor, int64_v.z - key.z * divisor);
48 | packedPoint.c.set(c.r, c.g, c.b, c.a);
49 |
50 | auto& brick = bricks[key];
51 | if (!brick)
52 | {
53 | brick = Brick::create();
54 | }
55 |
56 | brick->points.push_back(packedPoint);
57 | }
58 |
59 | size_t Bricks::count() const
60 | {
61 | size_t num = 0;
62 | for (auto& [key, brick] : bricks)
63 | {
64 | num += brick->points.size();
65 | }
66 | return num;
67 | }
68 |
--------------------------------------------------------------------------------
/src/vsgPoints/AsciiPoints.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright(c) 2023 Robert Osfield
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
10 |
11 | */
12 |
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include
22 |
23 | #include
24 |
25 | using namespace vsgPoints;
26 |
27 | AsciiPoints::AsciiPoints() :
28 | supportedExtensions{".3dc", ".asc"}
29 | {
30 | }
31 |
32 | vsg::ref_ptr AsciiPoints::read(const vsg::Path& filename, vsg::ref_ptr options) const
33 | {
34 | if (!vsg::compatibleExtension(filename, options, supportedExtensions)) return {};
35 |
36 | auto filenameToUse = vsg::findFile(filename, options);
37 | if (!filenameToUse) return {};
38 |
39 | vsg::ref_ptr settings;
40 | if (options) settings = const_cast(options.get())->getRefObject("settings");
41 | if (!settings) settings = vsgPoints::Settings::create();
42 |
43 | if (settings->bits != 8 && settings->bits != 10 && settings->bits != 16)
44 | {
45 | std::cout << "Error: " << settings->bits << " not supported, valid values are 8, 10 and 16." << std::endl;
46 | return {};
47 | }
48 |
49 | auto bricks = vsgPoints::Bricks::create(settings);
50 |
51 | auto values = vsg::doubleArray::create(10);
52 | uint8_t alpha = 255;
53 |
54 | std::ifstream fin(filenameToUse);
55 | while (fin)
56 | {
57 | if (auto numValuesRead = vsg::read_line(fin, values->data(), values->size()))
58 | {
59 | if (numValuesRead >= 6)
60 | {
61 | bricks->add(vsg::dvec3(values->at(0), values->at(1), values->at(2)), vsg::ubvec4(values->at(3), values->at(4), values->at(5), alpha));
62 | }
63 | }
64 | }
65 |
66 | if (bricks->empty()) return {};
67 |
68 | return bricks;
69 | }
70 |
--------------------------------------------------------------------------------
/src/vsgPoints/BIN.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright(c) 2023 Robert Osfield
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
10 |
11 | */
12 |
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 |
20 | #include
21 |
22 | #include
23 |
24 | using namespace vsgPoints;
25 |
26 | #pragma pack(1)
27 |
28 | struct VsgIOPoint
29 | {
30 | vsg::dvec3 v;
31 | vsg::ubvec3 c;
32 | };
33 |
34 | #pragma pack()
35 |
36 | BIN::BIN() :
37 | supportedExtensions{".bin"}
38 | {
39 | }
40 |
41 | vsg::ref_ptr BIN::read(const vsg::Path& filename, vsg::ref_ptr options) const
42 | {
43 | if (!vsg::compatibleExtension(filename, options, supportedExtensions)) return {};
44 |
45 | auto found_filename = vsg::findFile(filename, options);
46 | if (!found_filename) return {};
47 |
48 | vsg::ref_ptr settings;
49 | if (options) settings = const_cast(options.get())->getRefObject("settings");
50 | if (!settings) settings = vsgPoints::Settings::create();
51 |
52 | if (settings->bits != 8 && settings->bits != 10 && settings->bits != 16)
53 | {
54 | std::cout << "Error: " << settings->bits << " not supported, valid values are 8, 10 and 16." << std::endl;
55 | return {};
56 | }
57 |
58 | auto bricks = Bricks::create(settings);
59 |
60 | std::ifstream fin(found_filename, std::ios::in | std::ios::binary);
61 | if (!fin) return {};
62 |
63 | auto points = vsg::Array::create(settings->numPointsPerBlock);
64 | uint8_t alpha = 255;
65 |
66 | while (fin)
67 | {
68 | size_t bytesToRead = settings->numPointsPerBlock * sizeof(VsgIOPoint);
69 | fin.read(reinterpret_cast(points->dataPointer()), bytesToRead);
70 |
71 | size_t numPointsRead = static_cast(fin.gcount()) / sizeof(VsgIOPoint);
72 | if (numPointsRead == 0) break;
73 |
74 | for (size_t i = 0; i < numPointsRead; ++i)
75 | {
76 | auto& point = (*points)[i];
77 | bricks->add(point.v, vsg::ubvec4(point.c.r, point.c.g, point.c.b, alpha));
78 | }
79 | }
80 |
81 | if (bricks->empty())
82 | {
83 | std::cout << "Waring: unable to read file." << std::endl;
84 | return {};
85 | }
86 | else
87 | {
88 | return bricks;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | Language: Cpp
3 | # BasedOnStyle: LLVM
4 | AccessModifierOffset: -4
5 | AlignAfterOpenBracket: Align
6 | AlignConsecutiveAssignments: false
7 | AlignConsecutiveDeclarations: false
8 | AlignEscapedNewlines: Right
9 | AlignOperands: true
10 | AlignTrailingComments: true
11 | AllowAllParametersOfDeclarationOnNextLine: true
12 | AllowShortBlocksOnASingleLine: true
13 | AllowShortCaseLabelsOnASingleLine: true
14 | AllowShortFunctionsOnASingleLine: InlineOnly
15 | AllowShortIfStatementsOnASingleLine: true
16 | AllowShortLoopsOnASingleLine: true
17 | AlwaysBreakAfterDefinitionReturnType: None
18 | AlwaysBreakAfterReturnType: None
19 | AlwaysBreakBeforeMultilineStrings: false
20 | AlwaysBreakTemplateDeclarations: false
21 | BinPackArguments: true
22 | BinPackParameters: true
23 | BraceWrapping:
24 | AfterClass: true
25 | AfterControlStatement: true
26 | AfterEnum: true
27 | AfterFunction: true
28 | AfterNamespace: true
29 | AfterObjCDeclaration: true
30 | AfterStruct: true
31 | AfterUnion: true
32 | AfterExternBlock: true
33 | BeforeCatch: true
34 | BeforeElse: true
35 | IndentBraces: false
36 | SplitEmptyFunction: true
37 | SplitEmptyRecord: true
38 | SplitEmptyNamespace: true
39 | BreakBeforeBinaryOperators: None
40 | BreakBeforeBraces: Custom
41 | BreakBeforeInheritanceComma: false
42 | BreakBeforeTernaryOperators: true
43 | BreakConstructorInitializersBeforeComma: true
44 | BreakConstructorInitializers: AfterColon
45 | BreakAfterJavaFieldAnnotations: false
46 | BreakStringLiterals: true
47 | ColumnLimit: 0
48 | CommentPragmas: '^ IWYU pragma:'
49 | CompactNamespaces: false
50 | ConstructorInitializerAllOnOneLineOrOnePerLine: true
51 | ConstructorInitializerIndentWidth: 4
52 | ContinuationIndentWidth: 4
53 | Cpp11BracedListStyle: true
54 | DerivePointerAlignment: false
55 | DisableFormat: false
56 | ExperimentalAutoDetectBinPacking: false
57 | FixNamespaceComments: true
58 | ForEachMacros:
59 | - foreach
60 | - Q_FOREACH
61 | - BOOST_FOREACH
62 | IncludeBlocks: Preserve
63 | IncludeCategories:
64 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
65 | Priority: 2
66 | - Regex: '^(<|"(gtest|gmock|isl|json)/)'
67 | Priority: 3
68 | - Regex: '.*'
69 | Priority: 1
70 | IncludeIsMainRegex: '(Test)?$'
71 | IndentCaseLabels: false
72 | IndentPPDirectives: AfterHash
73 | IndentWidth: 4
74 | IndentWrappedFunctionNames: false
75 | JavaScriptQuotes: Leave
76 | JavaScriptWrapImports: true
77 | KeepEmptyLinesAtTheStartOfBlocks: true
78 | MacroBlockBegin: ''
79 | MacroBlockEnd: ''
80 | MaxEmptyLinesToKeep: 1
81 | NamespaceIndentation: All
82 | ObjCBlockIndentWidth: 4
83 | ObjCSpaceAfterProperty: false
84 | ObjCSpaceBeforeProtocolList: true
85 | PenaltyBreakAssignment: 2
86 | PenaltyBreakBeforeFirstCallParameter: 19
87 | PenaltyBreakComment: 300
88 | PenaltyBreakFirstLessLess: 120
89 | PenaltyBreakString: 1000
90 | PenaltyExcessCharacter: 1000000
91 | PenaltyReturnTypeOnItsOwnLine: 60
92 | PointerAlignment: Left
93 | ReflowComments: false
94 | SortIncludes: true
95 | SortUsingDeclarations: true
96 | SpaceAfterCStyleCast: false
97 | SpaceAfterTemplateKeyword: false
98 | SpaceBeforeAssignmentOperators: true
99 | SpaceBeforeParens: ControlStatements
100 | SpaceInEmptyParentheses: false
101 | SpacesBeforeTrailingComments: 1
102 | SpacesInAngles: false
103 | SpacesInContainerLiterals: true
104 | SpacesInCStyleCastParentheses: false
105 | SpacesInParentheses: false
106 | SpacesInSquareBrackets: false
107 | Standard: Cpp11
108 | TabWidth: 8
109 | UseTab: Never
110 | ...
111 |
112 |
--------------------------------------------------------------------------------
/src/vsgPoints/shaders/brick_flat_shaded_frag.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | static auto brick_flat_shaded_frag = []() {
4 | static const char str[] =
5 | R"(#vsga 1.1.2
6 | Root id=1 vsg::ShaderStage
7 | {
8 | userObjects 0
9 | mask 18446744073709551615
10 | stage 16
11 | entryPointName "main"
12 | module id=2 vsg::ShaderModule
13 | {
14 | userObjects 0
15 | hints id=0
16 | source "#version 450
17 | #extension GL_ARB_separate_shader_objects : enable
18 | #pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP)
19 |
20 | #define VIEW_DESCRIPTOR_SET 0
21 | #define MATERIAL_DESCRIPTOR_SET 1
22 |
23 | #ifdef VSG_DIFFUSE_MAP
24 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap;
25 | #endif
26 |
27 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform MaterialData
28 | {
29 | vec4 ambientColor;
30 | vec4 diffuseColor;
31 | vec4 specularColor;
32 | vec4 emissiveColor;
33 | float shininess;
34 | float alphaMask;
35 | float alphaMaskCutoff;
36 | } material;
37 |
38 | layout(location = 2) in vec4 vertexColor;
39 |
40 | #ifndef VSG_POINT_SPRITE
41 | layout(location = 3) in vec2 texCoord0;
42 | #endif
43 |
44 | layout(location = 0) out vec4 outColor;
45 |
46 | void main()
47 | {
48 | #ifdef VSG_POINT_SPRITE
49 | vec2 texCoord0 = gl_PointCoord.xy;
50 | #endif
51 |
52 | vec4 diffuseColor = vertexColor * material.diffuseColor;
53 |
54 | #ifdef VSG_DIFFUSE_MAP
55 | #ifdef VSG_GREYSCALE_DIFFUSE_MAP
56 | float v = texture(diffuseMap, texCoord0.st).s;
57 | diffuseColor *= vec4(v, v, v, 1.0);
58 | #else
59 | diffuseColor *= texture(diffuseMap, texCoord0.st);
60 | #endif
61 | #endif
62 |
63 | if (material.alphaMask == 1.0f)
64 | {
65 | if (diffuseColor.a < material.alphaMaskCutoff)
66 | discard;
67 | }
68 |
69 | outColor = diffuseColor;
70 | }
71 | "
72 | code 386
73 | 119734787 65536 524299 49 0 131089 1 393227 1 1280527431 1685353262 808793134
74 | 0 196622 0 1 524303 4 4 1852399981 0 11 44 48
75 | 196624 4 7 196611 2 450 589828 1096764487 1935622738 1918988389 1600484449 1684105331
76 | 1868526181 1667590754 29556 262149 4 1852399981 0 393221 9 1717987684 1130722165 1919904879
77 | 0 327685 11 1953654134 1866692709 7499628 393221 13 1702125901 1818323314 1635017028 0
78 | 458758 13 0 1768058209 1131703909 1919904879 0 458758 13 1 1717987684 1130722165
79 | 1919904879 0 458758 13 2 1667592307 1918987381 1869377347 114 458758 13 3
80 | 1936289125 1702259059 1869377347 114 393222 13 4 1852401779 1936027241 115 393222 13
81 | 5 1752198241 1935756641 107 458758 13 6 1752198241 1935756641 1953842027 6710895 327685
82 | 15 1702125933 1818323314 0 327685 44 1131705711 1919904879 0 327685 48 1131963764
83 | 1685221231 48 262215 11 30 2 327752 13 0 35 0 327752
84 | 13 1 35 16 327752 13 2 35 32 327752 13 3
85 | 35 48 327752 13 4 35 64 327752 13 5 35 68
86 | 327752 13 6 35 72 196679 13 2 262215 15 34 1
87 | 262215 15 33 10 262215 44 30 0 262215 48 30 3
88 | 131091 2 196641 3 2 196630 6 32 262167 7 6 4
89 | 262176 8 7 7 262176 10 1 7 262203 10 11 1
90 | 589854 13 7 7 7 7 6 6 6 262176 14 2
91 | 13 262203 14 15 2 262165 16 32 1 262187 16 17
92 | 1 262176 18 2 7 262187 16 22 5 262176 23 2
93 | 6 262187 6 26 1065353216 131092 27 262165 31 32 0 262187
94 | 31 32 3 262176 33 7 6 262187 16 36 6 262176
95 | 43 3 7 262203 43 44 3 262167 46 6 2 262176
96 | 47 1 46 262203 47 48 1 327734 2 4 0 3
97 | 131320 5 262203 8 9 7 262205 7 12 11 327745 18
98 | 19 15 17 262205 7 20 19 327813 7 21 12 20
99 | 196670 9 21 327745 23 24 15 22 262205 6 25 24
100 | 327860 27 28 25 26 196855 30 0 262394 28 29 30
101 | 131320 29 327745 33 34 9 32 262205 6 35 34 327745
102 | 23 37 15 36 262205 6 38 37 327864 27 39 35
103 | 38 196855 41 0 262394 39 40 41 131320 40 65788 131320
104 | 41 131321 30 131320 30 262205 7 45 9 196670 44 45
105 | 65789 65592
106 | }
107 | NumSpecializationConstants 0
108 | }
109 | )";
110 | vsg::VSG io;
111 | return io.read_cast(reinterpret_cast(str), sizeof(str));
112 | };
113 |
--------------------------------------------------------------------------------
/src/vsgPoints/Brick.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright(c) 2023 Robert Osfield
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
10 |
11 | */
12 |
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 |
28 | using namespace vsgPoints;
29 |
30 | ////////////////////////////////////////////////////////////////////////////////////////////////////
31 | //
32 | // Brick
33 | //
34 | Brick::Brick()
35 | {
36 | }
37 |
38 | Brick::~Brick()
39 | {
40 | }
41 |
42 | vsg::ref_ptr Brick::createRendering(const Settings& settings, const vsg::vec4& positionScale, const vsg::vec2& pointSize)
43 | {
44 | vsg::ref_ptr vertices;
45 |
46 | auto normals = vsg::vec3Value::create(vsg::vec3(0.0f, 0.0f, 1.0f));
47 | auto colors = vsg::ubvec4Array::create(points.size(), vsg::Data::Properties(VK_FORMAT_R8G8B8A8_UNORM));
48 | auto positionScaleValue = vsg::vec4Value::create(positionScale);
49 | auto pointSizeValue = vsg::vec2Value::create(pointSize);
50 |
51 | normals->properties.format = VK_FORMAT_R32G32B32_SFLOAT;
52 | positionScaleValue->properties.format = VK_FORMAT_R32G32B32A32_SFLOAT;
53 | pointSizeValue->properties.format = VK_FORMAT_R32G32_SFLOAT;
54 |
55 | if (settings.bits == 8)
56 | {
57 | auto vertices_8bit = vsg::ubvec3Array::create(points.size(), vsg::Data::Properties(VK_FORMAT_R8G8B8_UNORM));
58 | auto vertex_itr = vertices_8bit->begin();
59 | auto color_itr = colors->begin();
60 | for (auto& point : points)
61 | {
62 | (vertex_itr++)->set(static_cast(point.v.x), static_cast(point.v.y), static_cast(point.v.z));
63 | *(color_itr++) = point.c;
64 | }
65 |
66 | vertices = vertices_8bit;
67 | }
68 | else if (settings.bits == 10)
69 | {
70 | auto vertices_10bit = vsg::uintArray::create(points.size(), vsg::Data::Properties(VK_FORMAT_A2R10G10B10_UNORM_PACK32));
71 | auto vertex_itr = vertices_10bit->begin();
72 | auto color_itr = colors->begin();
73 | for (auto& point : points)
74 | {
75 | *(vertex_itr++) = 3 << 30 | (static_cast(point.v.x) << 20) | (static_cast(point.v.y) << 10) | (static_cast(point.v.z));
76 | *(color_itr++) = point.c;
77 | }
78 |
79 | vertices = vertices_10bit;
80 | }
81 | else if (settings.bits == 16)
82 | {
83 | auto vertices_16bit = vsg::usvec3Array::create(points.size(), vsg::Data::Properties(VK_FORMAT_R16G16B16_UNORM));
84 | auto vertex_itr = vertices_16bit->begin();
85 | auto color_itr = colors->begin();
86 | for (auto& point : points)
87 | {
88 | (vertex_itr++)->set(static_cast(point.v.x), static_cast(point.v.y), static_cast(point.v.z));
89 | *(color_itr++) = point.c;
90 | }
91 |
92 | vertices = vertices_16bit;
93 | }
94 | else
95 | {
96 | return {};
97 | }
98 |
99 | // set up vertexDraw that will do the rendering.
100 | auto vertexDraw = vsg::VertexDraw::create();
101 | vertexDraw->assignArrays({vertices, normals, colors, positionScaleValue, pointSizeValue});
102 | vertexDraw->vertexCount = points.size();
103 | vertexDraw->instanceCount = 1;
104 |
105 | return vertexDraw;
106 | }
107 |
108 | vsg::ref_ptr Brick::createRendering(const Settings& settings, Key key, vsg::dbox& bound)
109 | {
110 | double brickPrecision = settings.precision * static_cast(key.w);
111 | double brickSize = brickPrecision * pow(2.0, static_cast(settings.bits));
112 |
113 | vsg::dvec3 position(static_cast(key.x) * brickSize, static_cast(key.y) * brickSize, static_cast(key.z) * brickSize);
114 | position -= settings.offset;
115 |
116 | for (auto& point : points)
117 | {
118 | auto& v = point.v;
119 | bound.add(position.x + brickPrecision * static_cast(v.x),
120 | position.y + brickPrecision * static_cast(v.y),
121 | position.z + brickPrecision * static_cast(v.z));
122 | }
123 |
124 | vsg::vec2 pointSize(brickPrecision * settings.pointSize, brickPrecision);
125 | vsg::vec4 positionScale(position.x, position.y, position.z, brickSize);
126 |
127 | return createRendering(settings, positionScale, pointSize);
128 | }
129 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vsgPoints - VulkanSceneGraph Point Cloud rendering
2 |
3 | Cross platform, open source (MIT license) C++17 library and example set for rendering large point cloud data using VulkanSceneGraph. vsgPoints provides support for generating hierarchical LOD and paged LOD scene graph hierarchies to provide excellent performance and scalability. The support for database paging enables handling of very large point databases - over a billion point datasets run at a solid 60fps even on integrated GPUs.
4 |
5 | To enable efficient use of main and GPU memory, point data is segmented into bricks and the source x, y, z values are quantized to 8bit, 10bit or 16bit values. Using the vsgPoints::Settings structure users can select the precision (default of 1mm) and bit representation they require, the higher precision and lower the brick count the smaller the bricks that will be used. The quantized data is packed into formats supported by graphics hardware enabling the vertex shaders to compute the final positions without any intermediate conversions.
6 |
7 | To enable handling of point data with very large world coordinates, the data is translated to a local origin with a vsg::MatrixTransform used to place the rendered points in their proper world coordinate system.
8 |
9 | The vsgPoints project contains a vsgPoints library that applications may link to if they wish to add point cloud loading and scene graph creation capabilities to their applications, and a vsgpoints_example utility program.
10 |
11 | ## System requirements/constraints
12 |
13 | vsgPoints is usable, but still early in its development. Currently the reading and building of scene graphs is single threaded, and no attempt is made to minimize memory footprint, beyond quantization to 8/10/16bit. During read and scene graph generation of very large datasets you will need sufficient main memory, for billion points datasets you'll need 32GB+ main memory in order to build the scene graph.
14 |
15 | For flat or LOD scene graphs, the GPU memory requirement loosely tracks the size of the scene graph in main memory/on disk so the larger it is, the more likely it will hit limits of available GPU memory. For very large point datasets it will be necessary to generate PagedLOD scene graphs which will result in creation of a hierarchy of PagedLOD nodes and associated files on disk, which can number in millions of files. Paged databases perform very well, reducing the memory requirement substantially and enabling much larger datasets to be viewed at high framerates with the VulkanSceneGraph's multi-threaded database pager seamlessly handling the file loading as well as load balancing.
16 |
17 | The downside with paged databases can be they stress the filesystem/OS more when you want to delete or move the directory hierarchy that has been generated by vsgPoints. In particular Windows can struggle when handling millions of files even on fast solid state disks, in particular if virus scanners are invoked during file operations.
18 |
19 | ## Roadmap
20 |
21 | Possible features for future development:
22 |
23 | * Multi-thread the reading of data and scene graph building,
24 | * Saving intermediate results to avoid overloading main memory when building large point datasets and reduce memory footprint.
25 | * Features like picking would also be nice features to add.
26 |
27 | vsgPoints is open source, if you wish to see features developed then you are welcome to contribute time or funding to help make this happen.
28 |
29 | ## Dependencies
30 |
31 | 3rd party dependencies:
32 |
33 | C++17
34 | CMake
35 | VulkanSDK
36 | GLslang
37 | VulkanSceneGraph
38 | vsgXchange
39 |
40 | ## Building vsgPoints
41 |
42 | Unix in source build:
43 |
44 | cd vsgPoints
45 | cmake .
46 | make -j 8
47 | make install
48 |
49 | # vsgpoints_example application usage
50 |
51 | To view .3dc or .asc point clouds, or .BIN (double x,y,z; uint8_t r, g, b) data :
52 |
53 | ~~~ sh
54 | vsgpoints_example mydata.asc
55 | ~~~~
56 |
57 | To convert point cloud data to VulkanSceneGraph native format:
58 |
59 | ~~~ sh
60 | vsgpoints_example mydata.BIN -o mydata.vsgb
61 | ~~~~
62 |
63 | Once you have converted to native .vsgb format you can load the data in any VulkanSceneGraph application:
64 |
65 | ~~~ sh
66 | vsgviewer mydata.vsgb
67 | ~~~
68 |
69 | vsgpoints_example supports generating scene graphs in three ways, the command line options for these are:
70 |
71 | | command line option | technique |
72 | | --lod | using LOD's (the default) |
73 | | --plod | Generation of paged databases |
74 | | --flat | flat group of point bricks |
75 |
76 | ~~~ sh
77 | # create vsg::LOD scene graph
78 | vsgpoints_example mydata.BIN --lod
79 | # or just rely upon the default being vsg::LOD scene graph
80 | vsgpoints_example mydata.BIN
81 |
82 | # create a flat group of point bricks
83 | vsgpoints_example mydata.BIN --flat
84 |
85 | # create a paged database, requires specification of output file
86 | vsgpoints_example mydata.BIN -o paged.vsgb --plod
87 | ~~~
88 |
89 | vsgpoints_example also supports generating points from meshed models, which can be enabled with --mesh
90 |
91 | ~~~ sh
92 | # load a mesh model and convert to points as input rather than required loading of points data.
93 | vsgpoints_example mymodel.gltf --mesh
94 | ~~~
95 |
96 | If you don't include an output filename using ~ -o filename.vsgb ~ then vsgpoints_example will automatically create a viewer to view the created scene graph, but if you output to a file no viewer will be created. If you still want the viewer to appear then add the -v option to force the viewer to be created.
97 |
98 | To alter the precision and point size you can use the -p size_in_metres and --ps multiplier to control the precision (defaults to 0.001) and point size (defaults to 4 x precision).
99 |
100 | ~~~ sh
101 | # choose 5mm precision and ~50mm rendered point size (10 x 0.005)
102 | vsgpoints_example mydata.3dc -p 0.005 --ps 10
103 | ~~~
104 |
--------------------------------------------------------------------------------
/src/vsgPoints/shaders/brick_vert.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | static auto brick_vert = []() {
4 | static const char str[] =
5 | R"(#vsga 1.1.2
6 | Root id=1 vsg::ShaderStage
7 | {
8 | userObjects 0
9 | mask 18446744073709551615
10 | stage 1
11 | entryPointName "main"
12 | module id=2 vsg::ShaderModule
13 | {
14 | userObjects 0
15 | hints id=0
16 | source "#version 450
17 | #extension GL_ARB_separate_shader_objects : enable
18 | #pragma import_defines (VSG_POSITION_SCALE)
19 |
20 | #define VIEW_DESCRIPTOR_SET 0
21 | #define MATERIAL_DESCRIPTOR_SET 1
22 |
23 | layout(push_constant) uniform PushConstants {
24 | mat4 projection;
25 | mat4 modelView;
26 | } pc;
27 |
28 |
29 | layout(location = 0) in vec3 vsg_Vertex;
30 | layout(location = 1) in vec3 vsg_Normal;
31 | layout(location = 2) in vec4 vsg_Color;
32 |
33 | #ifdef VSG_POSITION_SCALE
34 | layout(location = 3) in vec4 vsg_PositionScale;
35 | #endif
36 |
37 | layout(location = 4) in vec2 vsg_PointSize;
38 |
39 | layout(location = 0) out vec3 eyePos;
40 | layout(location = 1) out vec3 normalDir;
41 | layout(location = 2) out vec4 vertexColor;
42 |
43 | layout(location = 5) out vec3 viewDir;
44 |
45 | layout(set = VIEW_DESCRIPTOR_SET, binding = 1) buffer ViewportData
46 | {
47 | vec4 values[];
48 | } viewportData;
49 |
50 | out gl_PerVertex{
51 | vec4 gl_Position;
52 | float gl_PointSize;
53 | };
54 |
55 | void main()
56 | {
57 |
58 | #ifdef VSG_POSITION_SCALE
59 | vec4 vertex = vec4(vsg_PositionScale.xyz + vsg_Vertex * vsg_PositionScale.w, 1.0);
60 | #else
61 | vec4 vertex = vec4(vsg_Vertex, 1.0);
62 | #endif
63 |
64 | vec4 normal = vec4(vsg_Normal, 0.0);
65 |
66 | gl_Position = (pc.projection * pc.modelView) * vertex;
67 |
68 | eyePos = vec4(pc.modelView * vertex).xyz;
69 | viewDir = -eyePos;//normalize(-eyePos);
70 | normalDir = (pc.modelView * normal).xyz;
71 | vertexColor = vsg_Color;
72 |
73 | float dist = max(vsg_PointSize[1], abs(eyePos.z));
74 | vec4 viewport = viewportData.values[0];
75 | gl_PointSize = viewport[3] * (vsg_PointSize[0] / dist);
76 | }
77 |
78 | "
79 | code 749
80 | 119734787 65536 524299 106 0 131089 1 393227 1 1280527431 1685353262 808793134
81 | 0 196622 0 1 917519 0 4 1852399981 0 12 20 29
82 | 48 59 62 68 70 76 196611 2 450 589828 1096764487 1935622738
83 | 1918988389 1600484449 1684105331 1868526181 1667590754 29556 262149 4 1852399981 0 262149 9
84 | 1953654134 30821 327685 12 1600615286 1953654102 30821 262149 19 1836216174 27745 327685
85 | 20 1600615286 1836216142 27745 393221 27 1348430951 1700164197 2019914866 0 393222 27
86 | 0 1348430951 1953067887 7237481 458758 27 1 1348430951 1953393007 1702521171 0 196613
87 | 29 0 393221 33 1752397136 1936617283 1953390964 115 393222 33 0 1785688688
88 | 1769235301 28271 393222 33 1 1701080941 1701402220 119 196613 35 25456 262149
89 | 48 1348827493 29551 262149 59 2003134838 7498052 327685 62 1836216174 1766091873 114
90 | 327685 68 1953654134 1866692709 7499628 327685 70 1600615286 1869377347 114 262149 73
91 | 1953720676 0 393221 76 1600615286 1852403536 2053722996 101 327685 88 2003134838 1953656688
92 | 0 393221 90 2003134806 1953656688 1635017028 0 327686 90 0 1970037110 29541
93 | 393221 92 2003134838 1953656688 1635017028 0 262215 12 30 0 262215 20
94 | 30 1 327752 27 0 11 0 327752 27 1 11 1
95 | 196679 27 2 262216 33 0 5 327752 33 0 35 0
96 | 327752 33 0 7 16 262216 33 1 5 327752 33 1
97 | 35 64 327752 33 1 7 16 196679 33 2 262215 48
98 | 30 0 262215 59 30 5 262215 62 30 1 262215 68
99 | 30 2 262215 70 30 2 262215 76 30 4 262215 89
100 | 6 16 327752 90 0 35 0 196679 90 3 262215 92
101 | 34 0 262215 92 33 1 131091 2 196641 3 2 196630
102 | 6 32 262167 7 6 4 262176 8 7 7 262167 10
103 | 6 3 262176 11 1 10 262203 11 12 1 262187 6
104 | 14 1065353216 262203 11 20 1 262187 6 22 0 262174 27
105 | 7 6 262176 28 3 27 262203 28 29 3 262165 30
106 | 32 1 262187 30 31 0 262168 32 7 4 262174 33
107 | 32 32 262176 34 9 33 262203 34 35 9 262176 36
108 | 9 32 262187 30 39 1 262176 45 3 7 262176 47
109 | 3 10 262203 47 48 3 262203 47 59 3 262203 47
110 | 62 3 262203 45 68 3 262176 69 1 7 262203 69
111 | 70 1 262176 72 7 6 262167 74 6 2 262176 75
112 | 1 74 262203 75 76 1 262165 77 32 0 262187 77
113 | 78 1 262176 79 1 6 262187 77 82 2 262176 83
114 | 3 6 196637 89 7 196638 90 89 262176 91 2 90
115 | 262203 91 92 2 262176 93 2 7 262187 77 96 3
116 | 262187 77 99 0 327734 2 4 0 3 131320 5 262203
117 | 8 9 7 262203 8 19 7 262203 72 73 7 262203
118 | 8 88 7 262205 10 13 12 327761 6 15 13 0
119 | 327761 6 16 13 1 327761 6 17 13 2 458832 7
120 | 18 15 16 17 14 196670 9 18 262205 10 21 20
121 | 327761 6 23 21 0 327761 6 24 21 1 327761 6
122 | 25 21 2 458832 7 26 23 24 25 22 196670 19
123 | 26 327745 36 37 35 31 262205 32 38 37 327745 36
124 | 40 35 39 262205 32 41 40 327826 32 42 38 41
125 | 262205 7 43 9 327825 7 44 42 43 327745 45 46
126 | 29 31 196670 46 44 327745 36 49 35 39 262205 32
127 | 50 49 262205 7 51 9 327825 7 52 50 51 327761
128 | 6 53 52 0 327761 6 54 52 1 327761 6 55
129 | 52 2 327761 6 56 52 3 458832 7 57 53 54
130 | 55 56 524367 10 58 57 57 0 1 2 196670 48
131 | 58 262205 10 60 48 262271 10 61 60 196670 59 61
132 | 327745 36 63 35 39 262205 32 64 63 262205 7 65
133 | 19 327825 7 66 64 65 524367 10 67 66 66 0
134 | 1 2 196670 62 67 262205 7 71 70 196670 68 71
135 | 327745 79 80 76 78 262205 6 81 80 327745 83 84
136 | 48 82 262205 6 85 84 393228 6 86 1 4 85
137 | 458764 6 87 1 40 81 86 196670 73 87 393281 93
138 | 94 92 31 31 262205 7 95 94 196670 88 95 327745
139 | 72 97 88 96 262205 6 98 97 327745 79 100 76
140 | 99 262205 6 101 100 262205 6 102 73 327816 6 103
141 | 101 102 327813 6 104 98 103 327745 83 105 29 39
142 | 196670 105 104 65789 65592
143 | }
144 | NumSpecializationConstants 0
145 | }
146 | )";
147 | vsg::VSG io;
148 | return io.read_cast(reinterpret_cast(str), sizeof(str));
149 | };
150 |
--------------------------------------------------------------------------------
/applications/vsgpoints_example/ConvertMeshToPoints.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "ConvertMeshToPoints.h"
4 |
5 | #include
6 |
7 | ConvertMeshToPoints::ConvertMeshToPoints(vsg::ref_ptr settings) :
8 | bricks(vsgPoints::Bricks::create(settings))
9 | {
10 | arrayStateStack.reserve(4);
11 | arrayStateStack.emplace_back(vsg::ArrayState::create());
12 | }
13 |
14 |
15 | void ConvertMeshToPoints::applyDraw(uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount)
16 | {
17 | auto& arrayState = *arrayStateStack.back();
18 | uint32_t lastIndex = instanceCount > 1 ? (firstInstance + instanceCount) : firstInstance + 1;
19 | uint32_t endVertex = firstVertex + vertexCount;
20 | auto matrix = localToWorld();
21 |
22 | vsg::ubvec4 color(255,255,255,255);
23 |
24 | for (uint32_t instanceIndex = firstInstance; instanceIndex < lastIndex; ++instanceIndex)
25 | {
26 | if (auto vertices = arrayState.vertexArray(instanceIndex))
27 | {
28 | for (uint32_t i = firstVertex; i < endVertex; ++i)
29 | {
30 | bricks->add(matrix * vsg::dvec3(vertices->at(i)), color);
31 | }
32 | }
33 | }
34 | }
35 |
36 | void ConvertMeshToPoints::applyDrawIndexed(uint32_t firstIndex, uint32_t indexCount, uint32_t firstInstance, uint32_t instanceCount)
37 | {
38 | auto& arrayState = *arrayStateStack.back();
39 | uint32_t lastIndex = instanceCount > 1 ? (firstInstance + instanceCount) : firstInstance + 1;
40 | uint32_t endIndex = firstIndex + indexCount;
41 | auto matrix = localToWorld();
42 |
43 | vsg::ubvec4 color(255,255,255,255);
44 |
45 | if (ushort_indices)
46 | {
47 | for (uint32_t instanceIndex = firstInstance; instanceIndex < lastIndex; ++instanceIndex)
48 | {
49 | if (auto vertices = arrayState.vertexArray(instanceIndex))
50 | {
51 | for (uint32_t i = firstIndex; i < endIndex; ++i)
52 | {
53 | bricks->add(matrix * vsg::dvec3(vertices->at(ushort_indices->at(i))), color);
54 | }
55 | }
56 | }
57 | }
58 | else if (uint_indices)
59 | {
60 | for (uint32_t instanceIndex = firstInstance; instanceIndex < lastIndex; ++instanceIndex)
61 | {
62 | if (auto vertices = arrayState.vertexArray(instanceIndex))
63 | {
64 | for (uint32_t i = firstIndex; i < endIndex; ++i)
65 | {
66 | bricks->add(matrix * vsg::dvec3(vertices->at(uint_indices->at(i))), color);
67 | }
68 | }
69 | }
70 | }
71 | }
72 |
73 | void ConvertMeshToPoints::apply(const vsg::Node& node)
74 | {
75 | node.traverse(*this);
76 | }
77 |
78 | void ConvertMeshToPoints::apply(const vsg::StateGroup& stategroup)
79 | {
80 | auto arrayState = stategroup.prototypeArrayState ? stategroup.prototypeArrayState->cloneArrayState(arrayStateStack.back()) : arrayStateStack.back()->cloneArrayState();
81 |
82 | for (auto& statecommand : stategroup.stateCommands)
83 | {
84 | statecommand->accept(*arrayState);
85 | }
86 |
87 | arrayStateStack.emplace_back(arrayState);
88 |
89 | stategroup.traverse(*this);
90 |
91 | arrayStateStack.pop_back();
92 | }
93 |
94 | void ConvertMeshToPoints::apply(const vsg::Transform& transform)
95 | {
96 | auto& l2wStack = localToWorldStack();
97 |
98 | vsg::dmat4 localToWorld = l2wStack.empty() ? transform.transform({}) : transform.transform(l2wStack.back());
99 | l2wStack.push_back(localToWorld);
100 |
101 | transform.traverse(*this);
102 |
103 | l2wStack.pop_back();
104 | }
105 |
106 | void ConvertMeshToPoints::apply(const vsg::LOD& lod)
107 | {
108 | if (!lod.children.empty() && lod.children[0].node) lod.children[0].node->accept(*this);
109 | }
110 |
111 | void ConvertMeshToPoints::apply(const vsg::PagedLOD& plod)
112 | {
113 | if (plod.children[0].node) plod.children[0].node->accept(*this);
114 | else if (plod.children[1].node) plod.children[1].node->accept(*this);
115 | }
116 |
117 | void ConvertMeshToPoints::apply(const vsg::VertexDraw& vid)
118 | {
119 | auto& arrayState = *arrayStateStack.back();
120 | arrayState.apply(vid);
121 | if (!arrayState.vertices) return;
122 |
123 | applyDraw(vid.firstVertex, vid.vertexCount, vid.firstInstance, vid.instanceCount);
124 | }
125 |
126 | void ConvertMeshToPoints::apply(const vsg::VertexIndexDraw& vid)
127 | {
128 | auto& arrayState = *arrayStateStack.back();
129 | arrayState.apply(vid);
130 | if (!arrayState.vertices) return;
131 |
132 | if (vid.indices) vid.indices->accept(*this);
133 |
134 | applyDrawIndexed(vid.firstIndex, vid.indexCount, vid.firstInstance, vid.instanceCount);
135 | }
136 |
137 | void ConvertMeshToPoints::apply(const vsg::Geometry& geometry)
138 | {
139 | auto& arrayState = *arrayStateStack.back();
140 | arrayState.apply(geometry);
141 | if (!arrayState.vertices) return;
142 |
143 | if (geometry.indices) geometry.indices->accept(*this);
144 |
145 | for (auto& command : geometry.commands)
146 | {
147 | command->accept(*this);
148 | }
149 | }
150 |
151 | void ConvertMeshToPoints::apply(const vsg::BindVertexBuffers& bvb)
152 | {
153 | arrayStateStack.back()->apply(bvb);
154 | }
155 |
156 | void ConvertMeshToPoints::apply(const vsg::BindIndexBuffer& bib)
157 | {
158 | bib.indices->accept(*this);
159 | }
160 |
161 | void ConvertMeshToPoints::apply(const vsg::BufferInfo& bufferInfo)
162 | {
163 | if (bufferInfo.data) bufferInfo.data->accept(*this);
164 | }
165 |
166 | void ConvertMeshToPoints::apply(const vsg::ushortArray& array)
167 | {
168 | ushort_indices = &array;
169 | uint_indices = nullptr;
170 | }
171 |
172 | void ConvertMeshToPoints::apply(const vsg::uintArray& array)
173 | {
174 | ushort_indices = nullptr;
175 | uint_indices = &array;
176 | }
177 |
178 | void ConvertMeshToPoints::apply(const vsg::Draw& draw)
179 | {
180 | applyDraw(draw.firstVertex, draw.vertexCount, draw.firstInstance, draw.instanceCount);
181 | }
182 |
183 | void ConvertMeshToPoints::apply(const vsg::DrawIndexed& drawIndexed)
184 | {
185 | applyDrawIndexed(drawIndexed.firstIndex, drawIndexed.indexCount, drawIndexed.firstInstance, drawIndexed.instanceCount);
186 | }
187 |
--------------------------------------------------------------------------------
/src/vsgPoints/BrickShaderSet.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright(c) 2022 Robert Osfield
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
10 |
11 | */
12 |
13 | #include
14 |
15 | #include "shaders/brick_flat_shaded_frag.cpp"
16 | #include "shaders/brick_phong_frag.cpp"
17 | #include "shaders/brick_vert.cpp"
18 |
19 | #include
20 | #include
21 |
22 | using namespace vsgPoints;
23 |
24 | #define VIEW_DESCRIPTOR_SET 0
25 | #define MATERIAL_DESCRIPTOR_SET 1
26 |
27 | vsg::ref_ptr vsgPoints::createParticleImage(uint32_t dim)
28 | {
29 | auto data = vsg::ubvec4Array2D::create(dim, dim);
30 | data->properties.format = VK_FORMAT_R8G8B8A8_UNORM;
31 | float div = 2.0f / static_cast(dim - 1);
32 | float distance_at_one = 0.5f;
33 | float distance_at_zero = 1.0f;
34 |
35 | vsg::vec2 v;
36 | for (uint32_t r = 0; r < dim; ++r)
37 | {
38 | v.y = static_cast(r) * div - 1.0f;
39 | for (uint32_t c = 0; c < dim; ++c)
40 | {
41 | v.x = static_cast(c) * div - 1.0f;
42 | float distance_from_center = vsg::length(v);
43 | float intensity = 1.0f - (distance_from_center - distance_at_one) / (distance_at_zero - distance_at_one);
44 | if (intensity > 1.0f) intensity = 1.0f;
45 | if (intensity < 0.0f) intensity = 0.0f;
46 | uint8_t alpha = static_cast(intensity * 255);
47 | data->set(c, r, vsg::ubvec4(255, 255, 255, alpha));
48 | }
49 | }
50 | return data;
51 | }
52 |
53 | vsg::ref_ptr vsgPoints::createPointsFlatShadedShaderSet(vsg::ref_ptr options)
54 | {
55 | if (options)
56 | {
57 | // check if a ShaderSet has already been assigned to the options object, if so return it
58 | if (auto itr = options->shaderSets.find("points_flat"); itr != options->shaderSets.end()) return itr->second;
59 | }
60 |
61 | auto vertexShader = vsg::read_cast("shaders/brick.vert", options);
62 | if (!vertexShader) vertexShader = brick_vert(); // fallback to shaders/brick_vert.cpp
63 |
64 | auto fragmentShader = vsg::read_cast("shaders/brick_flat_shaded.frag", options);
65 | if (!fragmentShader) fragmentShader = brick_flat_shaded_frag();
66 |
67 | auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader});
68 |
69 | shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1));
70 | shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1));
71 | shaderSet->addAttributeBinding("vsg_Color", "", 2, VK_FORMAT_R8G8B8A8_UNORM, vsg::ubvec4Array::create(1));
72 | shaderSet->addAttributeBinding("vsg_PositionScale", "VSG_POSITION_SCALE", 3, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Value::create(0.0f, 0.0f, 0.0, 1.0f));
73 | shaderSet->addAttributeBinding("vsg_PointSize", "", 4, VK_FORMAT_R32G32_SFLOAT, vsg::vec2Value::create(0.0035f, 0.001f));
74 |
75 | shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", MATERIAL_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM}));
76 | shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PhongMaterialValue::create());
77 |
78 | shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64));
79 | shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0, 0, 1280, 1024));
80 | shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT}));
81 |
82 | shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_VERTEX_BIT, 0, 128);
83 |
84 | shaderSet->optionalDefines = {"VSG_POINT_SPRITE", "VSG_GREYSCALE_DIFFUSE_MAP"};
85 |
86 | shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET));
87 |
88 | return shaderSet;
89 | }
90 |
91 | vsg::ref_ptr vsgPoints::createPointsPhongShaderSet(vsg::ref_ptr options)
92 | {
93 | if (options)
94 | {
95 | // check if a ShaderSet has already been assigned to the options object, if so return it
96 | if (auto itr = options->shaderSets.find("points_phong"); itr != options->shaderSets.end()) return itr->second;
97 | }
98 |
99 | auto vertexShader = vsg::read_cast("shaders/brick.vert", options);
100 | if (!vertexShader) vertexShader = brick_vert(); // fallback to shaders/brick_vert.cpp
101 |
102 | auto fragmentShader = vsg::read_cast("shaders/brick_phong.frag", options);
103 | if (!fragmentShader) fragmentShader = brick_phong_frag();
104 |
105 | auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader});
106 |
107 | shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1));
108 | shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1));
109 | shaderSet->addAttributeBinding("vsg_Color", "", 2, VK_FORMAT_R8G8B8A8_UNORM, vsg::ubvec4Array::create(1));
110 | shaderSet->addAttributeBinding("vsg_PositionScale", "VSG_POSITION_SCALE", 3, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Value::create(0.0f, 0.0f, 0.0, 1.0f));
111 | shaderSet->addAttributeBinding("vsg_PointSize", "", 4, VK_FORMAT_R32G32_SFLOAT, vsg::vec2Value::create(0.0035f, 0.001f));
112 |
113 | shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", MATERIAL_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM}));
114 | shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PhongMaterialValue::create());
115 |
116 | shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64));
117 | shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0, 0, 1280, 1024));
118 | shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT}));
119 |
120 | shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_VERTEX_BIT, 0, 128);
121 |
122 | shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_POINT_SPRITE"};
123 |
124 | shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET));
125 |
126 | return shaderSet;
127 | }
128 |
--------------------------------------------------------------------------------
/applications/vsgpoints_example/vsgpoints_example.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #ifdef vsgXchange_FOUND
4 | # include
5 | #endif
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include "ConvertMeshToPoints.h"
12 |
13 | #include
14 | #include
15 |
16 | template
17 | std::string format_number(T v)
18 | {
19 | std::vector parts;
20 | do
21 | {
22 | parts.push_back(v % 1000);
23 | v /= 1000;
24 | } while (v > 0);
25 |
26 | std::stringstream s;
27 | auto itr = parts.rbegin();
28 | s << *(itr++);
29 | while(itr != parts.rend())
30 | {
31 | s << ',';
32 | s << std::setfill('0') << std::setw(3) << *(itr++);
33 | }
34 |
35 | return s.str();
36 | }
37 |
38 | int main(int argc, char** argv)
39 | {
40 | // set up defaults and read command line arguments to override them
41 | vsg::CommandLine arguments(&argc, argv);
42 |
43 | auto options = vsg::Options::create();
44 | options->paths = vsg::getEnvPaths("VSG_FILE_PATH");
45 | options->sharedObjects = vsg::SharedObjects::create();
46 |
47 | options->add(vsgPoints::BIN::create());
48 | options->add(vsgPoints::AsciiPoints::create());
49 |
50 | #ifdef vsgXchange_all
51 | // add vsgXchange's support for reading and writing 3rd party file formats
52 | options->add(vsgXchange::all::create());
53 | #endif
54 |
55 | options->readOptions(arguments);
56 |
57 | if (int type; arguments.read("--allocator", type)) vsg::Allocator::instance()->allocatorType = vsg::AllocatorType(type);
58 | if (size_t objectsBlockSize; arguments.read("--objects", objectsBlockSize)) vsg::Allocator::instance()->setBlockSize(vsg::ALLOCATOR_AFFINITY_OBJECTS, objectsBlockSize);
59 | if (size_t nodesBlockSize; arguments.read("--nodes", nodesBlockSize)) vsg::Allocator::instance()->setBlockSize(vsg::ALLOCATOR_AFFINITY_NODES, nodesBlockSize);
60 | if (size_t dataBlockSize; arguments.read("--data", dataBlockSize)) vsg::Allocator::instance()->setBlockSize(vsg::ALLOCATOR_AFFINITY_DATA, dataBlockSize);
61 |
62 | auto windowTraits = vsg::WindowTraits::create();
63 | windowTraits->windowTitle = "vsgpoints";
64 | windowTraits->debugLayer = arguments.read({"--debug", "-d"});
65 | windowTraits->apiDumpLayer = arguments.read({"--api", "-a"});
66 | if (arguments.read("--test"))
67 | {
68 | windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
69 | windowTraits->fullscreen = true;
70 | }
71 | if (arguments.read({"--st", "--small-test"}))
72 | {
73 | windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
74 | windowTraits->width = 192, windowTraits->height = 108;
75 | windowTraits->decoration = false;
76 | }
77 |
78 | // set up the Settings used to guide how point clouds are setup in the scene graph
79 | auto settings = vsgPoints::Settings::create();
80 | options->setObject("settings", settings);
81 | settings->options = vsg::Options::create(*options);
82 |
83 | arguments.read("-b", settings->numPointsPerBlock);
84 | arguments.read("-p", settings->precision);
85 | arguments.read("-t", settings->transition);
86 | arguments.read("--ps", settings->pointSize);
87 | arguments.read("--bits", settings->bits);
88 | auto maxPagedLOD = arguments.value(0, "--maxPagedLOD");
89 | bool convert_mesh = arguments.read("--mesh");
90 | bool add_model = !arguments.read("--no-model");
91 |
92 | if (arguments.read("--plod")) settings->createType = vsgPoints::CREATE_PAGEDLOD;
93 | else if (arguments.read("--lod")) settings->createType = vsgPoints::CREATE_LOD;
94 | else if (arguments.read("--flat")) settings->createType = vsgPoints::CREATE_FLAT;
95 |
96 | bool writeOnly = false;
97 | auto outputFilename = arguments.value("", "-o");
98 | if (outputFilename)
99 | {
100 | settings->path = vsg::filePath(outputFilename)/vsg::simpleFilename(outputFilename);
101 | settings->extension = vsg::fileExtension(outputFilename);
102 | writeOnly = !arguments.read({"-v", "--viewer"});
103 | }
104 | else
105 | {
106 | if (settings->createType == vsgPoints::CREATE_PAGEDLOD)
107 | {
108 | std::cout<<"PagedLOD generation not possible without output filename. Please specify ouput filename using: -o filename.vsgb"<(vsg::clock::now() - before_read).count();
122 | std::cout<<"Time to read points = "<())
125 | {
126 | if (convert_mesh)
127 | {
128 | ConvertMeshToPoints convert(settings);
129 | node->accept(convert);
130 | auto bricks = convert.bricks;
131 |
132 | std::cout<<"Converted mesh to "<count())<<" points."<addChild(scene);
136 | }
137 | }
138 |
139 | if (add_model)
140 | {
141 | group->addChild(node);
142 | }
143 | }
144 | else if (auto bricks = object.cast())
145 | {
146 | std::cout<<"Read "<count())<<" points."<addChild(scene);
151 | }
152 | double time_to_create = std::chrono::duration(vsg::clock::now() - before_create).count();
153 | std::cout<<"Time to create scene graph = "<children.empty())
158 | {
159 | std::cout<<"Error: no data loaded."< vsg_scene;
164 | if (group->children.size()==1) vsg_scene = group->children[0];
165 | else vsg_scene = group;
166 |
167 | if (outputFilename)
168 | {
169 | vsg::write(vsg_scene, outputFilename, options);
170 |
171 | std::cout<<"Written scene graph to "<addWindow(window);
186 |
187 | // compute the bounds of the scene graph to help position camera
188 | vsg::dbox bounds = vsg::visit(vsg_scene).bounds;
189 |
190 | vsg::dvec3 center = (bounds.min + bounds.max) * 0.5;
191 | double radius = vsg::length(bounds.max - bounds.min) * 0.6;
192 | double nearFarRatio = 0.001;
193 |
194 | auto lookAt = vsg::LookAt::create(center + vsg::dvec3(0.0, -radius * 3.5, 0.0), center, vsg::dvec3(0.0, 0.0, 1.0));
195 | auto perspective = vsg::Perspective::create(30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio * radius, radius * 4.5);
196 |
197 | auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D()));
198 |
199 | // add close handler to respond to the close window button and pressing escape
200 | viewer->addEventHandler(vsg::CloseHandler::create(viewer));
201 | viewer->addEventHandler(vsg::Trackball::create(camera));
202 |
203 | auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene);
204 | viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph});
205 |
206 | viewer->compile();
207 |
208 | if (maxPagedLOD > 0)
209 | {
210 | // set targetMaxNumPagedLODWithHighResSubgraphs after Viewer::compile() as it will assign any DatabasePager if required.
211 | for(auto& task : viewer->recordAndSubmitTasks)
212 | {
213 | if (task->databasePager) task->databasePager->targetMaxNumPagedLODWithHighResSubgraphs = maxPagedLOD;
214 | }
215 | }
216 |
217 | viewer->start_point() = vsg::clock::now();
218 |
219 | // rendering main loop
220 | while (viewer->advanceToNextFrame())
221 | {
222 | // pass any events into EventHandlers assigned to the Viewer
223 | viewer->handleEvents();
224 |
225 | viewer->update();
226 |
227 | viewer->recordAndSubmit();
228 |
229 | viewer->present();
230 | }
231 |
232 | auto fs = viewer->getFrameStamp();
233 | double fps = static_cast(fs->frameCount) / std::chrono::duration(vsg::clock::now() - viewer->start_point()).count();
234 | std::cout<<"Average frame rate = "< 0.0)
98 | {
99 | vec3 halfDir = normalize(ld + vd);
100 | color.rgb += specularColor * pow(max(dot(halfDir, nd), 0.0), shininess);
101 | }
102 |
103 | vec3 result = color + emissiveColor;
104 | result *= ambientOcclusion;
105 |
106 | return result;
107 | }
108 |
109 |
110 | void main()
111 | {
112 | float brightnessCutoff = 0.001;
113 |
114 | #ifdef VSG_POINT_SPRITE
115 | vec2 texCoord0 = gl_PointCoord.xy;
116 | #endif
117 |
118 | vec4 diffuseColor = vertexColor * material.diffuseColor;
119 | #ifdef VSG_DIFFUSE_MAP
120 | #ifdef VSG_GREYSCALE_DIFFUSE_MAP
121 | float v = texture(diffuseMap, texCoord0.st).s;
122 | diffuseColor *= vec4(v, v, v, 1.0);
123 | #else
124 | diffuseColor *= texture(diffuseMap, texCoord0.st);
125 | #endif
126 | #endif
127 |
128 | vec4 ambientColor = diffuseColor * material.ambientColor * material.ambientColor.a;
129 | vec4 specularColor = material.specularColor;
130 | vec4 emissiveColor = material.emissiveColor;
131 | float shininess = material.shininess;
132 | float ambientOcclusion = 1.0;
133 |
134 | if (material.alphaMask == 1.0f)
135 | {
136 | if (diffuseColor.a < material.alphaMaskCutoff)
137 | discard;
138 | }
139 |
140 | #ifdef VSG_EMISSIVE_MAP
141 | emissiveColor *= texture(emissiveMap, texCoord0.st);
142 | #endif
143 |
144 | #ifdef VSG_LIGHTMAP_MAP
145 | ambientOcclusion *= texture(aoMap, texCoord0.st).r;
146 | #endif
147 |
148 | #ifdef VSG_SPECULAR_MAP
149 | specularColor *= texture(specularMap, texCoord0.st);
150 | #endif
151 |
152 | vec3 nd = getNormal();
153 | vec3 vd = normalize(viewDir);
154 |
155 | vec3 color = vec3(0.0, 0.0, 0.0);
156 |
157 | vec4 lightNums = lightData.values[0];
158 | int numAmbientLights = int(lightNums[0]);
159 | int numDirectionalLights = int(lightNums[1]);
160 | int numPointLights = int(lightNums[2]);
161 | int numSpotLights = int(lightNums[3]);
162 | int index = 1;
163 |
164 | if (numAmbientLights>0)
165 | {
166 | // ambient lights
167 | for(int i = 0; i0)
178 | {
179 | // directional lights
180 | for(int i = 0; i 0.0 && brightness > brightnessCutoff) && !matched)
191 | {
192 | mat4 sm_matrix = mat4(lightData.values[index++],
193 | lightData.values[index++],
194 | lightData.values[index++],
195 | lightData.values[index++]);
196 |
197 | vec4 sm_tc = (sm_matrix) * vec4(eyePos, 1.0);
198 |
199 | if (sm_tc.x >= 0.0 && sm_tc.x <= 1.0 && sm_tc.y >= 0.0 && sm_tc.y <= 1.0 && sm_tc.z >= 0.0 /* && sm_tc.z <= 1.0*/)
200 | {
201 | matched = true;
202 |
203 | float coverage = texture(shadowMaps, vec4(sm_tc.st, shadowMapIndex, sm_tc.z)).r;
204 | brightness *= (1.0-coverage);
205 |
206 | #ifdef SHADOWMAP_DEBUG
207 | if (shadowMapIndex==0) color = vec3(1.0, 0.0, 0.0);
208 | else if (shadowMapIndex==1) color = vec3(0.0, 1.0, 0.0);
209 | else if (shadowMapIndex==2) color = vec3(0.0, 0.0, 1.0);
210 | else if (shadowMapIndex==3) color = vec3(1.0, 1.0, 0.0);
211 | else if (shadowMapIndex==4) color = vec3(0.0, 1.0, 1.0);
212 | else color = vec3(1.0, 1.0, 1.0);
213 | #endif
214 | }
215 |
216 | ++shadowMapIndex;
217 | shadowMapSettings.r -= 1.0;
218 | }
219 |
220 | if (shadowMapSettings.r > 0.0)
221 | {
222 | // skip lightData and shadowMap entries for shadow maps that we haven't visited for this light
223 | // so subsequent light pointions are correct.
224 | index += 4 * int(shadowMapSettings.r);
225 | shadowMapIndex += int(shadowMapSettings.r);
226 | }
227 |
228 | // if light is too dim/shadowed to effect the rendering skip it
229 | if (brightness <= brightnessCutoff ) continue;
230 |
231 | float unclamped_LdotN = dot(direction, nd);
232 |
233 | float diff = max(unclamped_LdotN, 0.0);
234 | color.rgb += (diffuseColor.rgb * lightColor.rgb) * (diff * brightness);
235 |
236 | if (shininess > 0.0 && diff > 0.0)
237 | {
238 | vec3 halfDir = normalize(direction + vd);
239 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * brightness);
240 | }
241 | }
242 | }
243 |
244 | if (numPointLights>0)
245 | {
246 | // point light
247 | for(int i = 0; i 0.0 && diff > 0.0)
268 | {
269 | vec3 halfDir = normalize(direction + vd);
270 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale);
271 | }
272 | }
273 | }
274 |
275 | if (numSpotLights>0)
276 | {
277 | // spot light
278 | for(int i = 0; i 0.0 && diff > 0.0)
301 | {
302 | vec3 halfDir = normalize(direction + vd);
303 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale);
304 | }
305 | }
306 | }
307 |
308 |
309 | outColor.rgb = (color * ambientOcclusion) + emissiveColor.rgb;
310 | outColor.a = diffuseColor.a;
311 | }
312 |
--------------------------------------------------------------------------------
/src/vsgPoints/create.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright(c) 2023 Robert Osfield
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
10 |
11 | */
12 |
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include
29 |
30 | using namespace vsgPoints;
31 |
32 | vsg::ref_ptr vsgPoints::createSceneGraph(vsg::ref_ptr bricks, vsg::ref_ptr settings)
33 | {
34 | if (bricks->empty())
35 | {
36 | vsg::warn("createSceneGraph(", bricks, ", ", settings, ") bricks is empty(), cannot create scene graph.");
37 | return {};
38 | }
39 |
40 | if (settings->createType == vsgPoints::CREATE_FLAT)
41 | {
42 |
43 | auto cullGroup = vsg::CullGroup::create();
44 | cullGroup->bound.center = (settings->bound.max + settings->bound.min) * 0.5;
45 | cullGroup->bound.radius = vsg::length(settings->bound.max - settings->bound.min) * 0.5;
46 |
47 | if (settings->bound.valid())
48 | {
49 | settings->offset = (settings->bound.max + settings->bound.min) * 0.5;
50 | }
51 |
52 | auto transform = vsg::MatrixTransform::create();
53 | transform->matrix = vsg::translate(settings->offset);
54 | cullGroup->addChild(transform);
55 |
56 | auto group = vsgPoints::createStateGroup(*settings);
57 | transform->addChild(group);
58 |
59 | vsg::dbox bound;
60 | for (auto& [key, brick] : *bricks)
61 | {
62 | if (auto node = brick->createRendering(*(bricks->settings), key, bound))
63 | {
64 | group->addChild(node);
65 | }
66 | }
67 |
68 | return cullGroup;
69 | }
70 | else
71 | {
72 | auto transform = vsg::MatrixTransform::create();
73 |
74 | vsg::t_box keyBounds;
75 | for (auto& [key, brick] : *bricks)
76 | {
77 | keyBounds.add(key.x, key.y, key.z);
78 | }
79 |
80 | auto key_origin = keyBounds.min;
81 | auto translated_bricks = Bricks::create();
82 | for (auto& [key, brick] : *bricks)
83 | {
84 | (*translated_bricks)[Key{key.x - key_origin.x, key.y - key_origin.y, key.z - key_origin.z, key.w}] = brick;
85 | }
86 |
87 | bricks = translated_bricks;
88 |
89 | double brickPrecision = settings->precision;
90 | double brickSize = brickPrecision * pow(2.0, static_cast(settings->bits));
91 |
92 | vsg::dvec3 offset(static_cast(key_origin.x) * brickSize,
93 | static_cast(key_origin.y) * brickSize,
94 | static_cast(key_origin.z) * brickSize);
95 |
96 | settings->offset = vsg::dvec3(0.0, 0.0, 0.0);
97 |
98 | transform->matrix = vsg::translate(offset);
99 |
100 | vsgPoints::Levels levels;
101 | levels.push_back(bricks);
102 |
103 | while (levels.back()->size() > 1)
104 | {
105 | auto& source = levels.back();
106 |
107 | levels.push_back(vsgPoints::Bricks::create());
108 | auto& destination = levels.back();
109 |
110 | if (!vsgPoints::generateLevel(*source, *destination, *settings)) break;
111 | }
112 |
113 | vsg::debug("levels = ", levels.size());
114 |
115 | if (auto model = createPagedLOD(levels, *settings))
116 | {
117 | transform->addChild(model);
118 | }
119 |
120 | return transform;
121 | }
122 | }
123 |
124 | bool vsgPoints::generateLevel(vsgPoints::Bricks& source, vsgPoints::Bricks& destination, const vsgPoints::Settings& settings)
125 | {
126 | int32_t bits = settings.bits;
127 | for (auto& [source_key, source_brick] : source)
128 | {
129 | vsgPoints::Key destination_key = {source_key.x / 2, source_key.y / 2, source_key.z / 2, source_key.w * 2};
130 | vsg::ivec3 offset = {(source_key.x & 1) << bits, (source_key.y & 1) << bits, (source_key.z & 1) << bits};
131 |
132 | auto& destination_brick = destination[destination_key];
133 | if (!destination_brick) destination_brick = vsgPoints::Brick::create();
134 |
135 | auto& source_points = source_brick->points;
136 | auto& destination_points = destination_brick->points;
137 | size_t count = source_points.size();
138 | for (size_t i = 0; i < count; i += 4)
139 | {
140 | auto& p = source_points[i];
141 |
142 | vsgPoints::PackedPoint new_p;
143 | new_p.v.x = static_cast((static_cast(p.v.x) + offset.x) / 2);
144 | new_p.v.y = static_cast((static_cast(p.v.y) + offset.y) / 2);
145 | new_p.v.z = static_cast((static_cast(p.v.z) + offset.z) / 2);
146 | new_p.c = p.c;
147 |
148 | destination_points.push_back(new_p);
149 | }
150 | }
151 | return !destination.empty();
152 | }
153 |
154 | vsg::ref_ptr vsgPoints::createStateGroup(const vsgPoints::Settings& settings)
155 | {
156 | auto textureData = vsgPoints::createParticleImage(64);
157 | auto shaderSet = vsgPoints::createPointsFlatShadedShaderSet(settings.options);
158 | auto config = vsg::GraphicsPipelineConfig::create(shaderSet);
159 | bool blending = false;
160 |
161 | if (settings.options) config->assignInheritedState(settings.options->inheritedState);
162 |
163 | auto& defines = config->shaderHints->defines;
164 | defines.insert("VSG_POINT_SPRITE");
165 |
166 | if (settings.bits == 8)
167 | {
168 | config->enableArray("vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, sizeof(vsg::ubvec3), VK_FORMAT_R8G8B8_UNORM);
169 | }
170 | else if (settings.bits == 10)
171 | {
172 | config->enableArray("vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, 4, VK_FORMAT_A2R10G10B10_UNORM_PACK32);
173 | }
174 | else if (settings.bits == 16)
175 | {
176 | config->enableArray("vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, sizeof(vsg::usvec3), VK_FORMAT_R16G16B16_UNORM);
177 | }
178 | else
179 | {
180 | vsg::info("Unsupported number of bits ", settings.bits);
181 | return {};
182 | }
183 |
184 | config->enableArray("vsg_Normal", VK_VERTEX_INPUT_RATE_INSTANCE, sizeof(vsg::vec3), VK_FORMAT_R32G32B32_SFLOAT);
185 | config->enableArray("vsg_Color", VK_VERTEX_INPUT_RATE_VERTEX, sizeof(vsg::ubvec4), VK_FORMAT_R8G8B8A8_UNORM);
186 | config->enableArray("vsg_PositionScale", VK_VERTEX_INPUT_RATE_INSTANCE, sizeof(vsg::vec4), VK_FORMAT_R32G32B32A32_SFLOAT);
187 | config->enableArray("vsg_PointSize", VK_VERTEX_INPUT_RATE_INSTANCE, sizeof(vsg::vec2), VK_FORMAT_R32G32_SFLOAT);
188 |
189 | if (textureData)
190 | {
191 | auto sampler = vsg::Sampler::create();
192 | sampler->addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
193 | sampler->addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
194 | config->assignTexture("diffuseMap", textureData, sampler);
195 | }
196 |
197 | auto mat = vsg::PhongMaterialValue::create();
198 | mat->value().alphaMask = 1.0f;
199 | mat->value().alphaMaskCutoff = 0.0025f;
200 | config->assignDescriptor("material", mat);
201 |
202 | struct SetPipelineStates : public vsg::Visitor
203 | {
204 | bool blending = false;
205 | SetPipelineStates(bool in_blending) { blending = in_blending; }
206 |
207 | void apply(vsg::Object& object) { object.traverse(*this); }
208 | void apply(vsg::InputAssemblyState& ias) { ias.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; }
209 | void apply(vsg::ColorBlendState& cbs) { cbs.configureAttachments(blending); }
210 | } sps(blending);
211 |
212 | config->accept(sps);
213 |
214 | config->init();
215 |
216 | // create StateGroup as the root of the scene/command graph to hold the GraphicsPipeline, and binding of Descriptors to decorate the whole graph
217 | auto stateGroup = vsg::StateGroup::create();
218 |
219 | config->copyTo(stateGroup);
220 |
221 | return stateGroup;
222 | }
223 |
224 | vsg::ref_ptr vsgPoints::subtile(vsgPoints::Settings& settings, vsgPoints::Levels::reverse_iterator level_itr, vsgPoints::Levels::reverse_iterator end_itr, vsgPoints::Key key, vsg::dbox& bound, bool root)
225 | {
226 | if (level_itr == end_itr) return {};
227 |
228 | auto& bricks = *level_itr;
229 | auto itr = bricks->find(key);
230 | if (itr == bricks->end())
231 | {
232 | //std::cout<<" "<second);
237 | auto next_itr = level_itr;
238 | ++next_itr;
239 |
240 | if (next_itr != end_itr)
241 | {
242 | std::array, 8> children;
243 | size_t num_children = 0;
244 |
245 | vsgPoints::Key subkey{key.x * 2, key.y * 2, key.z * 2, key.w / 2};
246 |
247 | vsg::dbox subtiles_bound;
248 |
249 | if (auto child = subtile(settings, next_itr, end_itr, subkey, subtiles_bound)) children[num_children++] = child;
250 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 0, 0, 0), subtiles_bound)) children[num_children++] = child;
251 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(0, 1, 0, 0), subtiles_bound)) children[num_children++] = child;
252 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 1, 0, 0), subtiles_bound)) children[num_children++] = child;
253 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(0, 0, 1, 0), subtiles_bound)) children[num_children++] = child;
254 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 0, 1, 0), subtiles_bound)) children[num_children++] = child;
255 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(0, 1, 1, 0), subtiles_bound)) children[num_children++] = child;
256 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 1, 1, 0), subtiles_bound)) children[num_children++] = child;
257 |
258 | vsg::dbox local_bound;
259 | auto brick_node = brick->createRendering(settings, key, local_bound);
260 |
261 | if (num_children == 0)
262 | {
263 | //vsg::info("Warning: unable to set PagedLOD bounds, key = ",key,", num_children = ", num_children, ", brick_node = ", brick_node, ", brick->points.size() = ", brick->points.size());
264 | return brick_node;
265 | }
266 |
267 | double transition = settings.transition;
268 | vsg::dsphere bs;
269 |
270 | if (subtiles_bound.valid())
271 | {
272 | bound.add(subtiles_bound);
273 | bs.center = (subtiles_bound.min + subtiles_bound.max) * 0.5;
274 | bs.radius = vsg::length(subtiles_bound.max - subtiles_bound.min) * 0.5;
275 |
276 | double brickPrecision = settings.precision * static_cast(key.w);
277 | double brickSize = brickPrecision * pow(2.0, static_cast(settings.bits));
278 |
279 | vsg::dvec3 subtilesSize = (subtiles_bound.max - subtiles_bound.min);
280 | double maxSize = std::max(brickPrecision, std::max(std::max(subtilesSize.x, subtilesSize.y), subtilesSize.z));
281 |
282 | transition *= (maxSize / brickSize);
283 |
284 | // vsg::info("maxSize = ", maxSize,", brickSize = ",brickSize,", ratio = ",maxSize/brickSize);
285 | }
286 | else
287 | {
288 | vsg::warn("unable to set PagedLOD bounds, num_children = ", num_children);
289 | bs.center = (local_bound.min + local_bound.max) * 0.5;
290 | bs.radius = vsg::length(local_bound.max - local_bound.max) * 0.5;
291 | }
292 |
293 | if (settings.createType == CREATE_PAGEDLOD)
294 | {
295 | vsg::Path path = vsg::make_string(settings.path, "/", key.w, "/", key.z, "/", key.y);
296 | vsg::Path filename = vsg::make_string(key.x, settings.extension);
297 | vsg::Path full_path = path / filename;
298 |
299 | vsg::makeDirectory(path);
300 |
301 | if (num_children == 1)
302 | {
303 | vsg::write(children[0], full_path);
304 | }
305 | else
306 | {
307 | auto group = vsg::Group::create();
308 | for (size_t i = 0; i < num_children; ++i)
309 | {
310 | group->addChild(children[i]);
311 | }
312 | vsg::write(group, full_path);
313 | }
314 |
315 | auto plod = vsg::PagedLOD::create();
316 | plod->bound = bs;
317 | plod->children[0] = vsg::PagedLOD::Child{transition, {}}; // external child visible when its bound occupies more than ~1/4 of the height of the window
318 | plod->children[1] = vsg::PagedLOD::Child{0.0, brick_node}; // visible always
319 |
320 | if (root)
321 | {
322 | plod->filename = full_path;
323 | }
324 | else
325 | {
326 | plod->filename = vsg::Path("../../../..") / full_path;
327 | }
328 |
329 | //vsg::info("plod ", key, " ", brick, " plod ", plod, ", brick->points.size() = ", brick->points.size());
330 |
331 | return plod;
332 | }
333 | else
334 | {
335 | vsg::ref_ptr child_node;
336 | if (num_children == 1)
337 | {
338 | child_node = children[0];
339 | }
340 | else
341 | {
342 | auto group = vsg::Group::create();
343 | for (size_t i = 0; i < num_children; ++i)
344 | {
345 | group->addChild(children[i]);
346 | }
347 |
348 | child_node = group;
349 | }
350 |
351 | auto lod = vsg::LOD::create();
352 | lod->bound = bs;
353 | lod->addChild(vsg::LOD::Child{transition, child_node}); // high res child
354 | lod->addChild(vsg::LOD::Child{0.0, brick_node}); // lower res child
355 |
356 | //vsg::info("lod ", key, " ", brick, " lod ", lod, ", brick->points.size() = ", brick->points.size());
357 |
358 | return lod;
359 | }
360 | }
361 | else
362 | {
363 | auto leaf = brick->createRendering(settings, key, bound);
364 | //vsg::info("leaf key ",key, " ", brick, " leaf ", leaf, ", bound ", bound, ", brick->points.size() = ", brick->points.size());
365 | return leaf;
366 | }
367 |
368 | return vsg::Node::create();
369 | }
370 |
371 | vsg::ref_ptr vsgPoints::createPagedLOD(vsgPoints::Levels& levels, vsgPoints::Settings& settings)
372 | {
373 | if (levels.empty()) return {};
374 |
375 | auto stateGroup = createStateGroup(settings);
376 |
377 | std::basic_ostringstream str;
378 |
379 | double brickSize = settings.precision * pow(2.0, static_cast(settings.bits));
380 | double rootBrickSize = brickSize * std::pow(2.0, levels.size() - 1);
381 |
382 | vsg::debug("rootBrickSize = ", rootBrickSize);
383 |
384 | // If only one level is present then PagedLOD is not required so just add all the levels bricks to the StateGroup
385 | if (levels.size() == 1)
386 | {
387 | vsg::dbox bound;
388 | for (auto& [key, brick] : *(levels.back()))
389 | {
390 | auto tile = brick->createRendering(settings, key, bound);
391 | stateGroup->addChild(tile);
392 | }
393 |
394 | return stateGroup;
395 | }
396 |
397 | // more than 1 level so create a PagedLOD hierarchy.
398 |
399 | auto current_itr = levels.rbegin();
400 |
401 | // root tile
402 | auto& root_level = *current_itr;
403 | vsg::debug("root level ", root_level->size());
404 |
405 | for (auto& [key, brick] : *root_level)
406 | {
407 | vsg::debug("root key = ", key, " ", brick);
408 | vsg::dbox bound;
409 | if (auto child = subtile(settings, current_itr, levels.rend(), key, bound, true))
410 | {
411 | vsg::debug("root child ", child);
412 | stateGroup->addChild(child);
413 | }
414 | }
415 |
416 | return stateGroup;
417 | }
418 |
--------------------------------------------------------------------------------
/src/vsgPoints/shaders/brick_phong_frag.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | static auto brick_phong_frag = []() {
4 | static const char str[] =
5 | R"(#vsga 1.1.2
6 | Root id=1 vsg::ShaderStage
7 | {
8 | userObjects 0
9 | mask 18446744073709551615
10 | stage 16
11 | entryPointName "main"
12 | module id=2 vsg::ShaderModule
13 | {
14 | userObjects 0
15 | hints id=0
16 | source "#version 450
17 | #extension GL_ARB_separate_shader_objects : enable
18 | #pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, SHADOWMAP_DEBUG)
19 |
20 | #define VIEW_DESCRIPTOR_SET 0
21 | #define MATERIAL_DESCRIPTOR_SET 1
22 |
23 | #ifdef VSG_DIFFUSE_MAP
24 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap;
25 | #endif
26 |
27 | #ifdef VSG_NORMAL_MAP
28 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 2) uniform sampler2D normalMap;
29 | #endif
30 |
31 | #ifdef VSG_LIGHTMAP_MAP
32 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 3) uniform sampler2D aoMap;
33 | #endif
34 |
35 | #ifdef VSG_EMISSIVE_MAP
36 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 4) uniform sampler2D emissiveMap;
37 | #endif
38 |
39 | #ifdef VSG_SPECULAR_MAP
40 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 5) uniform sampler2D specularMap;
41 | #endif
42 |
43 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform MaterialData
44 | {
45 | vec4 ambientColor;
46 | vec4 diffuseColor;
47 | vec4 specularColor;
48 | vec4 emissiveColor;
49 | float shininess;
50 | float alphaMask;
51 | float alphaMaskCutoff;
52 | } material;
53 |
54 | layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData
55 | {
56 | vec4 values[2048];
57 | } lightData;
58 |
59 |
60 | layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps;
61 |
62 | layout(location = 0) in vec3 eyePos;
63 | layout(location = 1) in vec3 normalDir;
64 | layout(location = 2) in vec4 vertexColor;
65 | #ifndef VSG_POINT_SPRITE
66 | layout(location = 3) in vec2 texCoord0;
67 | #endif
68 | layout(location = 5) in vec3 viewDir;
69 |
70 | layout(location = 0) out vec4 outColor;
71 |
72 | // Find the normal for this fragment, pulling either from a predefined normal map
73 | // or from the interpolated mesh normal and tangent attributes.
74 | vec3 getNormal()
75 | {
76 | vec3 result;
77 | #ifdef VSG_NORMAL_MAP
78 | // Perturb normal, see http://www.thetenthplanet.de/archives/1180
79 | vec3 tangentNormal = texture(normalMap, texCoord0).xyz * 2.0 - 1.0;
80 |
81 | //tangentNormal *= vec3(2,2,1);
82 |
83 | vec3 q1 = dFdx(eyePos);
84 | vec3 q2 = dFdy(eyePos);
85 | vec2 st1 = dFdx(texCoord0);
86 | vec2 st2 = dFdy(texCoord0);
87 |
88 | vec3 N = normalize(normalDir);
89 | vec3 T = normalize(q1 * st2.t - q2 * st1.t);
90 | vec3 B = -normalize(cross(N, T));
91 | mat3 TBN = mat3(T, B, N);
92 |
93 | result = normalize(TBN * tangentNormal);
94 | #else
95 | result = normalize(normalDir);
96 | #endif
97 | #ifdef VSG_TWO_SIDED_LIGHTING
98 | if (!gl_FrontFacing)
99 | result = -result;
100 | #endif
101 | return result;
102 | }
103 |
104 | vec3 computeLighting(vec3 ambientColor, vec3 diffuseColor, vec3 specularColor, vec3 emissiveColor, float shininess, float ambientOcclusion, vec3 ld, vec3 nd, vec3 vd)
105 | {
106 | vec3 color = vec3(0.0);
107 | color.rgb += ambientColor;
108 |
109 | float diff = max(dot(ld, nd), 0.0);
110 | color.rgb += diffuseColor * diff;
111 |
112 | if (diff > 0.0)
113 | {
114 | vec3 halfDir = normalize(ld + vd);
115 | color.rgb += specularColor * pow(max(dot(halfDir, nd), 0.0), shininess);
116 | }
117 |
118 | vec3 result = color + emissiveColor;
119 | result *= ambientOcclusion;
120 |
121 | return result;
122 | }
123 |
124 |
125 | void main()
126 | {
127 | float brightnessCutoff = 0.001;
128 |
129 | #ifdef VSG_POINT_SPRITE
130 | vec2 texCoord0 = gl_PointCoord.xy;
131 | #endif
132 |
133 | vec4 diffuseColor = vertexColor * material.diffuseColor;
134 | #ifdef VSG_DIFFUSE_MAP
135 | #ifdef VSG_GREYSCALE_DIFFUSE_MAP
136 | float v = texture(diffuseMap, texCoord0.st).s;
137 | diffuseColor *= vec4(v, v, v, 1.0);
138 | #else
139 | diffuseColor *= texture(diffuseMap, texCoord0.st);
140 | #endif
141 | #endif
142 |
143 | vec4 ambientColor = diffuseColor * material.ambientColor * material.ambientColor.a;
144 | vec4 specularColor = material.specularColor;
145 | vec4 emissiveColor = material.emissiveColor;
146 | float shininess = material.shininess;
147 | float ambientOcclusion = 1.0;
148 |
149 | if (material.alphaMask == 1.0f)
150 | {
151 | if (diffuseColor.a < material.alphaMaskCutoff)
152 | discard;
153 | }
154 |
155 | #ifdef VSG_EMISSIVE_MAP
156 | emissiveColor *= texture(emissiveMap, texCoord0.st);
157 | #endif
158 |
159 | #ifdef VSG_LIGHTMAP_MAP
160 | ambientOcclusion *= texture(aoMap, texCoord0.st).r;
161 | #endif
162 |
163 | #ifdef VSG_SPECULAR_MAP
164 | specularColor *= texture(specularMap, texCoord0.st);
165 | #endif
166 |
167 | vec3 nd = getNormal();
168 | vec3 vd = normalize(viewDir);
169 |
170 | vec3 color = vec3(0.0, 0.0, 0.0);
171 |
172 | vec4 lightNums = lightData.values[0];
173 | int numAmbientLights = int(lightNums[0]);
174 | int numDirectionalLights = int(lightNums[1]);
175 | int numPointLights = int(lightNums[2]);
176 | int numSpotLights = int(lightNums[3]);
177 | int index = 1;
178 |
179 | if (numAmbientLights>0)
180 | {
181 | // ambient lights
182 | for(int i = 0; i0)
193 | {
194 | // directional lights
195 | for(int i = 0; i 0.0 && brightness > brightnessCutoff) && !matched)
206 | {
207 | mat4 sm_matrix = mat4(lightData.values[index++],
208 | lightData.values[index++],
209 | lightData.values[index++],
210 | lightData.values[index++]);
211 |
212 | vec4 sm_tc = (sm_matrix) * vec4(eyePos, 1.0);
213 |
214 | if (sm_tc.x >= 0.0 && sm_tc.x <= 1.0 && sm_tc.y >= 0.0 && sm_tc.y <= 1.0 && sm_tc.z >= 0.0 /* && sm_tc.z <= 1.0*/)
215 | {
216 | matched = true;
217 |
218 | float coverage = texture(shadowMaps, vec4(sm_tc.st, shadowMapIndex, sm_tc.z)).r;
219 | brightness *= (1.0-coverage);
220 |
221 | #ifdef SHADOWMAP_DEBUG
222 | if (shadowMapIndex==0) color = vec3(1.0, 0.0, 0.0);
223 | else if (shadowMapIndex==1) color = vec3(0.0, 1.0, 0.0);
224 | else if (shadowMapIndex==2) color = vec3(0.0, 0.0, 1.0);
225 | else if (shadowMapIndex==3) color = vec3(1.0, 1.0, 0.0);
226 | else if (shadowMapIndex==4) color = vec3(0.0, 1.0, 1.0);
227 | else color = vec3(1.0, 1.0, 1.0);
228 | #endif
229 | }
230 |
231 | ++shadowMapIndex;
232 | shadowMapSettings.r -= 1.0;
233 | }
234 |
235 | if (shadowMapSettings.r > 0.0)
236 | {
237 | // skip lightData and shadowMap entries for shadow maps that we haven't visited for this light
238 | // so subsequent light pointions are correct.
239 | index += 4 * int(shadowMapSettings.r);
240 | shadowMapIndex += int(shadowMapSettings.r);
241 | }
242 |
243 | // if light is too dim/shadowed to effect the rendering skip it
244 | if (brightness <= brightnessCutoff ) continue;
245 |
246 | float unclamped_LdotN = dot(direction, nd);
247 |
248 | float diff = max(unclamped_LdotN, 0.0);
249 | color.rgb += (diffuseColor.rgb * lightColor.rgb) * (diff * brightness);
250 |
251 | if (shininess > 0.0 && diff > 0.0)
252 | {
253 | vec3 halfDir = normalize(direction + vd);
254 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * brightness);
255 | }
256 | }
257 | }
258 |
259 | if (numPointLights>0)
260 | {
261 | // point light
262 | for(int i = 0; i 0.0 && diff > 0.0)
283 | {
284 | vec3 halfDir = normalize(direction + vd);
285 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale);
286 | }
287 | }
288 | }
289 |
290 | if (numSpotLights>0)
291 | {
292 | // spot light
293 | for(int i = 0; i 0.0 && diff > 0.0)
316 | {
317 | vec3 halfDir = normalize(direction + vd);
318 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale);
319 | }
320 | }
321 | }
322 |
323 |
324 | outColor.rgb = (color * ambientOcclusion) + emissiveColor.rgb;
325 | outColor.a = diffuseColor.a;
326 | }
327 | "
328 | code 3794
329 | 119734787 65536 524299 632 0 131089 1 393227 1 1280527431 1685353262 808793134
330 | 0 196622 0 1 720911 4 4 1852399981 0 14 27 83
331 | 242 613 631 196624 4 7 196611 2 450 589828 1096764487 1935622738
332 | 1918988389 1600484449 1684105331 1868526181 1667590754 29556 262149 4 1852399981 0 327685 9
333 | 1316250983 1634562671 10348 262149 12 1970496882 29804 327685 14 1836216174 1766091873 114
334 | 458757 21 1734963810 1701737576 1967354739 1717989236 0 393221 25 1717987684 1130722165 1919904879
335 | 0 327685 27 1953654134 1866692709 7499628 393221 29 1702125901 1818323314 1635017028 0
336 | 458758 29 0 1768058209 1131703909 1919904879 0 458758 29 1 1717987684 1130722165
337 | 1919904879 0 458758 29 2 1667592307 1918987381 1869377347 114 458758 29 3
338 | 1936289125 1702259059 1869377347 114 393222 29 4 1852401779 1936027241 115 393222 29
339 | 5 1752198241 1935756641 107 458758 29 6 1752198241 1935756641 1953842027 6710895 327685
340 | 31 1702125933 1818323314 0 393221 38 1768058209 1131703909 1919904879 0 393221 50
341 | 1667592307 1918987381 1869377347 114 393221 54 1936289125 1702259059 1869377347 114 327685 58
342 | 1852401779 1936027241 115 458757 62 1768058209 1333030501 1970037603 1852795251 0 196613 80
343 | 25710 196613 82 25718 262149 83 2003134838 7498052 262149 86 1869377379 114
344 | 327685 89 1751607660 1836404340 115 327685 92 1751607628 1952531572 97 327686 92
345 | 0 1970037110 29541 327685 94 1751607660 1952531572 97 458757 98 1097692526 1701405293
346 | 1766618222 1937008743 0 524293 103 1148024174 1667592809 1852795252 1766616161 1937008743 0 393221
347 | 108 1349350766 1953393007 1751607628 29556 393221 113 1399682414 1282699120 1952999273 115 262149
348 | 117 1701080681 120 196613 122 105 327685 131 1751607660 1819231092 29295 393221
349 | 148 1684105331 1632466799 1684949360 30821 196613 153 105 327685 162 1751607660 1819231092
350 | 29295 327685 167 1701996900 1869182051 110 458757 174 1684105331 1632466799 1952797552 1735289204
351 | 115 327685 179 1734963810 1701737576 29555 262149 183 1668571501 6579560 327685 202
352 | 1834970483 1769108577 120 262149 240 1952410995 99 262149 242 1348827493 29551 327685
353 | 279 1702260579 1701273970 0 327685 283 1684105331 1632466799 29552 393221 329 1818455669
354 | 1701866849 1682726756 5141615 262149 333 1717987684 0 262149 354 1718378856 7498052 196613
355 | 378 105 327685 387 1751607660 1819231092 29295 327685 392 1769172848 1852795252 0
356 | 327685 398 1734963810 1701737576 29555 262149 407 1953260900 97 327685 411 1953720676
357 | 1701015137 50 327685 429 1701996900 1869182051 110 262149 435 1818321779 101 393221
358 | 439 1818455669 1701866849 1682726756 5141615 262149 443 1717987684 0 262149 464 1718378856
359 | 7498052 196613 488 105 327685 497 1751607660 1819231092 29295 524293 502 1769172848
360 | 1852795252 1936679775 1701736009 1735278962 25964 655365 507 1751607660 1919501428 1769235301 1667198575 1968141167
361 | 1098016116 1701603182 0 327685 512 1734963810 1701737576 29555 262149 521 1953260900 97
362 | 327685 526 1953720676 1701015137 50 327685 544 1701996900 1869182051 110 458757 550
363 | 1601466212 1751607660 1919509620 1769235301 28271 262149 556 1818321779 101 393221 567 1818455669
364 | 1701866849 1682726756 5141615 262149 571 1717987684 0 262149 592 1718378856 7498052 327685
365 | 613 1131705711 1919904879 0 327685 631 1131963764 1685221231 48 262215 14 30
366 | 1 262215 27 30 2 327752 29 0 35 0 327752 29
367 | 1 35 16 327752 29 2 35 32 327752 29 3 35
368 | 48 327752 29 4 35 64 327752 29 5 35 68 327752
369 | 29 6 35 72 196679 29 2 262215 31 34 1 262215
370 | 31 33 10 262215 83 30 5 262215 91 6 16 327752
371 | 92 0 35 0 196679 92 2 262215 94 34 0 262215
372 | 94 33 0 262215 242 30 0 262215 283 34 0 262215
373 | 283 33 2 262215 613 30 0 262215 631 30 3 131091
374 | 2 196641 3 2 196630 6 32 262167 7 6 3 196641
375 | 8 7 262176 11 7 7 262176 13 1 7 262203 13
376 | 14 1 262176 20 7 6 262187 6 22 981668463 262167 23
377 | 6 4 262176 24 7 23 262176 26 1 23 262203 26
378 | 27 1 589854 29 23 23 23 23 6 6 6 262176
379 | 30 2 29 262203 30 31 2 262165 32 32 1 262187
380 | 32 33 1 262176 34 2 23 262187 32 40 0 262165
381 | 44 32 0 262187 44 45 3 262176 46 2 6 262187
382 | 32 51 2 262187 32 55 3 262187 32 59 4 262187
383 | 6 63 1065353216 262187 32 64 5 131092 67 262187 32 73
384 | 6 262203 13 83 1 262187 6 87 0 393260 7 88
385 | 87 87 87 262187 44 90 2048 262172 91 23 90 196638
386 | 92 91 262176 93 2 92 262203 93 94 2 262176 97
387 | 7 32 262187 44 99 0 262187 44 104 1 262187 44
388 | 109 2 262176 182 7 67 196650 67 184 262168 200 23
389 | 4 262176 201 7 200 262203 13 242 1 196649 67 278
390 | 589849 280 6 1 1 1 0 1 0 196635 281 280
391 | 262176 282 0 281 262203 282 283 0 262167 285 6 2
392 | 262176 612 3 23 262203 612 613 3 262176 620 3 6
393 | 262176 630 1 285 262203 630 631 1 327734 2 4 0
394 | 3 131320 5 262203 20 21 7 262203 24 25 7 262203
395 | 24 38 7 262203 24 50 7 262203 24 54 7 262203
396 | 20 58 7 262203 20 62 7 262203 11 80 7 262203
397 | 11 82 7 262203 11 86 7 262203 24 89 7 262203
398 | 97 98 7 262203 97 103 7 262203 97 108 7 262203
399 | 97 113 7 262203 97 117 7 262203 97 122 7 262203
400 | 24 131 7 262203 97 148 7 262203 97 153 7 262203
401 | 24 162 7 262203 11 167 7 262203 24 174 7 262203
402 | 20 179 7 262203 182 183 7 262203 201 202 7 262203
403 | 24 240 7 262203 20 279 7 262203 20 329 7 262203
404 | 20 333 7 262203 11 354 7 262203 97 378 7 262203
405 | 24 387 7 262203 11 392 7 262203 20 398 7 262203
406 | 11 407 7 262203 20 411 7 262203 11 429 7 262203
407 | 20 435 7 262203 20 439 7 262203 20 443 7 262203
408 | 11 464 7 262203 97 488 7 262203 24 497 7 262203
409 | 24 502 7 262203 24 507 7 262203 20 512 7 262203
410 | 11 521 7 262203 20 526 7 262203 11 544 7 262203
411 | 20 550 7 262203 20 556 7 262203 20 567 7 262203
412 | 20 571 7 262203 11 592 7 196670 21 22 262205 23
413 | 28 27 327745 34 35 31 33 262205 23 36 35 327813
414 | 23 37 28 36 196670 25 37 262205 23 39 25 327745
415 | 34 41 31 40 262205 23 42 41 327813 23 43 39
416 | 42 393281 46 47 31 40 45 262205 6 48 47 327822
417 | )"
418 | R"( 23 49 43 48 196670 38 49 327745 34 52 31 51
419 | 262205 23 53 52 196670 50 53 327745 34 56 31 55
420 | 262205 23 57 56 196670 54 57 327745 46 60 31 59
421 | 262205 6 61 60 196670 58 61 196670 62 63 327745 46
422 | 65 31 64 262205 6 66 65 327860 67 68 66 63
423 | 196855 70 0 262394 68 69 70 131320 69 327745 20 71
424 | 25 45 262205 6 72 71 327745 46 74 31 73 262205
425 | 6 75 74 327864 67 76 72 75 196855 78 0 262394
426 | 76 77 78 131320 77 65788 131320 78 131321 70 131320 70
427 | 262201 7 81 9 196670 80 81 262205 7 84 83 393228
428 | 7 85 1 69 84 196670 82 85 196670 86 88 393281
429 | 34 95 94 40 40 262205 23 96 95 196670 89 96
430 | 327745 20 100 89 99 262205 6 101 100 262254 32 102
431 | 101 196670 98 102 327745 20 105 89 104 262205 6 106
432 | 105 262254 32 107 106 196670 103 107 327745 20 110 89
433 | 109 262205 6 111 110 262254 32 112 111 196670 108 112
434 | 327745 20 114 89 45 262205 6 115 114 262254 32 116
435 | 115 196670 113 116 196670 117 33 262205 32 118 98 327853
436 | 67 119 118 40 196855 121 0 262394 119 120 121 131320
437 | 120 196670 122 40 131321 123 131320 123 262390 125 126 0
438 | 131321 127 131320 127 262205 32 128 122 262205 32 129 98
439 | 327857 67 130 128 129 262394 130 124 125 131320 124 262205
440 | 32 132 117 327808 32 133 132 33 196670 117 133 393281
441 | 34 134 94 40 132 262205 23 135 134 196670 131 135
442 | 262205 23 136 38 524367 7 137 136 136 0 1 2
443 | 262205 23 138 131 524367 7 139 138 138 0 1 2
444 | 327813 7 140 137 139 327745 20 141 131 45 262205 6
445 | 142 141 327822 7 143 140 142 262205 7 144 86 327809
446 | 7 145 144 143 196670 86 145 131321 126 131320 126 262205
447 | 32 146 122 327808 32 147 146 33 196670 122 147 131321
448 | 123 131320 125 131321 121 131320 121 196670 148 40 262205 32
449 | 149 103 327853 67 150 149 40 196855 152 0 262394 150
450 | 151 152 131320 151 196670 153 40 131321 154 131320 154 262390
451 | 156 157 0 131321 158 131320 158 262205 32 159 153 262205
452 | 32 160 103 327857 67 161 159 160 262394 161 155 156
453 | 131320 155 262205 32 163 117 327808 32 164 163 33 196670
454 | 117 164 393281 34 165 94 40 163 262205 23 166 165
455 | 196670 162 166 262205 32 168 117 327808 32 169 168 33
456 | 196670 117 169 393281 34 170 94 40 168 262205 23 171
457 | 170 524367 7 172 171 171 0 1 2 262271 7 173
458 | 172 196670 167 173 262205 32 175 117 327808 32 176 175
459 | 33 196670 117 176 393281 34 177 94 40 175 262205 23
460 | 178 177 196670 174 178 327745 20 180 162 45 262205 6
461 | 181 180 196670 179 181 196670 183 184 131321 185 131320 185
462 | 262390 187 188 0 131321 189 131320 189 327745 20 190 174
463 | 99 262205 6 191 190 327866 67 192 191 87 262205 6
464 | 193 179 262205 6 194 21 327866 67 195 193 194 327847
465 | 67 196 192 195 262205 67 197 183 262312 67 198 197
466 | 327847 67 199 196 198 262394 199 186 187 131320 186 262205
467 | 32 203 117 327808 32 204 203 33 196670 117 204 393281
468 | 34 205 94 40 203 262205 23 206 205 262205 32 207
469 | 117 327808 32 208 207 33 196670 117 208 393281 34 209
470 | 94 40 207 262205 23 210 209 262205 32 211 117 327808
471 | 32 212 211 33 196670 117 212 393281 34 213 94 40
472 | 211 262205 23 214 213 262205 32 215 117 327808 32 216
473 | 215 33 196670 117 216 393281 34 217 94 40 215 262205
474 | 23 218 217 327761 6 219 206 0 327761 6 220 206
475 | 1 327761 6 221 206 2 327761 6 222 206 3 327761
476 | 6 223 210 0 327761 6 224 210 1 327761 6 225
477 | 210 2 327761 6 226 210 3 327761 6 227 214 0
478 | 327761 6 228 214 1 327761 6 229 214 2 327761 6
479 | 230 214 3 327761 6 231 218 0 327761 6 232 218
480 | 1 327761 6 233 218 2 327761 6 234 218 3 458832
481 | 23 235 219 220 221 222 458832 23 236 223 224 225
482 | 226 458832 23 237 227 228 229 230 458832 23 238 231
483 | 232 233 234 458832 200 239 235 236 237 238 196670 202
484 | 239 262205 200 241 202 262205 7 243 242 327761 6 244
485 | 243 0 327761 6 245 243 1 327761 6 246 243 2
486 | 458832 23 247 244 245 246 63 327825 23 248 241 247
487 | 196670 240 248 327745 20 249 240 99 262205 6 250 249
488 | 327870 67 251 250 87 196855 253 0 262394 251 252 253
489 | 131320 252 327745 20 254 240 99 262205 6 255 254 327868
490 | 67 256 255 63 131321 253 131320 253 458997 67 257 251
491 | 186 256 252 196855 259 0 262394 257 258 259 131320 258
492 | 327745 20 260 240 104 262205 6 261 260 327870 67 262
493 | 261 87 131321 259 131320 259 458997 67 263 257 253 262
494 | 258 196855 265 0 262394 263 264 265 131320 264 327745 20
495 | 266 240 104 262205 6 267 266 327868 67 268 267 63
496 | 131321 265 131320 265 458997 67 269 263 259 268 264 196855
497 | 271 0 262394 269 270 271 131320 270 327745 20 272 240
498 | 109 262205 6 273 272 327870 67 274 273 87 131321 271
499 | 131320 271 458997 67 275 269 265 274 270 196855 277 0
500 | 262394 275 276 277 131320 276 196670 183 278 262205 281 284
501 | 283 262205 23 286 240 458831 285 287 286 286 0 1
502 | 262205 32 288 148 262255 6 289 288 327745 20 290 240
503 | 109 262205 6 291 290 327761 6 292 287 0 327761 6
504 | 293 287 1 458832 23 294 292 293 289 291 327761 6
505 | 295 294 3 393305 6 296 284 294 295 196670 279 296
506 | 262205 6 297 279 327811 6 298 63 297 262205 6 299
507 | 179 327813 6 300 299 298 196670 179 300 131321 277 131320
508 | 277 262205 32 301 148 327808 32 302 301 33 196670 148
509 | 302 327745 20 303 174 99 262205 6 304 303 327811 6
510 | 305 304 63 327745 20 306 174 99 196670 306 305 131321
511 | 188 131320 188 131321 185 131320 187 327745 20 307 174 99
512 | 262205 6 308 307 327866 67 309 308 87 196855 311 0
513 | 262394 309 310 311 131320 310 327745 20 312 174 99 262205
514 | 6 313 312 262254 32 314 313 327812 32 315 59 314
515 | 262205 32 316 117 327808 32 317 316 315 196670 117 317
516 | 327745 20 318 174 99 262205 6 319 318 262254 32 320
517 | 319 262205 32 321 148 327808 32 322 321 320 196670 148
518 | 322 131321 311 131320 311 262205 6 323 179 262205 6 324
519 | 21 327868 67 325 323 324 196855 327 0 262394 325 326
520 | 327 131320 326 131321 157 131320 327 262205 7 330 167 262205
521 | 7 331 80 327828 6 332 330 331 196670 329 332 262205
522 | 6 334 329 458764 6 335 1 40 334 87 196670 333
523 | 335 262205 23 336 25 524367 7 337 336 336 0 1
524 | 2 262205 23 338 162 524367 7 339 338 338 0 1
525 | 2 327813 7 340 337 339 262205 6 341 333 262205 6
526 | 342 179 327813 6 343 341 342 327822 7 344 340 343
527 | 262205 7 345 86 327809 7 346 345 344 196670 86 346
528 | 262205 6 347 58 327866 67 348 347 87 262205 6 349
529 | 333 327866 67 350 349 87 327847 67 351 348 350 196855
530 | 353 0 262394 351 352 353 131320 352 262205 7 355 167
531 | 262205 7 356 82 327809 7 357 355 356 393228 7 358
532 | 1 69 357 196670 354 358 262205 23 359 50 524367 7
533 | 360 359 359 0 1 2 262205 7 361 354 262205 7
534 | 362 80 327828 6 363 361 362 458764 6 364 1 40
535 | 363 87 262205 6 365 58 458764 6 366 1 26 364
536 | 365 262205 6 367 179 327813 6 368 366 367 327822 7
537 | 369 360 368 262205 7 370 86 327809 7 371 370 369
538 | 196670 86 371 131321 353 131320 353 131321 157 131320 157 262205
539 | 32 372 153 327808 32 373 372 33 196670 153 373 131321
540 | 154 131320 156 131321 152 131320 152 262205 32 374 108 327853
541 | 67 375 374 40 196855 377 0 262394 375 376 377 131320
542 | 376 196670 378 40 131321 379 131320 379 262390 381 382 0
543 | 131321 383 131320 383 262205 32 384 378 262205 32 385 108
544 | 327857 67 386 384 385 262394 386 380 381 131320 380 262205
545 | 32 388 117 327808 32 389 388 33 196670 117 389 393281
546 | 34 390 94 40 388 262205 23 391 390 196670 387 391
547 | 262205 32 393 117 327808 32 394 393 33 196670 117 394
548 | 393281 34 395 94 40 393 262205 23 396 395 524367 7
549 | 397 396 396 0 1 2 196670 392 397 327745 20 399
550 | 387 45 262205 6 400 399 196670 398 400 262205 6 401
551 | 398 262205 6 402 21 327868 67 403 401 402 196855 405
552 | 0 262394 403 404 405 131320 404 131321 382 131320 405 262205
553 | 7 408 392 262205 7 409 242 327811 7 410 408 409
554 | 196670 407 410 327745 20 412 407 99 262205 6 413 412
555 | 327745 20 414 407 99 262205 6 415 414 327813 6 416
556 | 413 415 327745 20 417 407 104 262205 6 418 417 327745
557 | 20 419 407 104 262205 6 420 419 327813 6 421 418
558 | 420 327809 6 422 416 421 327745 20 423 407 109 262205
559 | 6 424 423 327745 20 425 407 109 262205 6 426 425
560 | 327813 6 427 424 426 327809 6 428 422 427 196670 411
561 | 428 262205 7 430 407 262205 6 431 411 393228 6 432
562 | 1 31 431 393296 7 433 432 432 432 327816 7 434
563 | 430 433 196670 429 434 262205 6 436 398 262205 6 437
564 | 411 327816 6 438 436 437 196670 435 438 262205 7 440
565 | 429 262205 7 441 80 327828 6 442 440 441 196670 439
566 | 442 262205 6 444 435 262205 6 445 439 458764 6 446
567 | 1 40 445 87 327813 6 447 444 446 196670 443 447
568 | 262205 23 448 25 524367 7 449 448 448 0 1 2
569 | 262205 23 450 387 524367 7 451 450 450 0 1 2
570 | 327813 7 452 449 451 262205 6 453 443 327822 7 454
571 | 452 453 262205 7 455 86 327809 7 456 455 454 196670
572 | 86 456 262205 6 457 58 327866 67 458 457 87 262205
573 | 6 459 443 327866 67 460 459 87 327847 67 461 458
574 | 460 196855 463 0 262394 461 462 463 131320 462 262205 7
575 | 465 429 262205 7 466 82 327809 7 467 465 466 393228
576 | 7 468 1 69 467 196670 464 468 262205 23 469 50
577 | 524367 7 470 469 469 0 1 2 262205 7 471 464
578 | 262205 7 472 80 327828 6 473 471 472 458764 6 474
579 | 1 40 473 87 262205 6 475 58 458764 6 476 1
580 | 26 474 475 262205 6 477 435 327813 6 478 476 477
581 | 327822 7 479 470 478 262205 7 480 86 327809 7 481
582 | 480 479 196670 86 481 131321 463 131320 463 131321 382 131320
583 | 382 262205 32 482 378 327808 32 483 482 33 196670 378
584 | 483 131321 379 131320 381 131321 377 131320 377 262205 32 484
585 | 113 327853 67 485 484 40 196855 487 0 262394 485 486
586 | 487 131320 486 196670 488 40 131321 489 131320 489 262390 491
587 | 492 0 131321 493 131320 493 262205 32 494 488 262205 32
588 | 495 113 327857 67 496 494 495 262394 496 490 491 131320
589 | 490 262205 32 498 117 327808 32 499 498 33 196670 117
590 | 499 393281 34 500 94 40 498 262205 23 501 500 196670
591 | 497 501 262205 32 503 117 327808 32 504 503 33 196670
592 | 117 504 393281 34 505 94 40 503 262205 23 506 505
593 | 196670 502 506 262205 32 508 117 327808 32 509 508 33
594 | 196670 117 509 393281 34 510 94 40 508 262205 23 511
595 | 510 196670 507 511 327745 20 513 497 45 262205 6 514
596 | 513 196670 512 514 262205 6 515 512 262205 6 516 21
597 | 327868 67 517 515 516 196855 519 0 262394 517 518 519
598 | 131320 518 131321 492 131320 519 262205 23 522 502 524367 7
599 | 523 522 522 0 1 2 262205 7 524 242 327811 7
600 | 525 523 524 196670 521 525 327745 20 527 521 99 262205
601 | 6 528 527 327745 20 529 521 99 262205 6 530 529
602 | 327813 6 531 528 530 327745 20 532 521 104 262205 6
603 | 533 532 327745 20 534 521 104 262205 6 535 534 327813
604 | 6 536 533 535 327809 6 537 531 536 327745 20 538
605 | 521 109 262205 6 539 538 327745 20 540 521 109 262205
606 | 6 541 540 327813 6 542 539 541 327809 6 543 537
607 | 542 196670 526 543 262205 7 545 521 262205 6 546 526
608 | 393228 6 547 1 31 546 393296 7 548 547 547 547
609 | 327816 7 549 545 548 196670 544 549 262205 23 551 507
610 | 524367 7 552 551 551 0 1 2 262205 7 553 544
611 | 262271 7 554 553 327828 6 555 552 554 196670 550 555
612 | 262205 6 557 512 327745 20 558 507 45 262205 6 559
613 | 558 327745 20 560 502 45 262205 6 561 560 262205 6
614 | 562 550 524300 6 563 1 49 559 561 562 327813 6
615 | 564 557 563 262205 6 565 526 327816 6 566 564 565
616 | 196670 556 566 262205 7 568 544 262205 7 569 80 327828
617 | 6 570 568 569 196670 567 570 262205 6 572 556 262205
618 | 6 573 567 458764 6 574 1 40 573 87 327813 6
619 | 575 572 574 196670 571 575 262205 23 576 25 524367 7
620 | 577 576 576 0 1 2 262205 23 578 497 524367 7
621 | 579 578 578 0 1 2 327813 7 580 577 579 262205
622 | 6 581 571 327822 7 582 580 581 262205 7 583 86
623 | 327809 7 584 583 582 196670 86 584 262205 6 585 58
624 | 327866 67 586 585 87 262205 6 587 571 327866 67 588
625 | 587 87 327847 67 589 586 588 196855 591 0 262394 589
626 | 590 591 131320 590 262205 7 593 544 262205 7 594 82
627 | 327809 7 595 593 594 393228 7 596 1 69 595 196670
628 | 592 596 262205 23 597 50 524367 7 598 597 597 0
629 | 1 2 262205 7 599 592 262205 7 600 80 327828 6
630 | 601 599 600 458764 6 602 1 40 601 87 262205 6
631 | 603 58 458764 6 604 1 26 602 603 262205 6 605
632 | 556 327813 6 606 604 605 327822 7 607 598 606 262205
633 | 7 608 86 327809 7 609 608 607 196670 86 609 131321
634 | 591 131320 591 131321 492 131320 492 262205 32 610 488 327808
635 | 32 611 610 33 196670 488 611 131321 489 131320 491 131321
636 | 487 131320 487 262205 7 614 86 262205 6 615 62 327822
637 | 7 616 614 615 262205 23 617 54 524367 7 618 617
638 | 617 0 1 2 327809 7 619 616 618 327745 620 621
639 | 613 99 327761 6 622 619 0 196670 621 622 327745 620
640 | 623 613 104 327761 6 624 619 1 196670 623 624 327745
641 | 620 625 613 109 327761 6 626 619 2 196670 625 626
642 | 327745 20 627 25 45 262205 6 628 627 327745 620 629
643 | 613 45 196670 629 628 65789 65592 327734 7 9 0 8
644 | 131320 10 262203 11 12 7 262205 7 15 14 393228 7
645 | 16 1 69 15 196670 12 16 262205 7 17 12 131326
646 | 17 65592
647 | }
648 | NumSpecializationConstants 0
649 | }
650 | )";
651 | vsg::VSG io;
652 | return io.read_cast(reinterpret_cast(str), sizeof(str));
653 | };
654 |
--------------------------------------------------------------------------------