update
This commit is contained in:
parent
f2815b796a
commit
7b2946a961
@ -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,7 +47,7 @@ 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)
|
||||
|
1
ToDo.txt
1
ToDo.txt
@ -1,4 +1,5 @@
|
||||
LIB:
|
||||
- fix polygonize
|
||||
- improve marching cube
|
||||
- create patches
|
||||
- use lscm
|
||||
|
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
|
Loading…
Reference in New Issue
Block a user