mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 12:02:47 -05:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fb70dbae6 | ||
|
|
916e9a8906 | ||
|
|
5e3b4defd7 | ||
|
|
1705215bff | ||
|
|
6aaa393228 | ||
| 98ad0bf62e | |||
| ec09506a74 | |||
| dfea554289 | |||
| 9ff1dda9df | |||
| ea3b7a0691 | |||
| 465f863687 | |||
| 18abe824d2 | |||
| a639fb40e4 | |||
| 7c1f1a8b9f | |||
| 05d4314cec | |||
| 45584f0621 | |||
| d16693189e | |||
| 47f8da7192 |
13
.gitmodules
vendored
13
.gitmodules
vendored
@@ -1,12 +1,13 @@
|
|||||||
[submodule "vendor/glfw"]
|
|
||||||
path = vendor/glfw
|
|
||||||
url = https://github.com/glfw/glfw.git
|
|
||||||
[submodule "vendor/glm"]
|
|
||||||
path = vendor/glm
|
|
||||||
url = https://github.com/g-truc/glm.git
|
|
||||||
[submodule "vendor/toddcox"]
|
[submodule "vendor/toddcox"]
|
||||||
path = vendor/toddcox
|
path = vendor/toddcox
|
||||||
url = https://github.com/JCRaymond/toddcox-faster.git
|
url = https://github.com/JCRaymond/toddcox-faster.git
|
||||||
[submodule "vendor/yaml-cpp"]
|
[submodule "vendor/yaml-cpp"]
|
||||||
path = vendor/yaml-cpp
|
path = vendor/yaml-cpp
|
||||||
url = git://github.com/jbeder/yaml-cpp.git
|
url = git://github.com/jbeder/yaml-cpp.git
|
||||||
|
[submodule "vendor/cgl"]
|
||||||
|
path = vendor/cgl
|
||||||
|
url = git://github.com/allemangD/cgl.git
|
||||||
|
[submodule "vendor/nanogui"]
|
||||||
|
path = vendor/nanogui
|
||||||
|
url = https://github.com/allemangD/nanogui
|
||||||
|
branch = master
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(toddcox-faster)
|
project(toddcox-visualize)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
add_subdirectory(vendor/toddcox)
|
add_subdirectory(vendor/toddcox)
|
||||||
|
|
||||||
add_subdirectory(vendor/yaml-cpp)
|
add_subdirectory(vendor/yaml-cpp)
|
||||||
add_subdirectory(vendor/glad)
|
|
||||||
add_subdirectory(vendor/glfw)
|
set(NANOGUI_BUILD_EXAMPLE OFF CACHE BOOL " " FORCE)
|
||||||
add_subdirectory(vendor/glm)
|
set(NANOGUI_BUILD_PYTHON OFF CACHE BOOL " " FORCE)
|
||||||
|
set(NANOGUI_INSTALL OFF CACHE BOOL " " FORCE)
|
||||||
|
set(NANOGUI_USE_GLAD ON CACHE BOOL " " FORCE)
|
||||||
|
add_subdirectory(vendor/nanogui)
|
||||||
|
set_property(TARGET glfw glfw_objects nanogui PROPERTY FOLDER "dependencies")
|
||||||
|
|
||||||
add_subdirectory(vis)
|
add_subdirectory(vis)
|
||||||
|
|
||||||
|
|||||||
2
vendor/glad/CMakeLists.txt
vendored
2
vendor/glad/CMakeLists.txt
vendored
@@ -1,2 +0,0 @@
|
|||||||
add_library(glad src/glad.c)
|
|
||||||
target_include_directories(glad PUBLIC include)
|
|
||||||
290
vendor/glad/include/KHR/khrplatform.h
vendored
290
vendor/glad/include/KHR/khrplatform.h
vendored
@@ -1,290 +0,0 @@
|
|||||||
#ifndef __khrplatform_h_
|
|
||||||
#define __khrplatform_h_
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
|
||||||
**
|
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
** copy of this software and/or associated documentation files (the
|
|
||||||
** "Materials"), to deal in the Materials without restriction, including
|
|
||||||
** without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
** permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
** the following conditions:
|
|
||||||
**
|
|
||||||
** The above copyright notice and this permission notice shall be included
|
|
||||||
** in all copies or substantial portions of the Materials.
|
|
||||||
**
|
|
||||||
** THE MATERIALS ARE 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
|
|
||||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Khronos platform-specific types and definitions.
|
|
||||||
*
|
|
||||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
|
||||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
|
||||||
* The last semantic modification to khrplatform.h was at commit ID:
|
|
||||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
|
||||||
*
|
|
||||||
* Adopters may modify this file to suit their platform. Adopters are
|
|
||||||
* encouraged to submit platform specific modifications to the Khronos
|
|
||||||
* group so that they can be included in future versions of this file.
|
|
||||||
* Please submit changes by filing pull requests or issues on
|
|
||||||
* the EGL Registry repository linked above.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* See the Implementer's Guidelines for information about where this file
|
|
||||||
* should be located on your system and for more details of its use:
|
|
||||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
|
||||||
*
|
|
||||||
* This file should be included as
|
|
||||||
* #include <KHR/khrplatform.h>
|
|
||||||
* by Khronos client API header files that use its types and defines.
|
|
||||||
*
|
|
||||||
* The types in khrplatform.h should only be used to define API-specific types.
|
|
||||||
*
|
|
||||||
* Types defined in khrplatform.h:
|
|
||||||
* khronos_int8_t signed 8 bit
|
|
||||||
* khronos_uint8_t unsigned 8 bit
|
|
||||||
* khronos_int16_t signed 16 bit
|
|
||||||
* khronos_uint16_t unsigned 16 bit
|
|
||||||
* khronos_int32_t signed 32 bit
|
|
||||||
* khronos_uint32_t unsigned 32 bit
|
|
||||||
* khronos_int64_t signed 64 bit
|
|
||||||
* khronos_uint64_t unsigned 64 bit
|
|
||||||
* khronos_intptr_t signed same number of bits as a pointer
|
|
||||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
|
||||||
* khronos_ssize_t signed size
|
|
||||||
* khronos_usize_t unsigned size
|
|
||||||
* khronos_float_t signed 32 bit floating point
|
|
||||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
|
||||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
|
||||||
* nanoseconds
|
|
||||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
|
||||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
|
||||||
* only be used as a base type when a client API's boolean type is
|
|
||||||
* an enum. Client APIs which use an integer or other type for
|
|
||||||
* booleans cannot use this as the base type for their boolean.
|
|
||||||
*
|
|
||||||
* Tokens defined in khrplatform.h:
|
|
||||||
*
|
|
||||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
|
||||||
*
|
|
||||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
|
||||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
|
||||||
*
|
|
||||||
* Calling convention macros defined in this file:
|
|
||||||
* KHRONOS_APICALL
|
|
||||||
* KHRONOS_APIENTRY
|
|
||||||
* KHRONOS_APIATTRIBUTES
|
|
||||||
*
|
|
||||||
* These may be used in function prototypes as:
|
|
||||||
*
|
|
||||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
|
||||||
* int arg1,
|
|
||||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
|
||||||
# define KHRONOS_STATIC 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APICALL
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This precedes the return type of the function in the function prototype.
|
|
||||||
*/
|
|
||||||
#if defined(KHRONOS_STATIC)
|
|
||||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
|
||||||
* header compatible with static linking. */
|
|
||||||
# define KHRONOS_APICALL
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
# define KHRONOS_APICALL __declspec(dllimport)
|
|
||||||
#elif defined (__SYMBIAN32__)
|
|
||||||
# define KHRONOS_APICALL IMPORT_C
|
|
||||||
#elif defined(__ANDROID__)
|
|
||||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
|
||||||
#else
|
|
||||||
# define KHRONOS_APICALL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APIENTRY
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This follows the return type of the function and precedes the function
|
|
||||||
* name in the function prototype.
|
|
||||||
*/
|
|
||||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(KHRONOS_STATIC)
|
|
||||||
/* Win32 but not WinCE */
|
|
||||||
# define KHRONOS_APIENTRY __stdcall
|
|
||||||
#else
|
|
||||||
# define KHRONOS_APIENTRY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APIATTRIBUTES
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This follows the closing parenthesis of the function prototype arguments.
|
|
||||||
*/
|
|
||||||
#if defined (__ARMCC_2__)
|
|
||||||
#define KHRONOS_APIATTRIBUTES __softfp
|
|
||||||
#else
|
|
||||||
#define KHRONOS_APIATTRIBUTES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* basic type definitions
|
|
||||||
*-----------------------------------------------------------------------*/
|
|
||||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Using <stdint.h>
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(__VMS ) || defined(__sgi)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Using <inttypes.h>
|
|
||||||
*/
|
|
||||||
#include <inttypes.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Win32
|
|
||||||
*/
|
|
||||||
typedef __int32 khronos_int32_t;
|
|
||||||
typedef unsigned __int32 khronos_uint32_t;
|
|
||||||
typedef __int64 khronos_int64_t;
|
|
||||||
typedef unsigned __int64 khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(__sun__) || defined(__digital__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sun or Digital
|
|
||||||
*/
|
|
||||||
typedef int khronos_int32_t;
|
|
||||||
typedef unsigned int khronos_uint32_t;
|
|
||||||
#if defined(__arch64__) || defined(_LP64)
|
|
||||||
typedef long int khronos_int64_t;
|
|
||||||
typedef unsigned long int khronos_uint64_t;
|
|
||||||
#else
|
|
||||||
typedef long long int khronos_int64_t;
|
|
||||||
typedef unsigned long long int khronos_uint64_t;
|
|
||||||
#endif /* __arch64__ */
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hypothetical platform with no float or int64 support
|
|
||||||
*/
|
|
||||||
typedef int khronos_int32_t;
|
|
||||||
typedef unsigned int khronos_uint32_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 0
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 0
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic fallback
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Types that are (so far) the same on all platforms
|
|
||||||
*/
|
|
||||||
typedef signed char khronos_int8_t;
|
|
||||||
typedef unsigned char khronos_uint8_t;
|
|
||||||
typedef signed short int khronos_int16_t;
|
|
||||||
typedef unsigned short int khronos_uint16_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
|
||||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
|
||||||
* to be the only LLP64 architecture in current use.
|
|
||||||
*/
|
|
||||||
#ifdef _WIN64
|
|
||||||
typedef signed long long int khronos_intptr_t;
|
|
||||||
typedef unsigned long long int khronos_uintptr_t;
|
|
||||||
typedef signed long long int khronos_ssize_t;
|
|
||||||
typedef unsigned long long int khronos_usize_t;
|
|
||||||
#else
|
|
||||||
typedef signed long int khronos_intptr_t;
|
|
||||||
typedef unsigned long int khronos_uintptr_t;
|
|
||||||
typedef signed long int khronos_ssize_t;
|
|
||||||
typedef unsigned long int khronos_usize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if KHRONOS_SUPPORT_FLOAT
|
|
||||||
/*
|
|
||||||
* Float type
|
|
||||||
*/
|
|
||||||
typedef float khronos_float_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if KHRONOS_SUPPORT_INT64
|
|
||||||
/* Time types
|
|
||||||
*
|
|
||||||
* These types can be used to represent a time interval in nanoseconds or
|
|
||||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
|
||||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
|
||||||
* time the system booted). The Unadjusted System Time is an unsigned
|
|
||||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
|
||||||
* may be either signed or unsigned.
|
|
||||||
*/
|
|
||||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
|
||||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dummy value used to pad enum types to 32 bits.
|
|
||||||
*/
|
|
||||||
#ifndef KHRONOS_MAX_ENUM
|
|
||||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enumerated boolean type
|
|
||||||
*
|
|
||||||
* Values other than zero should be considered to be true. Therefore
|
|
||||||
* comparisons should not be made against KHRONOS_TRUE.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
KHRONOS_FALSE = 0,
|
|
||||||
KHRONOS_TRUE = 1,
|
|
||||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
|
||||||
} khronos_boolean_enum_t;
|
|
||||||
|
|
||||||
#endif /* __khrplatform_h_ */
|
|
||||||
5157
vendor/glad/include/glad/glad.h
vendored
5157
vendor/glad/include/glad/glad.h
vendored
File diff suppressed because it is too large
Load Diff
2532
vendor/glad/src/glad.c
vendored
2532
vendor/glad/src/glad.c
vendored
File diff suppressed because it is too large
Load Diff
1
vendor/glfw
vendored
1
vendor/glfw
vendored
Submodule vendor/glfw deleted from fe57e3c292
1
vendor/glm
vendored
1
vendor/glm
vendored
Submodule vendor/glm deleted from 8828c3f1fd
1
vendor/nanogui
vendored
Submodule
1
vendor/nanogui
vendored
Submodule
Submodule vendor/nanogui added at a9b069f8a7
@@ -12,10 +12,10 @@ add_custom_command(
|
|||||||
COMMENT "copied preses"
|
COMMENT "copied preses"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(vis-util INTERFACE)
|
add_definitions(${NANOGUI_EXTRA_DEFS})
|
||||||
target_include_directories(vis-util INTERFACE include)
|
include_directories(${NANOGUI_EXTRA_INCS})
|
||||||
|
|
||||||
add_executable(vis src/main.cpp)
|
add_executable(vis-gui src/main-gui.cpp)
|
||||||
target_include_directories(vis PRIVATE include)
|
target_include_directories(vis-gui PRIVATE include)
|
||||||
target_link_libraries(vis PRIVATE tc glad glm glfw yaml-cpp)
|
target_link_libraries(vis-gui PRIVATE tc nanogui yaml-cpp ${NANOGUI_EXTRA_LIBS})
|
||||||
add_dependencies(vis shaders presets)
|
add_dependencies(vis-gui shaders presets)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
namespace cgl {
|
namespace cgl {
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -24,7 +24,7 @@ namespace cgl {
|
|||||||
put(data, usage);
|
put(data, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer(Buffer &) = delete;
|
Buffer(const Buffer &) = delete;
|
||||||
|
|
||||||
Buffer(Buffer &&o) noexcept {
|
Buffer(Buffer &&o) noexcept {
|
||||||
id = std::exchange(o.id, 0);
|
id = std::exchange(o.id, 0);
|
||||||
@@ -62,6 +62,17 @@ namespace cgl {
|
|||||||
action();
|
action();
|
||||||
glBindBuffer(target, 0);
|
glBindBuffer(target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<T> getSubData(size_t offset, size_t count) const {
|
||||||
|
GLintptr glOffset = offset * sizeof(T);
|
||||||
|
GLsizeiptr glSize = count * sizeof(T);
|
||||||
|
|
||||||
|
std::vector<T> data(count);
|
||||||
|
|
||||||
|
glad_glGetNamedBufferSubData(id, glOffset, glSize, data.data());
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
namespace cgl {
|
namespace cgl {
|
||||||
class GlError : public std::domain_error {
|
class GlError : public std::domain_error {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
#include <cgl/error.hpp>
|
#include <cgl/error.hpp>
|
||||||
#include <cgl/shaderprogram.hpp>
|
#include <cgl/shaderprogram.hpp>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
#include <cgl/error.hpp>
|
#include <cgl/error.hpp>
|
||||||
#include <cgl/shader.hpp>
|
#include <cgl/shader.hpp>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
#include <cgl/error.hpp>
|
#include <cgl/error.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
#include <cgl/error.hpp>
|
#include <cgl/error.hpp>
|
||||||
#include <cgl/shader.hpp>
|
#include <cgl/shader.hpp>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
#include <cgl/error.hpp>
|
#include <cgl/error.hpp>
|
||||||
#include <cgl/buffer.hpp>
|
#include <cgl/buffer.hpp>
|
||||||
|
|||||||
@@ -28,269 +28,9 @@ struct Primitive {
|
|||||||
|
|
||||||
~Primitive() = default;
|
~Primitive() = default;
|
||||||
|
|
||||||
inline void flip() {
|
|
||||||
if (N > 1) std::swap(inds[0], inds[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(const tc::Cosets &table, int gen) {
|
void apply(const tc::Cosets &table, int gen) {
|
||||||
for (auto &ind : inds) {
|
for (auto &ind : inds) {
|
||||||
ind = table.get(ind, gen);
|
ind = table.get(ind, gen);
|
||||||
}
|
}
|
||||||
flip();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Produce a list of all generators for the group context. The range [0..group.ngens).
|
|
||||||
*/
|
|
||||||
std::vector<int> generators(const tc::Group &context) {
|
|
||||||
std::vector<int> g_gens(context.ngens);
|
|
||||||
std::iota(g_gens.begin(), g_gens.end(), 0);
|
|
||||||
return g_gens;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine which of g_gens are the correct names for sg_gens within the current context
|
|
||||||
*/
|
|
||||||
std::vector<int> recontext_gens(
|
|
||||||
const tc::Group &context,
|
|
||||||
std::vector<int> g_gens,
|
|
||||||
std::vector<int> sg_gens) {
|
|
||||||
|
|
||||||
std::sort(g_gens.begin(), g_gens.end());
|
|
||||||
|
|
||||||
int inv_gen_map[context.ngens];
|
|
||||||
for (size_t i = 0; i < g_gens.size(); i++) {
|
|
||||||
inv_gen_map[g_gens[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> s_sg_gens;
|
|
||||||
s_sg_gens.reserve(sg_gens.size());
|
|
||||||
for (const auto gen : sg_gens) {
|
|
||||||
s_sg_gens.push_back(inv_gen_map[gen]);
|
|
||||||
}
|
|
||||||
std::sort(s_sg_gens.begin(), s_sg_gens.end());
|
|
||||||
|
|
||||||
return s_sg_gens;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the orientation of the group sg_gens is reversed from the group g_gens within group context
|
|
||||||
*/
|
|
||||||
int get_parity(
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
if (g_gens.size() != sg_gens.size() + 1) return 0;
|
|
||||||
|
|
||||||
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (; i < sg_gens.size(); ++i) {
|
|
||||||
if (proper_sg_gens[i] != i) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return i & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Solve the cosets generated by sg_gens within the subgroup generated by g_gens of the group context
|
|
||||||
*/
|
|
||||||
tc::Cosets solve(
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
|
||||||
return context.subgroup(g_gens).solve(proper_sg_gens);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply some context transformation to all primitives of this mesh.
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
std::vector<Primitive<N>> apply(std::vector<Primitive<N>> prims, const tc::Cosets &table, int gen) {
|
|
||||||
for (auto &prim : prims) {
|
|
||||||
prim.apply(table, gen);
|
|
||||||
}
|
|
||||||
return prims;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the orientation of all primitives in this mesh.
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
void flip(std::vector<Primitive<N>> prims) {
|
|
||||||
for (auto &prim : prims) {
|
|
||||||
prim.flip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the indexes of this mesh to those of a different context, using g_gens to build the parent context and sg_gens to build this context.
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<Primitive<N>> recontext(
|
|
||||||
std::vector<Primitive<N>> prims,
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
|
||||||
const auto table = solve(context, g_gens, {});
|
|
||||||
const auto path = solve(context, sg_gens, {}).path;
|
|
||||||
|
|
||||||
auto map = path.template walk<int, int>(0, proper_sg_gens, [table](int coset, int gen) {
|
|
||||||
return table.get(coset, gen);
|
|
||||||
});
|
|
||||||
|
|
||||||
std::vector<Primitive<N>> res(prims);
|
|
||||||
for (Primitive<N> &prim : res) {
|
|
||||||
for (auto &ind : prim.inds) {
|
|
||||||
ind = map[ind];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_parity(context, g_gens, sg_gens) == 1)
|
|
||||||
flip(res);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Union several meshes of the same dimension
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
std::vector<Primitive<N>> merge(const std::vector<std::vector<Primitive<N>>> &meshes) {
|
|
||||||
size_t size = 0;
|
|
||||||
for (const auto &mesh : meshes) {
|
|
||||||
size += mesh.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Primitive<N>> res;
|
|
||||||
res.reserve(size);
|
|
||||||
for (const auto &mesh : meshes) {
|
|
||||||
res.insert(res.end(), mesh.begin(), mesh.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<std::vector<Primitive<N>>> each_tile(
|
|
||||||
std::vector<Primitive<N>> prims,
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
std::vector<Primitive<N>> base = recontext(prims, context, g_gens, sg_gens);
|
|
||||||
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
|
||||||
|
|
||||||
const auto table = solve(context, g_gens, {});
|
|
||||||
const auto path = solve(context, g_gens, sg_gens).path;
|
|
||||||
|
|
||||||
auto _gens = generators(context);
|
|
||||||
|
|
||||||
auto res = path.walk<std::vector<Primitive<N>>, int>(base, generators(context), [&](auto from, auto gen) {
|
|
||||||
return apply(from, table, gen);
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<Primitive<N>> tile(
|
|
||||||
std::vector<Primitive<N>> prims,
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
auto res = each_tile<N>(prims, context, g_gens, sg_gens);
|
|
||||||
|
|
||||||
return merge(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Produce a mesh of higher dimension by fanning a single point to all primitives in this mesh.
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<Primitive<N + 1>> fan(std::vector<Primitive<N>> prims, int root) {
|
|
||||||
std::vector<Primitive<N + 1>> res(prims.size());
|
|
||||||
std::transform(prims.begin(), prims.end(), res.begin(),
|
|
||||||
[root](const Primitive<N> &prim) {
|
|
||||||
return Primitive<N + 1>(prim, root);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Produce a mesh of primitives that fill out the volume of the subgroup generated by generators g_gens within the group context
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
std::vector<Primitive<N>> triangulate(
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens
|
|
||||||
) {
|
|
||||||
if (g_gens.size() + 1 != N) // todo make static assert
|
|
||||||
throw std::logic_error("g_gens size must be one less than N");
|
|
||||||
|
|
||||||
const auto &combos = Combos(g_gens, g_gens.size() - 1);
|
|
||||||
|
|
||||||
std::vector<std::vector<Primitive<N>>> meshes;
|
|
||||||
|
|
||||||
for (const auto &sg_gens : combos) {
|
|
||||||
auto base = triangulate<N - 1>(context, sg_gens);
|
|
||||||
auto raised = tile(base, context, g_gens, sg_gens);
|
|
||||||
raised.erase(raised.begin(), raised.begin() + base.size());
|
|
||||||
meshes.push_back(fan(raised, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return merge(meshes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Single-index primitives should not be further triangulated.
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
std::vector<Primitive<1>> triangulate(
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens
|
|
||||||
) {
|
|
||||||
if (not g_gens.empty()) // todo make static assert
|
|
||||||
throw std::logic_error("g_gens must be empty for a trivial Mesh");
|
|
||||||
|
|
||||||
std::vector<Primitive<1>> res;
|
|
||||||
res.emplace_back();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N, class T>
|
|
||||||
auto hull(const tc::Group &group, T all_sg_gens, const std::vector<std::vector<int>> &exclude) {
|
|
||||||
std::vector<std::vector<Primitive<N>>> parts;
|
|
||||||
auto g_gens = generators(group);
|
|
||||||
for (const std::vector<int> &sg_gens : all_sg_gens) {
|
|
||||||
bool excluded = false;
|
|
||||||
for (const auto &test : exclude) {
|
|
||||||
if (sg_gens == test) {
|
|
||||||
excluded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (excluded) continue;
|
|
||||||
|
|
||||||
const auto &base = triangulate<N>(group, sg_gens);
|
|
||||||
const auto &tiles = each_tile(base, group, g_gens, sg_gens);
|
|
||||||
for (const auto &tile : tiles) {
|
|
||||||
parts.push_back(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parts;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
template<unsigned N>
|
#include <nanogui/glutil.h>
|
||||||
using vec = std::array<float, N>;
|
|
||||||
|
template<int N>
|
||||||
|
using vec = Eigen::Matrix<float, N, 1>;
|
||||||
|
template<int N>
|
||||||
|
using mat = Eigen::Matrix<float, N, N>;
|
||||||
|
|
||||||
using vec1 = vec<1>;
|
using vec1 = vec<1>;
|
||||||
using vec2 = vec<2>;
|
using vec2 = vec<2>;
|
||||||
@@ -15,65 +19,11 @@ using vec3 = vec<3>;
|
|||||||
using vec4 = vec<4>;
|
using vec4 = vec<4>;
|
||||||
using vec5 = vec<5>;
|
using vec5 = vec<5>;
|
||||||
|
|
||||||
template<class V>
|
using mat1 = mat<1>;
|
||||||
V operator*(V a, const float &b) {
|
using mat2 = mat<2>;
|
||||||
for (auto &e : a) e *= b;
|
using mat3 = mat<3>;
|
||||||
return a;
|
using mat4 = mat<4>;
|
||||||
}
|
using mat5 = mat<5>;
|
||||||
|
|
||||||
template<class V>
|
|
||||||
V operator*(const float &b, V a) {
|
|
||||||
for (auto &e : a) e *= b;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
V operator/(V a, const float &b) {
|
|
||||||
for (auto &e : a) e /= b;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
V operator+(const V &a, V b) {
|
|
||||||
for (int i = 0; i < a.size(); ++i) {
|
|
||||||
a[i] += b[i];
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
V operator-(V a, const V &b) {
|
|
||||||
for (int i = 0; i < a.size(); ++i) {
|
|
||||||
a[i] -= b[i];
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
void operator-=(V &a, const V &b) {
|
|
||||||
for (int i = 0; i < a.size(); ++i) {
|
|
||||||
a[i] -= b[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
void operator+=(V &a, const V &b) {
|
|
||||||
for (int i = 0; i < a.size(); ++i) {
|
|
||||||
a[i] += b[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
float length(const V &a) {
|
|
||||||
float sum = 0;
|
|
||||||
for (const auto &e : a) sum += e * e;
|
|
||||||
return sqrtf(sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
|
||||||
V normalized(const V &a) {
|
|
||||||
return a / length(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
float dot(int n, const V &a, const V &b) {
|
float dot(int n, const V &a, const V &b) {
|
||||||
@@ -84,15 +34,6 @@ float dot(int n, const V &a, const V &b) {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class V>
|
|
||||||
float dot(const V &a, const V &b) {
|
|
||||||
float sum = 0;
|
|
||||||
for (int i = 0; i < a.size(); ++i) {
|
|
||||||
sum += a[i] * b[i];
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N>
|
template<unsigned N>
|
||||||
std::vector<vec<N>> mirror(const tc::Group &group) {
|
std::vector<vec<N>> mirror(const tc::Group &group) {
|
||||||
std::vector<std::vector<float>> mirrors;
|
std::vector<std::vector<float>> mirrors;
|
||||||
@@ -119,7 +60,7 @@ std::vector<vec<N>> mirror(const tc::Group &group) {
|
|||||||
|
|
||||||
std::vector<vec<N>> res;
|
std::vector<vec<N>> res;
|
||||||
for (const auto &v : mirrors) {
|
for (const auto &v : mirrors) {
|
||||||
vec<N> rv{};
|
vec<N> rv = vec<N>::Zero();
|
||||||
|
|
||||||
// ortho proj
|
// ortho proj
|
||||||
for (int i = 0; i < std::min(v.size(), (size_t) N); ++i) {
|
for (int i = 0; i < std::min(v.size(), (size_t) N); ++i) {
|
||||||
@@ -140,9 +81,18 @@ vec<N> stereo(const vec<N + 1> &v) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<unsigned N>
|
||||||
|
vec<N> ortho(const vec<N + 1> &v) {
|
||||||
|
vec<N> r;
|
||||||
|
for (int i = 0; i < N; ++i) {
|
||||||
|
r[i] = v[i];
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
V project(const V &vec, const V &target) {
|
V project(const V &vec, const V &target) {
|
||||||
return dot(vec, target) / dot(target, target) * target;
|
return vec.dot(target) / target.dot(target) * target;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
@@ -158,14 +108,14 @@ V gram_schmidt_last(std::vector<V> vecs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalized(vecs[vecs.size() - 1]);
|
return vecs[vecs.size() - 1].normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class V, class C>
|
template<class V, class C>
|
||||||
V barycentric(const std::vector<V> &basis, const C &coords) {
|
V barycentric(const std::vector<V> &basis, const C &coords) {
|
||||||
V res{};
|
V res = V::Zero();
|
||||||
|
|
||||||
int N = std::min(basis.size(), coords.size());
|
int N = std::min((int) basis.size(), (int) coords.rows());
|
||||||
for (int i = 0; i < N; ++i) {
|
for (int i = 0; i < N; ++i) {
|
||||||
res += basis[i] * coords[i];
|
res += basis[i] * coords[i];
|
||||||
}
|
}
|
||||||
@@ -184,11 +134,22 @@ std::vector<V> plane_intersections(std::vector<V> normals) {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 utilRotate(const int u, const int v, const float theta) {
|
template<unsigned N>
|
||||||
auto res = glm::identity<glm::mat4>();
|
mat<N> rot(int u, int v, float theta) {
|
||||||
res[u][u] = std::cos(theta);
|
mat<N> res = mat<N>::Identity();
|
||||||
res[u][v] = std::sin(theta);
|
res(u, u) = std::cos(theta);
|
||||||
res[v][u] = -std::sin(theta);
|
res(u, v) = std::sin(theta);
|
||||||
res[v][v] = std::cos(theta);
|
res(v, u) = -std::sin(theta);
|
||||||
|
res(v, v) = std::cos(theta);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 ortho(float left, float right, float bottom, float top, float front, float back) {
|
||||||
|
mat<4> res = mat4();
|
||||||
|
res <<
|
||||||
|
2 / (right - left), 0, 0, -(right + left) / (right - left),
|
||||||
|
0, 2 / (top - bottom), 0, -(top + bottom) / (top - bottom),
|
||||||
|
0, 0, 2 / (front - back), -(front + back) / (front - back),
|
||||||
|
0, 0, 0, 1;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
51
vis/include/rendering.hpp
Normal file
51
vis/include/rendering.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# pragma once
|
||||||
|
|
||||||
|
#include <cgl/vertexarray.hpp>
|
||||||
|
#include <cgl/buffer.hpp>
|
||||||
|
#include <cgl/pipeline.hpp>
|
||||||
|
#include <geometry.hpp>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
template<unsigned N, class... T>
|
||||||
|
struct Prop {
|
||||||
|
cgl::VertexArray vao;
|
||||||
|
std::tuple<cgl::Buffer<T>...> vbos;
|
||||||
|
cgl::Buffer<Primitive<N>> ibo;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned N, class T>
|
||||||
|
struct Renderer {
|
||||||
|
cgl::pipeline pipe;
|
||||||
|
|
||||||
|
virtual void draw(const Prop<N, T> &prop) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned N, class T>
|
||||||
|
struct SliceRenderer : public Renderer<N, T> {
|
||||||
|
cgl::pgm::vert defer = cgl::pgm::vert::file(
|
||||||
|
"shaders/slice/deferred.vs.glsl");
|
||||||
|
cgl::pgm::geom slice = cgl::pgm::geom::file(
|
||||||
|
"shaders/slice/slice.gm.glsl");
|
||||||
|
cgl::pgm::frag solid = cgl::pgm::frag::file(
|
||||||
|
"shaders/solid.fs.glsl");
|
||||||
|
|
||||||
|
cgl::pipeline pipe;
|
||||||
|
|
||||||
|
SliceRenderer() {
|
||||||
|
pipe.stage(defer);
|
||||||
|
pipe.stage(slice);
|
||||||
|
pipe.stage(solid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(const Prop<N, T> &prop) const override {
|
||||||
|
pipe.bound([&]() {
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, std::get<0>(prop.vbos));
|
||||||
|
//// glProgramUniform3fv(solid, 2, 1, &prop.color.front());
|
||||||
|
glProgramUniform3f(solid, 2, 1.f, 1.f, 1.f);
|
||||||
|
prop.vao.bound([&]() {
|
||||||
|
glDrawArrays(GL_POINTS, 0, prop.ibo.count() * N);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
231
vis/include/solver.hpp
Normal file
231
vis/include/solver.hpp
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <tc/core.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
#include <optional>
|
||||||
|
#include <numeric>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <geometry.hpp>
|
||||||
|
|
||||||
|
#include "combo_iterator.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a list of all generators for the group context. The range [0..group.ngens).
|
||||||
|
*/
|
||||||
|
std::vector<int> generators(const tc::Group &context) {
|
||||||
|
std::vector<int> g_gens(context.ngens);
|
||||||
|
std::iota(g_gens.begin(), g_gens.end(), 0);
|
||||||
|
return g_gens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine which of g_gens are the correct names for sg_gens within the current context
|
||||||
|
*/
|
||||||
|
std::vector<int> recontext_gens(
|
||||||
|
const tc::Group &context,
|
||||||
|
std::vector<int> g_gens,
|
||||||
|
std::vector<int> sg_gens) {
|
||||||
|
|
||||||
|
std::sort(g_gens.begin(), g_gens.end());
|
||||||
|
|
||||||
|
int inv_gen_map[context.ngens];
|
||||||
|
for (size_t i = 0; i < g_gens.size(); i++) {
|
||||||
|
inv_gen_map[g_gens[i]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> s_sg_gens;
|
||||||
|
s_sg_gens.reserve(sg_gens.size());
|
||||||
|
for (const auto gen : sg_gens) {
|
||||||
|
s_sg_gens.push_back(inv_gen_map[gen]);
|
||||||
|
}
|
||||||
|
std::sort(s_sg_gens.begin(), s_sg_gens.end());
|
||||||
|
|
||||||
|
return s_sg_gens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solve the cosets generated by sg_gens within the subgroup generated by g_gens of the group context
|
||||||
|
*/
|
||||||
|
tc::Cosets solve(
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
||||||
|
return context.subgroup(g_gens).solve(proper_sg_gens);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply some context transformation to all primitives of this mesh.
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
std::vector<Primitive<N>> apply(std::vector<Primitive<N>> prims, const tc::Cosets &table, int gen) {
|
||||||
|
for (auto &prim : prims) {
|
||||||
|
prim.apply(table, gen);
|
||||||
|
}
|
||||||
|
return prims;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the indexes of this mesh to those of a different context, using g_gens to build the parent context and sg_gens to build this context.
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<Primitive<N>> recontext(
|
||||||
|
std::vector<Primitive<N>> prims,
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
||||||
|
const auto table = solve(context, g_gens, {});
|
||||||
|
const auto path = solve(context, sg_gens, {}).path;
|
||||||
|
|
||||||
|
auto map = path.template walk<int, int>(0, proper_sg_gens, [table](int coset, int gen) {
|
||||||
|
return table.get(coset, gen);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<Primitive<N>> res(prims);
|
||||||
|
for (Primitive<N> &prim : res) {
|
||||||
|
for (auto &ind : prim.inds) {
|
||||||
|
ind = map[ind];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Union several meshes of the same dimension
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
std::vector<Primitive<N>> merge(const std::vector<std::vector<Primitive<N>>> &meshes) {
|
||||||
|
size_t size = 0;
|
||||||
|
for (const auto &mesh : meshes) {
|
||||||
|
size += mesh.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Primitive<N>> res;
|
||||||
|
res.reserve(size);
|
||||||
|
for (const auto &mesh : meshes) {
|
||||||
|
res.insert(res.end(), mesh.begin(), mesh.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<std::vector<Primitive<N>>> each_tile(
|
||||||
|
std::vector<Primitive<N>> prims,
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
std::vector<Primitive<N>> base = recontext(prims, context, g_gens, sg_gens);
|
||||||
|
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
||||||
|
|
||||||
|
const auto table = solve(context, g_gens, {});
|
||||||
|
const auto path = solve(context, g_gens, sg_gens).path;
|
||||||
|
|
||||||
|
auto _gens = generators(context);
|
||||||
|
|
||||||
|
auto res = path.walk<std::vector<Primitive<N>>, int>(base, generators(context), [&](auto from, auto gen) {
|
||||||
|
return apply(from, table, gen);
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<Primitive<N>> tile(
|
||||||
|
std::vector<Primitive<N>> prims,
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
auto res = each_tile<N>(prims, context, g_gens, sg_gens);
|
||||||
|
|
||||||
|
return merge(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a mesh of higher dimension by fanning a single point to all primitives in this mesh.
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<Primitive<N + 1>> fan(std::vector<Primitive<N>> prims, int root) {
|
||||||
|
std::vector<Primitive<N + 1>> res(prims.size());
|
||||||
|
std::transform(prims.begin(), prims.end(), res.begin(),
|
||||||
|
[root](const Primitive<N> &prim) {
|
||||||
|
return Primitive<N + 1>(prim, root);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a mesh of primitives that fill out the volume of the subgroup generated by generators g_gens within the group context
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
std::vector<Primitive<N>> triangulate(
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens
|
||||||
|
) {
|
||||||
|
if (g_gens.size() + 1 != N) // todo make static assert
|
||||||
|
throw std::logic_error("g_gens size must be one less than N");
|
||||||
|
|
||||||
|
const auto &combos = Combos(g_gens, g_gens.size() - 1);
|
||||||
|
|
||||||
|
std::vector<std::vector<Primitive<N>>> meshes;
|
||||||
|
|
||||||
|
for (const auto &sg_gens : combos) {
|
||||||
|
auto base = triangulate<N - 1>(context, sg_gens);
|
||||||
|
auto raised = tile(base, context, g_gens, sg_gens);
|
||||||
|
raised.erase(raised.begin(), raised.begin() + base.size());
|
||||||
|
meshes.push_back(fan(raised, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return merge(meshes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single-index primitives should not be further triangulated.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
std::vector<Primitive<1>> triangulate(
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens
|
||||||
|
) {
|
||||||
|
if (not g_gens.empty()) // todo make static assert
|
||||||
|
throw std::logic_error("g_gens must be empty for a trivial Mesh");
|
||||||
|
|
||||||
|
std::vector<Primitive<1>> res;
|
||||||
|
res.emplace_back();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned N, class T>
|
||||||
|
auto hull(const tc::Group &group, T all_sg_gens, const std::vector<std::vector<int>> &exclude) {
|
||||||
|
std::vector<std::vector<Primitive<N>>> parts;
|
||||||
|
auto g_gens = generators(group);
|
||||||
|
for (const std::vector<int> &sg_gens : all_sg_gens) {
|
||||||
|
bool excluded = false;
|
||||||
|
for (const auto &test : exclude) {
|
||||||
|
if (sg_gens == test) {
|
||||||
|
excluded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (excluded) continue;
|
||||||
|
|
||||||
|
const auto &base = triangulate<N>(group, sg_gens);
|
||||||
|
const auto &tiles = each_tile(base, group, g_gens, sg_gens);
|
||||||
|
for (const auto &tile : tiles) {
|
||||||
|
parts.push_back(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <nanogui/opengl.h>
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
|
||||||
|
|
||||||
std::string utilInfo() {
|
std::string utilInfo() {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss
|
ss
|
||||||
@@ -19,6 +19,10 @@ std::string utilInfo() {
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string utilGetString(GLenum name) {
|
||||||
|
return reinterpret_cast<char const*>(glGetString(name));
|
||||||
|
}
|
||||||
|
|
||||||
std::string utilReadFile(const std::string &filename) {
|
std::string utilReadFile(const std::string &filename) {
|
||||||
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
||||||
if (in) {
|
if (in) {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ dimension: 3
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3]
|
- symbol: [4, 3]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.85, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
wires:
|
wires:
|
||||||
- root: [0.85, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.3, 0.3, 0.3]
|
color: [0.3, 0.3, 0.3]
|
||||||
ortho: true
|
ortho: true
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ dimension: 3
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3]
|
- symbol: [4, 3]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.85, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
wires:
|
wires:
|
||||||
- root: [0.85, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.3, 0.3, 0.3]
|
color: [0.3, 0.3, 0.3]
|
||||||
ortho: false
|
ortho: false
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ dimension: 4
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3, 3]
|
- symbol: [4, 3, 3]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
wires:
|
wires:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.3, 0.3, 0.3]
|
color: [0.3, 0.3, 0.3]
|
||||||
ortho: true
|
ortho: true
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ dimension: 4
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3, 3]
|
- symbol: [4, 3, 3]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
wires:
|
wires:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.3, 0.3, 0.3]
|
color: [0.3, 0.3, 0.3]
|
||||||
ortho: false
|
ortho: false
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ dimension: 4
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3, 3]
|
- symbol: [4, 3, 3]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
exclude:
|
exclude:
|
||||||
- [0, 1, 2]
|
- [0, 1, 2]
|
||||||
wires:
|
wires:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.3, 0.3, 0.3]
|
color: [0.3, 0.3, 0.3]
|
||||||
ortho: false
|
ortho: false
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ dimension: 4
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3, 3]
|
- symbol: [4, 3, 3]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
exclude:
|
exclude:
|
||||||
- [0, 1, 2]
|
- [0, 1, 2]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ dimension: 5
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3, 3, 2]
|
- symbol: [4, 3, 3, 2]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.09]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.09]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
exclude:
|
exclude:
|
||||||
- [0, 1, 2]
|
- [0, 1, 2]
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ dimension: 4
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [4, 3, 3]
|
- symbol: [4, 3, 3]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.85, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
wires:
|
wires:
|
||||||
- root: [0.85, 0.09, 0.09, 0.09, 0.01]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
color: [0.3, 0.3, 0.3]
|
color: [0.3, 0.3, 0.3]
|
||||||
ortho: false
|
ortho: false
|
||||||
|
|||||||
12
vis/presets/f_4_stereo.yaml
Normal file
12
vis/presets/f_4_stereo.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
dimension: 4
|
||||||
|
groups:
|
||||||
|
- symbol: [3, 4, 3, 2]
|
||||||
|
slices:
|
||||||
|
- root: [1.00, 0.10, 0.10, 0.10, 0.05]
|
||||||
|
color: [1.0, 1.0, 1.0]
|
||||||
|
exclude:
|
||||||
|
- [0, 1, 2]
|
||||||
|
wires:
|
||||||
|
- root: [1.00, 0.10, 0.10, 0.10, 0.05]
|
||||||
|
color: [1.0, 1.0, 1.0]
|
||||||
|
ortho: false
|
||||||
10
vis/presets/h_4_stereo.yaml
Normal file
10
vis/presets/h_4_stereo.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
dimension: 4
|
||||||
|
groups:
|
||||||
|
- symbol: [5, 3, 3]
|
||||||
|
slices:
|
||||||
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
|
color: [0.9, 0.9, 0.9]
|
||||||
|
wires:
|
||||||
|
- root: [0.90, 0.09, 0.09, 0.09, 0.01]
|
||||||
|
color: [0.3, 0.3, 0.3]
|
||||||
|
ortho: false
|
||||||
@@ -2,7 +2,7 @@ dimension: 5
|
|||||||
groups:
|
groups:
|
||||||
- symbol: [5, 3, 3, 2]
|
- symbol: [5, 3, 3, 2]
|
||||||
slices:
|
slices:
|
||||||
- root: [0.80, 0.09, 0.09, 0.09, 0.09]
|
- root: [0.90, 0.09, 0.09, 0.09, 0.09]
|
||||||
color: [0.9, 0.9, 0.9]
|
color: [0.9, 0.9, 0.9]
|
||||||
exclude:
|
exclude:
|
||||||
- [0, 1, 2]
|
- [0, 1, 2]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
layout(location=2) uniform vec3 col;
|
layout(location=2) uniform vec3 col;
|
||||||
|
|
||||||
layout(location=0) in vec3 pos;
|
layout(location=0) in vec4 pos;
|
||||||
layout(location=2) in vec3 normal;
|
layout(location=2) in vec3 normal;
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|||||||
189
vis/src/main-gui.cpp
Normal file
189
vis/src/main-gui.cpp
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
src/example4.cpp -- C++ version of an example application that shows
|
||||||
|
how to use the OpenGL widget. For a Python implementation, see
|
||||||
|
'../python/example4.py'.
|
||||||
|
|
||||||
|
NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
|
||||||
|
The widget drawing code is based on the NanoVG demo application
|
||||||
|
by Mikko Mononen.
|
||||||
|
|
||||||
|
All rights reserved. Use of this source code is governed by a
|
||||||
|
BSD-style license that can be found in the LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nanogui/opengl.h>
|
||||||
|
#include <nanogui/nanogui.h>
|
||||||
|
#include <nanogui/glutil.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <geometry.hpp>
|
||||||
|
#include <solver.hpp>
|
||||||
|
#include <rendering.hpp>
|
||||||
|
#include <mirror.hpp>
|
||||||
|
#include <util.hpp>
|
||||||
|
#include <tc/groups.hpp>
|
||||||
|
|
||||||
|
struct Matrices {
|
||||||
|
mat4 proj = mat4::Identity();
|
||||||
|
mat4 view = mat4::Identity();
|
||||||
|
|
||||||
|
Matrices() = default;
|
||||||
|
|
||||||
|
Matrices(mat4 proj, mat4 view) : proj(std::move(proj)), view(std::move(view)) {}
|
||||||
|
|
||||||
|
static Matrices build(const nanogui::Screen &screen) {
|
||||||
|
auto aspect = (float) screen.width() / (float) screen.height();
|
||||||
|
auto pheight = 1.4f;
|
||||||
|
auto pwidth = aspect * pheight;
|
||||||
|
mat4 proj = ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f);
|
||||||
|
|
||||||
|
// if (!glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)) {
|
||||||
|
// state.st += state.time_delta / 8;
|
||||||
|
// }
|
||||||
|
|
||||||
|
auto view = mat4::Identity();
|
||||||
|
return Matrices(proj, view);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class C>
|
||||||
|
std::vector<vec4> points(const tc::Group &group, const C &coords, const float time) {
|
||||||
|
auto cosets = group.solve();
|
||||||
|
auto mirrors = mirror<5>(group);
|
||||||
|
|
||||||
|
auto corners = plane_intersections(mirrors);
|
||||||
|
auto start = barycentric(corners, coords);
|
||||||
|
|
||||||
|
auto higher = cosets.path.walk<vec5, vec5>(start, mirrors, reflect<vec5>);
|
||||||
|
|
||||||
|
mat5 r = mat5::Identity();
|
||||||
|
r *= rot<5>(0, 2, time * .21f);
|
||||||
|
// r *= rot<5>(1, 4, time * .27f);
|
||||||
|
|
||||||
|
r *= rot<5>(0, 3, time * .17f);
|
||||||
|
r *= rot<5>(1, 3, time * .25f);
|
||||||
|
r *= rot<5>(2, 3, time * .12f);
|
||||||
|
|
||||||
|
std::transform(higher.begin(), higher.end(), higher.begin(), [&](vec5 v) { return r * v; });
|
||||||
|
|
||||||
|
std::vector<vec4> lower(higher.size());
|
||||||
|
std::transform(higher.begin(), higher.end(), lower.begin(), stereo<4>);
|
||||||
|
return lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int N, class T, class C>
|
||||||
|
Prop<4, vec4> make_slice(
|
||||||
|
const tc::Group &g,
|
||||||
|
const C &coords,
|
||||||
|
vec3 color,
|
||||||
|
T all_sg_gens,
|
||||||
|
const std::vector<std::vector<int>> &exclude
|
||||||
|
) {
|
||||||
|
Prop<N, vec4> res{};
|
||||||
|
|
||||||
|
// res.vbo.put(points(g, coords));
|
||||||
|
res.ibo.put(merge<N>(hull<N>(g, all_sg_gens, exclude)));
|
||||||
|
res.vao.ipointer(0, res.ibo, 4, GL_UNSIGNED_INT);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExampleApplication : public nanogui::Screen {
|
||||||
|
public:
|
||||||
|
vec5 root;
|
||||||
|
std::unique_ptr<tc::Group> group;
|
||||||
|
std::unique_ptr<Prop<4, vec4>> prop;
|
||||||
|
std::unique_ptr<cgl::Buffer<Matrices>> ubo;
|
||||||
|
std::unique_ptr<SliceRenderer<4, vec4>> ren;
|
||||||
|
|
||||||
|
float glfw_time = 0;
|
||||||
|
float last_frame = 0;
|
||||||
|
float frame_time = 0;
|
||||||
|
float time = 0;
|
||||||
|
|
||||||
|
bool paused = false;
|
||||||
|
|
||||||
|
ExampleApplication() : nanogui::Screen(
|
||||||
|
Eigen::Vector2i(1920, 1080),
|
||||||
|
"Coset Visualization",
|
||||||
|
true, false,
|
||||||
|
8, 8, 24, 8,
|
||||||
|
4,
|
||||||
|
4, 5) {
|
||||||
|
using namespace nanogui;
|
||||||
|
|
||||||
|
Window *window = new Window(this, "Sample Window");
|
||||||
|
window->setPosition(Vector2i(15, 15));
|
||||||
|
window->setFixedWidth(250);
|
||||||
|
window->setLayout(new BoxLayout(Orientation::Vertical));
|
||||||
|
|
||||||
|
auto pause = new ToolButton(window, ENTYPO_ICON_CONTROLLER_PAUS);
|
||||||
|
pause->setFlags(Button::ToggleButton);
|
||||||
|
pause->setChangeCallback([&](bool value) { this->paused = value; });
|
||||||
|
|
||||||
|
performLayout();
|
||||||
|
|
||||||
|
std::cout << utilInfo();
|
||||||
|
|
||||||
|
std::vector<int> symbol = {5, 3, 3, 2};
|
||||||
|
root << .80, .02, .02, .02, .02;
|
||||||
|
|
||||||
|
group = std::make_unique<tc::Group>(tc::schlafli(symbol));
|
||||||
|
auto gens = generators(*group);
|
||||||
|
std::vector<std::vector<int>> exclude = {{0, 1, 2}};
|
||||||
|
auto combos = Combos<int>(gens, 3);
|
||||||
|
|
||||||
|
prop = std::make_unique<Prop<4, vec4>>(make_slice<4>(*group, root, {}, combos, exclude));
|
||||||
|
|
||||||
|
ubo = std::make_unique<cgl::Buffer<Matrices>>();
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, 1, *ubo);
|
||||||
|
|
||||||
|
ren = std::make_unique<SliceRenderer<4, vec4>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawContents() override {
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
glViewport(0, 0, width(), height());
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glfw_time = (float) glfwGetTime();
|
||||||
|
frame_time = glfw_time - last_frame;
|
||||||
|
last_frame = glfw_time;
|
||||||
|
if (!paused) time += frame_time;
|
||||||
|
|
||||||
|
std::get<0>(prop->vbos).put(points(*group, root, time));
|
||||||
|
|
||||||
|
Matrices mats = Matrices::build(*this);
|
||||||
|
ubo->put(mats);
|
||||||
|
ren->draw(*prop);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int /* argc */, char ** /* argv */) {
|
||||||
|
try {
|
||||||
|
nanogui::init();
|
||||||
|
|
||||||
|
/* scoped variables */ {
|
||||||
|
nanogui::ref<ExampleApplication> app = new ExampleApplication();
|
||||||
|
app->drawAll();
|
||||||
|
app->setVisible(true);
|
||||||
|
nanogui::mainloop(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
nanogui::shutdown();
|
||||||
|
} catch (const std::runtime_error &e) {
|
||||||
|
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
|
||||||
|
std::cerr << error_msg << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
400
vis/src/main.cpp
400
vis/src/main.cpp
@@ -1,23 +1,24 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
#include <tc/groups.hpp>
|
#include <tc/groups.hpp>
|
||||||
|
|
||||||
#include "util.hpp"
|
|
||||||
#include "mirror.hpp"
|
|
||||||
#include "geometry.hpp"
|
|
||||||
|
|
||||||
#include <cgl/vertexarray.hpp>
|
#include <cgl/vertexarray.hpp>
|
||||||
#include <cgl/shaderprogram.hpp>
|
#include <cgl/shaderprogram.hpp>
|
||||||
#include <cgl/pipeline.hpp>
|
#include <cgl/pipeline.hpp>
|
||||||
#include <random>
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <util.hpp>
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <mirror.hpp>
|
||||||
|
#include <rendering.hpp>
|
||||||
|
#include <solver.hpp>
|
||||||
|
#include <geometry.hpp>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -26,10 +27,12 @@ __attribute__((unused)) __declspec(dllexport) int NvOptimusEnablement = 0x000000
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Matrices {
|
struct Matrices {
|
||||||
glm::mat4 proj;
|
mat4 proj;
|
||||||
glm::mat4 view;
|
mat4 view;
|
||||||
|
|
||||||
Matrices(const glm::mat4 &proj, const glm::mat4 &view)
|
Matrices() = default;
|
||||||
|
|
||||||
|
Matrices(const mat4 &proj, const mat4 &view)
|
||||||
: proj(proj), view(view) {
|
: proj(proj), view(view) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -50,235 +53,57 @@ Matrices build(GLFWwindow *window, State &state) {
|
|||||||
auto aspect = (float) width / (float) height;
|
auto aspect = (float) width / (float) height;
|
||||||
auto pheight = 1.4f;
|
auto pheight = 1.4f;
|
||||||
auto pwidth = aspect * pheight;
|
auto pwidth = aspect * pheight;
|
||||||
glm::mat4 proj = glm::ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f);
|
mat4 proj = ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f);
|
||||||
|
|
||||||
if (!glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)) {
|
if (!glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)) {
|
||||||
state.st += state.time_delta / 8;
|
state.st += state.time_delta / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto view = glm::identity<glm::mat4>();
|
auto view = identity<4>();
|
||||||
if (state.dimension < 4) {
|
|
||||||
view *= utilRotate(2, 3, M_PI_2f32 + 0.01f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dimension > 1) {
|
|
||||||
view *= utilRotate(0, 1, state.st * .40f);
|
|
||||||
}
|
|
||||||
if (state.dimension > 2) {
|
|
||||||
view *= utilRotate(0, 2, state.st * .20f);
|
|
||||||
view *= utilRotate(1, 2, state.st * .50f);
|
|
||||||
}
|
|
||||||
if (state.dimension > 3) {
|
|
||||||
view *= utilRotate(0, 3, state.st * 1.30f);
|
|
||||||
view *= utilRotate(1, 3, state.st * .25f);
|
|
||||||
view *= utilRotate(2, 3, state.st * 1.42f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Matrices(proj, view);
|
return Matrices(proj, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class C>
|
template<class C>
|
||||||
std::vector<vec4> points(const tc::Group &group, const C &coords) {
|
std::vector<vec4> points(const tc::Group &group, const C &coords, const float time) {
|
||||||
auto cosets = group.solve();
|
auto cosets = group.solve();
|
||||||
auto mirrors = mirror<5>(group);
|
auto mirrors = mirror<5>(group);
|
||||||
|
|
||||||
auto corners = plane_intersections(mirrors);
|
auto corners = plane_intersections(mirrors);
|
||||||
|
|
||||||
auto start = barycentric(corners, coords);
|
auto start = barycentric(corners, coords);
|
||||||
|
|
||||||
const auto &higher = cosets.path.walk<vec5, vec5>(start, mirrors, reflect<vec5>);
|
auto higher = cosets.path.walk<vec5, vec5>(start, mirrors, reflect<vec5>);
|
||||||
|
|
||||||
|
auto r = identity<5>();
|
||||||
|
r = mul(r, rot<5>(0, 2, time * .21f));
|
||||||
|
r = mul(r, rot<5>(1, 4, time * .27f));
|
||||||
|
|
||||||
|
r = mul(r, rot<5>(0, 3, time * .17f));
|
||||||
|
r = mul(r, rot<5>(1, 3, time * .25f));
|
||||||
|
r = mul(r, rot<5>(2, 3, time * .12f));
|
||||||
|
|
||||||
|
std::transform(higher.begin(), higher.end(), higher.begin(), [&](vec5 v) { return mul(v, r); });
|
||||||
|
|
||||||
std::vector<vec4> lower(higher.size());
|
std::vector<vec4> lower(higher.size());
|
||||||
std::transform(higher.begin(), higher.end(), lower.begin(), stereo<4>);
|
std::transform(higher.begin(), higher.end(), lower.begin(), stereo<4>);
|
||||||
return lower;
|
return lower;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned N>
|
template<int N, class T, class C>
|
||||||
struct Prop {
|
Prop<4, vec4> make_slice(
|
||||||
cgl::VertexArray vao;
|
const tc::Group &g,
|
||||||
cgl::Buffer<vec4> vbo;
|
const C &coords,
|
||||||
cgl::Buffer<Primitive<N>> ibo;
|
vec3 color,
|
||||||
|
T all_sg_gens,
|
||||||
|
const std::vector<std::vector<int>> &exclude
|
||||||
|
) {
|
||||||
|
Prop<N, vec4> res{};
|
||||||
|
|
||||||
Prop() : vao(), vbo(), ibo() {}
|
// res.vbo.put(points(g, coords));
|
||||||
};
|
res.ibo.put(merge<N>(hull<N>(g, all_sg_gens, exclude)));
|
||||||
|
res.vao.ipointer(0, res.ibo, 4, GL_UNSIGNED_INT);
|
||||||
|
|
||||||
template<unsigned N>
|
return res;
|
||||||
struct Renderer {
|
}
|
||||||
std::vector<Prop<N>> props;
|
|
||||||
|
|
||||||
virtual void bound(const std::function<void()> &action) const = 0;
|
|
||||||
|
|
||||||
virtual void _draw(const Prop<N> &) const = 0;
|
|
||||||
|
|
||||||
void render() const {
|
|
||||||
bound([&]() {
|
|
||||||
for (const auto &prop : props) {
|
|
||||||
_draw(prop);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
struct SliceProp : public Prop<N> {
|
|
||||||
vec3 color;
|
|
||||||
|
|
||||||
SliceProp(vec3 color) : Prop<N>(), color(color) {}
|
|
||||||
|
|
||||||
SliceProp(SliceProp &) = delete;
|
|
||||||
|
|
||||||
SliceProp(SliceProp &&) noexcept = default;
|
|
||||||
|
|
||||||
template<class T, class C>
|
|
||||||
static SliceProp<N> build(
|
|
||||||
const tc::Group &g,
|
|
||||||
const C &coords,
|
|
||||||
vec3 color,
|
|
||||||
T all_sg_gens,
|
|
||||||
const std::vector<std::vector<int>> &exclude
|
|
||||||
) {
|
|
||||||
SliceProp<N> res(color);
|
|
||||||
|
|
||||||
res.vbo.put(points(g, coords));
|
|
||||||
res.ibo.put(merge<N>(hull<N>(g, all_sg_gens, exclude)));
|
|
||||||
res.vao.ipointer(0, res.ibo, 4, GL_UNSIGNED_INT);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
struct SliceRenderer : public Renderer<N> {
|
|
||||||
cgl::pgm::vert defer = cgl::pgm::vert::file(
|
|
||||||
"shaders/slice/deferred.vs.glsl");
|
|
||||||
cgl::pgm::geom slice = cgl::pgm::geom::file(
|
|
||||||
"shaders/slice/slice.gm.glsl");
|
|
||||||
cgl::pgm::frag solid = cgl::pgm::frag::file(
|
|
||||||
"shaders/solid.fs.glsl");
|
|
||||||
|
|
||||||
cgl::pipeline pipe;
|
|
||||||
|
|
||||||
SliceRenderer() {
|
|
||||||
pipe.stage(defer);
|
|
||||||
pipe.stage(slice);
|
|
||||||
pipe.stage(solid);
|
|
||||||
}
|
|
||||||
|
|
||||||
SliceRenderer(SliceRenderer &) = delete;
|
|
||||||
|
|
||||||
SliceRenderer(SliceRenderer &&) noexcept = default;
|
|
||||||
|
|
||||||
void bound(const std::function<void()> &action) const override {
|
|
||||||
pipe.bound(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _draw(const Prop<N> &prop) const override {
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, prop.vbo);
|
|
||||||
// glProgramUniform3fv(solid, 2, 1, &prop.color.front());
|
|
||||||
glProgramUniform3f(solid, 2, 1.f, 1.f, 1.f);
|
|
||||||
prop.vao.bound([&]() {
|
|
||||||
glDrawArrays(GL_POINTS, 0, prop.ibo.count() * N);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
struct DirectRenderer : public Renderer<N> {
|
|
||||||
cgl::pipeline pipe;
|
|
||||||
|
|
||||||
DirectRenderer() = default;
|
|
||||||
|
|
||||||
DirectRenderer(DirectRenderer &) = delete;
|
|
||||||
|
|
||||||
DirectRenderer(DirectRenderer &&) noexcept = default;
|
|
||||||
|
|
||||||
void bound(const std::function<void()> &action) const override {
|
|
||||||
pipe.bound(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _draw(const Prop<N> &prop) const override {
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, prop.vbo);
|
|
||||||
// glProgramUniform3fv(sh.solid, 2, 1, &wire.color.front());
|
|
||||||
prop.vao.bound([&]() {
|
|
||||||
prop.ibo.bound(GL_ELEMENT_ARRAY_BUFFER, [&]() {
|
|
||||||
glDrawElements(GL_LINES, prop.ibo.count() * N, GL_UNSIGNED_INT, nullptr);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//struct WireframeRenderer : public DirectRenderer<2> {
|
|
||||||
// WireframeRenderer() : DirectRenderer<2>() {
|
|
||||||
// cgl::pgm::vert direct_stereo = cgl::pgm::vert::file(
|
|
||||||
// "shaders/direct-ortho.vs.glsl");
|
|
||||||
// cgl::pgm::frag solid = cgl::pgm::frag::file(
|
|
||||||
// "shaders/solid.fs.glsl");
|
|
||||||
//
|
|
||||||
// glProgramUniform3f(solid, 2, .3f, .3f, .3f);
|
|
||||||
//
|
|
||||||
// this->pipe.stage(direct_stereo);
|
|
||||||
// this->pipe.stage(solid);
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//struct WireframeStereoRenderer : public WireframeRenderer {
|
|
||||||
// WireframeStereoRenderer() : WireframeRenderer() {
|
|
||||||
// cgl::pgm::vert direct_stereo = cgl::pgm::vert::file(
|
|
||||||
// "shaders/direct-stereo.vs.glsl");
|
|
||||||
// cgl::pgm::frag solid = cgl::pgm::frag::file(
|
|
||||||
// "shaders/solid.fs.glsl");
|
|
||||||
//
|
|
||||||
// glProgramUniform3f(solid, 2, .3f, .3f, .4f);
|
|
||||||
//
|
|
||||||
// this->pipe.stage(direct_stereo);
|
|
||||||
// this->pipe.stage(solid);
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//struct WireframeStereoCurveRenderer : public WireframeStereoRenderer {
|
|
||||||
// WireframeStereoCurveRenderer() : WireframeStereoRenderer() {
|
|
||||||
// cgl::pgm::vert direct_stereo = cgl::pgm::vert::file(
|
|
||||||
// "shaders/direct-stereo.vs.glsl");
|
|
||||||
// cgl::pgm::geom curve = cgl::pgm::geom::file(
|
|
||||||
// "shaders/curve-stereo.gm.glsl"
|
|
||||||
// );
|
|
||||||
// cgl::pgm::frag solid = cgl::pgm::frag::file(
|
|
||||||
// "shaders/solid.fs.glsl");
|
|
||||||
//
|
|
||||||
// glProgramUniform3f(solid, 2, .4f, .3f, .3f);
|
|
||||||
//
|
|
||||||
// this->pipe.stage(direct_stereo);
|
|
||||||
// this->pipe.stage(curve);
|
|
||||||
// this->pipe.stage(solid);
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
|
|
||||||
struct WireframeProp : public Prop<2> {
|
|
||||||
vec3 color;
|
|
||||||
|
|
||||||
WireframeProp(vec3 color) : Prop<2>(), color(color) {}
|
|
||||||
|
|
||||||
WireframeProp(WireframeProp &) = delete;
|
|
||||||
|
|
||||||
WireframeProp(WireframeProp &&) noexcept = default;
|
|
||||||
|
|
||||||
template<class T, class C>
|
|
||||||
static WireframeProp build(const tc::Group &g,
|
|
||||||
const C &coords,
|
|
||||||
bool curve,
|
|
||||||
bool ortho,
|
|
||||||
vec3 color,
|
|
||||||
T all_sg_gens,
|
|
||||||
const std::vector<std::vector<int>> &exclude
|
|
||||||
) {
|
|
||||||
WireframeProp res(color);
|
|
||||||
|
|
||||||
res.vbo.put(points(g, coords));
|
|
||||||
res.ibo.put(merge<2>(hull<2>(g, all_sg_gens, exclude)));
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void run(const std::string &config_file, GLFWwindow *window) {
|
void run(const std::string &config_file, GLFWwindow *window) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
@@ -286,126 +111,21 @@ void run(const std::string &config_file, GLFWwindow *window) {
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
SliceRenderer<4> sRen{};
|
std::vector<int> symbol = {4, 3, 3, 3};
|
||||||
|
vec5 root = {.80, .02, .02, .02, .02};
|
||||||
|
|
||||||
cgl::pgm::vert o = cgl::pgm::vert::file("shaders/direct-ortho.vs.glsl");
|
auto group = tc::schlafli(symbol);
|
||||||
cgl::pgm::vert s = cgl::pgm::vert::file("shaders/direct-stereo.vs.glsl");
|
auto gens = generators(group);
|
||||||
cgl::pgm::geom co = cgl::pgm::geom::file("shaders/curve-ortho.gm.glsl");
|
std::vector<std::vector<int>> exclude = {{0, 1, 2}};
|
||||||
cgl::pgm::geom cs = cgl::pgm::geom::file("shaders/curve-stereo.gm.glsl");
|
auto combos = Combos<int>(gens, 3);
|
||||||
cgl::pgm::frag solid = cgl::pgm::frag::file("shaders/solid.fs.glsl");
|
|
||||||
glProgramUniform3f(solid, 2, 1.f, 0.f, 0.f);
|
|
||||||
|
|
||||||
DirectRenderer<2> woRen{};
|
SliceRenderer<4, vec4> ren{};
|
||||||
woRen.pipe.stage(o);
|
Prop<4, vec4> prop = make_slice<4>(group, root, {}, combos, exclude);
|
||||||
woRen.pipe.stage(solid);
|
|
||||||
|
|
||||||
DirectRenderer<2> wocRen{};
|
|
||||||
wocRen.pipe.stage(o);
|
|
||||||
wocRen.pipe.stage(co);
|
|
||||||
wocRen.pipe.stage(solid);
|
|
||||||
|
|
||||||
DirectRenderer<2> wsRen{};
|
|
||||||
wsRen.pipe.stage(s);
|
|
||||||
wsRen.pipe.stage(solid);
|
|
||||||
|
|
||||||
DirectRenderer<2> wscRen{};
|
|
||||||
wscRen.pipe.stage(s);
|
|
||||||
wscRen.pipe.stage(cs);
|
|
||||||
wscRen.pipe.stage(solid);
|
|
||||||
|
|
||||||
auto scene = YAML::LoadFile(config_file);
|
|
||||||
|
|
||||||
State state{};
|
State state{};
|
||||||
|
state.dimension = 4;
|
||||||
glfwSetWindowUserPointer(window, &state);
|
glfwSetWindowUserPointer(window, &state);
|
||||||
|
|
||||||
state.dimension = scene["dimension"].as<int>();
|
|
||||||
|
|
||||||
for (const auto &group_info : scene["groups"]) {
|
|
||||||
auto symbol = group_info["symbol"].as<std::vector<int>>();
|
|
||||||
auto group = tc::schlafli(symbol);
|
|
||||||
auto gens = generators(group);
|
|
||||||
|
|
||||||
if (group_info["slices"].IsDefined()) {
|
|
||||||
for (const auto &slice_info : group_info["slices"]) {
|
|
||||||
auto root = slice_info["root"].as<vec5>();
|
|
||||||
auto color = slice_info["color"].as<vec3>();
|
|
||||||
auto exclude = std::vector<std::vector<int>>();
|
|
||||||
|
|
||||||
if (slice_info["exclude"].IsDefined()) {
|
|
||||||
exclude = slice_info["exclude"].as<std::vector<std::vector<int>>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slice_info["subgroups"].IsDefined()) {
|
|
||||||
auto subgroups = slice_info["subgroups"].as<std::vector<std::vector<int>>>();
|
|
||||||
sRen.props.push_back(SliceProp<4>::build(
|
|
||||||
group, root, color, subgroups, exclude
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
auto combos = Combos<int>(gens, 3);
|
|
||||||
sRen.props.push_back(SliceProp<4>::build(
|
|
||||||
group, root, color, combos, exclude
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group_info["wires"].IsDefined()) {
|
|
||||||
for (const auto &wire_info : group_info["wires"]) {
|
|
||||||
auto root = wire_info["root"].as<vec5>();
|
|
||||||
auto color = wire_info["color"].as<vec3>();
|
|
||||||
auto exclude = std::vector<std::vector<int>>();
|
|
||||||
auto curve = wire_info["curve"].IsDefined() && wire_info["curve"].as<bool>();
|
|
||||||
auto ortho = wire_info["ortho"].IsDefined() && wire_info["ortho"].as<bool>();
|
|
||||||
|
|
||||||
if (wire_info["exclude"].IsDefined()) {
|
|
||||||
exclude = wire_info["exclude"].as<std::vector<std::vector<int>>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wire_info["subgroups"].IsDefined()) {
|
|
||||||
auto subgroups = wire_info["subgroups"].as<std::vector<std::vector<int>>>();
|
|
||||||
|
|
||||||
if (ortho && curve) {
|
|
||||||
wocRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, subgroups, exclude
|
|
||||||
));
|
|
||||||
} else if (ortho) {
|
|
||||||
woRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, subgroups, exclude
|
|
||||||
));
|
|
||||||
} else if (curve) {
|
|
||||||
wscRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, subgroups, exclude
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
wsRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, subgroups, exclude
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto combos = Combos<int>(gens, 1);
|
|
||||||
|
|
||||||
if (ortho && curve) {
|
|
||||||
wocRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, combos, exclude
|
|
||||||
));
|
|
||||||
} else if (ortho) {
|
|
||||||
woRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, combos, exclude
|
|
||||||
));
|
|
||||||
} else if (curve) {
|
|
||||||
wscRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, combos, exclude
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
wsRen.props.push_back(WireframeProp::build(
|
|
||||||
group, root, curve, ortho, color, combos, exclude
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ubo = cgl::Buffer<Matrices>();
|
auto ubo = cgl::Buffer<Matrices>();
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 1, ubo);
|
glBindBufferBase(GL_UNIFORM_BUFFER, 1, ubo);
|
||||||
|
|
||||||
@@ -416,21 +136,19 @@ void run(const std::string &config_file, GLFWwindow *window) {
|
|||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
Matrices mats = build(window, state);
|
|
||||||
ubo.put(mats);
|
|
||||||
|
|
||||||
glLineWidth(1.5);
|
glLineWidth(1.5);
|
||||||
|
|
||||||
woRen.render();
|
std::get<0>(prop.vbos).put(points(group, root, time));
|
||||||
wsRen.render();
|
|
||||||
wocRen.render();
|
|
||||||
wscRen.render();
|
|
||||||
|
|
||||||
sRen.render();
|
Matrices mats{};
|
||||||
|
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
mats = build(window, state);
|
||||||
|
ubo.put(mats);
|
||||||
|
ren.draw(prop);
|
||||||
|
|
||||||
glfwSwapInterval(2);
|
glfwSwapInterval(2);
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
|||||||
Reference in New Issue
Block a user