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,9 +47,9 @@ add_executable(asteroidgen
|
||||
vendor/imgui_draw.cpp
|
||||
vendor/imgui_impl_glfw_gl3.cpp
|
||||
)
|
||||
target_link_libraries(asteroidgen ${OPENMESH_LIBRARIES} dl glfw)
|
||||
target_link_libraries(asteroidgen ${OPENMESH_LIBRARIES} dl glfw ${OpenMP_CXX_LIBRARIES})
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES RELEASE)
|
||||
set_target_properties(asteroidgen PROPERTIES LINK_SEARCH_START_STATIC 1)
|
||||
set_target_properties(asteroidgen PROPERTIES LINK_SEARCH_END_STATIC 1)
|
||||
endif()
|
||||
endif()
|
||||
|
3
ToDo.txt
3
ToDo.txt
@ -1,4 +1,5 @@
|
||||
LIB:
|
||||
- fix polygonize
|
||||
- improve marching cube
|
||||
- create patches
|
||||
- use lscm
|
||||
@ -18,4 +19,4 @@ GUI:
|
||||
- Progress
|
||||
- Arcball
|
||||
- PBR https://learnopengl.com/#!PBR/Lighting
|
||||
- save
|
||||
- save
|
||||
|
147
cmake/FindOpenMesh.cmake
Normal file
147
cmake/FindOpenMesh.cmake
Normal file
@ -0,0 +1,147 @@
|
||||
#
|
||||
# Try to find OPENMESH
|
||||
# Once done this will define
|
||||
#
|
||||
# OPENMESH_FOUND - system has OPENMESH
|
||||
# OPENMESH_INCLUDE_DIRS - the OPENMESH include directories
|
||||
# OPENMESH_LIBRARIES - Link these to use OPENMESH
|
||||
# OPENMESH_LIBRARY_DIR - directory where the libraries are included
|
||||
#
|
||||
# Copyright 2015 Computer Graphics Group, RWTH Aachen University
|
||||
# Authors: Jan Möbius <moebius@cs.rwth-aachen.de>
|
||||
# Hans-Christian Ebke <ebke@cs.rwth-aachen.de>
|
||||
#
|
||||
#
|
||||
#===========================================================================
|
||||
#
|
||||
# OpenMesh
|
||||
# Copyright (c) 2001-2015, RWTH-Aachen University
|
||||
# Department of Computer Graphics and Multimedia
|
||||
# All rights reserved.
|
||||
# www.openmesh.org
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
# This file is part of OpenMesh.
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
|
||||
#if already found via finder or simulated finder in openmesh CMakeLists.txt, skip the search
|
||||
IF (NOT OPENMESH_FOUND)
|
||||
SET (SEARCH_PATHS
|
||||
/usr/local/
|
||||
/usr/
|
||||
"${CMAKE_SOURCE_DIR}/OpenMesh/src/OpenMesh"
|
||||
"${CMAKE_SOURCE_DIR}/libs_required/OpenMesh/src/OpenMesh"
|
||||
"${CMAKE_SOURCE_DIR}/../OpenMesh/src/OpenMesh"
|
||||
"C:/Program Files/OpenMesh 6.3"
|
||||
"C:/Program Files/OpenMesh 6.2"
|
||||
"C:/Program Files/OpenMesh 6.1"
|
||||
"C:/Program Files/OpenMesh 6.0"
|
||||
"C:/Program Files/OpenMesh 5.2"
|
||||
"C:/Program Files/OpenMesh 5.1"
|
||||
"C:/Program Files/OpenMesh 5.0"
|
||||
"C:/Program Files/OpenMesh 4.2"
|
||||
"C:/Program Files/OpenMesh 4.1"
|
||||
"C:/Program Files/OpenMesh 4.0"
|
||||
"C:/Program Files/OpenMesh 3.4"
|
||||
"C:/Program Files/OpenMesh 3.3"
|
||||
"C:/Program Files/OpenMesh 3.2"
|
||||
"C:/Program Files/OpenMesh 3.1"
|
||||
"C:/Program Files/OpenMesh 3.0"
|
||||
"C:/Program Files/OpenMesh 2.4.1"
|
||||
"C:/Program Files/OpenMesh 2.4"
|
||||
"C:/Program Files/OpenMesh 2.0/include"
|
||||
"C:/libs/OpenMesh 6.3"
|
||||
"C:/libs/OpenMesh 6.2"
|
||||
"C:/libs/OpenMesh 6.1"
|
||||
"C:/libs/OpenMesh 6.0"
|
||||
"C:/libs/OpenMesh 5.2"
|
||||
"C:/libs/OpenMesh 5.1"
|
||||
"C:/libs/OpenMesh 5.0"
|
||||
"C:/libs/OpenMesh 4.2"
|
||||
"C:/libs/OpenMesh 4.1"
|
||||
"C:/libs/OpenMesh 4.0"
|
||||
"C:/libs/OpenMesh 3.4"
|
||||
"C:/libs/OpenMesh 3.3"
|
||||
"C:/libs/OpenMesh 3.2"
|
||||
"C:/libs/OpenMesh 3.1"
|
||||
"C:/libs/OpenMesh 3.0"
|
||||
"C:/libs/OpenMesh 2.4.1"
|
||||
"C:/libs/OpenMesh 2.4"
|
||||
"${OPENMESH_LIBRARY_DIR}"
|
||||
)
|
||||
|
||||
FIND_PATH (OPENMESH_INCLUDE_DIR OpenMesh/Core/Mesh/PolyMeshT.hh
|
||||
PATHS ${SEARCH_PATHS}
|
||||
PATH_SUFFIXES include)
|
||||
|
||||
FIND_LIBRARY(OPENMESH_CORE_LIBRARY_RELEASE NAMES OpenMeshCore
|
||||
PATHS ${SEARCH_PATHS}
|
||||
PATH_SUFFIXES lib lib64)
|
||||
|
||||
FIND_LIBRARY(OPENMESH_CORE_LIBRARY_DEBUG NAMES OpenMeshCored
|
||||
PATHS ${SEARCH_PATHS}
|
||||
PATH_SUFFIXES lib lib64)
|
||||
|
||||
FIND_LIBRARY(OPENMESH_TOOLS_LIBRARY_RELEASE NAMES OpenMeshTools
|
||||
PATHS ${SEARCH_PATHS}
|
||||
PATH_SUFFIXES lib lib64)
|
||||
|
||||
FIND_LIBRARY(OPENMESH_TOOLS_LIBRARY_DEBUG NAMES OpenMeshToolsd
|
||||
PATHS ${SEARCH_PATHS}
|
||||
PATH_SUFFIXES lib lib64)
|
||||
|
||||
#select configuration depending on platform (optimized... on windows)
|
||||
include(SelectLibraryConfigurations)
|
||||
select_library_configurations( OPENMESH_TOOLS )
|
||||
select_library_configurations( OPENMESH_CORE )
|
||||
|
||||
set(OPENMESH_LIBRARIES ${OPENMESH_CORE_LIBRARY} ${OPENMESH_TOOLS_LIBRARY} )
|
||||
set(OPENMESH_INCLUDE_DIRS ${OPENMESH_INCLUDE_DIR} )
|
||||
|
||||
#checks, if OPENMESH was found and sets OPENMESH_FOUND if so
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(OpenMesh DEFAULT_MSG
|
||||
OPENMESH_CORE_LIBRARY OPENMESH_TOOLS_LIBRARY OPENMESH_INCLUDE_DIR)
|
||||
|
||||
#sets the library dir
|
||||
if ( OPENMESH_CORE_LIBRARY_RELEASE )
|
||||
get_filename_component(_OPENMESH_LIBRARY_DIR ${OPENMESH_CORE_LIBRARY_RELEASE} PATH)
|
||||
else( OPENMESH_CORE_LIBRARY_RELEASE )
|
||||
get_filename_component(_OPENMESH_LIBRARY_DIR ${OPENMESH_CORE_LIBRARY_DEBUG} PATH)
|
||||
endif( OPENMESH_CORE_LIBRARY_RELEASE )
|
||||
set (OPENMESH_LIBRARY_DIR "${_OPENMESH_LIBRARY_DIR}" CACHE PATH "The directory where the OpenMesh libraries can be found.")
|
||||
|
||||
|
||||
mark_as_advanced(OPENMESH_INCLUDE_DIR OPENMESH_CORE_LIBRARY_RELEASE OPENMESH_CORE_LIBRARY_DEBUG OPENMESH_TOOLS_LIBRARY_RELEASE OPENMESH_TOOLS_LIBRARY_DEBUG OPENMESH_LIBRARY_DIR)
|
||||
endif()
|
12
shader/skybox.fragment.glsl
Normal file
12
shader/skybox.fragment.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 330
|
||||
|
||||
in vec3 TexCoord0;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform samplerCube gCubemapTexture;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(gCubemapTexture, TexCoord0);
|
||||
}
|
14
shader/skybox.vertex.glsl
Normal file
14
shader/skybox.vertex.glsl
Normal file
@ -0,0 +1,14 @@
|
||||
#version 330
|
||||
|
||||
in vec3 Position;
|
||||
|
||||
uniform mat4 gWVP;
|
||||
|
||||
out vec3 TexCoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 WVP_Pos = gWVP * vec4(Position, 1.0);
|
||||
gl_Position = WVP_Pos.xyww;
|
||||
TexCoord0 = Position;
|
||||
}
|
206
src/AlignedAllocator.h
Normal file
206
src/AlignedAllocator.h
Normal file
@ -0,0 +1,206 @@
|
||||
#pragma once
|
||||
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
enum class Alignment
|
||||
: size_t
|
||||
{
|
||||
Normal = sizeof(void*), SSE = 16, AVX = 32,
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
void* allocate_aligned_memory(size_t align, size_t size);
|
||||
void deallocate_aligned_memory(void* ptr) noexcept;
|
||||
}
|
||||
|
||||
template<typename T, Alignment Align = Alignment::SSE>
|
||||
class AlignedAllocator;
|
||||
|
||||
template<Alignment Align>
|
||||
class AlignedAllocator<void, Align> {
|
||||
public:
|
||||
typedef void* pointer;
|
||||
typedef const void* const_pointer;
|
||||
typedef void value_type;
|
||||
|
||||
template<class U> struct rebind {
|
||||
typedef AlignedAllocator<U, Align> other;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T, Alignment Align>
|
||||
class AlignedAllocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
typedef std::true_type propagate_on_container_move_assignment;
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
typedef AlignedAllocator<U, Align> other;
|
||||
};
|
||||
|
||||
public:
|
||||
AlignedAllocator() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
template<class U>
|
||||
AlignedAllocator(const AlignedAllocator<U, Align>&) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
size_type max_size() const noexcept
|
||||
{
|
||||
return (size_type(~0) - size_type(Align)) / sizeof(T);
|
||||
}
|
||||
|
||||
pointer address(reference x) const noexcept
|
||||
{
|
||||
return std::addressof(x);
|
||||
}
|
||||
|
||||
const_pointer address(const_reference x) const noexcept
|
||||
{
|
||||
return std::addressof(x);
|
||||
}
|
||||
|
||||
pointer allocate(size_type n,
|
||||
typename AlignedAllocator<void, Align>::const_pointer = 0) {
|
||||
const size_type alignment = static_cast<size_type>(Align);
|
||||
void* ptr = detail::allocate_aligned_memory(alignment, n * sizeof(T));
|
||||
if (ptr == nullptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return reinterpret_cast<pointer>(ptr);
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type) noexcept
|
||||
{
|
||||
detail::deallocate_aligned_memory(p);
|
||||
}
|
||||
|
||||
template<class U, class ...Args>
|
||||
void construct(U* p, Args&&... args) {
|
||||
::new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void destroy(pointer p) {
|
||||
p->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, Alignment Align>
|
||||
class AlignedAllocator<const T, Align> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef const T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef const T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
typedef std::true_type propagate_on_container_move_assignment;
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
typedef AlignedAllocator<U, Align> other;
|
||||
};
|
||||
|
||||
public:
|
||||
AlignedAllocator() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
template<class U>
|
||||
AlignedAllocator(const AlignedAllocator<U, Align>&) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
size_type max_size() const noexcept
|
||||
{
|
||||
return (size_type(~0) - size_type(Align)) / sizeof(T);
|
||||
}
|
||||
|
||||
const_pointer address(const_reference x) const noexcept
|
||||
{
|
||||
return std::addressof(x);
|
||||
}
|
||||
|
||||
pointer allocate(size_type n,
|
||||
typename AlignedAllocator<void, Align>::const_pointer = 0) {
|
||||
const size_type alignment = static_cast<size_type>(Align);
|
||||
void* ptr = detail::allocate_aligned_memory(alignment, n * sizeof(T));
|
||||
if (ptr == nullptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return reinterpret_cast<pointer>(ptr);
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type) noexcept
|
||||
{
|
||||
detail::deallocate_aligned_memory(p);
|
||||
}
|
||||
|
||||
template<class U, class ...Args>
|
||||
void construct(U* p, Args&&... args) {
|
||||
::new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void destroy(pointer p) {
|
||||
p->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, Alignment TAlign, typename U, Alignment UAlign>
|
||||
inline
|
||||
bool operator==(const AlignedAllocator<T, TAlign>&,
|
||||
const AlignedAllocator<U, UAlign>&) noexcept
|
||||
{
|
||||
return TAlign == UAlign;
|
||||
}
|
||||
|
||||
template<typename T, Alignment TAlign, typename U, Alignment UAlign>
|
||||
inline
|
||||
bool operator!=(const AlignedAllocator<T, TAlign>&,
|
||||
const AlignedAllocator<U, UAlign>&) noexcept
|
||||
{
|
||||
return TAlign != UAlign;
|
||||
}
|
||||
|
||||
inline void*
|
||||
detail::allocate_aligned_memory(size_t align, size_t size) {
|
||||
assert(align >= sizeof(void*));
|
||||
//assert(nail::is_power_of_two(align));
|
||||
|
||||
if (size == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* ptr = nullptr;
|
||||
int rc = posix_memalign(&ptr, align, size);
|
||||
|
||||
if (rc != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void detail::deallocate_aligned_memory(void *ptr) noexcept
|
||||
{
|
||||
free(ptr);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#include "Application.h"
|
||||
#include "Mesh.h"
|
||||
#include "Shader.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
@ -82,7 +83,8 @@ Application::Application() :
|
||||
textureSize), programId(0), vPositionLoc(-1), vTexCoordLoc(-1), vNormalLoc(
|
||||
-1), meteoridCount(1000), meteroidMinRadius(0.005), meteroidMaxRadius(
|
||||
0.2), meteroidSizeExponent(2048), densityFrequency(2), densityOctave(
|
||||
2), densityScale(1.0f), resolution(0.1), viewDistance(3.0f), fpsMode(
|
||||
2), densityScale(1.0f), resolution(0.1), smoothMesh(true), viewDistance(
|
||||
3.0f), fpsMode(false), meshUploadRequest(false), textureUploadRequest(
|
||||
false) {
|
||||
init();
|
||||
}
|
||||
@ -157,7 +159,6 @@ void Application::init() {
|
||||
loadShader();
|
||||
updateVertexArrayObject();
|
||||
generateAsteroid();
|
||||
uploadMesh();
|
||||
}
|
||||
|
||||
void Application::shutdown() {
|
||||
@ -215,47 +216,98 @@ void Application::toogleFpsMode() {
|
||||
}
|
||||
|
||||
void Application::generateAsteroid() {
|
||||
std::srand(123);
|
||||
if (meshProgress.begin("Random Impacts", 1)) {
|
||||
//if (density.getImpacts().size() == 0)
|
||||
density.addRandomImpacts(1000, densityIsolevel, 0.01, 0.005, 0.2, 256);
|
||||
|
||||
if (density.getImpacts().size() == 0)
|
||||
density.addRandomImpacts(1000, 0.2, 0.01, 0.005, 0.2, 4096);
|
||||
//density.saveCrossSection("density.png", 512);
|
||||
//density.saveCrossSection("density.png", 512);
|
||||
}
|
||||
polygonizer.polygonize(resolution, meshProgress);
|
||||
|
||||
polygonizer.polygonize(resolution);
|
||||
if (smoothMesh && meshProgress.begin("Smooth", 1)) {
|
||||
smooth(polygonizer.vertices, polygonizer.indices);
|
||||
// {
|
||||
// std::ofstream out("stage2.obj");
|
||||
// saveAttrib(out, "v ", polygonizer.vertices);
|
||||
// saveFaces(out, polygonizer.indices, 1);
|
||||
// }
|
||||
}
|
||||
|
||||
uvec4v_t edges;
|
||||
if (meshProgress.begin("Find Edges", 1)) {
|
||||
findEdges(polygonizer.vertices, polygonizer.indices, edges);
|
||||
}
|
||||
uvec3v_t adjacents;
|
||||
if (meshProgress.begin("Find Adjacent", 1)) {
|
||||
findAdjacent(edges, polygonizer.indices.size(), adjacents);
|
||||
}
|
||||
vec3v_t faceNormals;
|
||||
calculateFaceNormals(polygonizer.vertices, polygonizer.indices,
|
||||
faceNormals);
|
||||
|
||||
vec3v_t positions;
|
||||
uvec3v_t indices;
|
||||
uintv_t patches;
|
||||
|
||||
createPatches(polygonizer.vertices, polygonizer.indices, faceNormals,
|
||||
adjacents, positions, indices, patches, 0.9);
|
||||
{
|
||||
std::ofstream out("stage1.obj");
|
||||
saveAttrib(out, "v ", polygonizer.vertices);
|
||||
saveFaces(out, polygonizer.indices, 1);
|
||||
saveAttrib(out, "v ", positions);
|
||||
saveFaces(out, indices, 1);
|
||||
}
|
||||
|
||||
smooth(polygonizer.vertices, polygonizer.indices);
|
||||
{
|
||||
std::ofstream out("stage2.obj");
|
||||
saveAttrib(out, "v ", polygonizer.vertices);
|
||||
saveFaces(out, polygonizer.indices, 1);
|
||||
}
|
||||
calculateNormals(polygonizer.vertices, polygonizer.indices, normals);
|
||||
{
|
||||
std::ofstream out("stage3.obj");
|
||||
saveAttrib(out, "v ", polygonizer.vertices);
|
||||
saveAttrib(out, "vn ", normals);
|
||||
saveFaces(out, polygonizer.indices, 2);
|
||||
if (meshProgress.begin("Calculate Vertex Normals", 1)) {
|
||||
calculateVertexNormals(polygonizer.vertices, polygonizer.indices,
|
||||
normals);
|
||||
// {
|
||||
// std::ofstream out("stage3.obj");
|
||||
// saveAttrib(out, "v ", polygonizer.vertices);
|
||||
// saveAttrib(out, "vn ", normals);
|
||||
// saveFaces(out, polygonizer.indices, 2);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
vector<glm::uvec4> edges;
|
||||
std::cout << "Vertices: " << polygonizer.vertices.size() << std::endl;
|
||||
std::cout << "Triangles: " << polygonizer.indices.size() << std::endl;
|
||||
|
||||
texturemapper.map(polygonizer.vertices, normals, polygonizer.indices);
|
||||
moveToMean(texturemapper.vertices);
|
||||
|
||||
{
|
||||
std::ofstream out("stage4.obj");
|
||||
saveAttrib(out, "v ", texturemapper.vertices);
|
||||
saveAttrib(out, "vn ", texturemapper.normals);
|
||||
saveAttrib(out, "vt ", texturemapper.texcoords);
|
||||
saveFaces(out, texturemapper.indices, 3);
|
||||
if (meshProgress.begin("Map Textures", 1)) {
|
||||
texturemapper.map(polygonizer.vertices, normals, polygonizer.indices);
|
||||
}
|
||||
|
||||
if (meshProgress.begin("Move To Mean", 1)) {
|
||||
moveToMean(texturemapper.vertices);
|
||||
|
||||
// {
|
||||
// std::ofstream out("stage4.obj");
|
||||
// saveAttrib(out, "v ", texturemapper.vertices);
|
||||
// saveAttrib(out, "vn ", texturemapper.normals);
|
||||
// saveAttrib(out, "vt ", texturemapper.texcoords);
|
||||
// saveFaces(out, texturemapper.indices, 3);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
if (meshProgress.begin("Save", 4)) {
|
||||
std::ofstream out("asteroid.obj");
|
||||
saveAttrib(out, "v ", texturemapper.vertices);
|
||||
meshProgress.advance();
|
||||
saveAttrib(out, "vn ", texturemapper.normals);
|
||||
meshProgress.advance();
|
||||
saveAttrib(out, "vt ", texturemapper.texcoords);
|
||||
meshProgress.advance();
|
||||
saveFaces(out, texturemapper.indices, 3);
|
||||
meshProgress.advance();
|
||||
}
|
||||
|
||||
meshProgress.finish();
|
||||
|
||||
if (!meshProgress.isCanceled()) {
|
||||
meshUploadRequest = true;
|
||||
textureUploadRequest = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Application::bindVertexAttrib(GLuint id, GLint loc, GLuint size) {
|
||||
@ -267,7 +319,7 @@ bool Application::bindVertexAttrib(GLuint id, GLint loc, GLuint size) {
|
||||
size,// size
|
||||
GL_FLOAT,// type
|
||||
GL_FALSE,// normalized?
|
||||
0, // stride
|
||||
0,// stride
|
||||
(void* ) 0// array buffer offset
|
||||
))
|
||||
return true;
|
||||
@ -290,102 +342,7 @@ void Application::updateVertexArrayObject() {
|
||||
GLCK(glBindVertexArray(0))
|
||||
}
|
||||
|
||||
GLuint Application::loadProgram(const std::string &name) {
|
||||
|
||||
// Create the shaders
|
||||
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
// Read the Vertex Shader code from the file
|
||||
std::string VertexShaderCode;
|
||||
std::string vertex_file_path = "shader/" + name + ".vertex.glsl";
|
||||
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
|
||||
if (VertexShaderStream.is_open()) {
|
||||
std::string Line = "";
|
||||
while (getline(VertexShaderStream, Line))
|
||||
VertexShaderCode += "\n" + Line;
|
||||
VertexShaderStream.close();
|
||||
} else {
|
||||
std::cout << "Failed to open " << vertex_file_path << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read the Fragment Shader code from the file
|
||||
std::string FragmentShaderCode;
|
||||
std::string fragment_file_path = "shader/" + name + ".fragment.glsl";
|
||||
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
|
||||
if (FragmentShaderStream.is_open()) {
|
||||
std::string Line = "";
|
||||
while (getline(FragmentShaderStream, Line))
|
||||
FragmentShaderCode += "\n" + Line;
|
||||
FragmentShaderStream.close();
|
||||
} else {
|
||||
std::cout << "Failed to open " << vertex_file_path << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
|
||||
// Compile Vertex Shader
|
||||
std::cout << "Compiling vertex shader : " << name << std::endl;
|
||||
char const * VertexSourcePointer = VertexShaderCode.c_str();
|
||||
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
|
||||
glCompileShader(VertexShaderID);
|
||||
|
||||
// Check Vertex Shader
|
||||
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
|
||||
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
if (InfoLogLength > 0) {
|
||||
vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
|
||||
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL,
|
||||
&VertexShaderErrorMessage[0]);
|
||||
printf("%s\n", &VertexShaderErrorMessage[0]);
|
||||
}
|
||||
|
||||
// Compile Fragment Shader
|
||||
std::cout << "Compiling fragment shader : " << name << std::endl;
|
||||
|
||||
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
|
||||
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
|
||||
glCompileShader(FragmentShaderID);
|
||||
|
||||
// Check Fragment Shader
|
||||
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
|
||||
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
if (InfoLogLength > 0) {
|
||||
vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
|
||||
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL,
|
||||
&FragmentShaderErrorMessage[0]);
|
||||
printf("%s\n", &FragmentShaderErrorMessage[0]);
|
||||
}
|
||||
|
||||
// Link the program
|
||||
std::cout << "Linking program : " << name << std::endl;
|
||||
|
||||
GLuint ProgramID = glCreateProgram();
|
||||
glAttachShader(ProgramID, VertexShaderID);
|
||||
glAttachShader(ProgramID, FragmentShaderID);
|
||||
glLinkProgram(ProgramID);
|
||||
|
||||
// Check the program
|
||||
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
|
||||
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
if (InfoLogLength > 0) {
|
||||
vector<char> ProgramErrorMessage(InfoLogLength + 1);
|
||||
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL,
|
||||
&ProgramErrorMessage[0]);
|
||||
printf("%s\n", &ProgramErrorMessage[0]);
|
||||
}
|
||||
|
||||
glDetachShader(ProgramID, VertexShaderID);
|
||||
glDetachShader(ProgramID, FragmentShaderID);
|
||||
|
||||
glDeleteShader(VertexShaderID);
|
||||
glDeleteShader(FragmentShaderID);
|
||||
|
||||
return ProgramID;
|
||||
}
|
||||
|
||||
void Application::loadShader() {
|
||||
if (programId >= 0)
|
||||
@ -409,6 +366,7 @@ void Application::loadShader() {
|
||||
}
|
||||
|
||||
void Application::uploadMesh() {
|
||||
printf("upload mesh\n");
|
||||
GLCK(glBindVertexArray(vertexArrayId))
|
||||
|
||||
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vPositionId))
|
||||
@ -428,10 +386,13 @@ void Application::uploadMesh() {
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, texturemapper.indices.size() * sizeof(uvec3), texturemapper.indices.data(), GL_STATIC_DRAW))
|
||||
|
||||
GLCK(glBindVertexArray(0))
|
||||
}
|
||||
|
||||
void Application::uploadTexture() {
|
||||
printf("upload texture\n");
|
||||
glBindTexture(GL_TEXTURE_2D, tAlbedoId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texturemapper.getTextureSize(),
|
||||
texturemapper.getTextureSize(), 0, GL_BGR, GL_UNSIGNED_BYTE,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturemapper.getTextureSize(),
|
||||
texturemapper.getTextureSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
texturemapper.albedo.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
@ -446,9 +407,11 @@ void Application::renderMesh() {
|
||||
}
|
||||
|
||||
void Application::prepareShader() {
|
||||
glm::mat4 model(1.0f);
|
||||
glm::mat4 view;
|
||||
|
||||
double mouseX, mouseY;
|
||||
glfwGetCursorPos(window, &mouseX, &mouseY);
|
||||
|
||||
if (fpsMode) {
|
||||
glm::mat4 fpsTrafoInv = glm::inverse(fpsTrafo);
|
||||
|
||||
@ -458,37 +421,53 @@ void Application::prepareShader() {
|
||||
} else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
|
||||
movement -= glm::vec4(0.0, 0.0, 0.1, 0.0);
|
||||
}
|
||||
double mouseX, mouseY;
|
||||
glfwGetCursorPos(window, &mouseX, &mouseY);
|
||||
glm::vec3 up = fpsTrafoInv * glm::vec4(0.0, 1.0, 0.0, 0.0);
|
||||
glm::vec3 side = fpsTrafoInv * glm::vec4(1.0, 0.0, 0.0, 0.0);
|
||||
glm::vec3 front = fpsTrafoInv * glm::vec4(0.0, 0.0, 1.0, 0.0);
|
||||
fpsTrafo = glm::rotate(fpsTrafo, (float)(mouseX - lastMouseX) * 0.01f, up);
|
||||
fpsTrafo = glm::rotate(fpsTrafo, (float)(mouseY - lastMouseY) * 0.01f, side);
|
||||
|
||||
if (glfwGetMouseButton(window, 0) == GLFW_PRESS) {
|
||||
glm::vec3 up = fpsTrafoInv * glm::vec4(0.0, 1.0, 0.0, 0.0);
|
||||
glm::vec3 side = fpsTrafoInv * glm::vec4(1.0, 0.0, 0.0, 0.0);
|
||||
glm::vec3 front = fpsTrafoInv * glm::vec4(0.0, 0.0, 1.0, 0.0);
|
||||
fpsTrafo = glm::rotate(fpsTrafo,
|
||||
(float) (mouseX - lastMouseX) * 0.01f, up);
|
||||
fpsTrafo = glm::rotate(fpsTrafo,
|
||||
(float) (mouseY - lastMouseY) * 0.01f, side);
|
||||
}
|
||||
//fpsTrafo = glm::rotate(fpsTrafo, mouseX - lastMouseX, up);
|
||||
glm::vec3 absolute = fpsTrafoInv * movement;
|
||||
fpsTrafo = glm::translate(fpsTrafo, absolute);
|
||||
lastMouseX = mouseX;
|
||||
lastMouseY = mouseY;
|
||||
|
||||
view = fpsTrafo;
|
||||
} else {
|
||||
model = glm::rotate(model, (float) glfwGetTime(), vec3(0.f, 1.f, 0.f));
|
||||
|
||||
if (!ImGui::IsMouseHoveringAnyWindow() && glfwGetMouseButton(window, 0) == GLFW_PRESS) {
|
||||
glm::mat4 modelTrafoInv = glm::inverse(modelTrafo);
|
||||
modelTrafo = glm::rotate(modelTrafo,
|
||||
(float) (mouseX - lastMouseX) * 0.01f,
|
||||
vec3(modelTrafoInv * glm::vec4(0.0, 1.0, 0.0, 0.0)));
|
||||
modelTrafo = glm::rotate(modelTrafo,
|
||||
(float) (mouseY - lastMouseY) * 0.01f,
|
||||
vec3(modelTrafoInv * glm::vec4(1.0, 0.0, 0.0, 0.0)));
|
||||
}
|
||||
|
||||
//model = glm::rotate(model, (float) glfwGetTime(), vec3(0.f, 1.f, 0.f));
|
||||
|
||||
view = glm::lookAt(vec3(0, 0, viewDistance), // Camera is at (4,3,3), in World Space
|
||||
vec3(0, 0, 0), // and looks at the origin
|
||||
vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
|
||||
);
|
||||
}
|
||||
lastMouseX = mouseX;
|
||||
lastMouseY = mouseY;
|
||||
|
||||
glm::mat4 perspective = glm::perspective(glm::radians(45.0f),
|
||||
(float) width / (float) height, 0.1f, 100.0f);
|
||||
glm::mat4 mvp = perspective * view * model;
|
||||
glm::mat4 mvp = perspective * view * modelTrafo;
|
||||
|
||||
GLCK(glUseProgram(programId))
|
||||
if (MVPloc >= 0) {
|
||||
GLCK(glUniformMatrix4fv(MVPloc, 1, GL_FALSE, glm::value_ptr(mvp)))
|
||||
}
|
||||
if (Mloc >= 0) {
|
||||
GLCK(glUniformMatrix4fv(Mloc, 1, GL_FALSE, glm::value_ptr(model)))
|
||||
GLCK(glUniformMatrix4fv(Mloc, 1, GL_FALSE, glm::value_ptr(modelTrafo)))
|
||||
}
|
||||
if (Vloc >= 0) {
|
||||
GLCK(glUniformMatrix4fv(Vloc, 1, GL_FALSE, glm::value_ptr(view)))
|
||||
@ -536,6 +515,7 @@ void Application::gui() {
|
||||
density.setFrequency(densityFrequency);
|
||||
if (ImGui::SliderFloat("Octave", &densityOctave, 1, 10, "%.0f", 1))
|
||||
density.setOctave(densityOctave);
|
||||
ImGui::Checkbox("Smooth", &smoothMesh);
|
||||
|
||||
// if (ImGui::InputFloat("Frequency", &densityFrequency))
|
||||
// if (ImGui::InputFloat("Octave", &densityOctave))
|
||||
@ -549,9 +529,17 @@ void Application::gui() {
|
||||
texturemapper.setTextureSize(textureSizes[currentTextureSize]);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Generate")) {
|
||||
generateAsteroid();
|
||||
uploadMesh();
|
||||
if (meshProgress.isRunning()) {
|
||||
if (ImGui::Button("Cancel"))
|
||||
meshProgress.cancel();
|
||||
ImGui::Text("Task: %s", meshProgress.getTask().c_str());
|
||||
ImGui::ProgressBar(meshProgress.getProgress());
|
||||
} else {
|
||||
if (meshProgress.isFinished() && meshThread.joinable())
|
||||
meshThread.join();
|
||||
|
||||
if (ImGui::Button("Generate"))
|
||||
meshThread = std::thread(&Application::generateAsteroid, this);
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
@ -590,6 +578,14 @@ void Application::run() {
|
||||
glDepthFunc(GL_LESS);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
if (meshUploadRequest) {
|
||||
uploadMesh();
|
||||
meshUploadRequest = false;
|
||||
}
|
||||
if (textureUploadRequest) {
|
||||
uploadTexture();
|
||||
textureUploadRequest = false;
|
||||
}
|
||||
prepareShader();
|
||||
renderMesh();
|
||||
|
||||
|
@ -3,11 +3,13 @@
|
||||
#include "Density.h"
|
||||
#include "Polygoniser.h"
|
||||
#include "TextureMapper.h"
|
||||
#include "ProgressMonitor.h"
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
@ -29,10 +31,10 @@ class Application {
|
||||
int vPositionLoc, vTexCoordLoc, vNormalLoc, tAlbedoLoc, tNormalLoc,
|
||||
tRoughnessLoc, tMetalicLoc;
|
||||
|
||||
std::vector<glm::vec3> vertices;
|
||||
std::vector<glm::vec3> normals;
|
||||
std::vector<glm::vec2> texcoords;
|
||||
std::vector<glm::uvec3> indices;
|
||||
vec3v_t vertices;
|
||||
vec3v_t normals;
|
||||
vec2v_t texcoords;
|
||||
uvec3v_t indices;
|
||||
|
||||
size_t meteoridCount;
|
||||
float meteroidMinRadius;
|
||||
@ -41,12 +43,18 @@ class Application {
|
||||
float densityFrequency, densityOctave;
|
||||
glm::vec3 densityScale;
|
||||
float resolution;
|
||||
bool smoothMesh;
|
||||
|
||||
float viewDistance;
|
||||
|
||||
glm::mat4 fpsTrafo;
|
||||
bool fpsMode;
|
||||
double lastMouseX, lastMouseY;
|
||||
glm::mat4 modelTrafo;
|
||||
|
||||
ProgressMonitor meshProgress, textureProgress;
|
||||
std::thread meshThread, textureThread;
|
||||
bool meshUploadRequest, textureUploadRequest;
|
||||
|
||||
void toogleFpsMode();
|
||||
public:
|
||||
@ -74,11 +82,10 @@ public:
|
||||
|
||||
void updateVertexArrayObject();
|
||||
|
||||
unsigned int loadProgram(const std::string &name);
|
||||
|
||||
void loadShader();
|
||||
|
||||
void uploadMesh();
|
||||
void uploadTexture();
|
||||
|
||||
void renderMesh();
|
||||
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
|
||||
void setSeed(uint32_t seed) {
|
||||
noise.reseed(seed);
|
||||
version++;
|
||||
impacts.clear();
|
||||
}
|
||||
|
||||
@ -77,7 +78,7 @@ public:
|
||||
}
|
||||
|
||||
float operator()(const glm::vec3 &p, bool includeImpacts = true) const {
|
||||
if (includeImpacts & impacts.size()) {
|
||||
if (includeImpacts && impacts.size() > 0) {
|
||||
bool insideImpact = false;
|
||||
impactTree.Search(&p.x, &p.x, [&](int idx) -> bool {
|
||||
if (impacts[idx].contains(p)) {
|
||||
@ -119,6 +120,7 @@ public:
|
||||
Impact impact;
|
||||
if (intersectIsolevel(start, end, impact.pos, isolevel,
|
||||
resolution)) {
|
||||
impact.pos -= (impact.r / 1.5f) * normalize(end-start);
|
||||
impact.r = minRadius
|
||||
+ pow(glm::linearRand(0.f, 1.f), exponent) * maxRadius;
|
||||
addImpact(impact);
|
||||
|
394
src/MarchingCube.cpp
Normal file
394
src/MarchingCube.cpp
Normal file
@ -0,0 +1,394 @@
|
||||
#include "MarchingCube.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
using namespace glm;
|
||||
|
||||
static const int edgeTable[256] = { 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f,
|
||||
0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||
0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895,
|
||||
0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, 0x230, 0x339, 0x33, 0x13a,
|
||||
0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33,
|
||||
0xc39, 0xd30, 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac,
|
||||
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, 0x460, 0x569,
|
||||
0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66,
|
||||
0x86a, 0x963, 0xa69, 0xb60, 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff,
|
||||
0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
||||
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c, 0xe5c, 0xf55,
|
||||
0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, 0x7c0, 0x6c9, 0x5c3, 0x4ca,
|
||||
0x3c6, 0x2cf, 0x1c5, 0xcc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3,
|
||||
0x9c9, 0x8c0, 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
|
||||
0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, 0x950, 0x859,
|
||||
0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55, 0x35f, 0x256,
|
||||
0x55a, 0x453, 0x759, 0x650, 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff,
|
||||
0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
||||
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265,
|
||||
0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa,
|
||||
0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3,
|
||||
0x2a9, 0x3a0, 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
|
||||
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230, 0xe90, 0xf99,
|
||||
0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596,
|
||||
0x29a, 0x393, 0x99, 0x190, 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f,
|
||||
0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 };
|
||||
static const int triTable[256][16] = { { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1 }, { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1 }, { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0,
|
||||
8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 9,
|
||||
2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 2,
|
||||
8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, { 3, 11,
|
||||
2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0,
|
||||
11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1,
|
||||
9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1,
|
||||
11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, { 3,
|
||||
10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0,
|
||||
10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, { 3,
|
||||
9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 8,
|
||||
10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 7,
|
||||
8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 1, 9,
|
||||
8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 1, 9, 4,
|
||||
7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 10, 8, 4,
|
||||
7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 4, 7, 3, 0, 4,
|
||||
1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, { 9, 2, 10, 9, 0, 2, 8,
|
||||
4, 7, -1, -1, -1, -1, -1, -1, -1 }, { 2, 10, 9, 2, 9, 7, 2, 7,
|
||||
3, 7, 9, 4, -1, -1, -1, -1 }, { 8, 4, 7, 3, 11, 2, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1 }, { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1,
|
||||
-1, -1, -1, -1, -1, -1 }, { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1,
|
||||
-1, -1, -1, -1, -1 }, { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1,
|
||||
-1, -1, -1, -1 }, { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1,
|
||||
-1, -1, -1, -1 }, { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1,
|
||||
-1, -1, -1 }, { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1,
|
||||
-1, -1 }, { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1,
|
||||
-1 }, { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1 },
|
||||
{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, { 5, 2, 10,
|
||||
5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, { 2, 10, 5, 3,
|
||||
2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, { 9, 5, 4, 2, 3, 11,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 11, 2, 0, 8, 11,
|
||||
4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, { 0, 5, 4, 0, 1, 5, 2, 3,
|
||||
11, -1, -1, -1, -1, -1, -1, -1 }, { 2, 1, 5, 2, 5, 8, 2, 8, 11,
|
||||
4, 8, 5, -1, -1, -1, -1 }, { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1,
|
||||
-1, -1, -1, -1, -1, -1 }, { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11,
|
||||
10, -1, -1, -1, -1 }, { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3,
|
||||
-1, -1, -1, -1 }, { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1,
|
||||
-1, -1, -1, -1 }, { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1 }, { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1,
|
||||
-1, -1, -1 }, { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1,
|
||||
-1 }, { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, {
|
||||
8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, { 2, 10,
|
||||
5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, { 7, 9, 5, 7,
|
||||
8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 7, 9, 7,
|
||||
2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, { 2, 3, 11, 0, 1, 8, 1,
|
||||
7, 8, 1, 5, 7, -1, -1, -1, -1 }, { 11, 2, 1, 11, 1, 7, 7, 1, 5,
|
||||
-1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10,
|
||||
3, 11, -1, -1, -1, -1 }, { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10,
|
||||
11, 10, 0, -1 }, { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7,
|
||||
0, -1 }, { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1 }, { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1 }, { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1 }, { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1,
|
||||
-1 }, { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, { 2, 3, 11, 10,
|
||||
6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 11, 0, 8, 11,
|
||||
2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, { 0, 1, 9, 2, 3,
|
||||
11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, { 5, 10, 6, 1, 9, 2,
|
||||
9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, { 6, 3, 11, 6, 5, 3, 5, 1,
|
||||
3, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 11, 0, 11, 5, 0, 5, 1,
|
||||
5, 11, 6, -1, -1, -1, -1 }, { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5,
|
||||
9, -1, -1, -1, -1 }, { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1,
|
||||
-1, -1, -1, -1 }, { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1 }, { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1,
|
||||
-1, -1, -1 }, { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1,
|
||||
-1, -1 },
|
||||
{ 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, { 6, 1, 2, 6,
|
||||
5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 5, 5, 2, 6,
|
||||
3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, { 8, 4, 7, 9, 0, 5, 0, 6, 5,
|
||||
0, 2, 6, -1, -1, -1, -1 }, { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6,
|
||||
2, 6, 9, -1 }, { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1,
|
||||
-1, -1, -1 }, { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1,
|
||||
-1, -1 },
|
||||
{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, { 9, 2, 1, 9,
|
||||
11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, { 8, 4, 7, 3, 11, 5,
|
||||
3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, { 5, 1, 11, 5, 11, 6, 1, 0,
|
||||
11, 7, 11, 4, 0, 4, 11, -1 }, { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11,
|
||||
6, 3, 8, 4, 7, -1 }, { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1,
|
||||
-1, -1, -1 }, { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1 }, { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1,
|
||||
-1 }, { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, {
|
||||
1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0,
|
||||
8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, { 0, 2, 4, 4, 2,
|
||||
6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, 3, 2, 8, 2, 4,
|
||||
4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, { 10, 4, 9, 10, 6, 4, 11,
|
||||
2, 3, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 2, 2, 8, 11, 4, 9,
|
||||
10, 4, 10, 6, -1, -1, -1, -1 }, { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6,
|
||||
1, 10, -1, -1, -1, -1 }, { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11,
|
||||
8, 11, 1, -1 }, { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1,
|
||||
-1, -1 }, { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
|
||||
{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, { 6, 4, 8,
|
||||
11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 7, 10, 6,
|
||||
7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, { 0, 7, 3, 0,
|
||||
10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, { 10, 6, 7, 1, 10,
|
||||
7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, { 10, 6, 7, 10, 7, 1, 1,
|
||||
7, 3, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 6, 1, 6, 8, 1, 8, 9,
|
||||
8, 6, 7, -1, -1, -1, -1 }, { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3,
|
||||
7, 3, 9, -1 }, { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1 }, { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1,
|
||||
-1 }, { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, {
|
||||
1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, { 11, 2,
|
||||
1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, { 8, 9, 6, 8,
|
||||
6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, { 0, 9, 1, 11, 6, 7, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 7, 8, 0, 7, 0, 6, 3, 11,
|
||||
0, 11, 6, 0, -1, -1, -1, -1 }, { 7, 11, 6, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1 }, { 7, 6, 11, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 8, 11, 7, 6, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 1, 9, 11, 7, 6, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, 1, 9, 8, 3, 1, 11, 7,
|
||||
6, -1, -1, -1, -1, -1, -1, -1 }, { 10, 1, 2, 6, 11, 7, - |