update
This commit is contained in:
		| @@ -2,17 +2,26 @@ project (AsteroGen CXX C) | ||||
| cmake_minimum_required (VERSION 2.6) | ||||
| set (CMAKE_CXX_STANDARD 11) | ||||
| set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") | ||||
| FIND_PACKAGE(OpenMP) | ||||
|  | ||||
| if(CMAKE_BUILD_TYPE MATCHES DEBUG) | ||||
| 	set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}") | ||||
| endif() | ||||
|  | ||||
| SET(CMAKE_C_FLAGS_RELEASE "-Ofast -msse4 -DNDEBUG") | ||||
| SET(CMAKE_CXX_FLAGS_RELEASE "-Ofast -msse4 -DNDEBUG") | ||||
|  | ||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||
| 	set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") | ||||
| 	set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") | ||||
| 	add_definitions(-DOM_STATIC_BUILD) | ||||
| endif() | ||||
|  | ||||
| IF(OPENMP_CXX_FOUND) | ||||
|   SET(CMAKE_C_FLAGS "${OpenMP_C_FLAGS} ${CMAKE_C_FLAGS}") | ||||
|   SET(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS} ") | ||||
| ENDIF() | ||||
|    | ||||
| FIND_PACKAGE(OpenMesh REQUIRED) | ||||
| link_directories(${OPENMESH_LIBRARY_DIR}) | ||||
| include_directories(${OPENMESH_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/vendor) | ||||
| @@ -24,6 +33,9 @@ add_executable(asteroidgen | ||||
| 	src/Polygoniser.cpp | ||||
| 	src/TextureMapper.cpp | ||||
| 	src/Mesh.cpp | ||||
| 	src/MarchingCube.cpp | ||||
| 	src/SkyBox.cpp | ||||
| 	src/Shader.cpp | ||||
| #	src/TexturePainter.cpp | ||||
| #	src/gen.cpp | ||||
| 	vendor/stb_impl.cpp | ||||
| @@ -35,9 +47,9 @@ add_executable(asteroidgen | ||||
| 	vendor/imgui_draw.cpp | ||||
| 	vendor/imgui_impl_glfw_gl3.cpp | ||||
| ) | ||||
| target_link_libraries(asteroidgen ${OPENMESH_LIBRARIES} dl glfw) | ||||
| target_link_libraries(asteroidgen ${OPENMESH_LIBRARIES} dl glfw ${OpenMP_CXX_LIBRARIES}) | ||||
|  | ||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||
| 	set_target_properties(asteroidgen PROPERTIES LINK_SEARCH_START_STATIC 1) | ||||
| 	set_target_properties(asteroidgen PROPERTIES LINK_SEARCH_END_STATIC 1) | ||||
| endif() | ||||
| endif() | ||||
|   | ||||
							
								
								
									
										3
									
								
								ToDo.txt
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								ToDo.txt
									
									
									
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| LIB: | ||||
| - fix polygonize | ||||
| - improve marching cube | ||||
| - create patches | ||||
| - use lscm | ||||
| @@ -18,4 +19,4 @@ GUI: | ||||
| - Progress | ||||
| - Arcball | ||||
| - PBR https://learnopengl.com/#!PBR/Lighting | ||||
| - save | ||||
| - save | ||||
|   | ||||
							
								
								
									
										147
									
								
								cmake/FindOpenMesh.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								cmake/FindOpenMesh.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| # | ||||
| # Try to find OPENMESH | ||||
| # Once done this will define | ||||
| #   | ||||
| # OPENMESH_FOUND           - system has OPENMESH | ||||
| # OPENMESH_INCLUDE_DIRS    - the OPENMESH include directories | ||||
| # OPENMESH_LIBRARIES       - Link these to use OPENMESH | ||||
| # OPENMESH_LIBRARY_DIR     - directory where the libraries are included | ||||
| # | ||||
| # Copyright 2015 Computer Graphics Group, RWTH Aachen University | ||||
| # Authors: Jan Möbius <moebius@cs.rwth-aachen.de> | ||||
| #          Hans-Christian Ebke <ebke@cs.rwth-aachen.de> | ||||
| # | ||||
| # | ||||
| #=========================================================================== | ||||
| #                                                                            | ||||
| #                               OpenMesh                                     | ||||
| #           Copyright (c) 2001-2015, RWTH-Aachen University                  | ||||
| #           Department of Computer Graphics and Multimedia                  | ||||
| #                          All rights reserved.                              | ||||
| #                            www.openmesh.org                                | ||||
| #                                                                            | ||||
| #--------------------------------------------------------------------------- | ||||
| # This file is part of OpenMesh.                                             | ||||
| #--------------------------------------------------------------------------- | ||||
| #                                                                            | ||||
| # Redistribution and use in source and binary forms, with or without         | ||||
| # modification, are permitted provided that the following conditions         | ||||
| # are met:                                                                   | ||||
| #                                                                            | ||||
| # 1. Redistributions of source code must retain the above copyright notice,  | ||||
| #    this list of conditions and the following disclaimer.                   | ||||
| #                                                                            | ||||
| # 2. Redistributions in binary form must reproduce the above copyright       | ||||
| #    notice, this list of conditions and the following disclaimer in the     | ||||
| #    documentation and/or other materials provided with the distribution.    | ||||
| #                                                                            | ||||
| # 3. Neither the name of the copyright holder nor the names of its           | ||||
| #    contributors may be used to endorse or promote products derived from    | ||||
| #    this software without specific prior written permission.                | ||||
| #                                                                            | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS        | ||||
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED  | ||||
| # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A            | ||||
| # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER  | ||||
| # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   | ||||
| # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,        | ||||
| # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR         | ||||
| # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF     | ||||
| # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING       | ||||
| # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS         | ||||
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.               | ||||
| #                                                                             | ||||
| #=========================================================================== | ||||
|  | ||||
| cmake_minimum_required(VERSION 2.8.9) | ||||
|  | ||||
| #if already found via finder or simulated finder in openmesh CMakeLists.txt, skip the search | ||||
| IF (NOT OPENMESH_FOUND)  | ||||
|   SET (SEARCH_PATHS  | ||||
|     /usr/local/ | ||||
|     /usr/ | ||||
|     "${CMAKE_SOURCE_DIR}/OpenMesh/src/OpenMesh" | ||||
|     "${CMAKE_SOURCE_DIR}/libs_required/OpenMesh/src/OpenMesh" | ||||
|     "${CMAKE_SOURCE_DIR}/../OpenMesh/src/OpenMesh" | ||||
|     "C:/Program Files/OpenMesh 6.3" | ||||
|     "C:/Program Files/OpenMesh 6.2" | ||||
|     "C:/Program Files/OpenMesh 6.1" | ||||
|     "C:/Program Files/OpenMesh 6.0" | ||||
|     "C:/Program Files/OpenMesh 5.2" | ||||
|     "C:/Program Files/OpenMesh 5.1" | ||||
|     "C:/Program Files/OpenMesh 5.0" | ||||
|     "C:/Program Files/OpenMesh 4.2" | ||||
|     "C:/Program Files/OpenMesh 4.1" | ||||
|     "C:/Program Files/OpenMesh 4.0" | ||||
|     "C:/Program Files/OpenMesh 3.4" | ||||
|     "C:/Program Files/OpenMesh 3.3" | ||||
|     "C:/Program Files/OpenMesh 3.2" | ||||
|     "C:/Program Files/OpenMesh 3.1" | ||||
|     "C:/Program Files/OpenMesh 3.0" | ||||
|     "C:/Program Files/OpenMesh 2.4.1" | ||||
|     "C:/Program Files/OpenMesh 2.4" | ||||
|     "C:/Program Files/OpenMesh 2.0/include" | ||||
|     "C:/libs/OpenMesh 6.3" | ||||
|     "C:/libs/OpenMesh 6.2" | ||||
|     "C:/libs/OpenMesh 6.1" | ||||
|     "C:/libs/OpenMesh 6.0" | ||||
|     "C:/libs/OpenMesh 5.2" | ||||
|     "C:/libs/OpenMesh 5.1" | ||||
|     "C:/libs/OpenMesh 5.0" | ||||
|     "C:/libs/OpenMesh 4.2" | ||||
|     "C:/libs/OpenMesh 4.1" | ||||
|     "C:/libs/OpenMesh 4.0" | ||||
|     "C:/libs/OpenMesh 3.4" | ||||
|     "C:/libs/OpenMesh 3.3" | ||||
|     "C:/libs/OpenMesh 3.2" | ||||
|     "C:/libs/OpenMesh 3.1" | ||||
|     "C:/libs/OpenMesh 3.0" | ||||
|     "C:/libs/OpenMesh 2.4.1" | ||||
|     "C:/libs/OpenMesh 2.4" | ||||
|     "${OPENMESH_LIBRARY_DIR}" | ||||
|   ) | ||||
|  | ||||
|   FIND_PATH (OPENMESH_INCLUDE_DIR OpenMesh/Core/Mesh/PolyMeshT.hh | ||||
|     PATHS ${SEARCH_PATHS} | ||||
|     PATH_SUFFIXES include) | ||||
|  | ||||
|   FIND_LIBRARY(OPENMESH_CORE_LIBRARY_RELEASE NAMES OpenMeshCore | ||||
|     PATHS ${SEARCH_PATHS} | ||||
|     PATH_SUFFIXES lib lib64) | ||||
|  | ||||
|   FIND_LIBRARY(OPENMESH_CORE_LIBRARY_DEBUG NAMES OpenMeshCored  | ||||
|     PATHS ${SEARCH_PATHS} | ||||
|     PATH_SUFFIXES lib lib64) | ||||
|  | ||||
|   FIND_LIBRARY(OPENMESH_TOOLS_LIBRARY_RELEASE NAMES OpenMeshTools | ||||
|     PATHS ${SEARCH_PATHS} | ||||
|     PATH_SUFFIXES lib lib64) | ||||
|  | ||||
|   FIND_LIBRARY(OPENMESH_TOOLS_LIBRARY_DEBUG NAMES OpenMeshToolsd | ||||
|     PATHS ${SEARCH_PATHS} | ||||
|     PATH_SUFFIXES lib lib64) | ||||
|  | ||||
| #select configuration depending on platform (optimized... on windows) | ||||
|   include(SelectLibraryConfigurations) | ||||
|   select_library_configurations( OPENMESH_TOOLS ) | ||||
|   select_library_configurations( OPENMESH_CORE ) | ||||
|  | ||||
|   set(OPENMESH_LIBRARIES ${OPENMESH_CORE_LIBRARY} ${OPENMESH_TOOLS_LIBRARY} ) | ||||
|   set(OPENMESH_INCLUDE_DIRS ${OPENMESH_INCLUDE_DIR} ) | ||||
|  | ||||
| #checks, if OPENMESH was found and sets OPENMESH_FOUND if so | ||||
|   include(FindPackageHandleStandardArgs) | ||||
|   find_package_handle_standard_args(OpenMesh  DEFAULT_MSG | ||||
|                                     OPENMESH_CORE_LIBRARY OPENMESH_TOOLS_LIBRARY OPENMESH_INCLUDE_DIR) | ||||
|   | ||||
| #sets the library dir  | ||||
|   if ( OPENMESH_CORE_LIBRARY_RELEASE ) | ||||
|     get_filename_component(_OPENMESH_LIBRARY_DIR ${OPENMESH_CORE_LIBRARY_RELEASE} PATH) | ||||
|   else( OPENMESH_CORE_LIBRARY_RELEASE ) | ||||
|     get_filename_component(_OPENMESH_LIBRARY_DIR ${OPENMESH_CORE_LIBRARY_DEBUG} PATH) | ||||
|   endif( OPENMESH_CORE_LIBRARY_RELEASE ) | ||||
|   set (OPENMESH_LIBRARY_DIR "${_OPENMESH_LIBRARY_DIR}" CACHE PATH "The directory where the OpenMesh libraries can be found.") | ||||
|    | ||||
|   | ||||
|   mark_as_advanced(OPENMESH_INCLUDE_DIR OPENMESH_CORE_LIBRARY_RELEASE OPENMESH_CORE_LIBRARY_DEBUG OPENMESH_TOOLS_LIBRARY_RELEASE OPENMESH_TOOLS_LIBRARY_DEBUG OPENMESH_LIBRARY_DIR) | ||||
| endif() | ||||
							
								
								
									
										12
									
								
								shader/skybox.fragment.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								shader/skybox.fragment.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #version 330 | ||||
|  | ||||
| in vec3 TexCoord0; | ||||
|  | ||||
| out vec4 FragColor; | ||||
|  | ||||
| uniform samplerCube gCubemapTexture; | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     FragColor = texture(gCubemapTexture, TexCoord0); | ||||
| } | ||||
							
								
								
									
										14
									
								
								shader/skybox.vertex.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								shader/skybox.vertex.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| #version 330 | ||||
|  | ||||
| in vec3 Position; | ||||
|  | ||||
| uniform mat4 gWVP; | ||||
|  | ||||
| out vec3 TexCoord0; | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     vec4 WVP_Pos = gWVP * vec4(Position, 1.0); | ||||
|     gl_Position = WVP_Pos.xyww; | ||||
|     TexCoord0 = Position; | ||||
| } | ||||
							
								
								
									
										206
									
								
								src/AlignedAllocator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								src/AlignedAllocator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,206 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <malloc.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| #include <type_traits> | ||||
| #include <memory> | ||||
|  | ||||
| enum class Alignment | ||||
| 	: size_t | ||||
| 	{ | ||||
| 		Normal = sizeof(void*), SSE = 16, AVX = 32, | ||||
| }; | ||||
|  | ||||
| namespace detail { | ||||
| void* allocate_aligned_memory(size_t align, size_t size); | ||||
| void deallocate_aligned_memory(void* ptr) noexcept; | ||||
| } | ||||
|  | ||||
| template<typename T, Alignment Align = Alignment::SSE> | ||||
| class AlignedAllocator; | ||||
|  | ||||
| template<Alignment Align> | ||||
| class AlignedAllocator<void, Align> { | ||||
| public: | ||||
| 	typedef void* pointer; | ||||
| 	typedef const void* const_pointer; | ||||
| 	typedef void value_type; | ||||
|  | ||||
| 	template<class U> struct rebind { | ||||
| 		typedef AlignedAllocator<U, Align> other; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| template<typename T, Alignment Align> | ||||
| class AlignedAllocator { | ||||
| public: | ||||
| 	typedef T value_type; | ||||
| 	typedef T* pointer; | ||||
| 	typedef const T* const_pointer; | ||||
| 	typedef T& reference; | ||||
| 	typedef const T& const_reference; | ||||
| 	typedef size_t size_type; | ||||
| 	typedef ptrdiff_t difference_type; | ||||
|  | ||||
| 	typedef std::true_type propagate_on_container_move_assignment; | ||||
|  | ||||
| 	template<class U> | ||||
| 	struct rebind { | ||||
| 		typedef AlignedAllocator<U, Align> other; | ||||
| 	}; | ||||
|  | ||||
| public: | ||||
| 	AlignedAllocator() noexcept | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	template<class U> | ||||
| 	AlignedAllocator(const AlignedAllocator<U, Align>&) noexcept | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	size_type max_size() const noexcept | ||||
| 	{ | ||||
| 		return (size_type(~0) - size_type(Align)) / sizeof(T); | ||||
| 	} | ||||
|  | ||||
| 	pointer address(reference x) const noexcept | ||||
| 	{ | ||||
| 		return std::addressof(x); | ||||
| 	} | ||||
|  | ||||
| 	const_pointer address(const_reference x) const noexcept | ||||
| 	{ | ||||
| 		return std::addressof(x); | ||||
| 	} | ||||
|  | ||||
| 	pointer allocate(size_type n, | ||||
| 			typename AlignedAllocator<void, Align>::const_pointer = 0) { | ||||
| 		const size_type alignment = static_cast<size_type>(Align); | ||||
| 		void* ptr = detail::allocate_aligned_memory(alignment, n * sizeof(T)); | ||||
| 		if (ptr == nullptr) { | ||||
| 			throw std::bad_alloc(); | ||||
| 		} | ||||
|  | ||||
| 		return reinterpret_cast<pointer>(ptr); | ||||
| 	} | ||||
|  | ||||
| 	void deallocate(pointer p, size_type) noexcept | ||||
| 	{ | ||||
| 		detail::deallocate_aligned_memory(p); | ||||
| 	} | ||||
|  | ||||
| 	template<class U, class ...Args> | ||||
| 	void construct(U* p, Args&&... args) { | ||||
| 		::new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...); | ||||
| 	} | ||||
|  | ||||
| 	void destroy(pointer p) { | ||||
| 		p->~T(); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| template<typename T, Alignment Align> | ||||
| class AlignedAllocator<const T, Align> { | ||||
| public: | ||||
| 	typedef T value_type; | ||||
| 	typedef const T* pointer; | ||||
| 	typedef const T* const_pointer; | ||||
| 	typedef const T& reference; | ||||
| 	typedef const T& const_reference; | ||||
| 	typedef size_t size_type; | ||||
| 	typedef ptrdiff_t difference_type; | ||||
|  | ||||
| 	typedef std::true_type propagate_on_container_move_assignment; | ||||
|  | ||||
| 	template<class U> | ||||
| 	struct rebind { | ||||
| 		typedef AlignedAllocator<U, Align> other; | ||||
| 	}; | ||||
|  | ||||
| public: | ||||
| 	AlignedAllocator() noexcept | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	template<class U> | ||||
| 	AlignedAllocator(const AlignedAllocator<U, Align>&) noexcept | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	size_type max_size() const noexcept | ||||
| 	{ | ||||
| 		return (size_type(~0) - size_type(Align)) / sizeof(T); | ||||
| 	} | ||||
|  | ||||
| 	const_pointer address(const_reference x) const noexcept | ||||
| 	{ | ||||
| 		return std::addressof(x); | ||||
| 	} | ||||
|  | ||||
| 	pointer allocate(size_type n, | ||||
| 			typename AlignedAllocator<void, Align>::const_pointer = 0) { | ||||
| 		const size_type alignment = static_cast<size_type>(Align); | ||||
| 		void* ptr = detail::allocate_aligned_memory(alignment, n * sizeof(T)); | ||||
| 		if (ptr == nullptr) { | ||||
| 			throw std::bad_alloc(); | ||||
| 		} | ||||
|  | ||||
| 		return reinterpret_cast<pointer>(ptr); | ||||
| 	} | ||||
|  | ||||
| 	void deallocate(pointer p, size_type) noexcept | ||||
| 	{ | ||||
| 		detail::deallocate_aligned_memory(p); | ||||
| 	} | ||||
|  | ||||
| 	template<class U, class ...Args> | ||||
| 	void construct(U* p, Args&&... args) { | ||||
| 		::new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...); | ||||
| 	} | ||||
|  | ||||
| 	void destroy(pointer p) { | ||||
| 		p->~T(); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| template<typename T, Alignment TAlign, typename U, Alignment UAlign> | ||||
| inline | ||||
| bool operator==(const AlignedAllocator<T, TAlign>&, | ||||
| 		const AlignedAllocator<U, UAlign>&) noexcept | ||||
| 		{ | ||||
| 	return TAlign == UAlign; | ||||
| } | ||||
|  | ||||
| template<typename T, Alignment TAlign, typename U, Alignment UAlign> | ||||
| inline | ||||
| bool operator!=(const AlignedAllocator<T, TAlign>&, | ||||
| 		const AlignedAllocator<U, UAlign>&) noexcept | ||||
| 		{ | ||||
| 	return TAlign != UAlign; | ||||
| } | ||||
|  | ||||
| inline void* | ||||
| detail::allocate_aligned_memory(size_t align, size_t size) { | ||||
| 	assert(align >= sizeof(void*)); | ||||
| 	//assert(nail::is_power_of_two(align)); | ||||
|  | ||||
| 	if (size == 0) { | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	void* ptr = nullptr; | ||||
| 	int rc = posix_memalign(&ptr, align, size); | ||||
|  | ||||
| 	if (rc != 0) { | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	return ptr; | ||||
| } | ||||
|  | ||||
| inline void detail::deallocate_aligned_memory(void *ptr) noexcept | ||||
| { | ||||
| 	free(ptr); | ||||
| } | ||||
| @@ -1,5 +1,6 @@ | ||||
| #include "Application.h" | ||||
| #include "Mesh.h" | ||||
| #include "Shader.h" | ||||
|  | ||||
| #include <glad/glad.h> | ||||
| #include <GLFW/glfw3.h> | ||||
| @@ -82,7 +83,8 @@ Application::Application() : | ||||
| 				textureSize), programId(0), vPositionLoc(-1), vTexCoordLoc(-1), vNormalLoc( | ||||
| 				-1), meteoridCount(1000), meteroidMinRadius(0.005), meteroidMaxRadius( | ||||
| 				0.2), meteroidSizeExponent(2048), densityFrequency(2), densityOctave( | ||||
| 				2), densityScale(1.0f), resolution(0.1), viewDistance(3.0f), fpsMode( | ||||
| 				2), densityScale(1.0f), resolution(0.1), smoothMesh(true), viewDistance( | ||||
| 				3.0f), fpsMode(false), meshUploadRequest(false), textureUploadRequest( | ||||
| 				false) { | ||||
| 	init(); | ||||
| } | ||||
| @@ -157,7 +159,6 @@ void Application::init() { | ||||
| 	loadShader(); | ||||
| 	updateVertexArrayObject(); | ||||
| 	generateAsteroid(); | ||||
| 	uploadMesh(); | ||||
| } | ||||
|  | ||||
| void Application::shutdown() { | ||||
| @@ -215,47 +216,98 @@ void Application::toogleFpsMode() { | ||||
| } | ||||
|  | ||||
| void Application::generateAsteroid() { | ||||
| 	std::srand(123); | ||||
| 	if (meshProgress.begin("Random Impacts", 1)) { | ||||
| 		//if (density.getImpacts().size() == 0) | ||||
| 		density.addRandomImpacts(1000, densityIsolevel, 0.01, 0.005, 0.2, 256); | ||||
|  | ||||
| 	if (density.getImpacts().size() == 0) | ||||
| 		density.addRandomImpacts(1000, 0.2, 0.01, 0.005, 0.2, 4096); | ||||
| 	//density.saveCrossSection("density.png", 512); | ||||
| 		//density.saveCrossSection("density.png", 512); | ||||
| 	} | ||||
| 	polygonizer.polygonize(resolution, meshProgress); | ||||
|  | ||||
| 	polygonizer.polygonize(resolution); | ||||
| 	if (smoothMesh && meshProgress.begin("Smooth", 1)) { | ||||
| 		smooth(polygonizer.vertices, polygonizer.indices); | ||||
| //		{ | ||||
| //			std::ofstream out("stage2.obj"); | ||||
| //			saveAttrib(out, "v ", polygonizer.vertices); | ||||
| //			saveFaces(out, polygonizer.indices, 1); | ||||
| //		} | ||||
| 	} | ||||
|  | ||||
| 	uvec4v_t edges; | ||||
| 	if (meshProgress.begin("Find Edges", 1)) { | ||||
| 		findEdges(polygonizer.vertices, polygonizer.indices, edges); | ||||
| 	} | ||||
| 	uvec3v_t adjacents; | ||||
| 	if (meshProgress.begin("Find Adjacent", 1)) { | ||||
| 		findAdjacent(edges, polygonizer.indices.size(), adjacents); | ||||
| 	} | ||||
| 	vec3v_t faceNormals; | ||||
| 	calculateFaceNormals(polygonizer.vertices, polygonizer.indices, | ||||
| 			faceNormals); | ||||
|  | ||||
| 	vec3v_t positions; | ||||
| 	uvec3v_t indices; | ||||
| 	uintv_t patches; | ||||
|  | ||||
| 	createPatches(polygonizer.vertices, polygonizer.indices, faceNormals, | ||||
| 			adjacents, positions, indices, patches, 0.9); | ||||
| 	{ | ||||
| 		std::ofstream out("stage1.obj"); | ||||
| 		saveAttrib(out, "v ", polygonizer.vertices); | ||||
| 		saveFaces(out, polygonizer.indices, 1); | ||||
| 		saveAttrib(out, "v ", positions); | ||||
| 		saveFaces(out, indices, 1); | ||||
| 	} | ||||
|  | ||||
| 	smooth(polygonizer.vertices, polygonizer.indices); | ||||
| 	{ | ||||
| 		std::ofstream out("stage2.obj"); | ||||
| 		saveAttrib(out, "v ", polygonizer.vertices); | ||||
| 		saveFaces(out, polygonizer.indices, 1); | ||||
| 	} | ||||
| 	calculateNormals(polygonizer.vertices, polygonizer.indices, normals); | ||||
| 	{ | ||||
| 		std::ofstream out("stage3.obj"); | ||||
| 		saveAttrib(out, "v ", polygonizer.vertices); | ||||
| 		saveAttrib(out, "vn ", normals); | ||||
| 		saveFaces(out, polygonizer.indices, 2); | ||||
| 	if (meshProgress.begin("Calculate Vertex Normals", 1)) { | ||||
| 		calculateVertexNormals(polygonizer.vertices, polygonizer.indices, | ||||
| 				normals); | ||||
| //		{ | ||||
| //			std::ofstream out("stage3.obj"); | ||||
| //			saveAttrib(out, "v ", polygonizer.vertices); | ||||
| //			saveAttrib(out, "vn ", normals); | ||||
| //			saveFaces(out, polygonizer.indices, 2); | ||||
| //		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	vector<glm::uvec4> edges; | ||||
| 	std::cout << "Vertices: " << polygonizer.vertices.size() << std::endl; | ||||
| 	std::cout << "Triangles: " << polygonizer.indices.size() << std::endl; | ||||
|  | ||||
| 	texturemapper.map(polygonizer.vertices, normals, polygonizer.indices); | ||||
| 	moveToMean(texturemapper.vertices); | ||||
|  | ||||
| 	{ | ||||
| 		std::ofstream out("stage4.obj"); | ||||
| 		saveAttrib(out, "v ", texturemapper.vertices); | ||||
| 		saveAttrib(out, "vn ", texturemapper.normals); | ||||
| 		saveAttrib(out, "vt ", texturemapper.texcoords); | ||||
| 		saveFaces(out, texturemapper.indices, 3); | ||||
| 	if (meshProgress.begin("Map Textures", 1)) { | ||||
| 		texturemapper.map(polygonizer.vertices, normals, polygonizer.indices); | ||||
| 	} | ||||
|  | ||||
| 	if (meshProgress.begin("Move To Mean", 1)) { | ||||
| 		moveToMean(texturemapper.vertices); | ||||
|  | ||||
| //		{ | ||||
| //			std::ofstream out("stage4.obj"); | ||||
| //			saveAttrib(out, "v ", texturemapper.vertices); | ||||
| //			saveAttrib(out, "vn ", texturemapper.normals); | ||||
| //			saveAttrib(out, "vt ", texturemapper.texcoords); | ||||
| //			saveFaces(out, texturemapper.indices, 3); | ||||
| //		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	if (meshProgress.begin("Save", 4)) { | ||||
| 		std::ofstream out("asteroid.obj"); | ||||
| 		saveAttrib(out, "v ", texturemapper.vertices); | ||||
| 		meshProgress.advance(); | ||||
| 		saveAttrib(out, "vn ", texturemapper.normals); | ||||
| 		meshProgress.advance(); | ||||
| 		saveAttrib(out, "vt ", texturemapper.texcoords); | ||||
| 		meshProgress.advance(); | ||||
| 		saveFaces(out, texturemapper.indices, 3); | ||||
| 		meshProgress.advance(); | ||||
| 	} | ||||
|  | ||||
| 	meshProgress.finish(); | ||||
|  | ||||
| 	if (!meshProgress.isCanceled()) { | ||||
| 		meshUploadRequest = true; | ||||
| 		textureUploadRequest = true; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| bool Application::bindVertexAttrib(GLuint id, GLint loc, GLuint size) { | ||||
| @@ -267,7 +319,7 @@ bool Application::bindVertexAttrib(GLuint id, GLint loc, GLuint size) { | ||||
| 			size,// size | ||||
| 			GL_FLOAT,// type | ||||
| 			GL_FALSE,// normalized? | ||||
| 			0,	 // stride | ||||
| 			0,// stride | ||||
| 			(void* ) 0// array buffer offset | ||||
| 			)) | ||||
| 	return true; | ||||
| @@ -290,102 +342,7 @@ void Application::updateVertexArrayObject() { | ||||
| 	GLCK(glBindVertexArray(0)) | ||||
| } | ||||
|  | ||||
| GLuint Application::loadProgram(const std::string &name) { | ||||
|  | ||||
| 	// Create the shaders | ||||
| 	GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); | ||||
| 	GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); | ||||
|  | ||||
| 	// Read the Vertex Shader code from the file | ||||
| 	std::string VertexShaderCode; | ||||
| 	std::string vertex_file_path = "shader/" + name + ".vertex.glsl"; | ||||
| 	std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); | ||||
| 	if (VertexShaderStream.is_open()) { | ||||
| 		std::string Line = ""; | ||||
| 		while (getline(VertexShaderStream, Line)) | ||||
| 			VertexShaderCode += "\n" + Line; | ||||
| 		VertexShaderStream.close(); | ||||
| 	} else { | ||||
| 		std::cout << "Failed to open " << vertex_file_path << std::endl; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	// Read the Fragment Shader code from the file | ||||
| 	std::string FragmentShaderCode; | ||||
| 	std::string fragment_file_path = "shader/" + name + ".fragment.glsl"; | ||||
| 	std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); | ||||
| 	if (FragmentShaderStream.is_open()) { | ||||
| 		std::string Line = ""; | ||||
| 		while (getline(FragmentShaderStream, Line)) | ||||
| 			FragmentShaderCode += "\n" + Line; | ||||
| 		FragmentShaderStream.close(); | ||||
| 	} else { | ||||
| 		std::cout << "Failed to open " << vertex_file_path << std::endl; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	GLint Result = GL_FALSE; | ||||
| 	int InfoLogLength; | ||||
|  | ||||
| 	// Compile Vertex Shader | ||||
| 	std::cout << "Compiling vertex shader : " << name << std::endl; | ||||
| 	char const * VertexSourcePointer = VertexShaderCode.c_str(); | ||||
| 	glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); | ||||
| 	glCompileShader(VertexShaderID); | ||||
|  | ||||
| 	// Check Vertex Shader | ||||
| 	glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); | ||||
| 	glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | ||||
| 	if (InfoLogLength > 0) { | ||||
| 		vector<char> VertexShaderErrorMessage(InfoLogLength + 1); | ||||
| 		glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, | ||||
| 				&VertexShaderErrorMessage[0]); | ||||
| 		printf("%s\n", &VertexShaderErrorMessage[0]); | ||||
| 	} | ||||
|  | ||||
| 	// Compile Fragment Shader | ||||
| 	std::cout << "Compiling fragment shader : " << name << std::endl; | ||||
|  | ||||
| 	char const * FragmentSourcePointer = FragmentShaderCode.c_str(); | ||||
| 	glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); | ||||
| 	glCompileShader(FragmentShaderID); | ||||
|  | ||||
| 	// Check Fragment Shader | ||||
| 	glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); | ||||
| 	glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | ||||
| 	if (InfoLogLength > 0) { | ||||
| 		vector<char> FragmentShaderErrorMessage(InfoLogLength + 1); | ||||
| 		glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, | ||||
| 				&FragmentShaderErrorMessage[0]); | ||||
| 		printf("%s\n", &FragmentShaderErrorMessage[0]); | ||||
| 	} | ||||
|  | ||||
| 	// Link the program | ||||
| 	std::cout << "Linking program : " << name << std::endl; | ||||
|  | ||||
| 	GLuint ProgramID = glCreateProgram(); | ||||
| 	glAttachShader(ProgramID, VertexShaderID); | ||||
| 	glAttachShader(ProgramID, FragmentShaderID); | ||||
| 	glLinkProgram(ProgramID); | ||||
|  | ||||
| 	// Check the program | ||||
| 	glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); | ||||
| 	glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); | ||||
| 	if (InfoLogLength > 0) { | ||||
| 		vector<char> ProgramErrorMessage(InfoLogLength + 1); | ||||
| 		glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, | ||||
| 				&ProgramErrorMessage[0]); | ||||
| 		printf("%s\n", &ProgramErrorMessage[0]); | ||||
| 	} | ||||
|  | ||||
| 	glDetachShader(ProgramID, VertexShaderID); | ||||
| 	glDetachShader(ProgramID, FragmentShaderID); | ||||
|  | ||||
| 	glDeleteShader(VertexShaderID); | ||||
| 	glDeleteShader(FragmentShaderID); | ||||
|  | ||||
| 	return ProgramID; | ||||
| } | ||||
|  | ||||
| void Application::loadShader() { | ||||
| 	if (programId >= 0) | ||||
| @@ -409,6 +366,7 @@ void Application::loadShader() { | ||||
| } | ||||
|  | ||||
| void Application::uploadMesh() { | ||||
| 	printf("upload mesh\n"); | ||||
| 	GLCK(glBindVertexArray(vertexArrayId)) | ||||
|  | ||||
| 	GLCK(glBindBuffer(GL_ARRAY_BUFFER, vPositionId)) | ||||
| @@ -428,10 +386,13 @@ void Application::uploadMesh() { | ||||
| 			glBufferData(GL_ELEMENT_ARRAY_BUFFER, texturemapper.indices.size() * sizeof(uvec3), texturemapper.indices.data(), GL_STATIC_DRAW)) | ||||
|  | ||||
| 	GLCK(glBindVertexArray(0)) | ||||
| } | ||||
|  | ||||
| void Application::uploadTexture() { | ||||
| 	printf("upload texture\n"); | ||||
| 	glBindTexture(GL_TEXTURE_2D, tAlbedoId); | ||||
| 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texturemapper.getTextureSize(), | ||||
| 			texturemapper.getTextureSize(), 0, GL_BGR, GL_UNSIGNED_BYTE, | ||||
| 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturemapper.getTextureSize(), | ||||
| 			texturemapper.getTextureSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE, | ||||
| 			texturemapper.albedo.data()); | ||||
| 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
| 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
| @@ -446,9 +407,11 @@ void Application::renderMesh() { | ||||
| } | ||||
|  | ||||
| void Application::prepareShader() { | ||||
| 	glm::mat4 model(1.0f); | ||||
| 	glm::mat4 view; | ||||
|  | ||||
| 	double mouseX, mouseY; | ||||
| 	glfwGetCursorPos(window, &mouseX, &mouseY); | ||||
|  | ||||
| 	if (fpsMode) { | ||||
| 		glm::mat4 fpsTrafoInv = glm::inverse(fpsTrafo); | ||||
|  | ||||
| @@ -458,37 +421,53 @@ void Application::prepareShader() { | ||||
| 		} else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { | ||||
| 			movement -= glm::vec4(0.0, 0.0, 0.1, 0.0); | ||||
| 		} | ||||
| 		double mouseX, mouseY; | ||||
| 		glfwGetCursorPos(window, &mouseX, &mouseY); | ||||
| 		glm::vec3 up = fpsTrafoInv * glm::vec4(0.0, 1.0, 0.0, 0.0); | ||||
| 		glm::vec3 side = fpsTrafoInv * glm::vec4(1.0, 0.0, 0.0, 0.0); | ||||
| 		glm::vec3 front = fpsTrafoInv * glm::vec4(0.0, 0.0, 1.0, 0.0); | ||||
| 		fpsTrafo = glm::rotate(fpsTrafo, (float)(mouseX - lastMouseX) * 0.01f, up); | ||||
| 		fpsTrafo = glm::rotate(fpsTrafo, (float)(mouseY - lastMouseY) * 0.01f, side); | ||||
|  | ||||
| 		if (glfwGetMouseButton(window, 0) == GLFW_PRESS) { | ||||
| 			glm::vec3 up = fpsTrafoInv * glm::vec4(0.0, 1.0, 0.0, 0.0); | ||||
| 			glm::vec3 side = fpsTrafoInv * glm::vec4(1.0, 0.0, 0.0, 0.0); | ||||
| 			glm::vec3 front = fpsTrafoInv * glm::vec4(0.0, 0.0, 1.0, 0.0); | ||||
| 			fpsTrafo = glm::rotate(fpsTrafo, | ||||
| 					(float) (mouseX - lastMouseX) * 0.01f, up); | ||||
| 			fpsTrafo = glm::rotate(fpsTrafo, | ||||
| 					(float) (mouseY - lastMouseY) * 0.01f, side); | ||||
| 		} | ||||
| 		//fpsTrafo = glm::rotate(fpsTrafo, mouseX - lastMouseX, up); | ||||
| 		glm::vec3 absolute = fpsTrafoInv * movement; | ||||
| 		fpsTrafo = glm::translate(fpsTrafo, absolute); | ||||
| 		lastMouseX = mouseX; | ||||
| 		lastMouseY = mouseY; | ||||
|  | ||||
| 		view = fpsTrafo; | ||||
| 	} else { | ||||
| 		model = glm::rotate(model, (float) glfwGetTime(), vec3(0.f, 1.f, 0.f)); | ||||
|  | ||||
| 		if (!ImGui::IsMouseHoveringAnyWindow() && glfwGetMouseButton(window, 0) == GLFW_PRESS) { | ||||
| 			glm::mat4 modelTrafoInv = glm::inverse(modelTrafo); | ||||
| 			modelTrafo = glm::rotate(modelTrafo, | ||||
| 					(float) (mouseX - lastMouseX) * 0.01f, | ||||
| 					vec3(modelTrafoInv * glm::vec4(0.0, 1.0, 0.0, 0.0))); | ||||
| 			modelTrafo = glm::rotate(modelTrafo, | ||||
| 					(float) (mouseY - lastMouseY) * 0.01f, | ||||
| 					vec3(modelTrafoInv * glm::vec4(1.0, 0.0, 0.0, 0.0))); | ||||
| 		} | ||||
|  | ||||
| 		//model = glm::rotate(model, (float) glfwGetTime(), vec3(0.f, 1.f, 0.f)); | ||||
|  | ||||
| 		view = glm::lookAt(vec3(0, 0, viewDistance), // Camera is at (4,3,3), in World Space | ||||
| 		vec3(0, 0, 0), // and looks at the origin | ||||
| 		vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down) | ||||
| 				); | ||||
| 	} | ||||
| 	lastMouseX = mouseX; | ||||
| 	lastMouseY = mouseY; | ||||
|  | ||||
| 	glm::mat4 perspective = glm::perspective(glm::radians(45.0f), | ||||
| 			(float) width / (float) height, 0.1f, 100.0f); | ||||
| 	glm::mat4 mvp = perspective * view * model; | ||||
| 	glm::mat4 mvp = perspective * view * modelTrafo; | ||||
|  | ||||
| 	GLCK(glUseProgram(programId)) | ||||
| 	if (MVPloc >= 0) { | ||||
| 		GLCK(glUniformMatrix4fv(MVPloc, 1, GL_FALSE, glm::value_ptr(mvp))) | ||||
| 	} | ||||
| 	if (Mloc >= 0) { | ||||
| 		GLCK(glUniformMatrix4fv(Mloc, 1, GL_FALSE, glm::value_ptr(model))) | ||||
| 		GLCK(glUniformMatrix4fv(Mloc, 1, GL_FALSE, glm::value_ptr(modelTrafo))) | ||||
| 	} | ||||
| 	if (Vloc >= 0) { | ||||
| 		GLCK(glUniformMatrix4fv(Vloc, 1, GL_FALSE, glm::value_ptr(view))) | ||||
| @@ -536,6 +515,7 @@ void Application::gui() { | ||||
| 		density.setFrequency(densityFrequency); | ||||
| 	if (ImGui::SliderFloat("Octave", &densityOctave, 1, 10, "%.0f", 1)) | ||||
| 		density.setOctave(densityOctave); | ||||
| 	ImGui::Checkbox("Smooth", &smoothMesh); | ||||
|  | ||||
| 	//	if (ImGui::InputFloat("Frequency", &densityFrequency)) | ||||
| //	if (ImGui::InputFloat("Octave", &densityOctave)) | ||||
| @@ -549,9 +529,17 @@ void Application::gui() { | ||||
| 		texturemapper.setTextureSize(textureSizes[currentTextureSize]); | ||||
| 	} | ||||
|  | ||||
| 	if (ImGui::Button("Generate")) { | ||||
| 		generateAsteroid(); | ||||
| 		uploadMesh(); | ||||
| 	if (meshProgress.isRunning()) { | ||||
| 		if (ImGui::Button("Cancel")) | ||||
| 			meshProgress.cancel(); | ||||
| 		ImGui::Text("Task: %s", meshProgress.getTask().c_str()); | ||||
| 		ImGui::ProgressBar(meshProgress.getProgress()); | ||||
| 	} else { | ||||
| 		if (meshProgress.isFinished() && meshThread.joinable()) | ||||
| 			meshThread.join(); | ||||
|  | ||||
| 		if (ImGui::Button("Generate")) | ||||
| 			meshThread = std::thread(&Application::generateAsteroid, this); | ||||
| 	} | ||||
| 	ImGui::End(); | ||||
|  | ||||
| @@ -590,6 +578,14 @@ void Application::run() { | ||||
| 		glDepthFunc(GL_LESS); | ||||
| 		glEnable(GL_CULL_FACE); | ||||
|  | ||||
| 		if (meshUploadRequest) { | ||||
| 			uploadMesh(); | ||||
| 			meshUploadRequest = false; | ||||
| 		} | ||||
| 		if (textureUploadRequest) { | ||||
| 			uploadTexture(); | ||||
| 			textureUploadRequest = false; | ||||
| 		} | ||||
| 		prepareShader(); | ||||
| 		renderMesh(); | ||||
|  | ||||
|   | ||||
| @@ -3,11 +3,13 @@ | ||||
| #include "Density.h" | ||||
| #include "Polygoniser.h" | ||||
| #include "TextureMapper.h" | ||||
| #include "ProgressMonitor.h" | ||||
|  | ||||
| #include <glm/mat4x4.hpp> | ||||
| #include <glm/vec3.hpp> | ||||
|  | ||||
| #include <string> | ||||
| #include <thread> | ||||
|  | ||||
| struct GLFWwindow; | ||||
|  | ||||
| @@ -29,10 +31,10 @@ class Application { | ||||
| 	int vPositionLoc, vTexCoordLoc, vNormalLoc, tAlbedoLoc, tNormalLoc, | ||||
| 			tRoughnessLoc, tMetalicLoc; | ||||
|  | ||||
| 	std::vector<glm::vec3> vertices; | ||||
| 	std::vector<glm::vec3> normals; | ||||
| 	std::vector<glm::vec2> texcoords; | ||||
| 	std::vector<glm::uvec3> indices; | ||||
| 	vec3v_t vertices; | ||||
| 	vec3v_t normals; | ||||
| 	vec2v_t texcoords; | ||||
| 	uvec3v_t indices; | ||||
|  | ||||
| 	size_t meteoridCount; | ||||
| 	float meteroidMinRadius; | ||||
| @@ -41,12 +43,18 @@ class Application { | ||||
| 	float densityFrequency, densityOctave; | ||||
| 	glm::vec3 densityScale; | ||||
| 	float resolution; | ||||
| 	bool smoothMesh; | ||||
|  | ||||
| 	float viewDistance; | ||||
|  | ||||
| 	glm::mat4 fpsTrafo; | ||||
| 	bool fpsMode; | ||||
| 	double lastMouseX, lastMouseY; | ||||
| 	glm::mat4 modelTrafo; | ||||
|  | ||||
| 	ProgressMonitor meshProgress, textureProgress; | ||||
| 	std::thread meshThread, textureThread; | ||||
| 	bool meshUploadRequest, textureUploadRequest; | ||||
|  | ||||
| 	void toogleFpsMode(); | ||||
| public: | ||||
| @@ -74,11 +82,10 @@ public: | ||||
|  | ||||
| 	void updateVertexArrayObject(); | ||||
|  | ||||
| 	unsigned int loadProgram(const std::string &name); | ||||
|  | ||||
| 	void loadShader(); | ||||
|  | ||||
| 	void uploadMesh(); | ||||
| 	void uploadTexture(); | ||||
|  | ||||
| 	void renderMesh(); | ||||
|  | ||||
|   | ||||
| @@ -53,6 +53,7 @@ public: | ||||
|  | ||||
| 	void setSeed(uint32_t seed) { | ||||
| 		noise.reseed(seed); | ||||
| 		version++; | ||||
| 		impacts.clear(); | ||||
| 	} | ||||
|  | ||||
| @@ -77,7 +78,7 @@ public: | ||||
| 	} | ||||
|  | ||||
| 	float operator()(const glm::vec3 &p, bool includeImpacts = true) const { | ||||
| 		if (includeImpacts & impacts.size()) { | ||||
| 		if (includeImpacts && impacts.size() > 0) { | ||||
| 			bool insideImpact = false; | ||||
| 			impactTree.Search(&p.x, &p.x, [&](int idx) -> bool { | ||||
| 				if (impacts[idx].contains(p)) { | ||||
| @@ -119,6 +120,7 @@ public: | ||||
| 			Impact impact; | ||||
| 			if (intersectIsolevel(start, end, impact.pos, isolevel, | ||||
| 					resolution)) { | ||||
| 				impact.pos -= (impact.r / 1.5f) * normalize(end-start); | ||||
| 				impact.r = minRadius | ||||
| 						+ pow(glm::linearRand(0.f, 1.f), exponent) * maxRadius; | ||||
| 				addImpact(impact); | ||||
|   | ||||
							
								
								
									
										394
									
								
								src/MarchingCube.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										394
									
								
								src/MarchingCube.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,394 @@ | ||||
| #include "MarchingCube.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| using namespace glm; | ||||
|  | ||||
| static const int edgeTable[256] = { 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, | ||||
| 		0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, | ||||
| 		0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, | ||||
| 		0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, 0x230, 0x339, 0x33, 0x13a, | ||||
| 		0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, | ||||
| 		0xc39, 0xd30, 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac, | ||||
| 		0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, 0x460, 0x569, | ||||
| 		0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, | ||||
| 		0x86a, 0x963, 0xa69, 0xb60, 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, | ||||
| 		0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, | ||||
| 		0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c, 0xe5c, 0xf55, | ||||
| 		0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, 0x7c0, 0x6c9, 0x5c3, 0x4ca, | ||||
| 		0x3c6, 0x2cf, 0x1c5, 0xcc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, | ||||
| 		0x9c9, 0x8c0, 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, | ||||
| 		0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, 0x950, 0x859, | ||||
| 		0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55, 0x35f, 0x256, | ||||
| 		0x55a, 0x453, 0x759, 0x650, 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, | ||||
| 		0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, | ||||
| 		0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, | ||||
| 		0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa, | ||||
| 		0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, | ||||
| 		0x2a9, 0x3a0, 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, | ||||
| 		0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230, 0xe90, 0xf99, | ||||
| 		0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, | ||||
| 		0x29a, 0x393, 0x99, 0x190, 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, | ||||
| 		0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 }; | ||||
| static const int triTable[256][16] = { { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 		-1, -1, -1, -1, -1, -1 }, { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 		-1, -1, -1, -1 }, { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 		-1, -1 }, { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 		{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, | ||||
| 				8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 9, | ||||
| 				2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 2, | ||||
| 				8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, { 3, 11, | ||||
| 				2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, | ||||
| 				11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, | ||||
| 				9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, | ||||
| 				11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, { 3, | ||||
| 				10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, | ||||
| 				10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, { 3, | ||||
| 				9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 8, | ||||
| 				10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 7, | ||||
| 				8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
|  | ||||
| 		{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 1, 9, | ||||
| 				8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 1, 9, 4, | ||||
| 				7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 10, 8, 4, | ||||
| 				7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 4, 7, 3, 0, 4, | ||||
| 				1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, { 9, 2, 10, 9, 0, 2, 8, | ||||
| 				4, 7, -1, -1, -1, -1, -1, -1, -1 }, { 2, 10, 9, 2, 9, 7, 2, 7, | ||||
| 				3, 7, 9, 4, -1, -1, -1, -1 }, { 8, 4, 7, 3, 11, 2, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, | ||||
| 				-1, -1, -1, -1, -1, -1 }, { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, | ||||
| 				-1, -1, -1, -1, -1 }, { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, | ||||
| 				-1, -1, -1, -1 }, { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, | ||||
| 				-1, -1, -1 }, { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, | ||||
| 				-1, -1 }, { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, | ||||
| 				-1 }, { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1 }, | ||||
| 		{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, { 5, 2, 10, | ||||
| 				5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, { 2, 10, 5, 3, | ||||
| 				2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, { 9, 5, 4, 2, 3, 11, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 11, 2, 0, 8, 11, | ||||
| 				4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, { 0, 5, 4, 0, 1, 5, 2, 3, | ||||
| 				11, -1, -1, -1, -1, -1, -1, -1 }, { 2, 1, 5, 2, 5, 8, 2, 8, 11, | ||||
| 				4, 8, 5, -1, -1, -1, -1 }, { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, | ||||
| 				-1, -1, -1, -1, -1, -1 }, { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, | ||||
| 				10, -1, -1, -1, -1 }, { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, | ||||
| 				-1, -1, -1, -1 }, { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, | ||||
| 				-1 }, { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, { | ||||
| 				8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, { 2, 10, | ||||
| 				5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, { 7, 9, 5, 7, | ||||
| 				8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 7, 9, 7, | ||||
| 				2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, { 2, 3, 11, 0, 1, 8, 1, | ||||
| 				7, 8, 1, 5, 7, -1, -1, -1, -1 }, { 11, 2, 1, 11, 1, 7, 7, 1, 5, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, | ||||
| 				3, 11, -1, -1, -1, -1 }, { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, | ||||
| 				11, 10, 0, -1 }, { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, | ||||
| 				0, -1 }, { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, | ||||
| 				-1 }, { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 		{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, { 2, 3, 11, 10, | ||||
| 				6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 11, 0, 8, 11, | ||||
| 				2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, { 0, 1, 9, 2, 3, | ||||
| 				11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, { 5, 10, 6, 1, 9, 2, | ||||
| 				9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, { 6, 3, 11, 6, 5, 3, 5, 1, | ||||
| 				3, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 11, 0, 11, 5, 0, 5, 1, | ||||
| 				5, 11, 6, -1, -1, -1, -1 }, { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, | ||||
| 				9, -1, -1, -1, -1 }, { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, | ||||
| 		{ 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, { 6, 1, 2, 6, | ||||
| 				5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 5, 5, 2, 6, | ||||
| 				3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, { 8, 4, 7, 9, 0, 5, 0, 6, 5, | ||||
| 				0, 2, 6, -1, -1, -1, -1 }, { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, | ||||
| 				2, 6, 9, -1 }, { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, | ||||
| 				-1, -1 }, | ||||
| 		{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, { 9, 2, 1, 9, | ||||
| 				11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, { 8, 4, 7, 3, 11, 5, | ||||
| 				3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, { 5, 1, 11, 5, 11, 6, 1, 0, | ||||
| 				11, 7, 11, 4, 0, 4, 11, -1 }, { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, | ||||
| 				6, 3, 8, 4, 7, -1 }, { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, | ||||
| 				-1, -1, -1 }, { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, | ||||
| 				-1 }, { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, { | ||||
| 				1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, | ||||
| 				8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, { 0, 2, 4, 4, 2, | ||||
| 				6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, 3, 2, 8, 2, 4, | ||||
| 				4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, { 10, 4, 9, 10, 6, 4, 11, | ||||
| 				2, 3, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 2, 2, 8, 11, 4, 9, | ||||
| 				10, 4, 10, 6, -1, -1, -1, -1 }, { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, | ||||
| 				1, 10, -1, -1, -1, -1 }, { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, | ||||
| 				8, 11, 1, -1 }, { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, | ||||
| 				-1, -1 }, { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 }, | ||||
| 		{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, { 6, 4, 8, | ||||
| 				11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 7, 10, 6, | ||||
| 				7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, { 0, 7, 3, 0, | ||||
| 				10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, { 10, 6, 7, 1, 10, | ||||
| 				7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, { 10, 6, 7, 10, 7, 1, 1, | ||||
| 				7, 3, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 6, 1, 6, 8, 1, 8, 9, | ||||
| 				8, 6, 7, -1, -1, -1, -1 }, { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, | ||||
| 				7, 3, 9, -1 }, { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, | ||||
| 				-1 }, { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, { | ||||
| 				1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, { 11, 2, | ||||
| 				1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, { 8, 9, 6, 8, | ||||
| 				6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, { 0, 9, 1, 11, 6, 7, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 7, 8, 0, 7, 0, 6, 3, 11, | ||||
| 				0, 11, 6, 0, -1, -1, -1, -1 }, { 7, 11, 6, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1 }, { 7, 6, 11, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 8, 11, 7, 6, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 1, 9, 11, 7, 6, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, 1, 9, 8, 3, 1, 11, 7, | ||||
| 				6, -1, -1, -1, -1, -1, -1, -1 }, { 10, 1, 2, 6, 11, 7, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 10, 3, 0, 8, 6, 11, 7, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, | ||||
| 				-1, -1, -1, -1, -1, -1 }, { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, | ||||
| 				8, -1, -1, -1, -1 }, { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, | ||||
| 		{ 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, { 10, 7, 6, 10, | ||||
| 				1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, { 10, 7, 6, 1, 7, | ||||
| 				10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, { 0, 3, 7, 0, 7, 10, 0, | ||||
| 				10, 9, 6, 10, 7, -1, -1, -1, -1 }, { 7, 6, 10, 7, 10, 8, 8, 10, | ||||
| 				9, -1, -1, -1, -1, -1, -1, -1 }, { 6, 8, 4, 11, 8, 6, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 6, 11, 3, 0, 6, 0, 4, 6, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1 }, { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, | ||||
| 				-1, -1, -1, -1 }, { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, | ||||
| 				-1, -1 }, { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, | ||||
| 				-1 }, { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, { | ||||
| 				8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, { 0, 4, | ||||
| 				2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 9, 0, | ||||
| 				2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, { 1, 9, 4, 1, 4, 2, | ||||
| 				2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, { 8, 1, 3, 8, 6, 1, 8, 4, | ||||
| 				6, 6, 10, 1, -1, -1, -1, -1 }, { 10, 1, 0, 10, 0, 6, 6, 0, 4, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, | ||||
| 				3, 9, 10, 9, 3, -1 }, { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1 }, { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1 }, { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, | ||||
| 				-1 }, | ||||
| 		{ 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, { 6, 11, 7, | ||||
| 				1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, { 7, 6, 11, 5, 4, | ||||
| 				10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, { 3, 4, 8, 3, 5, 4, 3, | ||||
| 				2, 5, 10, 5, 2, 11, 7, 6, -1 }, { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, | ||||
| 				-1, -1, -1, -1, -1, -1 }, { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, | ||||
| 				-1, -1, -1, -1 }, { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, | ||||
| 				-1, -1 }, { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 }, { | ||||
| 				9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, { 1, 6, | ||||
| 				10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 }, { 4, 0, 10, 4, 10, | ||||
| 				5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, { 7, 6, 10, 7, 10, 8, 5, | ||||
| 				4, 10, 4, 8, 10, -1, -1, -1, -1 }, { 6, 9, 5, 6, 11, 9, 11, 8, | ||||
| 				9, -1, -1, -1, -1, -1, -1, -1 }, { 3, 6, 11, 0, 6, 3, 0, 5, 6, | ||||
| 				0, 9, 5, -1, -1, -1, -1 }, { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, | ||||
| 				11, -1, -1, -1, -1 }, { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, | ||||
| 				-1, -1, -1 }, { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, | ||||
| 				-1 }, { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, { | ||||
| 				6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, { 5, 8, | ||||
| 				9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, { 9, 5, 6, 9, 6, | ||||
| 				0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, { 1, 5, 8, 1, 8, 0, 5, | ||||
| 				6, 8, 3, 8, 2, 6, 2, 8, -1 }, { 1, 5, 6, 2, 1, 6, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, | ||||
| 				6, 9, 8, 9, 6, -1 }, { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, | ||||
| 				-1, -1, -1 }, { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, | ||||
| 				-1, -1, -1 }, { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1 }, | ||||
| 		{ 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, { 9, 7, 5, 9, | ||||
| 				2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, { 7, 5, 2, 7, 2, 11, | ||||
| 				5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, { 2, 5, 10, 2, 3, 5, 3, 7, 5, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, | ||||
| 				2, 5, -1, -1, -1, -1 }, { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, | ||||
| 				-1, -1, -1, -1 }, { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, | ||||
| 				2, -1 }, { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1 }, { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 		{ 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, { 9, 8, 7, 5, | ||||
| 				9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 5, 8, 4, 5, | ||||
| 				10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, { 5, 0, 4, 5, | ||||
| 				11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 }, { 0, 1, 9, 8, 4, | ||||
| 				10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, { 10, 11, 4, 10, 4, | ||||
| 				5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 }, { 2, 5, 1, 2, 8, 5, 2, 11, | ||||
| 				8, 4, 5, 8, -1, -1, -1, -1 }, { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, | ||||
| 				11, 1, 5, 1, 11, -1 }, { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, | ||||
| 				11, 8, 5, -1 }, { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, | ||||
| 				-1 }, | ||||
| 		{ 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, { 3, 10, 2, | ||||
| 				3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, { 5, 10, 2, 5, 2, 4, | ||||
| 				1, 9, 2, 9, 4, 2, -1, -1, -1, -1 }, { 8, 4, 5, 8, 5, 3, 3, 5, 1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 0, 4, 5, 1, 0, 5, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1 }, { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, | ||||
| 				5, -1, -1, -1, -1 }, { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1 }, { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, | ||||
| 				-1, -1, -1, -1, -1 }, { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, | ||||
| 				-1, -1, -1, -1 }, { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, | ||||
| 				-1, -1, -1 }, { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, | ||||
| 				-1 }, { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, | ||||
| 		{ 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 }, { 11, 7, 4, 11, | ||||
| 				4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, { 11, 7, 4, 11, 4, | ||||
| 				2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 }, { 2, 9, 10, 2, 7, 9, 2, | ||||
| 				3, 7, 7, 4, 9, -1, -1, -1, -1 }, { 9, 10, 7, 9, 7, 4, 10, 2, 7, | ||||
| 				8, 7, 0, 2, 0, 7, -1 }, { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, | ||||
| 				0, 4, 0, 10, -1 }, { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1 }, { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, | ||||
| 				-1, -1, -1 }, { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, | ||||
| 				-1 }, | ||||
| 		{ 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 8, 7, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 9, 10, | ||||
| 				8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, | ||||
| 				9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, { 0, 1, | ||||
| 				10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, { 3, 1, | ||||
| 				10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, | ||||
| 				11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 9, | ||||
| 				3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 }, { 0, 2, 11, 8, 0, | ||||
| 				11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 2, 11, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 2, 3, 8, 2, | ||||
| 				8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 10, 2, 0, 9, | ||||
| 				2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 2, 3, 8, 2, 8, | ||||
| 				10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, { 1, 10, 2, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 3, 8, 9, 1, 8, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 9, 1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 3, 8, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, | ||||
| 				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }; | ||||
|  | ||||
| /* | ||||
|  Linearly interpolate the position where an isosurface cuts | ||||
|  an edge between two vertices, each with their own scalar value | ||||
|  */ | ||||
| XYZ VertexInterp(double isolevel, XYZ p1, XYZ p2, double valp1, double valp2) { | ||||
| 	double mu; | ||||
| 	XYZ p; | ||||
| 	float dx = p2.x - p1.x; | ||||
| 	float dy = p2.y - p1.y; | ||||
| 	float dz = p2.z - p1.z; | ||||
| 	float eps = sqrt(dx*dx+dy*dy+dz*dz) * 0.05; | ||||
| 	if (fabs(isolevel - valp1) < eps) | ||||
| 		return (p1); | ||||
| 	if (fabs(isolevel - valp2) < eps) | ||||
| 		return (p2); | ||||
| 	if (fabs(valp1 - valp2) < 0.0001) | ||||
| 		return (p1); | ||||
|  | ||||
| 	mu = (isolevel - valp1) / (valp2 - valp1); | ||||
| 	p.x = p1.x + mu * dx; | ||||
| 	p.y = p1.y + mu * dy; | ||||
| 	p.z = p1.z + mu * dz; | ||||
|  | ||||
| 	return (p); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  Given a grid cell and an isolevel, calculate the triangular | ||||
|  facets required to represent the isosurface through the cell. | ||||
|  Return the number of triangular facets, the array "triangles" | ||||
|  will be loaded up with the vertices at most 5 triangular facets. | ||||
|  0 will be returned if the grid cell is either totally above | ||||
|  of totally below the isolevel. | ||||
|  */ | ||||
| int Polygonise(GRIDCELL &grid, double isolevel, TRIANGLE *triangles) { | ||||
| 	int i, ntriang; | ||||
| 	int cubeindex; | ||||
| 	XYZ vertlist[12]; | ||||
|  | ||||
| 	/* | ||||
| 	 Determine the index into the edge table which | ||||
| 	 tells us which vertices are inside of the surface | ||||
| 	 */ | ||||
| 	cubeindex = 0; | ||||
| 	if (grid.val[0] < isolevel) | ||||
| 		cubeindex |= 1; | ||||
| 	if (grid.val[1] < isolevel) | ||||
| 		cubeindex |= 2; | ||||
| 	if (grid.val[2] < isolevel) | ||||
| 		cubeindex |= 4; | ||||
| 	if (grid.val[3] < isolevel) | ||||
| 		cubeindex |= 8; | ||||
| 	if (grid.val[4] < isolevel) | ||||
| 		cubeindex |= 16; | ||||
| 	if (grid.val[5] < isolevel) | ||||
| 		cubeindex |= 32; | ||||
| 	if (grid.val[6] < isolevel) | ||||
| 		cubeindex |= 64; | ||||
| 	if (grid.val[7] < isolevel) | ||||
| 		cubeindex |= 128; | ||||
|  | ||||
| 	/* Cube is entirely in/out of the surface */ | ||||
| 	if (edgeTable[cubeindex] == 0) | ||||
| 		return (0); | ||||
|  | ||||
| 	/* Find the vertices where the surface intersects the cube */ | ||||
| 	if (edgeTable[cubeindex] & 1) | ||||
| 		vertlist[0] = VertexInterp(isolevel, grid.p[0], grid.p[1], grid.val[0], | ||||
| 				grid.val[1]); | ||||
| 	if (edgeTable[cubeindex] & 2) | ||||
| 		vertlist[1] = VertexInterp(isolevel, grid.p[1], grid.p[2], grid.val[1], | ||||
| 				grid.val[2]); | ||||
| 	if (edgeTable[cubeindex] & 4) | ||||
| 		vertlist[2] = VertexInterp(isolevel, grid.p[2], grid.p[3], grid.val[2], | ||||
| 				grid.val[3]); | ||||
| 	if (edgeTable[cubeindex] & 8) | ||||
| 		vertlist[3] = VertexInterp(isolevel, grid.p[3], grid.p[0], grid.val[3], | ||||
| 				grid.val[0]); | ||||
| 	if (edgeTable[cubeindex] & 16) | ||||
| 		vertlist[4] = VertexInterp(isolevel, grid.p[4], grid.p[5], grid.val[4], | ||||
| 				grid.val[5]); | ||||
| 	if (edgeTable[cubeindex] & 32) | ||||
| 		vertlist[5] = VertexInterp(isolevel, grid.p[5], grid.p[6], grid.val[5], | ||||
| 				grid.val[6]); | ||||
| 	if (edgeTable[cubeindex] & 64) | ||||
| 		vertlist[6] = VertexInterp(isolevel, grid.p[6], grid.p[7], grid.val[6], | ||||
| 				grid.val[7]); | ||||
| 	if (edgeTable[cubeindex] & 128) | ||||
| 		vertlist[7] = VertexInterp(isolevel, grid.p[7], grid.p[4], grid.val[7], | ||||
| 				grid.val[4]); | ||||
| 	if (edgeTable[cubeindex] & 256) | ||||
| 		vertlist[8] = VertexInterp(isolevel, grid.p[0], grid.p[4], grid.val[0], | ||||
| 				grid.val[4]); | ||||
| 	if (edgeTable[cubeindex] & 512) | ||||
| 		vertlist[9] = VertexInterp(isolevel, grid.p[1], grid.p[5], grid.val[1], | ||||
| 				grid.val[5]); | ||||
| 	if (edgeTable[cubeindex] & 1024) | ||||
| 		vertlist[10] = VertexInterp(isolevel, grid.p[2], grid.p[6], grid.val[2], | ||||
| 				grid.val[6]); | ||||
| 	if (edgeTable[cubeindex] & 2048) | ||||
| 		vertlist[11] = VertexInterp(isolevel, grid.p[3], grid.p[7], grid.val[3], | ||||
| 				grid.val[7]); | ||||
|  | ||||
| 	/* Create the triangle */ | ||||
| 	ntriang = 0; | ||||
| 	for (i = 0; triTable[cubeindex][i] != -1; i += 3) { | ||||
| 		triangles[ntriang].p[0] = vertlist[triTable[cubeindex][i]]; | ||||
| 		triangles[ntriang].p[1] = vertlist[triTable[cubeindex][i + 1]]; | ||||
| 		triangles[ntriang].p[2] = vertlist[triTable[cubeindex][i + 2]]; | ||||
| 		ntriang++; | ||||
| 	} | ||||
|  | ||||
| 	return (ntriang); | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/MarchingCube.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/MarchingCube.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <glm/vec3.hpp> | ||||
|  | ||||
| typedef glm::vec3 XYZ; | ||||
|  | ||||
| struct TRIANGLE { | ||||
| 	XYZ p[3]; | ||||
| }; | ||||
|  | ||||
| struct GRIDCELL { | ||||
| 	XYZ p[8]; | ||||
| 	double val[8]; | ||||
| } ; | ||||
|  | ||||
| int Polygonise(GRIDCELL &grid, double isolevel, TRIANGLE *triangles); | ||||
							
								
								
									
										187
									
								
								src/Mesh.cpp
									
									
									
									
									
								
							
							
						
						
									
										187
									
								
								src/Mesh.cpp
									
									
									
									
									
								
							| @@ -3,16 +3,25 @@ | ||||
| #include <glm/geometric.hpp> | ||||
|  | ||||
| #include <map> | ||||
| #include <limits> | ||||
| #include <stack> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace glm; | ||||
|  | ||||
| void calculateNormals(const vec3v_t &vtx, uvec3v_t &tri, vec3v_t &normals) { | ||||
| static const uvec3::value_type InvalidIndex = | ||||
| 		numeric_limits<uvec3::value_type>::max(); | ||||
|  | ||||
| void calculateVertexNormals(const vec3v_t &positions, uvec3v_t &indices, | ||||
| 		vec3v_t &normals) { | ||||
| 	normals.clear(); | ||||
| 	normals.resize(vtx.size(), vec3(0)); | ||||
| 	for (size_t i = 0; i < tri.size(); i++) { | ||||
| 		int a = tri[i].x, b = tri[i].y, c = tri[i].z; | ||||
| 		vec3 faceNormal = normalize(cross(vtx[b] - vtx[a], vtx[c] - vtx[a])); | ||||
| 	normals.resize(positions.size(), vec3(0)); | ||||
| 	#pragma omp parallel for | ||||
| 	for (size_t i = 0; i < indices.size(); i++) { | ||||
| 		int a = indices[i].x, b = indices[i].y, c = indices[i].z; | ||||
| 		vec3 faceNormal = normalize( | ||||
| 				cross(positions[b] - positions[a], | ||||
| 						positions[c] - positions[a])); | ||||
| 		normals[a] += faceNormal; | ||||
| 		normals[b] += faceNormal; | ||||
| 		normals[c] += faceNormal; | ||||
| @@ -22,27 +31,40 @@ void calculateNormals(const vec3v_t &vtx, uvec3v_t &tri, vec3v_t &normals) { | ||||
|  | ||||
| } | ||||
|  | ||||
| void moveToMean(vec3v_t &vtx) { | ||||
| 	vec3 mean(0); | ||||
| 	for (size_t i = 0; i < vtx.size(); i++) { | ||||
| 		mean += vtx[i]; | ||||
| 	} | ||||
| 	mean *= vec3(1.f / vtx.size()); | ||||
| 	for (size_t i = 0; i < vtx.size(); i++) { | ||||
| 		vtx[i] -= mean; | ||||
| void calculateFaceNormals(const vec3v_t &positions, uvec3v_t &indices, | ||||
| 		vec3v_t &normals) { | ||||
| 	normals.clear(); | ||||
| 	normals.resize(indices.size(), vec3(uninitialize)); | ||||
| 	#pragma omp parallel for | ||||
| 	for (size_t i = 0; i < indices.size(); i++) { | ||||
| 		int a = indices[i].x, b = indices[i].y, c = indices[i].z; | ||||
| 		normals[i] = normalize( | ||||
| 				cross(positions[b] - positions[a], | ||||
| 						positions[c] - positions[a])); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void smooth(vec3v_t &vtx, const uvec3v_t &tri) { | ||||
| 	vec3v_t cogs(vtx.size(), vec3(0.f)); | ||||
| 	vector<int> valence(vtx.size(), 0); | ||||
| void moveToMean(vec3v_t &positions) { | ||||
| 	vec3 mean(0); | ||||
| 	for (size_t i = 0; i < positions.size(); i++) { | ||||
| 		mean += positions[i]; | ||||
| 	} | ||||
| 	mean *= vec3(1.f / positions.size()); | ||||
| 	for (size_t i = 0; i < positions.size(); i++) { | ||||
| 		positions[i] -= mean; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 	for (size_t iTri = 0; iTri < tri.size(); iTri++) { | ||||
| 		const uvec3 &idx = tri[iTri]; | ||||
| void smooth(vec3v_t &positions, const uvec3v_t &indices) { | ||||
| 	vec3v_t cogs(positions.size(), vec3(0.f)); | ||||
| 	vector<int> valence(positions.size(), 0); | ||||
|  | ||||
| 	for (size_t iTri = 0; iTri < indices.size(); iTri++) { | ||||
| 		const uvec3 &idx = indices[iTri]; | ||||
| 		for (size_t iE = 0; iE < 3; iE++) { | ||||
| 			valence[idx[iE]] += 2; | ||||
| 			cogs[idx[iE]] += vtx[idx[(iE + 1) % 3]]; | ||||
| 			cogs[idx[iE]] += vtx[idx[(iE + 2) % 3]]; | ||||
| 			cogs[idx[iE]] += positions[idx[(iE + 1) % 3]]; | ||||
| 			cogs[idx[iE]] += positions[idx[(iE + 2) % 3]]; | ||||
| 		} | ||||
| 	} | ||||
| 	/* | ||||
| @@ -61,10 +83,11 @@ void smooth(vec3v_t &vtx, const uvec3v_t &tri) { | ||||
| 	 mesh.set_point(*v_it, *cog_it); | ||||
|  | ||||
| 	 */ | ||||
| 	for (size_t i = 0; i < vtx.size(); i++) { | ||||
| 	#pragma omp parallel for | ||||
| 	for (size_t i = 0; i < positions.size(); i++) { | ||||
| //		vtx[i] = vtx[i] * vec3(0.8) | ||||
| //				+ cogs[i] * vec3(0.2f / valence[i]); | ||||
| 		vtx[i] = cogs[i] * vec3(1.f / valence[i]); | ||||
| 		positions[i] = cogs[i] * vec3(1.f / valence[i]); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -81,12 +104,12 @@ void saveAttrib(std::ostream &out, const char *prefix, vec2v_t &elements) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void saveFaces(std::ostream &out, const uvec3v_t &tris, size_t attribs) { | ||||
| 	for (size_t i = 0; i < tris.size(); i++) { | ||||
| void saveFaces(std::ostream &out, const uvec3v_t &incdices, size_t attribs) { | ||||
| 	for (size_t i = 0; i < incdices.size(); i++) { | ||||
| 		out << "f"; | ||||
|  | ||||
| 		for (size_t j = 0; j < 3; j++) { | ||||
| 			int v = tris[i][j] + 1; | ||||
| 			int v = incdices[i][j] + 1; | ||||
| 			out << " " << v; | ||||
| 			if (attribs > 1) | ||||
| 				out << "/" << v; | ||||
| @@ -99,39 +122,43 @@ void saveFaces(std::ostream &out, const uvec3v_t &tris, size_t attribs) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void findEdges(const vec3v_t &vtx, uvec3v_t &tri, uvec4v_t &edges) { | ||||
| void findEdges(const vec3v_t &positions, const uvec3v_t &indices, | ||||
| 		uvec4v_t &edges) { | ||||
| 	edges.clear(); | ||||
| 	map<pair<uint32_t, uint32_t>, uint32_t> edgeMap; | ||||
| 	for (size_t iTri = 0; iTri < tri.size(); iTri++) { | ||||
| 		uvec3 idx = tri[iTri]; | ||||
| 	for (size_t iTri = 0; iTri < indices.size(); iTri++) { | ||||
| 		uvec3 idx = indices[iTri]; | ||||
| 		for (size_t k = 0; k < 3; k++) { | ||||
| 			int a = idx[k]; | ||||
| 			int b = idx[(k + 1) % 3]; | ||||
| 			uvec4 edge1(std::min(a, b), std::max(a, b), iTri, 0); | ||||
| 			auto it1 = edgeMap.find(std::make_pair(edge1.x, edge1.y)); | ||||
| 			auto key = std::make_pair(edge1.x, edge1.y); | ||||
| 			auto it1 = edgeMap.find(key); | ||||
| 			if (it1 != edgeMap.end()) { | ||||
| 				edges[it1->second].z = iTri; | ||||
| 				edges[it1->second].w = iTri; | ||||
| 			} else { | ||||
| 				size_t idx = edges.size(); | ||||
| 				edges.push_back(edge1); | ||||
| 				edgeMap[key] = idx; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void computeTangentBasis(vec3v_t & vertices, vec2v_t & uvs, vec3v_t & normals, | ||||
| 		vec3v_t & tangents, vec3v_t & bitangents) { | ||||
| void computeTangentBasis(vec3v_t & positions, vec2v_t & texcoords, | ||||
| 		vec3v_t & normals, vec3v_t & tangents, vec3v_t & bitangents) { | ||||
|  | ||||
| 	for (size_t i = 0; i < vertices.size(); i += 3) { | ||||
| 	for (size_t i = 0; i < positions.size(); i += 3) { | ||||
|  | ||||
| 		// Shortcuts for vertices | ||||
| 		vec3 & v0 = vertices[i + 0]; | ||||
| 		vec3 & v1 = vertices[i + 1]; | ||||
| 		vec3 & v2 = vertices[i + 2]; | ||||
| 		vec3 & v0 = positions[i + 0]; | ||||
| 		vec3 & v1 = positions[i + 1]; | ||||
| 		vec3 & v2 = positions[i + 2]; | ||||
|  | ||||
| 		// Shortcuts for UVs | ||||
| 		vec2 & uv0 = uvs[i + 0]; | ||||
| 		vec2 & uv1 = uvs[i + 1]; | ||||
| 		vec2 & uv2 = uvs[i + 2]; | ||||
| 		vec2 & uv0 = texcoords[i + 0]; | ||||
| 		vec2 & uv1 = texcoords[i + 1]; | ||||
| 		vec2 & uv2 = texcoords[i + 2]; | ||||
|  | ||||
| 		// Edges of the triangle : postion delta | ||||
| 		vec3 deltaPos1 = v1 - v0; | ||||
| @@ -157,3 +184,85 @@ void computeTangentBasis(vec3v_t & vertices, vec2v_t & uvs, vec3v_t & normals, | ||||
|  | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void findAdjacent(const uvec4v_t &edges, size_t nFaces, uvec3v_t &adjacents) { | ||||
| 	printf("findAdjacent: %lu\n", nFaces); | ||||
| 	adjacents.resize(nFaces, uvec3(InvalidIndex)); | ||||
| 	for (size_t i = 0; i < edges.size(); i++) { | ||||
| 		int a = edges[i].z; | ||||
| 		int b = edges[i].w; | ||||
|  | ||||
| 		uvec3 &aa = adjacents[a]; | ||||
| 		for (size_t j = 0; j < 3; j++) { | ||||
| 			if (aa[j] == InvalidIndex) { | ||||
| 				aa[j] = b; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		uvec3 &ab = adjacents[b]; | ||||
| 		for (size_t j = 0; j < 3; j++) { | ||||
| 			if (ab[j] == InvalidIndex) { | ||||
| 				ab[j] = a; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void createPatches(const vec3v_t &positions, const uvec3v_t &indices, | ||||
| 		const vec3v_t &faceNormals, const uvec3v_t &adjacents, | ||||
| 		vec3v_t &oPositions, uvec3v_t &oIndices, uintv_t &patches, | ||||
| 		float threshold) { | ||||
| 	assert(adjacents.size() == indices.size()); | ||||
| 	patches.clear(); | ||||
| 	oPositions.clear(); | ||||
| 	oIndices.clear(); | ||||
| 	vector<bool> processed(indices.size(), false); | ||||
|  | ||||
| 	for (size_t i = 0; i < indices.size(); i++) { | ||||
| 		if (processed[i]) | ||||
| 			continue; | ||||
| 		vector<uint32_t> faces; | ||||
| 		map<uint32_t, uint32_t> vertexMap; | ||||
|  | ||||
| 		vec3 normal = faceNormals[i]; | ||||
|  | ||||
| 		// check all adjacent faces | ||||
| 		stack<uint32_t> facesToCheck; | ||||
| 		facesToCheck.push(i); | ||||
| 		while (facesToCheck.size()) { | ||||
| 			uint32_t face = facesToCheck.top(); | ||||
| 			facesToCheck.pop(); | ||||
| 			if (face == InvalidIndex || processed[face]) | ||||
| 				continue; | ||||
| 			if (dot(normal, faceNormals[face]) > threshold) { | ||||
| 				faces.push_back(face); | ||||
| 				//normal = normalize(normal + 0.5f * faceNormals[face]); | ||||
| 				processed[face] = true; | ||||
| 				facesToCheck.push(adjacents[face].x); | ||||
| 				facesToCheck.push(adjacents[face].y); | ||||
| 				facesToCheck.push(adjacents[face].z); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// fill new arrays | ||||
| 		for (size_t j = 0; j < faces.size(); j++) { | ||||
| 			uvec3 idx = indices[faces[j]]; | ||||
| 			for (size_t k = 0; k < 3; k++) { | ||||
| 				auto it = vertexMap.find(idx[k]); | ||||
| 				if (it == vertexMap.end()) { | ||||
| 					uint32_t newIdx = oPositions.size(); | ||||
| 					oPositions.push_back(positions[idx[k]]); | ||||
| 					vertexMap[idx[k]] = newIdx; | ||||
| 					idx[k] = newIdx; | ||||
| 				} else { | ||||
| 					idx[k] = it->second; | ||||
| 				} | ||||
| 			} | ||||
| 			oIndices.push_back(idx); | ||||
| 		} | ||||
| 		printf("\n"); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										37
									
								
								src/Mesh.h
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								src/Mesh.h
									
									
									
									
									
								
							| @@ -1,28 +1,35 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "types.h" | ||||
|  | ||||
| #include <vector> | ||||
| #include <ostream> | ||||
|  | ||||
| #include <glm/vec3.hpp> | ||||
| #include <glm/vec4.hpp> | ||||
| void calculateVertexNormals(const vec3v_t &positions, uvec3v_t &indices, | ||||
| 		vec3v_t &normals); | ||||
| void calculateFaceNormals(const vec3v_t &positions, uvec3v_t &indices, | ||||
| 		vec3v_t &normals); | ||||
| void findEdges(const vec3v_t &positions, const uvec3v_t &indices, | ||||
| 		uvec4v_t &edges); | ||||
| //void createPatches(const vec3v_t &positions, const uvec3v_t &indices, | ||||
| //		const uvec4v_t &edges, vec3v_t &oPositions, uvec3v_t &oIndices, | ||||
| //		uvec4v_t &oEdges, uintv_t &patches, float threshold); | ||||
|  | ||||
| typedef std::vector<glm::vec3> vec3v_t; | ||||
| typedef std::vector<glm::vec2> vec2v_t; | ||||
| typedef std::vector<glm::uvec3> uvec3v_t; | ||||
| typedef std::vector<glm::uvec4> uvec4v_t; | ||||
| void moveToMean(vec3v_t &positions); | ||||
|  | ||||
| void calculateNormals(const vec3v_t &vtx, uvec3v_t &tri, vec3v_t &normals); | ||||
| void findEdges(const vec3v_t &vtx, uvec3v_t &tri, uvec4v_t &edges); | ||||
|  | ||||
| void moveToMean(vec3v_t &vtx); | ||||
|  | ||||
| void smooth(vec3v_t &vtx, const uvec3v_t &tri); | ||||
| void smooth(vec3v_t &positions, const uvec3v_t &indices); | ||||
|  | ||||
| void saveAttrib(std::ostream &out, const char *prefix, vec3v_t &elements); | ||||
|  | ||||
| void saveAttrib(std::ostream &out, const char *prefix, vec2v_t &elements); | ||||
|  | ||||
| void saveFaces(std::ostream &out, const uvec3v_t &tris, size_t attribs); | ||||
| void saveFaces(std::ostream &out, const uvec3v_t &indicess, size_t attributes); | ||||
|  | ||||
| void computeTangentBasis(vec3v_t & vertices, vec2v_t & uvs, vec3v_t & normals, | ||||
| 		vec3v_t & tangents, vec3v_t & bitangents); | ||||
| void findAdjacent(const uvec4v_t &edges, size_t nFaces, uvec3v_t &adjacents); | ||||
|  | ||||
| void computeTangentBasis(vec3v_t & vertices, vec2v_t & texcoords, | ||||
| 		vec3v_t & normals, vec3v_t & tangents, vec3v_t & bitangents); | ||||
| void createPatches(const vec3v_t &positions, const uvec3v_t &indices, | ||||
| 		const vec3v_t &faceNormals, const uvec3v_t &adjacents, | ||||
| 		vec3v_t &oPositions, uvec3v_t &oIndices, uintv_t &patches, | ||||
| 		float threshold); | ||||
|   | ||||
| @@ -5,31 +5,33 @@ | ||||
|  | ||||
| #include <glm/gtc/epsilon.hpp> | ||||
|  | ||||
| #include <MarchingCube.h> | ||||
| #include "MarchingCube.h" | ||||
|  | ||||
| static const int isocells = 32; | ||||
| using namespace glm; | ||||
|  | ||||
| #define ISOCELL 0 | ||||
| static const int isocells = 50; | ||||
|  | ||||
| Polygonizer::Polygonizer(Density &density, float isolevel) : | ||||
| 		density(density), isolevel(isolevel) { | ||||
| 	updateIsocell(); | ||||
| 		density(density), isolevel(isolevel), isocellIsolevel(0), isocellVersion( | ||||
| 				0) { | ||||
| } | ||||
|  | ||||
| void Polygonizer::setIsoLevel(float isolevel) { | ||||
| 	bool needIsocellUpdate = false; | ||||
| 	if (this->isolevel != isolevel) { | ||||
| 		this->isolevel = isolevel; | ||||
| 		needIsocellUpdate = true; | ||||
| 	} | ||||
| 	needIsocellUpdate |= (isocellVersion != density.getVersion()); | ||||
| 	if (needIsocellUpdate) | ||||
| 		updateIsocell(); | ||||
| 	this->isolevel = isolevel; | ||||
| } | ||||
|  | ||||
| #if ISOCELL | ||||
| void Polygonizer::updateIsocell() { | ||||
| 	if (density.getVersion() == isocellVersion && isocellIsolevel == isolevel) | ||||
| 	return; | ||||
| 	isocell.clear(); | ||||
| 	isocell.reserve(isocells * isocells * isocells); | ||||
| 	isocell.resize(isocells * isocells * isocells); | ||||
|  | ||||
| 	float step = 1. / isocells; | ||||
| 	const float lowerIso = isolevel * 0.7; | ||||
| 	const float upperIso = isolevel * 1.3; | ||||
| 	const float step = 1. / isocells; | ||||
| #pragma omp parallel for | ||||
| 	for (size_t ix = 0; ix < isocells; ix++) { | ||||
| 		float xmin = ix * step; | ||||
| 		float xmax = xmin + step; | ||||
| @@ -41,10 +43,10 @@ void Polygonizer::updateIsocell() { | ||||
| 			float Xyz = density(vec3(xmax, ymin, 0)); | ||||
| 			float xYz = density(vec3(xmin, ymax, 0)); | ||||
| 			float XYz = density(vec3(xmax, ymax, 0)); | ||||
| 			bool zAllUnder = (xyz < isolevel) && (Xyz < isolevel) | ||||
| 					&& (xYz < isolevel) && (XYz < isolevel); | ||||
| 			bool zAllOver = (xyz > isolevel) && (Xyz > isolevel) | ||||
| 					&& (xYz > isolevel) && (XYz > isolevel); | ||||
| 			bool zAllUnder = (xyz < lowerIso) && (Xyz < lowerIso) | ||||
| 			&& (xYz < lowerIso) && (XYz < lowerIso); | ||||
| 			bool zAllOver = (xyz > upperIso) && (Xyz > upperIso) | ||||
| 			&& (xYz > upperIso) && (XYz > upperIso); | ||||
|  | ||||
| 			for (size_t iz = 0; iz < isocells; iz++) { | ||||
| 				float zmin = iz * step; | ||||
| @@ -54,13 +56,13 @@ void Polygonizer::updateIsocell() { | ||||
| 				float XyZ = density(vec3(xmax, ymin, zmax)); | ||||
| 				float xYZ = density(vec3(xmin, ymax, zmax)); | ||||
| 				float XYZ = density(vec3(xmax, ymax, zmax)); | ||||
| 				bool ZAllUnder = (xyZ < isolevel) && (XyZ < isolevel) | ||||
| 						&& (xYZ < isolevel) && (XYZ < isolevel); | ||||
| 				bool ZAllOver = (xyZ > isolevel) && (XyZ > isolevel) | ||||
| 						&& (xYZ > isolevel) && (XYZ > isolevel); | ||||
| 				bool ZAllUnder = (xyZ < lowerIso) && (XyZ < lowerIso) | ||||
| 				&& (xYZ < lowerIso) && (XYZ < lowerIso); | ||||
| 				bool ZAllOver = (xyZ > upperIso) && (XyZ > upperIso) | ||||
| 				&& (xYZ > upperIso) && (XYZ > upperIso); | ||||
|  | ||||
| 				isocell[ix * isocells * isocells + iy * isocells + iz] = | ||||
| 						(zAllUnder && ZAllUnder) || (zAllOver && ZAllOver); | ||||
| 				!((zAllUnder && ZAllUnder) || (zAllOver && ZAllOver)); | ||||
|  | ||||
| 				xyz = xyZ; | ||||
| 				Xyz = XyZ; | ||||
| @@ -71,19 +73,25 @@ void Polygonizer::updateIsocell() { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	size_t n = 0; | ||||
| 	for(size_t i = 0; i < isocell.size(); i++) | ||||
| 	if(isocell[i]) n++; | ||||
| 	printf("%lu / %lu", n, isocell.size()); | ||||
| 	isocellVersion = density.getVersion(); | ||||
| 	isocellIsolevel = isolevel; | ||||
| } | ||||
|  | ||||
| void Polygonizer::polygonize(const glm::vec3 lower, const glm::vec3 upper, | ||||
| void Polygonizer::polygonize(const vec3 &lower, const vec3 &upper, | ||||
| 		float resolution) { | ||||
|  | ||||
| 	size_t nSteps = 1.f / resolution - 1; | ||||
| 	size_t nT = 0; | ||||
| 	for (size_t ix = 0; ix < nSteps; ix++) { | ||||
| 	vec3 l = round(lower * vec3(1.f / resolution)); | ||||
| 	vec3 u = round(upper * vec3(1.f / resolution)); | ||||
| 	for (size_t ix = l.x; ix < u.x; ix++) { | ||||
| 		double x = (double(ix) + 0.5) * resolution; | ||||
| 		for (size_t iy = 0; iy < nSteps; iy++) { | ||||
| 		for (size_t iy = l.y; iy < u.y; iy++) { | ||||
| 			double y = (double(iy) + 0.5) * resolution; | ||||
| 			for (size_t iz = 0; iz < nSteps; iz++) { | ||||
| 			for (size_t iz = l.z; iz < u.z; iz++) { | ||||
| 				double z = (double(iz) + 0.5) * resolution; | ||||
|  | ||||
| 				GRIDCELL gridCell; | ||||
| @@ -103,7 +111,6 @@ void Polygonizer::polygonize(const glm::vec3 lower, const glm::vec3 upper, | ||||
|  | ||||
| 				TRIANGLE tris[6]; | ||||
| 				int nTris = Polygonise(gridCell, isolevel, tris); | ||||
| 				nT += nTris; | ||||
| 				for (int iTri = 0; iTri < nTris; iTri++) { | ||||
| 					vec3 *ps = tris[iTri].p; | ||||
|  | ||||
| @@ -111,13 +118,13 @@ void Polygonizer::polygonize(const glm::vec3 lower, const glm::vec3 upper, | ||||
| 					if (all(epsilonEqual(ps[0], ps[1], 1e-8f)) | ||||
| 							|| all(epsilonEqual(ps[0], ps[2], 1e-8f)) | ||||
| 							|| all(epsilonEqual(ps[2], ps[1], 1e-8f))) | ||||
| 						continue; | ||||
| 					continue; | ||||
|  | ||||
| 					glm::uvec3 idc; | ||||
| 					uvec3 idc; | ||||
| 					for (size_t k = 0; k < 3; k++) { | ||||
| 						glm::vec3 &p = tris[iTri].p[k]; | ||||
| 						std::map<glm::vec3, int>::iterator vit = | ||||
| 								vertexLookup.find(p); | ||||
| 						vec3 &p = tris[iTri].p[k]; | ||||
| 						std::map<vec3, int>::iterator vit = vertexLookup.find( | ||||
| 								p); | ||||
| 						if (vit != vertexLookup.end()) { | ||||
| 							idc[k] = vit->second; | ||||
| 						} else { | ||||
| @@ -138,36 +145,116 @@ void Polygonizer::polygonize(float resolution) { | ||||
| 	vertices.clear(); | ||||
| 	indices.clear(); | ||||
|  | ||||
| // coarse scan | ||||
| 	float coarseResolution = resolution * 10; | ||||
| 	const float isocellSize = 1.f / isocells; | ||||
| 	if (resolution < isocellSize) { | ||||
| 		updateIsocell(); | ||||
|  | ||||
| 	size_t nSteps = 1.f / resolution - 1; | ||||
| 	size_t nT = 0; | ||||
| 	for (size_t ix = 0; ix < nSteps; ix++) { | ||||
| 		double x = (double(ix) + 0.5) * resolution; | ||||
| 		for (size_t iy = 0; iy < nSteps; iy++) { | ||||
| 			double y = (double(iy) + 0.5) * resolution; | ||||
| 			for (size_t iz = 0; iz < nSteps; iz++) { | ||||
| 				double z = (double(iz) + 0.5) * resolution; | ||||
| 		vec3 lower, upper; | ||||
| 		for (size_t ix = 0; ix < isocells - 1; ix++) { | ||||
| 			lower.x = double(ix) * isocellSize; | ||||
| 			upper.x = lower.x + isocellSize; | ||||
| 			for (size_t iy = 0; iy < isocells - 1; iy++) { | ||||
| 				lower.y = (double(iy) + 0.5) * isocellSize; | ||||
| 				upper.y = lower.y + isocellSize; | ||||
| 				for (size_t iz = 0; iz < isocells - 1; iz++) { | ||||
| 					if (!isocell[ix * isocells * isocells + iy * isocells + iz]) | ||||
| 					continue; | ||||
| 					lower.z = (double(iz) + 0.5) * isocellSize; | ||||
| 					upper.z = lower.z + isocellSize; | ||||
|  | ||||
| 				GRIDCELL gridCell; | ||||
| 				gridCell.p[0] = vec3(x, y, z); | ||||
| 				gridCell.p[1] = vec3(x + resolution, y, z); | ||||
| 				gridCell.p[2] = vec3(x + resolution, y + resolution, z); | ||||
| 				gridCell.p[3] = vec3(x, y + resolution, z); | ||||
| 				gridCell.p[4] = vec3(x, y, z + resolution); | ||||
| 				gridCell.p[5] = vec3(x + resolution, y, z + resolution); | ||||
| 				gridCell.p[6] = vec3(x + resolution, y + resolution, | ||||
| 						z + resolution); | ||||
| 				gridCell.p[7] = vec3(x, y + resolution, z + resolution); | ||||
|  | ||||
| 				for (size_t iCell = 0; iCell < 8; iCell++) { | ||||
| 					gridCell.val[iCell] = density(gridCell.p[iCell]); | ||||
| 					polygonize(lower, upper, resolution); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		polygonize(vec3(0.f), vec3(1.0f), resolution); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #else | ||||
| void Polygonizer::calculateLayer(std::vector<float> &layer, float resolution, | ||||
| 		size_t nSamples, float z) { | ||||
| #pragma omp parallel for | ||||
| 	for (size_t iy = 0; iy < nSamples; iy++) { | ||||
| 		float y = iy * resolution; | ||||
| 		size_t offset = iy * nSamples; | ||||
| 		for (size_t ix = 0; ix < nSamples; ix++) { | ||||
| 			float x = ix * resolution; | ||||
| 			layer[offset + ix] = density(glm::vec3(x, y, z)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) { | ||||
| 	vertexLookup.clear(); | ||||
| 	vertices.clear(); | ||||
| 	indices.clear(); | ||||
|  | ||||
| 	vertices.reserve(pow(1. / resolution, 2) * 8); | ||||
| 	indices.reserve(pow(1. / resolution, 2) * 8); | ||||
| 	size_t nSteps = 1.f / resolution; | ||||
| 	size_t nSamples = nSteps + 1; | ||||
|  | ||||
| 	// precalculate 2 layers | ||||
| 	std::vector<float> layers[2]; | ||||
| 	layers[0].resize(nSamples * nSamples); | ||||
| 	layers[1].resize(nSamples * nSamples); | ||||
|  | ||||
| 	calculateLayer(layers[0], resolution, nSamples, 0.0); | ||||
|  | ||||
| 	progress.begin("Polygonize", nSteps); | ||||
|  | ||||
| 	for (size_t iz = 0; iz < nSteps; iz++) { | ||||
| 		std::vector<float> &zLayer = layers[iz % 2]; | ||||
| 		std::vector<float> &ZLayer = layers[(iz + 1) % 2]; | ||||
| 		float z = iz * resolution; | ||||
| 		float Z = z + resolution; | ||||
| 		calculateLayer(ZLayer, resolution, nSamples, Z); | ||||
|  | ||||
| 		if (!progress.advance()) | ||||
| 			break; | ||||
|  | ||||
| 		for (size_t iy = 0; iy < nSteps; iy++) { | ||||
| 			float y = iy * resolution; | ||||
| 			float Y = y + resolution; | ||||
| 			size_t yOffset = iy * nSamples; | ||||
| 			size_t YOffset = yOffset + nSamples; | ||||
|  | ||||
| 			GRIDCELL gridCell; | ||||
| 			gridCell.p[0] = vec3(0, y, z); | ||||
| 			gridCell.p[1] = vec3(0, y, z); | ||||
| 			gridCell.p[2] = vec3(0, Y, z); | ||||
| 			gridCell.p[3] = vec3(0, Y, z); | ||||
| 			gridCell.p[4] = vec3(0, y, Z); | ||||
| 			gridCell.p[5] = vec3(0, y, Z); | ||||
| 			gridCell.p[6] = vec3(0, Y, Z); | ||||
| 			gridCell.p[7] = vec3(0, Y, Z); | ||||
|  | ||||
| 			for (size_t ix = 0; ix < nSteps; ix++) { | ||||
| 				float x = ix * resolution; | ||||
| 				float X = x + resolution; | ||||
|  | ||||
| 				gridCell.p[0].x = x; | ||||
| 				gridCell.p[1].x = X; | ||||
| 				gridCell.p[2].x = X; | ||||
| 				gridCell.p[3].x = x; | ||||
| 				gridCell.p[4].x = x; | ||||
| 				gridCell.p[5].x = X; | ||||
| 				gridCell.p[6].x = X; | ||||
| 				gridCell.p[7].x = x; | ||||
|  | ||||
| 				gridCell.val[0] = zLayer[yOffset + ix]; | ||||
| 				gridCell.val[1] = zLayer[yOffset + ix + 1]; | ||||
| 				gridCell.val[2] = zLayer[YOffset + ix + 1]; | ||||
| 				gridCell.val[3] = zLayer[YOffset + ix]; | ||||
|  | ||||
| 				gridCell.val[4] = ZLayer[yOffset + ix]; | ||||
| 				gridCell.val[5] = ZLayer[yOffset + ix + 1]; | ||||
| 				gridCell.val[6] = ZLayer[YOffset + ix + 1]; | ||||
| 				gridCell.val[7] = ZLayer[YOffset + ix]; | ||||
|  | ||||
| 				TRIANGLE tris[6]; | ||||
| 				int nTris = Polygonise(gridCell, isolevel, tris); | ||||
| 				nT += nTris; | ||||
| 				for (int iTri = 0; iTri < nTris; iTri++) { | ||||
| 					vec3 *ps = tris[iTri].p; | ||||
|  | ||||
| @@ -177,11 +264,11 @@ void Polygonizer::polygonize(float resolution) { | ||||
| 							|| all(epsilonEqual(ps[2], ps[1], 1e-8f))) | ||||
| 						continue; | ||||
|  | ||||
| 					glm::uvec3 idc; | ||||
| 					uvec3 idc; | ||||
| 					for (size_t k = 0; k < 3; k++) { | ||||
| 						glm::vec3 &p = tris[iTri].p[k]; | ||||
| 						std::map<glm::vec3, int>::iterator vit = | ||||
| 								vertexLookup.find(p); | ||||
| 						vec3 &p = tris[iTri].p[k]; | ||||
| 						std::map<vec3, int>::iterator vit = vertexLookup.find( | ||||
| 								p); | ||||
| 						if (vit != vertexLookup.end()) { | ||||
| 							idc[k] = vit->second; | ||||
| 						} else { | ||||
| @@ -197,3 +284,75 @@ void Polygonizer::polygonize(float resolution) { | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| //void Polygonizer::polygonize(float resolution) { | ||||
| //	vertexLookup.clear(); | ||||
| //	vertices.clear(); | ||||
| //	indices.clear(); | ||||
| // | ||||
| //	size_t nSteps = 1.f / resolution; | ||||
| //	size_t nSamples = nSteps + 1; | ||||
| // | ||||
| //	// precalculate 2 layers | ||||
| //	std::vector<float> layers[2]; | ||||
| //	layers[0].resize(nSamples*nSamples); | ||||
| //	layers[1].resize(nSamples*nSamples); | ||||
| // | ||||
| //	calculateLayer(layers[0], resolution, nSamples, 0.0); | ||||
| // | ||||
| //	size_t nT = 0; | ||||
| //	for (size_t ix = 0; ix < nSteps; ix++) { | ||||
| //		double x = (double(ix) + 0.5) * resolution; | ||||
| //		for (size_t iy = 0; iy < nSteps; iy++) { | ||||
| //			double y = (double(iy) + 0.5) * resolution; | ||||
| //			for (size_t iz = 0; iz < nSteps; iz++) { | ||||
| //				double z = (double(iz) + 0.5) * resolution; | ||||
| // | ||||
| //				GRIDCELL gridCell; | ||||
| //				gridCell.p[0] = vec3(x, y, z); | ||||
| //				gridCell.p[1] = vec3(x + resolution, y, z); | ||||
| //				gridCell.p[2] = vec3(x + resolution, y + resolution, z); | ||||
| //				gridCell.p[3] = vec3(x, y + resolution, z); | ||||
| //				gridCell.p[4] = vec3(x, y, z + resolution); | ||||
| //				gridCell.p[5] = vec3(x + resolution, y, z + resolution); | ||||
| //				gridCell.p[6] = vec3(x + resolution, y + resolution, | ||||
| //						z + resolution); | ||||
| //				gridCell.p[7] = vec3(x, y + resolution, z + resolution); | ||||
| // | ||||
| //				for (size_t iCell = 0; iCell < 8; iCell++) { | ||||
| //					gridCell.val[iCell] = density(gridCell.p[iCell]); | ||||
| //				} | ||||
| // | ||||
| //				TRIANGLE tris[6]; | ||||
| //				int nTris = Polygonise(gridCell, isolevel, tris); | ||||
| //				nT += nTris; | ||||
| //				for (int iTri = 0; iTri < nTris; iTri++) { | ||||
| //					vec3 *ps = tris[iTri].p; | ||||
| // | ||||
| //					// skip degenerate vertices | ||||
| //					if (all(epsilonEqual(ps[0], ps[1], 1e-8f)) | ||||
| //							|| all(epsilonEqual(ps[0], ps[2], 1e-8f)) | ||||
| //							|| all(epsilonEqual(ps[2], ps[1], 1e-8f))) | ||||
| //					continue; | ||||
| // | ||||
| //					uvec3 idc; | ||||
| //					for (size_t k = 0; k < 3; k++) { | ||||
| //						vec3 &p = tris[iTri].p[k]; | ||||
| //						std::map<vec3, int>::iterator vit = vertexLookup.find( | ||||
| //								p); | ||||
| //						if (vit != vertexLookup.end()) { | ||||
| //							idc[k] = vit->second; | ||||
| //						} else { | ||||
| //							idc[k] = vertices.size(); | ||||
| //							vertices.push_back(p); | ||||
| //							vertexLookup[p] = idc[k]; | ||||
| //						} | ||||
| //					} | ||||
| //					indices.push_back(idc); | ||||
| //				} | ||||
| //			} | ||||
| //		} | ||||
| //	} | ||||
| // | ||||
| //} | ||||
| #endif | ||||
|   | ||||
| @@ -3,9 +3,9 @@ | ||||
| #include <vector> | ||||
| #include <map> | ||||
|  | ||||
| #include <glm/vec3.hpp> | ||||
|  | ||||
| #include "types.h" | ||||
| #include "Density.h" | ||||
| #include "ProgressMonitor.h" | ||||
|  | ||||
| struct CompareVec3 { | ||||
| 	bool operator()(const glm::vec3 &lhs, const glm::vec3 &rhs) { | ||||
| @@ -36,20 +36,26 @@ struct CompareVec3 { | ||||
| class Polygonizer { | ||||
| 	Density &density; | ||||
| 	float isolevel; | ||||
| public: | ||||
| 	std::vector<glm::vec3> vertices; | ||||
| 	std::vector<glm::uvec3> indices; | ||||
| 	std::map<glm::vec3, int, CompareVec3> vertexLookup; | ||||
|  | ||||
| 	std::vector<bool> isocell; | ||||
| 	size_t isocellVersion; | ||||
| 	float isocellIsolevel; | ||||
|  | ||||
| 	void polygonize(const glm::vec3 &lower, const glm::vec3 &upper, | ||||
| 			float isolevel); | ||||
|  | ||||
| 	void calculateLayer(std::vector<float> &layer, float resolution, size_t nSamples, float z); | ||||
|  | ||||
| public: | ||||
| 	vec3v_t vertices; | ||||
| 	uvec3v_t indices; | ||||
| 	std::map<glm::vec3, int, CompareVec3> vertexLookup; | ||||
|  | ||||
|  | ||||
| 	Polygonizer(Density &density, float isolevel); | ||||
| 	void setIsoLevel(float isolevel); | ||||
|  | ||||
| 	void updateIsocell(); | ||||
|  | ||||
| 	void polygonize(float resolution); | ||||
| 	void polygonize(const glm::vec3 lower, const glm::vec3 upper, | ||||
| 			float isolevel); | ||||
| 	void polygonize(float resolution, ProgressMonitor &progress); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										77
									
								
								src/ProgressMonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/ProgressMonitor.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| class ProgressMonitor { | ||||
| public: | ||||
| 	ProgressMonitor() : | ||||
| 			finished(false), running(false), canceled(false), steps(0), currentStep( | ||||
| 					0) { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	bool begin(std::string task, size_t steps) { | ||||
| 		if (canceled) | ||||
| 			return false; | ||||
| 		this->task = task; | ||||
| 		this->steps = steps; | ||||
| 		this->running = true; | ||||
| 		finished = false; | ||||
| 		currentStep = 0; | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	bool advance(size_t count = 1) { | ||||
| 		currentStep += count; | ||||
| 		return !canceled; | ||||
| 	} | ||||
|  | ||||
| 	size_t getSteps() { | ||||
| 		return steps; | ||||
| 	} | ||||
|  | ||||
| 	size_t getCurrentStep() { | ||||
| 		return currentStep; | ||||
| 	} | ||||
|  | ||||
| 	float getProgress() { | ||||
| 		return float(currentStep) / float(steps); | ||||
| 	} | ||||
|  | ||||
| 	void finish() { | ||||
| 		task = "Finished"; | ||||
| 		currentStep = 0; | ||||
| 		steps = 0; | ||||
| 		running = false; | ||||
| 		finished = true; | ||||
| 		canceled = false; | ||||
| 	} | ||||
|  | ||||
| 	void cancel() { | ||||
| 		canceled = true; | ||||
| 	} | ||||
|  | ||||
| 	std::string &getTask() { | ||||
| 		return task; | ||||
| 	} | ||||
|  | ||||
| 	bool isFinished() { | ||||
| 		return finished; | ||||
| 	} | ||||
|  | ||||
| 	bool isRunning() { | ||||
| 		return running; | ||||
| 	} | ||||
|  | ||||
| 	bool isCanceled() { | ||||
| 		return canceled; | ||||
| 	} | ||||
|  | ||||
| protected: | ||||
| 	bool finished; | ||||
| 	bool running; | ||||
| 	bool canceled; | ||||
| 	std::string task; | ||||
| 	size_t steps; | ||||
| 	size_t currentStep; | ||||
| }; | ||||
							
								
								
									
										105
									
								
								src/Shader.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/Shader.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| #include "Shader.h" | ||||
|  | ||||
| #include <glad/glad.h> | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
| #include <vector> | ||||
|  | ||||
| using namespace std; | ||||
|  | ||||
| GLuint loadProgram(const string &name) { | ||||
|  | ||||
| 	// Create the shaders | ||||
| 	GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); | ||||
| 	GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); | ||||
|  | ||||
| 	// Read the Vertex Shader code from the file | ||||
| 	string VertexShaderCode; | ||||
| 	string vertex_file_path = "shader/" + name + ".vertex.glsl"; | ||||
| 	ifstream VertexShaderStream(vertex_file_path, ios::in); | ||||
| 	if (VertexShaderStream.is_open()) { | ||||
| 		string Line = ""; | ||||
| 		while (getline(VertexShaderStream, Line)) | ||||
| 			VertexShaderCode += "\n" + Line; | ||||
| 		VertexShaderStream.close(); | ||||
| 	} else { | ||||
| 		cout << "Failed to open " << vertex_file_path << endl; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	// Read the Fragment Shader code from the file | ||||
| 	string FragmentShaderCode; | ||||
| 	string fragment_file_path = "shader/" + name + ".fragment.glsl"; | ||||
| 	ifstream FragmentShaderStream(fragment_file_path, ios::in); | ||||
| 	if (FragmentShaderStream.is_open()) { | ||||
| 		string Line = ""; | ||||
| 		while (getline(FragmentShaderStream, Line)) | ||||
| 			FragmentShaderCode += "\n" + Line; | ||||
| 		FragmentShaderStream.close(); | ||||
| 	} else { | ||||
| 		cout << "Failed to open " << vertex_file_path << endl; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	GLint Result = GL_FALSE; | ||||
| 	int InfoLogLength; | ||||
|  | ||||
| 	// Compile Vertex Shader | ||||
| 	cout << "Compiling vertex shader : " << name << endl; | ||||
| 	char const * VertexSourcePointer = VertexShaderCode.c_str(); | ||||
| 	glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); | ||||
| 	glCompileShader(VertexShaderID); | ||||
|  | ||||
| 	// Check Vertex Shader | ||||
| 	glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); | ||||
| 	glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | ||||
| 	if (InfoLogLength > 0) { | ||||
| 		vector<char> VertexShaderErrorMessage(InfoLogLength + 1); | ||||
| 		glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, | ||||
| 				&VertexShaderErrorMessage[0]); | ||||
| 		printf("%s\n", &VertexShaderErrorMessage[0]); | ||||
| 	} | ||||
|  | ||||
| 	// Compile Fragment Shader | ||||
| 	cout << "Compiling fragment shader : " << name << endl; | ||||
|  | ||||
| 	char const * FragmentSourcePointer = FragmentShaderCode.c_str(); | ||||
| 	glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); | ||||
| 	glCompileShader(FragmentShaderID); | ||||
|  | ||||
| 	// Check Fragment Shader | ||||
| 	glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); | ||||
| 	glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | ||||
| 	if (InfoLogLength > 0) { | ||||
| 		vector<char> FragmentShaderErrorMessage(InfoLogLength + 1); | ||||
| 		glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, | ||||
| 				&FragmentShaderErrorMessage[0]); | ||||
| 		printf("%s\n", &FragmentShaderErrorMessage[0]); | ||||
| 	} | ||||
|  | ||||
| 	// Link the program | ||||
| 	cout << "Linking program : " << name << endl; | ||||
|  | ||||
| 	GLuint ProgramID = glCreateProgram(); | ||||
| 	glAttachShader(ProgramID, VertexShaderID); | ||||
| 	glAttachShader(ProgramID, FragmentShaderID); | ||||
| 	glLinkProgram(ProgramID); | ||||
|  | ||||
| 	// Check the program | ||||
| 	glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); | ||||
| 	glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); | ||||
| 	if (InfoLogLength > 0) { | ||||
| 		vector<char> ProgramErrorMessage(InfoLogLength + 1); | ||||
| 		glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, | ||||
| 				&ProgramErrorMessage[0]); | ||||
| 		printf("%s\n", &ProgramErrorMessage[0]); | ||||
| 	} | ||||
|  | ||||
| 	glDetachShader(ProgramID, VertexShaderID); | ||||
| 	glDetachShader(ProgramID, FragmentShaderID); | ||||
|  | ||||
| 	glDeleteShader(VertexShaderID); | ||||
| 	glDeleteShader(FragmentShaderID); | ||||
|  | ||||
| 	return ProgramID; | ||||
| } | ||||
							
								
								
									
										5
									
								
								src/Shader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/Shader.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| unsigned int loadProgram(const std::string &name); | ||||
							
								
								
									
										78
									
								
								src/SkyBox.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/SkyBox.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| #include "SkyBox.h" | ||||
| #include "Shader.h" | ||||
|  | ||||
| #include <glad/glad.h> | ||||
| #include <stb_image.h> | ||||
|  | ||||
| using namespace std; | ||||
|  | ||||
| SkyBox::SkyBox() { | ||||
| 	glGenTextures(1, &textureId); | ||||
| } | ||||
|  | ||||
| SkyBox::~SkyBox() { | ||||
| 	glDeleteTextures(1, &textureId); | ||||
| } | ||||
|  | ||||
| bool SkyBox::Load(const std::string basename) { | ||||
| 	glBindTexture(GL_TEXTURE_CUBE_MAP, textureId); | ||||
|  | ||||
| 	Load(GL_TEXTURE_CUBE_MAP_POSITIVE_X, basename + "_right1.png"); | ||||
| 	Load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, basename + "_left2.png"); | ||||
| 	Load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, basename + "_top3.png"); | ||||
| 	Load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, basename + "_bottom4.png"); | ||||
| 	Load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, basename + "_front5.png"); | ||||
| 	Load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, basename + "_back6.png"); | ||||
|  | ||||
| 	programId = loadProgram("skybox"); | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool SkyBox::Load(GLuint target, const std::string filename) { | ||||
| 	int x, y, comp; | ||||
| 	unsigned char *data = stbi_load(filename.c_str(), &x, &y, &comp, 4); | ||||
|  | ||||
| 	glTexImage2D(target, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | ||||
| 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
| 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, | ||||
| 	GL_CLAMP_TO_EDGE); | ||||
| 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, | ||||
| 	GL_CLAMP_TO_EDGE); | ||||
| 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, | ||||
| 	GL_CLAMP_TO_EDGE); | ||||
|  | ||||
| 	stbi_image_free(data); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void SkyBox::Render() { | ||||
| 	GLint OldCullFaceMode; | ||||
| 	glGetIntegerv(GL_CULL_FACE_MODE, &OldCullFaceMode); | ||||
| 	GLint OldDepthFuncMode; | ||||
| 	glGetIntegerv(GL_DEPTH_FUNC, &OldDepthFuncMode); | ||||
|  | ||||
| 	glCullFace(GL_FRONT); | ||||
| 	glDepthFunc(GL_LEQUAL); | ||||
| /* | ||||
| 	Pipeline p; | ||||
| 	p.Scale(20.0f, 20.0f, 20.0f); | ||||
| 	p.Rotate(0.0f, 0.0f, 0.0f); | ||||
| 	p.WorldPos(m_pCamera->GetPos().x, m_pCamera->GetPos().y, | ||||
| 			m_pCamera->GetPos().z); | ||||
| 	p.SetCamera(m_pCamera->GetPos(), m_pCamera->GetTarget(), | ||||
| 			m_pCamera->GetUp()); | ||||
| 	p.SetPerspectiveProj(m_persProjInfo); | ||||
| 	m_pSkyboxTechnique->SetWVP(p.GetWVPTrans()); | ||||
| 	m_pCubemapTex->Bind(GL_TEXTURE0); | ||||
| 	m_pMesh->Render(); | ||||
| */ | ||||
| 	glCullFace(OldCullFaceMode); | ||||
| 	glDepthFunc(OldDepthFuncMode); | ||||
| } | ||||
|  | ||||
| void SkyBox::Bind(GLenum unit) { | ||||
| 	glActiveTexture(unit); | ||||
| 	glBindTexture(GL_TEXTURE_CUBE_MAP, textureId); | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/SkyBox.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/SkyBox.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <glad/glad.h> | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| class SkyBox { | ||||
| public: | ||||
|  | ||||
| 	SkyBox(); | ||||
|  | ||||
| 	~SkyBox(); | ||||
|  | ||||
| 	bool Load(const std::string basename); | ||||
| 	bool Load(GLuint target, const std::string filename); | ||||
|  | ||||
| 	void Bind(GLenum TextureUnit); | ||||
|  | ||||
| 	void Render(); | ||||
| private: | ||||
|  | ||||
| 	std::string fileNames[6]; | ||||
| 	GLuint textureId, programId; | ||||
| }; | ||||
| @@ -9,8 +9,8 @@ | ||||
| TextureMapper::TextureMapper(Density &density, size_t textureSize) : | ||||
| 		density(density), textureSize(textureSize), albedo( | ||||
| 				textureSize * textureSize), normal(textureSize * textureSize), roughness( | ||||
| 				textureSize * textureSize), darkestColor(0.3, 0.25, 0.2), brightestColor( | ||||
| 				0.9, 0.85, 0.8) { | ||||
| 				textureSize * textureSize), darkestColor(0.3, 0.25, 0.2, 1.0), brightestColor( | ||||
| 				0.9, 0.85, 0.8, 1.0) { | ||||
|  | ||||
| } | ||||
| void TextureMapper::setTextureSize(size_t size) { | ||||
| @@ -35,9 +35,19 @@ void TextureMapper::map(const vec3v_t &inVertices, const vec3v_t &inNormals, | ||||
| 	texcoords.clear(); | ||||
| 	texcoords.reserve(inIndices.size() * 3); | ||||
|  | ||||
| 	// 2 px margin | ||||
| 	size_t marginPixels = 2; | ||||
| 	float margin = marginPixels * texf; | ||||
|  | ||||
| 	std::fill(albedo.begin(), albedo.end(), 255.f * brightestColor); | ||||
| 	std::fill(normal.begin(), normal.end(), ucvec4_t(255, 255, 255, 255)); | ||||
| 	std::fill(roughness.begin(), roughness.end(), 255); | ||||
|  | ||||
| 	int rects = ceil(sqrt(inIndices.size())), rx = 0, ry = 0; | ||||
| 	float rectSize = floor(float(textureSize) / rects) / textureSize; | ||||
| 	for (size_t i = 0; i != inIndices.size(); i++) { | ||||
| 	float rectSizePixel = floor(((float)textureSize - (rects + 1) * marginPixels) / rects); | ||||
| 	float rectSize = rectSizePixel / textureSize; | ||||
| 	printf("Rects: %d, Size: %f", rects, rectSize); | ||||
| 	for (size_t i = 0; i < inIndices.size(); i++) { | ||||
| 		glm::vec3 p[3], n[3]; | ||||
| 		glm::uvec3 idx = inIndices[i]; | ||||
| 		indices.push_back( | ||||
| @@ -62,17 +72,17 @@ void TextureMapper::map(const vec3v_t &inVertices, const vec3v_t &inNormals, | ||||
| 		t[2] -= lower; | ||||
| 		glm::vec3 extent = upper - lower; | ||||
| 		float s = std::max(std::max(extent.x, extent.y), extent.z); | ||||
| 		t[0] *= 0.8 * rectSize / s; | ||||
| 		t[1] *= 0.8 * rectSize / s; | ||||
| 		t[2] *= 0.8 * rectSize / s; | ||||
| 		glm::vec3 off(rx * rectSize, 0, ry * rectSize); | ||||
| 		t[0] *= 0.9 * rectSize / s; | ||||
| 		t[1] *= rectSize / s; | ||||
| 		t[2] *= rectSize / s; | ||||
| 		glm::vec3 off(margin + rx * (rectSize + margin), 0, margin + ry * (rectSize + margin)); | ||||
| 		t[0] += off; | ||||
| 		t[1] += off; | ||||
| 		t[2] += off; | ||||
| 		texcoords.push_back(glm::vec2(t[0].x, t[0].z)); | ||||
| 		texcoords.push_back(glm::vec2(t[1].x, t[1].z)); | ||||
| 		texcoords.push_back(glm::vec2(t[2].x, t[2].z)); | ||||
|  | ||||
| #if 0 | ||||
| 		//if (rx == 0 && ry == 0) { | ||||
| 		t[0].y = 0; | ||||
| 		t[1].y = 0; | ||||
| @@ -111,16 +121,22 @@ void TextureMapper::map(const vec3v_t &inVertices, const vec3v_t &inNormals, | ||||
| 		glm::mat3 faceBase = glm::mat3(db, glm::cross(db, dc), dc); | ||||
| 		glm::mat3 ifaceBase = glm::inverse(faceBase); | ||||
|  | ||||
| 		glm::vec3 tmin = max( | ||||
| 				floor( | ||||
| 						min(min(t[0], t[1]), t[2]) | ||||
| 								* glm::vec3((float) textureSize)) | ||||
| 						- glm::vec3(1.0f), glm::vec3(0.1)); | ||||
| 		glm::vec3 tmax = min( | ||||
| 				ceil( | ||||
| 						max(max(t[0], t[1]), t[2]) | ||||
| 								* glm::vec3((float) textureSize)) | ||||
| 						+ glm::vec3(1.0f), glm::vec3(textureSize-1)); | ||||
| 		glm::vec3 tmin = min(min(t[0], t[1]), t[2]); | ||||
| 		tmin = tmin * glm::vec3((float) textureSize); | ||||
| 		tmin = floor(tmin) - glm::vec3(2.0f); | ||||
| 		//tmin = tmin - glm::vec3(1.0f); | ||||
| 		tmin = max(tmin, glm::vec3(0.1)); | ||||
|  | ||||
| //		glm::vec3 tmax = min( | ||||
| //				ceil( | ||||
| //						max(max(t[0], t[1]), t[2]) | ||||
| //								* glm::vec3((float) textureSize)) | ||||
| //						+ glm::vec3(1.0f), glm::vec3(textureSize - 1)); | ||||
|  | ||||
| 		glm::vec3 tmax = max(max(t[0], t[1]), t[2]); | ||||
| 		tmax = tmax * glm::vec3((float) textureSize); | ||||
| 		tmax = ceil(tmax) + glm::vec3(2.0f); | ||||
| 		tmax = min(tmax, glm::vec3(textureSize)); | ||||
|  | ||||
| 		// TODO: borders! | ||||
| 		for (int ix = tmin.x; ix < tmax.x; ix++) { | ||||
| @@ -166,9 +182,9 @@ void TextureMapper::map(const vec3v_t &inVertices, const vec3v_t &inNormals, | ||||
| //				diff[ix + iy * ntex][2] = 0; //(0.5 + sp.z) * 255; | ||||
|  | ||||
| //				float rd = 1.f; //0.7 + 0.3 * length(r) * rects; | ||||
| //				albedo[ix + iy * textureSize][0] = rd * (0.5 + sp.x) * 255; | ||||
| //				albedo[ix + iy * textureSize][1] = rd * (0.5 + sp.y) * 255; | ||||
| //				albedo[ix + iy * textureSize][2] = rd * (0.5 + sp.z) * 255; | ||||
| //				albedo[ix + (textureSize - iy) * textureSize][0] = rd * (sp.x) * 255; | ||||
| //				albedo[ix + (textureSize - iy) * textureSize][1] = rd * (sp.y) * 255; | ||||
| //				albedo[ix + (textureSize - iy) * textureSize][2] = rd * (sp.z) * 255; | ||||
|  | ||||
| //					albedo[ix + iy * textureSize][0] = length(res) * rects * 255; | ||||
| //					albedo[ix + iy * textureSize][1] = length(res) * rects * 255; | ||||
| @@ -190,7 +206,7 @@ void TextureMapper::map(const vec3v_t &inVertices, const vec3v_t &inNormals, | ||||
| 			rx = 0; | ||||
| 			ry++; | ||||
| 		} | ||||
|  | ||||
| #endif | ||||
| 	} | ||||
| // | ||||
| //	for (int ix = 0; ix < ntex; ix++) { | ||||
|   | ||||
| @@ -1,19 +1,12 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "Density.h" | ||||
|  | ||||
| #include <vector> | ||||
| #include <glm/vec3.hpp> | ||||
| #include "types.h" | ||||
|  | ||||
| class TextureMapper { | ||||
| 	size_t textureSize; | ||||
|  | ||||
| public: | ||||
| 	typedef std::vector< glm::tvec3<uint8_t> > texture3_t; | ||||
| 	typedef std::vector<uint8_t> texture1_t; | ||||
| 	typedef std::vector<glm::vec3> vec3v_t; | ||||
| 	typedef std::vector<glm::vec2> vec2v_t; | ||||
| 	typedef std::vector<glm::uvec3> uvec3v_t; | ||||
|  | ||||
| 	Density &density; | ||||
|  | ||||
| @@ -27,7 +20,7 @@ public: | ||||
| 	vec2v_t texcoords; | ||||
| 	uvec3v_t indices; | ||||
|  | ||||
| 	glm::vec3 darkestColor, brightestColor; | ||||
| 	glm::vec4 darkestColor, brightestColor; | ||||
|  | ||||
| 	TextureMapper(Density &density, size_t textureSize); | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| #include "Application.h" | ||||
|  | ||||
| int main(void) { | ||||
|  | ||||
| 	srand(time(0)); | ||||
| 	Application::instance().run(); | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										15
									
								
								src/types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/types.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "AlignedAllocator.h" | ||||
| #include <glm/vec4.hpp> | ||||
| #include <glm/vec3.hpp> | ||||
| #include <vector> | ||||
|  | ||||
| typedef glm::tvec4<uint8_t> ucvec4_t; | ||||
| typedef std::vector<ucvec4_t, AlignedAllocator<ucvec4_t> > texture3_t; | ||||
| typedef std::vector<uint8_t, AlignedAllocator<uint8_t>> texture1_t; | ||||
| typedef std::vector<glm::vec3, AlignedAllocator<glm::vec3> > vec3v_t; | ||||
| typedef std::vector<glm::vec2, AlignedAllocator<glm::vec2> > vec2v_t; | ||||
| typedef std::vector<glm::uvec3, AlignedAllocator<glm::uvec3> > uvec3v_t; | ||||
| typedef std::vector<glm::uvec4, AlignedAllocator<glm::uvec4> > uvec4v_t; | ||||
| typedef std::vector<uint32_t> uintv_t; | ||||
							
								
								
									
										428
									
								
								vendor/MarchingCube.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										428
									
								
								vendor/MarchingCube.h
									
									
									
									
										vendored
									
									
								
							| @@ -1,428 +0,0 @@ | ||||
| /* | ||||
|  * MarchingCube.h | ||||
|  * | ||||
|  *  Created on: 19.10.2017 | ||||
|  *      Author: gmueller | ||||
|  */ | ||||
|  | ||||
| #ifndef MARCHINGCUBE_H_ | ||||
| #define MARCHINGCUBE_H_ | ||||
|  | ||||
| #include <glm/vec3.hpp> | ||||
| #include <iostream> | ||||
|  | ||||
| using glm::vec3; | ||||
|  | ||||
| typedef glm::vec3 XYZ; | ||||
|  | ||||
| struct TRIANGLE { | ||||
| 	XYZ p[3]; | ||||
| }; | ||||
|  | ||||
| struct GRIDCELL { | ||||
| 	XYZ p[8]; | ||||
| 	double val[8]; | ||||
| } ; | ||||
|  | ||||
| /* | ||||
|  Linearly interpolate the position where an isosurface cuts | ||||
|  an edge between two vertices, each with their own scalar value | ||||
|  */ | ||||
| XYZ VertexInterp(double isolevel, XYZ p1, XYZ p2, double valp1, double valp2) { | ||||
| 	double mu; | ||||
| 	XYZ p; | ||||
|  | ||||
| 	if (fabs(isolevel - valp1) < 0.00001) | ||||
| 		return (p1); | ||||
| 	if (fabs(isolevel - valp2) < 0.00001) | ||||
| 		return (p2); | ||||
| 	if (fabs(valp1 - valp2) < 0.00001) | ||||
| 		return (p1); | ||||
|  | ||||
| 	mu = (isolevel - valp1) / (valp2 - valp1); | ||||
| 	p.x = p1.x + mu * (p2.x - p1.x); | ||||
| 	p.y = p1.y + mu * (p2.y - p1.y); | ||||
| 	p.z = p1.z + mu * (p2.z - p1.z); | ||||
|  | ||||
| 	return (p); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  Given a grid cell and an isolevel, calculate the triangular | ||||
|  facets required to represent the isosurface through the cell. | ||||
|  Return the number of triangular facets, the array "triangles" | ||||
|  will be loaded up with the vertices at most 5 triangular facets. | ||||
|  0 will be returned if the grid cell is either totally above | ||||
|  of totally below the isolevel. | ||||
|  */ | ||||
| int Polygonise(GRIDCELL &grid, double isolevel, TRIANGLE *triangles) { | ||||
| 	int i, ntriang; | ||||
| 	int cubeindex; | ||||
| 	XYZ vertlist[12]; | ||||
|  | ||||
| 	int edgeTable[256] = { 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, | ||||
| 			0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, 0x190, 0x99, | ||||
| 			0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, | ||||
| 			0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, 0x230, 0x339, 0x33, 0x13a, 0x636, | ||||
| 			0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, | ||||
| 			0xc39, 0xd30, 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac, | ||||
| 			0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, 0x460, | ||||
| 			0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, | ||||
| 			0xf66, 0x86a, 0x963, 0xa69, 0xb60, 0x5f0, 0x4f9, 0x7f3, 0x6fa, | ||||
| 			0x1f6, 0xff, 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, | ||||
| 			0xbf9, 0xaf0, 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c, | ||||
| 			0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, 0x7c0, | ||||
| 			0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc, 0xfcc, 0xec5, 0xdcf, | ||||
| 			0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, 0x8c0, 0x9c9, 0xac3, 0xbca, | ||||
| 			0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, | ||||
| 			0x6c9, 0x7c0, 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, | ||||
| 			0xe5c, 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, 0xaf0, | ||||
| 			0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff, | ||||
| 			0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, 0xb60, 0xa69, 0x963, 0x86a, | ||||
| 			0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, | ||||
| 			0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, | ||||
| 			0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0, 0xd30, | ||||
| 			0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, | ||||
| 			0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230, 0xe90, 0xf99, 0xc93, 0xd9a, | ||||
| 			0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, | ||||
| 			0x393, 0x99, 0x190, 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, | ||||
| 			0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 }; | ||||
| 	int triTable[256][16] = { | ||||
| 			{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 1,					2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 9,					2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{					2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 1,					9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{					1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{					0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 9,					8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
|  | ||||
| 			{ | ||||
| 					4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, | ||||
| 					1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, { 1, | ||||
| 					2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, { 8, | ||||
| 					4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 }, { | ||||
| 					3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 }, { 4, 7, | ||||
| 					8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, { 4, 7, | ||||
| 					11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, { 9, | ||||
| 					5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, | ||||
| 					5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, { 5, 2, | ||||
| 					10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, { 2, 10, | ||||
| 					5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, { 9, 5, 4, | ||||
| 					2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 11, | ||||
| 					2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, { 0, 5, | ||||
| 					4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, { 2, 1, | ||||
| 					5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 }, { 10, 3, | ||||
| 					11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, { 4, 9, | ||||
| 					5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 }, { 5, 4, | ||||
| 					0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, { 5, 4, | ||||
| 					8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, { 9, | ||||
| 					7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, { 10, 1, | ||||
| 					2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, { 8, 0, 2, | ||||
| 					8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, { 2, 10, 5, 2, | ||||
| 					5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, { 7, 9, 5, 7, | ||||
| 					8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 7, 9, | ||||
| 					7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, { 2, 3, 11, 0, 1, | ||||
| 					8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, { 11, 2, 1, 11, 1, 7, | ||||
| 					7, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 8, 8, 5, 7, | ||||
| 					10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, { 5, 7, 0, 5, 0, 9, | ||||
| 					7, 11, 0, 1, 0, 10, 11, 10, 0, -1 }, { 11, 10, 0, 11, 0, 3, | ||||
| 					10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, { 11, 10, 5, 7, 11, 5, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 10, 6, 5, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 5, | ||||
| 					10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 9, 0, 1, | ||||
| 					5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 8, | ||||
| 					3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, { 1, 6, | ||||
| 					5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, | ||||
| 					6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 }, { 9, | ||||
| 					6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, { 5, | ||||
| 					9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, { 2, 3, | ||||
| 					11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, { 5, | ||||
| 					10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, { 6, | ||||
| 					3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, { 0, | ||||
| 					8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, { 3, | ||||
| 					11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, { 6, 5, | ||||
| 					9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, { 5, | ||||
| 					10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, { 6, | ||||
| 					1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, { 1, | ||||
| 					2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, { 8, 4, | ||||
| 					7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, { 7, 3, 9, | ||||
| 					7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 }, { 3, 11, 2, 7, 8, | ||||
| 					4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, { 5, 10, 6, 4, 7, | ||||
| 					2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, { 0, 1, 9, 4, 7, 8, | ||||
| 					2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, { 9, 2, 1, 9, 11, 2, | ||||
| 					9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, { 8, 4, 7, 3, 11, 5, 3, | ||||
| 					5, 1, 5, 11, 6, -1, -1, -1, -1 }, { 5, 1, 11, 5, 11, 6, 1, | ||||
| 					0, 11, 7, 11, 4, 0, 4, 11, -1 }, { 0, 5, 9, 0, 6, 5, 0, 3, | ||||
| 					6, 11, 6, 3, 8, 4, 7, -1 }, { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, | ||||
| 					11, 9, -1, -1, -1, -1 }, { 10, 4, 9, 6, 4, 10, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1 }, { 4, 10, 6, 4, 9, 10, 0, 8, 3, | ||||
| 					-1, -1, -1, -1, -1, -1, -1 }, { 10, 0, 1, 10, 6, 0, 6, 4, 0, | ||||
| 					-1, -1, -1, -1, -1, -1, -1 }, { 8, 3, 1, 8, 1, 6, 8, 6, 4, | ||||
| 					6, 1, 10, -1, -1, -1, -1 }, { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, | ||||
| 					4, -1, -1, -1, -1 }, { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, | ||||
| 					10, 6, -1, -1, -1, -1 }, { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, | ||||
| 					10, -1, -1, -1, -1 }, { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, | ||||
| 					11, 8, 11, 1, -1 }, { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, | ||||
| 					-1, -1, -1, -1 }, { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, | ||||
| 					4, 1, -1 }, { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, | ||||
| 					-1, -1, -1 }, { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1 }, { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, | ||||
| 					10, -1, -1, -1, -1 }, { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, | ||||
| 					0, -1, -1, -1, -1 }, { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, | ||||
| 					-1, -1, -1, -1 }, { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, | ||||
| 					3, 9, -1 }, { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, | ||||
| 					-1, -1 }, { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1 }, { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, | ||||
| 					-1, -1, -1 }, { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, | ||||
| 					7, -1 }, { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, | ||||
| 					-1 }, { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, | ||||
| 					-1 }, { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, | ||||
| 			{ 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 7, | ||||
| 					8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, { 7, | ||||
| 					11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, | ||||
| 					1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, { 10, | ||||
| 					1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 }, { | ||||
| 					7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, { 2, 7, | ||||
| 					6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, { 1, 6, | ||||
| 					2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, { 10, 7, 6, | ||||
| 					10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, { 10, 7, 6, | ||||
| 					1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, { 0, 3, 7, 0, | ||||
| 					7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, { 7, 6, 10, 7, | ||||
| 					10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, { 6, 8, 4, | ||||
| 					11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 6, | ||||
| 					11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, { 8, 6, | ||||
| 					11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, { 9, 4, | ||||
| 					6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 }, { 6, 8, 4, | ||||
| 					6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, | ||||
| 					10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 }, { 4, 11, | ||||
| 					8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, { 10, 9, | ||||
| 					3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, { 8, 2, 3, 8, | ||||
| 					4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, { 0, 4, 2, 4, | ||||
| 					6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 9, 0, | ||||
| 					2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, { 1, 9, 4, 1, | ||||
| 					4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, { 8, 1, 3, 8, | ||||
| 					6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, { 10, 1, 0, 10, | ||||
| 					0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, { 4, 6, 3, 4, | ||||
| 					3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, { 10, 9, 4, 6, 10, | ||||
| 					4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 9, 5, 7, | ||||
| 					6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, | ||||
| 					4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, { 5, 0, 1, | ||||
| 					5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, { 11, 7, 6, | ||||
| 					8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 }, { 9, 5, 4, 10, | ||||
| 					1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, { 6, 11, 7, 1, | ||||
| 					2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, { 7, 6, 11, 5, 4, | ||||
| 					10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, { 3, 4, 8, 3, 5, 4, | ||||
| 					3, 2, 5, 10, 5, 2, 11, 7, 6, -1 }, { 7, 2, 3, 7, 6, 2, 5, 4, | ||||
| 					9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 4, 0, 8, 6, 0, 6, | ||||
| 					2, 6, 8, 7, -1, -1, -1, -1 }, { 3, 6, 2, 3, 7, 6, 1, 5, 0, | ||||
| 					5, 4, 0, -1, -1, -1, -1 }, { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, | ||||
| 					8, 5, 1, 5, 8, -1 }, { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, | ||||
| 					-1, -1, -1, -1 }, { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, | ||||
| 					5, 4, -1 }, { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, | ||||
| 					10, -1 }, { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, | ||||
| 					-1, -1 }, { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, | ||||
| 					-1, -1 }, { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, | ||||
| 					-1 }, { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, | ||||
| 					-1 }, { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, | ||||
| 					-1 }, { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, | ||||
| 					-1 }, | ||||
| 			{ 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 }, { 11, 8, 5, | ||||
| 					11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, { 6, 11, 3, 6, | ||||
| 					3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, { 5, 8, 9, 5, 2, | ||||
| 					8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, { 9, 5, 6, 9, 6, 0, | ||||
| 					0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, { 1, 5, 8, 1, 8, 0, | ||||
| 					5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, { 1, 5, 6, 2, 1, 6, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 3, 6, 1, 6, 10, 3, 8, | ||||
| 					6, 5, 6, 9, 8, 9, 6, -1 }, { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, | ||||
| 					6, 0, -1, -1, -1, -1 }, { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 10, 5, 6, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1 }, { 11, 5, 10, 7, 5, 11, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 11, 5, 10, 11, 7, 5, | ||||
| 					8, 3, 0, -1, -1, -1, -1, -1, -1, -1 }, { 5, 11, 7, 5, 10, | ||||
| 					11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, { 10, 7, 5, 10, | ||||
| 					11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 }, { 11, 1, 2, 11, | ||||
| 					7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 1, | ||||
| 					2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, { 9, 7, 5, 9, 2, | ||||
| 					7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, { 7, 5, 2, 7, 2, 11, | ||||
| 					5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, { 2, 5, 10, 2, 3, 5, 3, 7, | ||||
| 					5, -1, -1, -1, -1, -1, -1, -1 }, { 8, 2, 0, 8, 5, 2, 8, 7, | ||||
| 					5, 10, 2, 5, -1, -1, -1, -1 }, { 9, 0, 1, 5, 10, 3, 5, 3, 7, | ||||
| 					3, 10, 2, -1, -1, -1, -1 }, { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, | ||||
| 					2, 5, 7, 5, 2, -1 }, { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 5, 8, 4, 5, 10, 8, 10, 11, 8, | ||||
| 					-1, -1, -1, -1, -1, -1, -1 }, { 5, 0, 4, 5, 11, 0, 5, 10, | ||||
| 					11, 11, 3, 0, -1, -1, -1, -1 }, { 0, 1, 9, 8, 4, 10, 8, 10, | ||||
| 					11, 10, 4, 5, -1, -1, -1, -1 }, { 10, 11, 4, 10, 4, 5, 11, | ||||
| 					3, 4, 9, 4, 1, 3, 1, 4, -1 }, { 2, 5, 1, 2, 8, 5, 2, 11, 8, | ||||
| 					4, 5, 8, -1, -1, -1, -1 }, { 0, 4, 11, 0, 11, 3, 4, 5, 11, | ||||
| 					2, 11, 1, 5, 1, 11, -1 }, { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, | ||||
| 					5, 8, 11, 8, 5, -1 }, { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, | ||||
| 					8, 4, -1, -1, -1, -1 }, { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, | ||||
| 					5, 8, 0, 1, 9, -1 }, { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, | ||||
| 					-1, -1, -1, -1 }, { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1 }, { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, | ||||
| 					-1, -1, -1, -1 }, { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, | ||||
| 					10, 11, -1, -1, -1, -1 }, { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, | ||||
| 					4, 11, -1, -1, -1, -1 }, { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, | ||||
| 					11, 10, 11, 4, -1 }, { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, | ||||
| 					2, -1, -1, -1, -1 }, { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, | ||||
| 					1, 0, 8, 3, -1 }, { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, | ||||
| 					-1, -1, -1, -1 }, { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, | ||||
| 					-1, -1, -1, -1 }, { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, | ||||
| 					-1, -1, -1 }, { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, | ||||
| 					7, -1 }, { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, | ||||
| 					-1 }, { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 					-1, -1 }, { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, | ||||
| 					-1, -1 }, { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, | ||||
| 					-1 }, { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 					-1, -1 }, { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1 }, { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, | ||||
| 					-1, -1, -1, -1 }, { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, | ||||
| 					-1, -1, -1, -1, -1 }, { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, | ||||
| 					-1, -1, -1, -1, -1, -1 }, { 3, 1, 10, 11, 3, 10, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 11, 1, 11, 9, 9, 11, | ||||
| 					8, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 9, 3, 9, 11, 1, 2, | ||||
| 					9, 2, 11, 9, -1, -1, -1, -1 }, { 0, 2, 11, 8, 0, 11, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 2, 11, -1, -1, -1, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 2, 3, 8, 2, 8, | ||||
| 					10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 10, 2, 0, | ||||
| 					9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 2, 3, 8, | ||||
| 					2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, { 1, 10, 2, | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, | ||||
| 					3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, | ||||
| 			{ 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { | ||||
| 					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||||
| 					-1 } }; | ||||
|  | ||||
| 	/* | ||||
| 	 Determine the index into the edge table which | ||||
| 	 tells us which vertices are inside of the surface | ||||
| 	 */ | ||||
| 	cubeindex = 0; | ||||
| 	if (grid.val[0] < isolevel) | ||||
| 		cubeindex |= 1; | ||||
| 	if (grid.val[1] < isolevel) | ||||
| 		cubeindex |= 2; | ||||
| 	if (grid.val[2] < isolevel) | ||||
| 		cubeindex |= 4; | ||||
| 	if (grid.val[3] < isolevel) | ||||
| 		cubeindex |= 8; | ||||
| 	if (grid.val[4] < isolevel) | ||||
| 		cubeindex |= 16; | ||||
| 	if (grid.val[5] < isolevel) | ||||
| 		cubeindex |= 32; | ||||
| 	if (grid.val[6] < isolevel) | ||||
| 		cubeindex |= 64; | ||||
| 	if (grid.val[7] < isolevel) | ||||
| 		cubeindex |= 128; | ||||
|  | ||||
| 	/* Cube is entirely in/out of the surface */ | ||||
| 	if (edgeTable[cubeindex] == 0) | ||||
| 		return (0); | ||||
|  | ||||
| 	/* Find the vertices where the surface intersects the cube */ | ||||
| 	if (edgeTable[cubeindex] & 1) | ||||
| 		vertlist[0] = VertexInterp(isolevel, grid.p[0], grid.p[1], grid.val[0], | ||||
| 				grid.val[1]); | ||||
| 	if (edgeTable[cubeindex] & 2) | ||||
| 		vertlist[1] = VertexInterp(isolevel, grid.p[1], grid.p[2], grid.val[1], | ||||
| 				grid.val[2]); | ||||
| 	if (edgeTable[cubeindex] & 4) | ||||
| 		vertlist[2] = VertexInterp(isolevel, grid.p[2], grid.p[3], grid.val[2], | ||||
| 				grid.val[3]); | ||||
| 	if (edgeTable[cubeindex] & 8) | ||||
| 		vertlist[3] = VertexInterp(isolevel, grid.p[3], grid.p[0], grid.val[3], | ||||
| 				grid.val[0]); | ||||
| 	if (edgeTable[cubeindex] & 16) | ||||
| 		vertlist[4] = VertexInterp(isolevel, grid.p[4], grid.p[5], grid.val[4], | ||||
| 				grid.val[5]); | ||||
| 	if (edgeTable[cubeindex] & 32) | ||||
| 		vertlist[5] = VertexInterp(isolevel, grid.p[5], grid.p[6], grid.val[5], | ||||
| 				grid.val[6]); | ||||
| 	if (edgeTable[cubeindex] & 64) | ||||
| 		vertlist[6] = VertexInterp(isolevel, grid.p[6], grid.p[7], grid.val[6], | ||||
| 				grid.val[7]); | ||||
| 	if (edgeTable[cubeindex] & 128) | ||||
| 		vertlist[7] = VertexInterp(isolevel, grid.p[7], grid.p[4], grid.val[7], | ||||
| 				grid.val[4]); | ||||
| 	if (edgeTable[cubeindex] & 256) | ||||
| 		vertlist[8] = VertexInterp(isolevel, grid.p[0], grid.p[4], grid.val[0], | ||||
| 				grid.val[4]); | ||||
| 	if (edgeTable[cubeindex] & 512) | ||||
| 		vertlist[9] = VertexInterp(isolevel, grid.p[1], grid.p[5], grid.val[1], | ||||
| 				grid.val[5]); | ||||
| 	if (edgeTable[cubeindex] & 1024) | ||||
| 		vertlist[10] = VertexInterp(isolevel, grid.p[2], grid.p[6], grid.val[2], | ||||
| 				grid.val[6]); | ||||
| 	if (edgeTable[cubeindex] & 2048) | ||||
| 		vertlist[11] = VertexInterp(isolevel, grid.p[3], grid.p[7], grid.val[3], | ||||
| 				grid.val[7]); | ||||
|  | ||||
| 	// std::cout << cubeindex << std::endl; | ||||
|  | ||||
| 	/* Create the triangle */ | ||||
| 	ntriang = 0; | ||||
| 	for (i = 0; triTable[cubeindex][i] != -1; i += 3) { | ||||
| 		triangles[ntriang].p[0] = vertlist[triTable[cubeindex][i]]; | ||||
| 		triangles[ntriang].p[1] = vertlist[triTable[cubeindex][i + 1]]; | ||||
| 		triangles[ntriang].p[2] = vertlist[triTable[cubeindex][i + 2]]; | ||||
| 		ntriang++; | ||||
| 	} | ||||
|  | ||||
| 	return (ntriang); | ||||
| } | ||||
|  | ||||
| #endif /* MARCHINGCUBE_H_ */ | ||||
							
								
								
									
										98
									
								
								vendor/MemoryPool.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								vendor/MemoryPool.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /*- | ||||
|  * Copyright (c) 2013 Cosku Acay, http://www.coskuacay.com | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  * to deal in the Software without restriction, including without limitation | ||||
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons to whom the | ||||
|  * Software is furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #ifndef MEMORY_POOL_H | ||||
| #define MEMORY_POOL_H | ||||
|  | ||||
| #include <climits> | ||||
| #include <cstddef> | ||||
|  | ||||
| template <typename T, size_t BlockSize = 4096> | ||||
| class MemoryPool | ||||
| { | ||||
|   public: | ||||
|     /* Member types */ | ||||
|     typedef T               value_type; | ||||
|     typedef T*              pointer; | ||||
|     typedef T&              reference; | ||||
|     typedef const T*        const_pointer; | ||||
|     typedef const T&        const_reference; | ||||
|     typedef size_t          size_type; | ||||
|     typedef ptrdiff_t       difference_type; | ||||
|     typedef std::false_type propagate_on_container_copy_assignment; | ||||
|     typedef std::true_type  propagate_on_container_move_assignment; | ||||
|     typedef std::true_type  propagate_on_container_swap; | ||||
|  | ||||
|     template <typename U> struct rebind { | ||||
|       typedef MemoryPool<U> other; | ||||
|     }; | ||||
|  | ||||
|     /* Member functions */ | ||||
|     MemoryPool() noexcept; | ||||
|     MemoryPool(const MemoryPool& memoryPool) noexcept; | ||||
|     MemoryPool(MemoryPool&& memoryPool) noexcept; | ||||
|     template <class U> MemoryPool(const MemoryPool<U>& memoryPool) noexcept; | ||||
|  | ||||
|     ~MemoryPool() noexcept; | ||||
|  | ||||
|     MemoryPool& operator=(const MemoryPool& memoryPool) = delete; | ||||
|     MemoryPool& operator=(MemoryPool&& memoryPool) noexcept; | ||||
|  | ||||
|     pointer address(reference x) const noexcept; | ||||
|     const_pointer address(const_reference x) const noexcept; | ||||
|  | ||||
|     // Can only allocate one object at a time. n and hint are ignored | ||||
|     pointer allocate(size_type n = 1, const_pointer hint = 0); | ||||
|     void deallocate(pointer p, size_type n = 1); | ||||
|  | ||||
|     size_type max_size() const noexcept; | ||||
|  | ||||
|     template <class U, class... Args> void construct(U* p, Args&&... args); | ||||
|     template <class U> void destroy(U* p); | ||||
|  | ||||
|     template <class... Args> pointer newElement(Args&&... args); | ||||
|     void deleteElement(pointer p); | ||||
|  | ||||
|   private: | ||||
|     union Slot_ { | ||||
|       value_type element; | ||||
|       Slot_* next; | ||||
|     }; | ||||
|  | ||||
|     typedef char* data_pointer_; | ||||
|     typedef Slot_ slot_type_; | ||||
|     typedef Slot_* slot_pointer_; | ||||
|  | ||||
|     slot_pointer_ currentBlock_; | ||||
|     slot_pointer_ currentSlot_; | ||||
|     slot_pointer_ lastSlot_; | ||||
|     slot_pointer_ freeSlots_; | ||||
|  | ||||
|     size_type padPointer(data_pointer_ p, size_type align) const noexcept; | ||||
|     void allocateBlock(); | ||||
|  | ||||
|     static_assert(BlockSize >= 2 * sizeof(slot_type_), "BlockSize too small."); | ||||
| }; | ||||
|  | ||||
| #include "MemoryPool.tcc" | ||||
|  | ||||
| #endif // MEMORY_POOL_H | ||||
							
								
								
									
										235
									
								
								vendor/MemoryPool.tcc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								vendor/MemoryPool.tcc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,235 @@ | ||||
| /*- | ||||
|  * Copyright (c) 2013 Cosku Acay, http://www.coskuacay.com | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  * to deal in the Software without restriction, including without limitation | ||||
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons to whom the | ||||
|  * Software is furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #ifndef MEMORY_BLOCK_TCC | ||||
| #define MEMORY_BLOCK_TCC | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| inline typename MemoryPool<T, BlockSize>::size_type | ||||
| MemoryPool<T, BlockSize>::padPointer(data_pointer_ p, size_type align) | ||||
| const noexcept | ||||
| { | ||||
|   uintptr_t result = reinterpret_cast<uintptr_t>(p); | ||||
|   return ((align - result) % align); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| MemoryPool<T, BlockSize>::MemoryPool() | ||||
| noexcept | ||||
| { | ||||
|   currentBlock_ = nullptr; | ||||
|   currentSlot_ = nullptr; | ||||
|   lastSlot_ = nullptr; | ||||
|   freeSlots_ = nullptr; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool& memoryPool) | ||||
| noexcept : | ||||
| MemoryPool() | ||||
| {} | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| MemoryPool<T, BlockSize>::MemoryPool(MemoryPool&& memoryPool) | ||||
| noexcept | ||||
| { | ||||
|   currentBlock_ = memoryPool.currentBlock_; | ||||
|   memoryPool.currentBlock_ = nullptr; | ||||
|   currentSlot_ = memoryPool.currentSlot_; | ||||
|   lastSlot_ = memoryPool.lastSlot_; | ||||
|   freeSlots_ = memoryPool.freeSlots; | ||||
| } | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| template<class U> | ||||
| MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool<U>& memoryPool) | ||||
| noexcept : | ||||
| MemoryPool() | ||||
| {} | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| MemoryPool<T, BlockSize>& | ||||
| MemoryPool<T, BlockSize>::operator=(MemoryPool&& memoryPool) | ||||
| noexcept | ||||
| { | ||||
|   if (this != &memoryPool) | ||||
|   { | ||||
|     std::swap(currentBlock_, memoryPool.currentBlock_); | ||||
|     currentSlot_ = memoryPool.currentSlot_; | ||||
|     lastSlot_ = memoryPool.lastSlot_; | ||||
|     freeSlots_ = memoryPool.freeSlots; | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| MemoryPool<T, BlockSize>::~MemoryPool() | ||||
| noexcept | ||||
| { | ||||
|   slot_pointer_ curr = currentBlock_; | ||||
|   while (curr != nullptr) { | ||||
|     slot_pointer_ prev = curr->next; | ||||
|     operator delete(reinterpret_cast<void*>(curr)); | ||||
|     curr = prev; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| inline typename MemoryPool<T, BlockSize>::pointer | ||||
| MemoryPool<T, BlockSize>::address(reference x) | ||||
| const noexcept | ||||
| { | ||||
|   return &x; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| inline typename MemoryPool<T, BlockSize>::const_pointer | ||||
| MemoryPool<T, BlockSize>::address(const_reference x) | ||||
| const noexcept | ||||
| { | ||||
|   return &x; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| void | ||||
| MemoryPool<T, BlockSize>::allocateBlock() | ||||
| { | ||||
|   // Allocate space for the new block and store a pointer to the previous one | ||||
|   data_pointer_ newBlock = reinterpret_cast<data_pointer_> | ||||
|                            (operator new(BlockSize)); | ||||
|   reinterpret_cast<slot_pointer_>(newBlock)->next = currentBlock_; | ||||
|   currentBlock_ = reinterpret_cast<slot_pointer_>(newBlock); | ||||
|   // Pad block body to staisfy the alignment requirements for elements | ||||
|   data_pointer_ body = newBlock + sizeof(slot_pointer_); | ||||
|   size_type bodyPadding = padPointer(body, alignof(slot_type_)); | ||||
|   currentSlot_ = reinterpret_cast<slot_pointer_>(body + bodyPadding); | ||||
|   lastSlot_ = reinterpret_cast<slot_pointer_> | ||||
|               (newBlock + BlockSize - sizeof(slot_type_) + 1); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| inline typename MemoryPool<T, BlockSize>::pointer | ||||
| MemoryPool<T, BlockSize>::allocate(size_type n, const_pointer hint) | ||||
| { | ||||
|   if (freeSlots_ != nullptr) { | ||||
|     pointer result = reinterpret_cast<pointer>(freeSlots_); | ||||
|     freeSlots_ = freeSlots_->next; | ||||
|     return result; | ||||
|   } | ||||
|   else { | ||||
|     if (currentSlot_ >= lastSlot_) | ||||
|       allocateBlock(); | ||||
|     return reinterpret_cast<pointer>(currentSlot_++); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| inline void | ||||
| MemoryPool<T, BlockSize>::deallocate(pointer p, size_type n) | ||||
| { | ||||
|   if (p != nullptr) { | ||||
|     reinterpret_cast<slot_pointer_>(p)->next = freeSlots_; | ||||
|     freeSlots_ = reinterpret_cast<slot_pointer_>(p); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| inline typename MemoryPool<T, BlockSize>::size_type | ||||
| MemoryPool<T, BlockSize>::max_size() | ||||
| const noexcept | ||||
| { | ||||
|   size_type maxBlocks = -1 / BlockSize; | ||||
|   return (BlockSize - sizeof(data_pointer_)) / sizeof(slot_type_) * maxBlocks; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| template <class U, class... Args> | ||||
| inline void | ||||
| MemoryPool<T, BlockSize>::construct(U* p, Args&&... args) | ||||
| { | ||||
|   new (p) U (std::forward<Args>(args)...); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| template <class U> | ||||
| inline void | ||||
| MemoryPool<T, BlockSize>::destroy(U* p) | ||||
| { | ||||
|   p->~U(); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| template <class... Args> | ||||
| inline typename MemoryPool<T, BlockSize>::pointer | ||||
| MemoryPool<T, BlockSize>::newElement(Args&&... args) | ||||
| { | ||||
|   pointer result = allocate(); | ||||
|   construct<value_type>(result, std::forward<Args>(args)...); | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template <typename T, size_t BlockSize> | ||||
| inline void | ||||
| MemoryPool<T, BlockSize>::deleteElement(pointer p) | ||||
| { | ||||
|   if (p != nullptr) { | ||||
|     p->~value_type(); | ||||
|     deallocate(p); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif // MEMORY_BLOCK_TCC | ||||
		Reference in New Issue
	
	Block a user