Compare commits
4 Commits
ebada328e8
...
7f8e249a18
Author | SHA1 | Date |
---|---|---|
May B. | 7f8e249a18 | |
May B. | 96f4bbf11c | |
May B. | b6bd32ebdb | |
May B. | 82cf0daa75 |
|
@ -1,29 +1,58 @@
|
|||
image: gcc
|
||||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
- apt-get update
|
||||
- apt-get install -y --no-install-recommends cmake libssl-dev libvulkan-dev xorg-dev doxygen graphviz
|
||||
|
||||
build:
|
||||
build:linux:
|
||||
stage: build
|
||||
image: gcc
|
||||
before_script:
|
||||
- apt-get update
|
||||
- apt-get install -y --no-install-recommends cmake libssl-dev libvulkan-dev xorg-dev doxygen graphviz
|
||||
script:
|
||||
- mkdir build # compile
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- make -j2 univerxel univerxel-client univerxel-server docs
|
||||
- mkdir -p ../out/full ../out/client ../out/server/content # package artifacts
|
||||
- cp -r univerxel content ../out/full
|
||||
- cp -r univerxel-client content ../out/client
|
||||
- rm ../out/client/content/cert.pem ../out/client/content/key.pem ../out/client/content/zstd.dict
|
||||
- cp univerxel-server ../out/server
|
||||
- cp content/cert.pem content/key.pem content/zstd.dict ../out/server/content
|
||||
dependencies: []
|
||||
artifacts:
|
||||
paths:
|
||||
- out/full
|
||||
- out/client
|
||||
- out/server
|
||||
- build/content
|
||||
- build/univerxel
|
||||
- build/univerxel-client
|
||||
- build/univerxel-server
|
||||
- build/docs
|
||||
expire_in: 1 week
|
||||
# cache:
|
||||
# paths:
|
||||
# - "*.o"
|
||||
|
||||
deploy:package:
|
||||
stage: deploy
|
||||
image: curlimages/curl
|
||||
script:
|
||||
- mkdir out # package
|
||||
- cd build
|
||||
- mkdir -p applications
|
||||
- cp ../resource/config/*.desktop applications
|
||||
- mkdir -p icons/hicolor/256x256/apps
|
||||
- cp ../univerxel.png icons/hicolor/256x256/apps
|
||||
- cp ../resource/config/full.toml config.toml
|
||||
- tar cfz ../out/full-nux64.tar.gz univerxel applications/fr.wadza.univerxel.desktop config.toml icons content
|
||||
- cp ../resource/config/client.toml config.toml
|
||||
- tar cfz ../out/client-nux64.tar.gz univerxel-client applications/fr.wadza.univerxel.client.desktop config.toml icons content/shaders content/textures
|
||||
- cp ../resource/config/server.toml config.toml
|
||||
- tar cfz ../out/server-nux64.tar.gz univerxel-server applications/fr.wadza.univerxel.server.desktop config.toml icons content/cert.pem content/key.pem content/zstd.dict
|
||||
- cd ../out # deploy
|
||||
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file full-nux64.tar.gz ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/Univerxel/$CI_COMMIT_TAG/Univerxel-$CI_COMMIT_TAG-nux64.tar.gz'
|
||||
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file client-nux64.tar.gz ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/Univerxel-client/$CI_COMMIT_TAG/Univerxel-client-$CI_COMMIT_TAG-nux64.tar.gz'
|
||||
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file server-nux64.tar.gz ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/Univerxel-server/$CI_COMMIT_TAG/Univerxel-server-$CI_COMMIT_TAG-nux64.tar.gz'
|
||||
dependencies:
|
||||
- build:linux
|
||||
artifacts:
|
||||
paths:
|
||||
- out
|
||||
expire_in: 1 week
|
||||
except:
|
||||
- branches
|
||||
only:
|
||||
- /\A\d+\.\d+\.\d+\z/
|
|
@ -8,7 +8,6 @@ option(USE_FMA "Use fma" 1)
|
|||
option(LOG_DEBUG "Show debug logs" 0)
|
||||
option(LOG_TRACE "Show trace logs" 0)
|
||||
option(NATIVE "Build with -march=native" 0)
|
||||
option(GL_OLD "Use OpenGL 4.2 not 4.6" 0)
|
||||
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
|
@ -24,7 +23,7 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
add_definitions(/std:c++latest)
|
||||
add_compile_definitions(WIN32_LEAN_AND_MEAN=)
|
||||
else()
|
||||
|
@ -32,7 +31,7 @@ else()
|
|||
endif()
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_compile_definitions(FIXED_WINDOW=${FIXED_WINDOW} LOG_DEBUG=${LOG_DEBUG} LOG_TRACE=${LOG_TRACE} GL_OLD=${GL_OLD} HN_USE_FILESYSTEM=1)
|
||||
add_compile_definitions(FIXED_WINDOW=${FIXED_WINDOW} LOG_DEBUG=${LOG_DEBUG} LOG_TRACE=${LOG_TRACE} HN_USE_FILESYSTEM=1)
|
||||
if(PROFILING)
|
||||
add_compile_definitions(TRACY_ENABLE=1)
|
||||
endif(PROFILING)
|
||||
|
@ -44,13 +43,13 @@ if(SIMD_LEVEL EQUAL "avx2")
|
|||
elseif(SIMD_LEVEL EQUAL "avx512f")
|
||||
add_compile_definitions(FN_COMPILE_AVX512=1)
|
||||
endif()
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
add_definitions(/arch:AVX2)
|
||||
else()
|
||||
add_definitions(-m${SIMD_LEVEL})
|
||||
endif()
|
||||
if(USE_FMA)
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
add_definitions(/GL /fp:fast)
|
||||
else()
|
||||
add_definitions(-mfma)
|
||||
|
@ -62,7 +61,7 @@ set(CORE_HEADERS "deps/toml++" "deps/robin_hood" "deps/libguarded" "deps/tracy")
|
|||
set(CORE_LIBS glm::glm_static zstd::zstd_static) # picoquic
|
||||
|
||||
file(GLOB_RECURSE CLIENT_SOURCES "src/client/*.cpp" "deps/imgui/*.cpp" "deps/meshoptimizer/*.cpp" "deps/gl3w/gl3w.c" "deps/volk/volk.c")
|
||||
set(CLIENT_HEADERS "deps/imgui" "deps/meshoptimizer" "deps/gl3w" "deps/volk") # vulkan
|
||||
set(CLIENT_HEADERS "deps/imgui" "deps/meshoptimizer" "deps/gl3w" "deps/volk")
|
||||
set(CLIENT_LIBS glfw)
|
||||
|
||||
file(GLOB_RECURSE SERVER_SOURCES "src/server/*.cpp" "deps/FastNoiseSIMD/*.cpp")
|
||||
|
@ -77,20 +76,26 @@ else()
|
|||
set(CORE_LIBS ${CORE_LIBS} picoquic-core pthread dl)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(ICON univerxel.rc)
|
||||
elseif (APPLE)
|
||||
set(ICON univerxel.icns)
|
||||
endif()
|
||||
|
||||
# All in one exec
|
||||
add_executable(univerxel "src/main.cpp" ${CORE_SOURCES} ${CLIENT_SOURCES} ${SERVER_SOURCES})
|
||||
add_executable(univerxel "src/main.cpp" ${ICON} ${CORE_SOURCES} ${CLIENT_SOURCES} ${SERVER_SOURCES})
|
||||
target_compile_features(univerxel PUBLIC cxx_std_17)
|
||||
target_link_libraries(univerxel ${CORE_LIBS} ${CLIENT_LIBS} ${SERVER_LIBS})
|
||||
target_include_directories(univerxel PRIVATE ${CORE_HEADERS} ${CLIENT_HEADERS} ${SERVER_HEADERS})
|
||||
|
||||
# Standalone server
|
||||
add_executable(univerxel-server EXCLUDE_FROM_ALL "src/server.cpp" ${CORE_SOURCES} ${SERVER_SOURCES})
|
||||
add_executable(univerxel-server EXCLUDE_FROM_ALL "src/server.cpp" ${ICON} ${CORE_SOURCES} ${SERVER_SOURCES})
|
||||
target_compile_features(univerxel-server PUBLIC cxx_std_17)
|
||||
target_link_libraries(univerxel-server ${CORE_LIBS} ${SERVER_LIBS})
|
||||
target_include_directories(univerxel-server PRIVATE ${CORE_HEADERS} ${SERVER_HEADERS})
|
||||
|
||||
# Dumb client
|
||||
add_executable(univerxel-client EXCLUDE_FROM_ALL "src/client.cpp" ${CORE_SOURCES} ${CLIENT_SOURCES})
|
||||
add_executable(univerxel-client EXCLUDE_FROM_ALL "src/client.cpp" ${ICON} ${CORE_SOURCES} ${CLIENT_SOURCES})
|
||||
target_compile_features(univerxel-client PUBLIC cxx_std_17)
|
||||
target_link_libraries(univerxel-client ${CORE_LIBS} ${CLIENT_LIBS})
|
||||
target_include_directories(univerxel-client PRIVATE ${CORE_HEADERS} ${CLIENT_HEADERS})
|
||||
|
@ -111,3 +116,15 @@ add_custom_target(docs
|
|||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Build doc."
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
set_target_properties(univerxel PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Univerxel")
|
||||
set_target_properties(univerxel-client PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Univerxel Client")
|
||||
set_target_properties(univerxel-server PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Univerxel Server")
|
||||
set_source_files_properties(univerxel.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
set_target_properties(univerxel univerxel-client PROPERTIES
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}
|
||||
MACOSX_BUNDLE_ICON_FILE univerxel.icns
|
||||
MACOSX_BUNDLE_INFO_PLIST "resource/config/Info.plist.in")
|
||||
endif()
|
|
@ -103,7 +103,6 @@ PROFILING | Tracy profiling | `0`
|
|||
LOG_DEBUG | Debug logs | `0`
|
||||
LOG_TRACE | Trace logs | `0`
|
||||
NATIVE | Optimize for native CPU | `0`
|
||||
GL_OLD | Use OpenGL 4.2 not 4.6 | `0`
|
||||
|
||||
1. Build Make
|
||||
```sh
|
||||
|
|
8
TODO.md
8
TODO.md
|
@ -43,12 +43,14 @@
|
|||
|
||||
## Hello universe
|
||||
|
||||
- [~] CI build
|
||||
- [ ] CMake package
|
||||
- [x] CI build
|
||||
- [x] CMake package
|
||||
- [x] GitLab CI
|
||||
- Platfoms
|
||||
- [x] Linux
|
||||
- [~] Windows
|
||||
- [x] Windows
|
||||
- Mingw: requires picotls, picoquic and FastNoise compatibility
|
||||
- [ ] MacOS
|
||||
- [ ] Universe
|
||||
- [ ] Galaxy
|
||||
- [ ] Rotation
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,85 @@
|
|||
contouring = '''iso = 0.1000000014901161
|
||||
keep_distance = 10
|
||||
load_distance = 9
|
||||
lod_levels = [ false, true, false, true, false ]
|
||||
lod_quality = 0.0
|
||||
lod_strength = 0.1500000059604645
|
||||
manifold = true
|
||||
reordering = true
|
||||
transparency = false
|
||||
'''
|
||||
enabled = true
|
||||
|
||||
[camera]
|
||||
far = 272.0
|
||||
fov = 1.221730589866638
|
||||
near = 0.1000000014901161
|
||||
|
||||
[connection]
|
||||
host = '127.0.0.1'
|
||||
port = 4242
|
||||
|
||||
[console]
|
||||
opacity = 0.800000011920929
|
||||
scroll = true
|
||||
visible = true
|
||||
|
||||
[control]
|
||||
collide = true
|
||||
sensibility = 50
|
||||
speed = 25.0
|
||||
|
||||
[debug_menu]
|
||||
bar = true
|
||||
contouring = false
|
||||
controls = false
|
||||
render = true
|
||||
world = false
|
||||
|
||||
[editor]
|
||||
visible = false
|
||||
|
||||
[editor.tool]
|
||||
empty_air = true
|
||||
material = 5
|
||||
radius = 2
|
||||
shape = 0
|
||||
|
||||
[overlay]
|
||||
corner = 3
|
||||
visible = true
|
||||
|
||||
[render]
|
||||
blend = true
|
||||
culling = 0
|
||||
curvature = true
|
||||
curvature_depth = true
|
||||
fog = true
|
||||
fog_color = '#0000'
|
||||
geometry = true
|
||||
pbr = true
|
||||
prefer_vulkan = false
|
||||
skybox = true
|
||||
stochastic = false
|
||||
texture_angular_quality = 0
|
||||
texture_quality = 100
|
||||
textures = '1024-realistic'
|
||||
transparency = false
|
||||
triplanar = false
|
||||
|
||||
[window]
|
||||
fullscreen = false
|
||||
parallel_frames = 2
|
||||
sampling = -1
|
||||
target_fps = 23
|
||||
|
||||
[world]
|
||||
edit_handling = true
|
||||
edit_prediction = true
|
||||
keep_distance = 12
|
||||
load_distance = 11
|
||||
trust_majorant = true
|
||||
use_averages = false
|
||||
voxel_density = 1
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[Desktop Entry]
|
||||
Name=Univerxel Client
|
||||
TryExec=univerxel-client
|
||||
Exec=univerxel-client %u
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Icon=univerxel
|
||||
Categories=Game;Network;
|
||||
Keywords=game;online;
|
||||
StartupNotify=true
|
||||
Actions=Composer;
|
|
@ -0,0 +1,11 @@
|
|||
[Desktop Entry]
|
||||
Name=Univerxel
|
||||
TryExec=univerxel
|
||||
Exec=univerxel %u
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Icon=univerxel
|
||||
Categories=Game;Network;
|
||||
Keywords=game;online;
|
||||
StartupNotify=true
|
||||
Actions=Composer;
|
|
@ -0,0 +1,11 @@
|
|||
[Desktop Entry]
|
||||
Name=Univerxel Server
|
||||
TryExec=univerxel-server
|
||||
Exec=univerxel-server %u
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Icon=univerxel
|
||||
Categories=Game;Network;
|
||||
Keywords=game;online;
|
||||
StartupNotify=true
|
||||
Actions=Composer;
|
|
@ -0,0 +1,102 @@
|
|||
[client]
|
||||
contouring = '''iso = 0.1000000014901161
|
||||
keep_distance = 10
|
||||
load_distance = 9
|
||||
lod_levels = [ false, true, false, true, false ]
|
||||
lod_quality = 0.0
|
||||
lod_strength = 0.1500000059604645
|
||||
manifold = true
|
||||
reordering = true
|
||||
transparency = false
|
||||
'''
|
||||
enabled = true
|
||||
|
||||
[client.camera]
|
||||
far = 272.0
|
||||
fov = 1.221730589866638
|
||||
near = 0.1000000014901161
|
||||
|
||||
[client.connection]
|
||||
use_local = true
|
||||
|
||||
[client.console]
|
||||
opacity = 0.800000011920929
|
||||
scroll = true
|
||||
visible = true
|
||||
|
||||
[client.control]
|
||||
collide = true
|
||||
sensibility = 50
|
||||
speed = 25.0
|
||||
|
||||
[client.debug_menu]
|
||||
bar = true
|
||||
contouring = false
|
||||
controls = false
|
||||
render = true
|
||||
world = false
|
||||
|
||||
[client.editor]
|
||||
visible = false
|
||||
|
||||
[client.editor.tool]
|
||||
empty_air = true
|
||||
material = 5
|
||||
radius = 2
|
||||
shape = 0
|
||||
|
||||
[client.overlay]
|
||||
corner = 3
|
||||
visible = true
|
||||
|
||||
[client.render]
|
||||
blend = true
|
||||
culling = 0
|
||||
curvature = true
|
||||
curvature_depth = true
|
||||
fog = true
|
||||
fog_color = '#0000'
|
||||
geometry = true
|
||||
pbr = true
|
||||
prefer_vulkan = false
|
||||
skybox = true
|
||||
stochastic = false
|
||||
texture_angular_quality = 0
|
||||
texture_quality = 100
|
||||
textures = '1024-realistic'
|
||||
transparency = false
|
||||
triplanar = false
|
||||
|
||||
[client.window]
|
||||
fullscreen = false
|
||||
parallel_frames = 2
|
||||
sampling = -1
|
||||
target_fps = 23
|
||||
|
||||
[client.world]
|
||||
edit_handling = true
|
||||
edit_prediction = true
|
||||
keep_distance = 12
|
||||
load_distance = 11
|
||||
trust_majorant = true
|
||||
use_averages = false
|
||||
voxel_density = 1
|
||||
|
||||
[server]
|
||||
allow_local = true
|
||||
enabled = true
|
||||
max_players = 1
|
||||
|
||||
[server.connection]
|
||||
cert = 'content/cert.pem'
|
||||
hosts = ''
|
||||
key = 'content/key.pem'
|
||||
port = 4242
|
||||
|
||||
[server.world]
|
||||
keep_distance = 6
|
||||
load_distance = 5
|
||||
max_part_size = 32768
|
||||
path = 'world'
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
enabled = true
|
||||
max_players = 10
|
||||
|
||||
[connection]
|
||||
cert = 'content/cert.pem'
|
||||
hosts = ''
|
||||
key = 'content/key.pem'
|
||||
port = 4242
|
||||
|
||||
[world]
|
||||
keep_distance = 12
|
||||
load_distance = 10
|
||||
max_part_size = 32768
|
||||
path = 'world'
|
||||
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
#include <thread>
|
||||
#include <chrono>
|
||||
#include "../core/utils/logger.hpp"
|
||||
#include "logo.cxx"
|
||||
|
||||
/// Default floating window width
|
||||
constexpr auto DEFAULT_WIDTH = 1280;
|
||||
|
@ -84,6 +85,7 @@ bool Window::create(const CreateInfo &opt) {
|
|||
glfwSetFramebufferSizeCallback(ptr, opt.pfnResize);
|
||||
|
||||
glfwSetWindowTitle(ptr, APP_NAME);
|
||||
glfwSetWindowIcon(ptr, 1, &LOGO);
|
||||
glfwSetWindowAttrib(ptr, GLFW_RESIZABLE, true);
|
||||
|
||||
setTargetFPS(opt.fps);
|
||||
|
|
|
@ -68,6 +68,8 @@ public:
|
|||
world.trustMajorant = config["world"]["trust_majorant"].value_or(world.trustMajorant);
|
||||
world.editPrediction = config["world"]["edit_prediction"].value_or(world.editPrediction);
|
||||
world.editHandling = config["world"]["edit_handling"].value_or(world.editHandling);
|
||||
world.movePrediction = config["world"]["move_prediction"].value_or(world.movePrediction);
|
||||
world.moveCollision = config["world"]["move_collision"].value_or(world.moveCollision);
|
||||
voxel_density = config["world"]["voxel_density"].value_or(voxel_density);
|
||||
|
||||
#ifndef STANDALONE
|
||||
|
@ -148,6 +150,8 @@ public:
|
|||
{"trust_majorant", world.trustMajorant},
|
||||
{"edit_prediction", world.editPrediction},
|
||||
{"edit_handling", world.editHandling},
|
||||
{"move_prediction", world.movePrediction},
|
||||
{"move_collision", world.moveCollision},
|
||||
{"voxel_density", voxel_density}
|
||||
}));
|
||||
if(connection.has_value()) {
|
||||
|
|
|
@ -0,0 +1,297 @@
|
|||
static const unsigned char LOGO_DATA[48 * 48 * 4 + 1] =
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\025\020\037(\034\026'\362\010\005\031\375\011\006\033\375\007\004"
|
||||
"\025\362%\037\060)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\023\016#I\027"
|
||||
"\022(\377\013\010\035\377\033\026,\377\012\007\033\377\011\006\032J\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000:)b\000\026\017>\034\030\021;\217gJu%\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\020\014$g\017\013%\377\024\017.\377\021\015$\377\017\013"
|
||||
"!\377\017\013!i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\022\014%%\025"
|
||||
"\020%\217\061)B\034\010\005\024\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\010\000M\071\206\007\060$iz\034\025"
|
||||
"J\363\033\024@\377\032\022?\313\023\015\071\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\034\024\066\205\023\015.\377\036\026\066\377\016\012#\377\013\007\037\377\025\017"
|
||||
"%\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\024\017&\010\022\015'\312\012\007\035"
|
||||
"\377\012\007\035\363\012\007\036{\010\006\033\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000</\212\000\065*|\231/$g\377\036\027"
|
||||
"J\377.&N\377wn\231\377)!T\223\040\026G\000\000\000\000\000\000\000\000\000\012\010#\000\012\010\"\013"
|
||||
"\014\011(\254\034\024\066\377\022\015-\377\061'C\377\062(?\377\011\007\040\255\023\013\066"
|
||||
"\013\017\013\064\000\000\000\000\000\000\000\000\000<$Z\000\030\021-\222\015\011%\377\015\012!\377\016\013"
|
||||
"$\377\023\016$\377\010\006\035\231\011\004\035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\060%uL\"\032\\\377\035\027I\377"
|
||||
"!\032J\377\034\026I\377\031\023>\375\020\013\062U\015\011,\063\014\011*\205\024\017\061\312"
|
||||
"\027\021-\365\027\021/\377\015\011(\377\033\025\062\377\030\021.\377\016\011#\377\022\016"
|
||||
"(\377\024\016\062\365\025\020\071\312\021\015.\206\015\012*\063\070/NT\030\021;\375+$B"
|
||||
"\377\025\020/\377\022\015\061\377\013\010%\377\012\007!M\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\037\030\\\004"
|
||||
"&\035T\332$\034O\377$\034O\377\027\023D\377\037\030E\377\017\012/\373\023\016\065\376"
|
||||
"\030\022\065\377K<a\377\025\016\063\377\016\013*\377\033\023\064\377\031\021\064\377D\064"
|
||||
"S\377\032\025-\377\016\012$\377\035\026\064\377\023\015\065\377\017\013\060\377\022\015"
|
||||
",\376E\071^\373$\034D\377)\037C\377\031\022>\377\060%c\377\035\026I\332\014\011'\004"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\003\000\030\023Jp\027\022E\377+\036N\377\"\031L\377!\031G\377\031"
|
||||
"\022:\377\022\015\065\377\023\016\060\377#\034=\377\020\014\061\377\021\014/\377\020\013"
|
||||
",\377\022\014\060\377\020\014&\377\023\016'\377\013\010#\377\013\010$\377%\032;\377\015"
|
||||
"\012*\377\031\023\065\377\024\016\070\377\022\016\067\377!\031@\377\037\027I\377\276\264"
|
||||
"\334\377|j\260p\001\001\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&\033U\025\033\024G\370&\034M\377"
|
||||
"'\037R\377(\037P\377\024\016\071\377/\"A\377\036\030\065\377)!@\377\032\023\070\377"
|
||||
"\020\014.\377\012\010\040\377\034\023,\377\013\010!\377\016\012#\377\032\024*\377\031\024"
|
||||
".\377\017\012,\377\026\020/\377\030\022\070\377\023\016\070\377\026\022;\377\031\023\067"
|
||||
"\377\063'X\377O?|\371dR\237\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\001\000\016\010+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\033\023M\015+!`\265\033"
|
||||
"\023J\377\036\026J\377\030\022G\377D\065_\377.&M\377:-R\377\023\016\061\377\021\015"
|
||||
"/\377\022\015\062\377\015\012+\376-\"<\363\014\010\037\351\010\006\032\351\010\005\031\363"
|
||||
"\011\007\036\376!\032\070\377%\035:\377\021\015'\377\025\017\066\377\031\022;\377\026\021"
|
||||
":\377\024\015\066\377\040\030B\377\027\017\067\377\027\020-\265\017\011+\015\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\005\023\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\015\011,\007\020\013\061\231\031\022>M\014\012\065\004\003\002\007\000\000"
|
||||
"\000\000\000/\"Z\015$\033R\302TG\177\377cY\207\377$\034Q\377\033\024D\377\"\030C\377"
|
||||
"\035\026B\377$\033?\377\016\012-\362\016\013\060\243)\035DW\015\011.$\012\007#\037\034\027"
|
||||
".'\007\005\031'\021\013$\037\011\007\037$\017\012/W\015\011%\243\025\017*\362\021\014\063\377"
|
||||
"\025\016<\377J>e\377(\034F\377\023\016\066\377\021\014/\377)\036=\377\017\011,\303\020"
|
||||
"\012.\015\000\000\000\000\000\000\001\000\026\020\064\004\017\011$M\026\017!\231\005\003\026\007\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\010-\000\016\013(y\031\024\065\377.\040F\377\031"
|
||||
"\023@\332\032\023Hq\037\026P\025\034\025L\264$\034P\377)\036W\377\036\026P\377\060$Q\377"
|
||||
"\037\030E\377)\036K\377>(]\361\026\020<~\021\014\061\036\017\013\061_\020\014\062\261\020"
|
||||
"\014\060\352\031\022\061\374\027\020'\377\016\012\"\377\020\014&\374\017\013*\352\013\010"
|
||||
"$\261\011\007\037`\014\011(\036\021\014\067~\033\023F\361*\037M\377\025\017<\377\040\031@"
|
||||
"\377\036\026?\377\024\015\061\377\021\013/\377\037\025<\265\022\013\060\025\026\016\064p"
|
||||
"\017\012)\332\017\012&\377\021\014\036\377\017\012\036{\010\005\027\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\015\012+\033\032\024\063\362\031\022\063\377\027\021;\377\037\027M\377"
|
||||
")\036S\377\070(Y\371\035\027L\377\036\027H\377!\030K\377\027\021@\377\030\021C\377,"
|
||||
"\037L\377.\040O\275\237|\255&\032\023=q\040\031;\351\026\021\066\377\034\025\071\377"
|
||||
"\021\014\062\354\033\026\071\304\040\030\070\256\035\027\070\255\021\015(\304\027\021\060"
|
||||
"\354\012\007\037\377\033\024+\377\013\010#\351\016\012.r\037\027J%<\060`\275\034\025I\377"
|
||||
"\033\023I\377(\034O\377\037\027<\377\037\027:\377\034\023<\377\037\030=\371WHp\377\024"
|
||||
"\014/\377\030\021.\377\040\027.\377\034\023)\363\017\012\040\034\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\022\015\064\216\023\016\063\377\021\014\063\377\030\021A\377&\034X\377$"
|
||||
"\034P\377\031\022D\377!\031N\377\037\031H\377\026\020@\377\031\022C\377\033\024C\377"
|
||||
"\031\023@\226\034\023L(\040\030P\311\027\021;\377\022\015\062\366\032\023\070\232!\032;"
|
||||
"\071\017\015\064\005\017\013\061\000\000\000\000\000\000\000\000\000\013\006\040\000\012\007#\005\011\007\036\071\023"
|
||||
"\016(\231\030\023\061\365\021\014\065\377\030\021B\312\030\021D(!\027R\226%\033N\377&"
|
||||
"\033Q\377&\033F\377!\027<\377\025\016\064\377\031\022:\377\032\021;\377!\027\067\377"
|
||||
"\021\013.\377#\033\067\377\015\010\037\377\031\022&\217\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\025\020<%\023\016\071\312\033\024;\377\026\020@\377\032\023F\377\032\024E\377\036"
|
||||
"\027H\377#\032O\377\036\026K\377\035\026K\377\031\024G\377\030\022D\226\032\024K\063a"
|
||||
"R\205\350!\031O\377\021\015\065\266\021\014\065\"\016\011/\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\007&\000\017\012.!.&L\265*\037T\377"
|
||||
"%\035U\350\036\026P\064\037\026L\226\034\024J\377\037\027D\377\062&N\377\034\023\071\377"
|
||||
"\031\022\067\377$\030B\377I\065X\377\030\021\064\377\035\025\067\377\024\015)\313\012\006"
|
||||
"\032%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021\014\064\010\024\016\071\222(\035"
|
||||
"G\375\033\024D\377#\034G\377\033\024C\377&\035Q\377-\040Z\377\037\027L\377=-[\275"
|
||||
"=\061](\033\024E\350&\034[\376\036\027R\203\023\016;\003\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030"
|
||||
"\023D\003\035\025K\202#\032U\376\031\023G\350\037\026P(\035\024J\275-#N\377\031\022=\377"
|
||||
"!\030A\377$\033E\377#\030C\377#\032?\377\060\"E\375XDe\223lW\205\010\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\010\063\000#\034BT\022\016\070"
|
||||
"\373\026\021A\377\025\020@\377(\035S\377*\037]\377(\036Z\361O\067e&#\032N\311&\035"
|
||||
"T\377&\035T\203!\027T\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\030U\000C\061"
|
||||
"g\203\062$S\377\060!_\312\037\027R%%\033O\361&\033K\377.\037P\377\033\024I\377\040"
|
||||
"\030P\377,!U\373\036\024JU\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021\014\064\063\023\016:\376\030\023H\377\034\025J\377"
|
||||
".\"Y\377G\071r\377g[\217~\036\026Sq?\060g\377.\"_\266K\071p\003\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\020[\003\037\027Q\265/\"f\377\062&o"
|
||||
"r%\033\\~%\033W\377G\065i\377\032\023H\377%\032W\377<*b\376F/m\064\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\026\021"
|
||||
"B\205\026\021A\377\033\026I\377\037\031N\377+\"V\377,![\362'\034`\036<-s\351/$p\366"
|
||||
"~i\236\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000$\033^!=+q\365\071+s\351\062$j\037&\034^\362-\040_\377!\030V\377$\032U\377"
|
||||
"\061!U\377\064\040`\206\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\027\023F\000\027\022C\312\027\022E\377#\034Q\377</c\377\035\026"
|
||||
"O\377\"\032P\244\062%l_:,s\377/%q\232\061't\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\040e\000+!i\231\070*v\377,\"j_\060"
|
||||
"$p\243;-r\377)\037d\377-!`\377A\062g\377+\037U\313\"\025Q\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\022G\013\035\027G\365\036\026"
|
||||
"F\377\034\025K\377\065(a\377'\036Y\377\031\024JX.#l\261\065)w\377\062's:\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\067*y\070>\061\200\377;.}\261\067+{W<-v\377\071+o\377-\"g\377(\034\\\377"
|
||||
"%\032X\365\037\026P\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\004\022(\021\015&I\024\016"
|
||||
"\065g\026\021@\206\034\025L\254!\030V\377\035\025M\377\060'X\377=\061j\377,\040]\376"
|
||||
"\037\027U$/$i\352D\065\201\355\066+{\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\070,}\005=\061\205\354;.\202"
|
||||
"\352\067+|$@\061\204\376p`\237\377\067)w\377\066'q\377\065'o\377\060$e\255I\064"
|
||||
"k\206&\032Rh\066(YJ</Q(\012\007\030\361\015\011\040\377\024\016\064\377\034\025K\377'\035"
|
||||
"\\\377n]\217\377%\034W\377!\031Y\377'\035b\377/$i\363*\040g\037.#h\374=\060|\304"
|
||||
"I\070\211\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000F\066\222\000N?\234\304@\062\206\374\067+|\037\071-|\363"
|
||||
"\060$o\377@\060{\377Q@\207\377<,w\377;*v\377\071(m\377\071)j\377\062#Z\377\061"
|
||||
"%L\361\027\020\061\375\021\013$\377\014\010&\377\033\024F\377'\034V\377#\032W\377!\030"
|
||||
"U\377$\033[\377TD\202\377zj\246\351)\040f'+\"h\377/$n\256\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000TD\243\256M>\227\377F\066\215';/\200\351\067*y\377F\065\203\377"
|
||||
"<-\177\377?.\201\377\066'u\377:)w\377\065't\377F\061q\377%\032S\374\027\020\065"
|
||||
"\375\024\016\060\377-#F\377+\037M\377\036\026O\377\036\026S\377C\067j\377'\034\\\377"
|
||||
"\067+o\377<.}\351+!j',!g\377A\060t\256\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`M\256"
|
||||
"\256ZH\251\377PB\236'I;\221\351VC\226\377B\062\207\377B\062\205\377C\061\205"
|
||||
"\377A\061\177\377O=\203\377J\067\177\377;,z\377;+q\374\030\021\066\361\025\017:"
|
||||
"\377\032\022E\377!\030O\377\037\026P\377\062%[\377\040\027O\377\071)i\377\063's\377"
|
||||
"\070+z\363\070*z\037/$n\374)\037e\304*\040h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000bK\266\000u]\302\304"
|
||||
"\232\202\320\374cN\266\037\\J\256\363SB\237\377K;\227\377M\071\217\377>-\177"
|
||||
"\377\061$n\377,\037g\377>.o\377]L\217\377D\061\204\361aSs(\027\020>I\033\022Fh!"
|
||||
"\027R\206!\030Q\255\033\024K\377\062'^\377.\"h\377Q<\201\377A.z\376\071*{$\063'"
|
||||
"t\352+\040g\355\060\040i\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000jR\300\005w_\305\354rY\301\352TE\247"
|
||||
"$VE\250\376UD\245\377_J\252\377Q?\226\377N;\210\377\061#m\255+\035c\206-\040"
|
||||
"_g\064%pIK\067\217(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000!\026S\013'\033]\365+\037^\377"
|
||||
"/#g\377R>\202\377@.x\377A/|X\061%n\261+\037e\377\061!j:\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000jQ\273"
|
||||
"\071t]\310\377nV\301\261hS\273WbN\262\377]J\255\377YF\243\377B\060\205\377"
|
||||
"=+}\365=+~\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000;(j\000-\037c\312,\037a\377\064'k\377\062$p\377\062$n\377\061#l\244/!h_\060!i"
|
||||
"\377\071&r\232A,|\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000WA\245\000VA\243\231~f\302\377\214t\321_\206n\322\243qZ\303"
|
||||
"\377`K\260\377R?\232\377<+s\377,\035`\312/\036h\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000+\034\\\205)\033]\377\062#g\377"
|
||||
"\064$m\377\064%m\377.\036c\362\061\040g\036\070%n\351\067#k\366\063\035`\"\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000eJ\263!j"
|
||||
"O\262\365~c\304\351\205o\323\037\200j\317\362nV\300\377^I\257\377I\066\220"
|
||||
"\377E\065y\377M>u\206\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000#\026Q\063!\024L\376\"\024L\377)\031S\377-\034]\377"
|
||||
"\063!d\377\071$m~\065\040gq\061\035`\377.\030S\266\060\030K\003\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000|a\307\003sY\301\265y\\\302\377\245\213"
|
||||
"\324r\223|\331~\210q\322\377sY\267\377VA\234\377E\062\210\377>+x\376-\034b"
|
||||
"\064\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000*\032V\000%\027QT#\025M\373\031\017<\377\036\021=\377)\027I\377*\030T\377R?y\362\063"
|
||||
"\034b&\062\034`\311;#f\377\060\031V\203(\017;\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\202c\307\000\225w\323\203\204i\315\377}b\311\311\216u\325&\221y\326"
|
||||
"\361\204k\315\377lS\263\377R;\225\377A,\201\377@+x\373<,lU\000\000C\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000G<U\010\024\013\061\222\"\025"
|
||||
"K\375\037\023F\377\022\012,\377\020\007!\377\033\015\063\377'\025L\377/\033]\377\066\037"
|
||||
"a\276\070\040g'F,x\350=%p\376.\027R\203\070\040d\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\241"
|
||||
"\200\331\003\225t\323\203\231|\331\376\225{\327\350\231\201\331(\244\213\340"
|
||||
"\275\244\214\337\377\211o\321\377gM\262\377R;\226\377C-\200\377\070%q\377"
|
||||
"\063!f\375<(m\223%\024P\011\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\010'%"
|
||||
"\025\015)\312\017\010$\377\020\010(\377\033\017<\377\020\007$\377\011\004\022\377\014\005\030"
|
||||
"\377\036\017\065\377-\030P\377\061\027U\377:\036f\227O\062\210\063G,x\350\071\037c\377"
|
||||
":\034[\266\070\031V\"B\037h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\212^\303\000\225k\304\"\235x\324\265\217l\315\377\230y\326"
|
||||
"\350\235\201\334\063\231y\322\226\247\214\337\377\244\207\333\377\211m\316"
|
||||
"\377rV\275\377ZA\241\377aK\225\377\061\037d\377\062\"Z\377+\034X\377\060\036Y\313"
|
||||
"&\027Q%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\006\034\216\031\021+\377\024\014\061\377"
|
||||
"\016\007#\377\017\007\040\377\013\004\024\377\012\004\021\377\015\005\030\377\027\012*\377*\023"
|
||||
"H\377:\034`\377H*w\377K-~\227?%r(F*w\311\071\035\\\377<\032Y\366fC\206\232R/"
|
||||
"\202\071Y\066\221\005Y\065\220\000\000\000\000\000\000\000\000\000oF\246\000\210^\303\005\201V\273\071"
|
||||
"\200T\270\231vN\252\366\203Z\272\377\200Z\275\311\210c\306(\253\211\334\226"
|
||||
"\234}\321\377xZ\260\377\234\177\321\377\220u\320\377eK\255\377S;\230\377"
|
||||
"F\060}\377\067#f\377\066#c\377:(f\377\064\"^\377P\064f\217\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\021\012+\033)\037<\362\030\015\067\377\035\022\066\377\017\006\034\377\010"
|
||||
"\004\016\377\014\005\025\371\025\010%\377\036\014\062\377+\021C\377P\062o\377O,|\377L*"
|
||||
"|\377N,\201\276Z\066\217&>!hq;\033T\351K\"h\377S+|\377`;\227\355b<\227\304"
|
||||
"jB\242\256c\071\226\256k<\231\304\201U\265\354oC\243\377mB\242\377c\071\223"
|
||||
"\351mB\235r\205[\267&\242|\326\275\255\215\340\377\252\211\335\377\235}\327"
|
||||
"\377\230}\323\377\204j\306\377[B\237\377A*}\371;%p\377\064\037g\377\062\036a"
|
||||
"\377\064\"b\377)\032Y\363&\030R\034\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\025\015\063"
|
||||
"\000\022\012-z\025\014\062\377\023\011)\377\016\006\032\332\007\004\014q\013\005\023\025#\016\063"
|
||||
"\264,\022A\377<\031T\377M\"i\377Y,\177\377P'v\377U,\200\377f;\225\361a\066\223"
|
||||
"~V,\177\036D\035[_T's\261c\065\220\352l@\231\374k?\234\377n?\232\377\260\177"
|
||||
"\276\374i\071\217\352b\065\216\261uG\252_\223h\306\036\207b\266~uK\250\361\230"
|
||||
"l\311\377\236x\324\377\235w\322\377\211g\303\377L\061}\377cI\250\377S<\230"
|
||||
"\265H/\200\025A(pp\062\034a\331\060\034]\377.\035Y\377/\034V{\"\030T\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\013\006\034\007\012\005\026\231\015\005\031M\026\011&\004\000"
|
||||
"\000\000\000\000\000\000\000*\021>\015;\031U\302d\065\201\377yB\233\377t?\240\377Z*z\377r\070"
|
||||
"\225\377\206L\257\377\200E\253\377u;\234\362h\061\212\244|=\237Xx\071\225$"
|
||||
"\201L\245\037j;\220'i\067\224'\221U\256\037o;\230$i\067\224W\215Z\275\243\245"
|
||||
"u\323\362\204Z\262\377\214\\\275\377\207U\265\377\204T\266\377\214b\301\377"
|
||||
"nK\245\377B(_\377;%h\303[A\240\015\000\000\000\000\001\000\004\000/\030Z\004-\030\\L)\030Y\231"
|
||||
"(\026S\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\004\017\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000Y*~\015\206L\257\265\215O\270\377"
|
||||
"\202D\254\377w:\227\377\216M\265\377\237a\302\377\243b\302\377\232S\271\377"
|
||||
"\221N\266\377\210D\251\377s\065\216\376{;\231\363u:\230\351\177J\254\351~"
|
||||
"I\257\363r>\237\376t?\240\377\216Z\275\377\264\213\327\377\234k\313\377\217"
|
||||
"[\275\377\205J\257\377zC\244\377vF\245\377lF\241\377R\061{\265\017\006\027\015"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\032\\\000\001\000\003\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\225Q\274\025\230W\276\370\231V\276\377\241c\300\377"
|
||||
"\237^\301\377\247i\306\377\260q\312\377\245d\300\377\240[\276\377\230W\272"
|
||||
"\377\232Y\273\377\223P\264\377q\066\215\377p\070\222\377{D\240\377t;\230\377"
|
||||
"s:\227\377\213P\265\377\223^\277\377\226b\305\377\222\\\275\377\204I\255"
|
||||
"\377\203P\250\377o>\233\377i?\232\371Z\064\215\025\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\014\003\020\000\236W\275p\242`\303\377\247d\304\377\262r\312\377\273\200\321\377"
|
||||
"\257o\307\377\267{\315\377\274\202\326\377\257r\313\377\276\206\330\377\257"
|
||||
"u\312\377\227S\260\377n\062\202\377Y&k\377\177O\224\377h/\201\377g\062}\377"
|
||||
"\221S\266\377\232^\300\377\230^\300\377\232d\301\377\220Q\270\377}A\244\377"
|
||||
"r?\236\377c\065\220\377zV\233p\023\013\027\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\243W\272\004\243Y"
|
||||
"\272\331\247e\303\377\252h\304\377\271z\317\377\305\211\331\377\266w\314"
|
||||
"\373\246b\276\376\256r\312\377\264x\317\377\271\177\323\377\255q\311\377"
|
||||
"\240]\274\377\205B\237\377o\062\202\377](p\377j/}\377p\064\212\377\215H\260"
|
||||
"\377\214F\255\377\226U\272\376\226\\\276\373\212J\262\377\215K\261\377\212"
|
||||
"K\261\377d\062\215\377X/~\332M$t\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\250c\275L\247]\271\377\247"
|
||||
"b\276\377\262r\312\377\272{\317\377\312\230\334\375\337\300\352U\250d\301"
|
||||
"\063\261t\315\205\261t\314\312\255s\313\365\242b\300\377\244c\303\377\223"
|
||||
"Q\257\377\227R\262\377\216N\246\377\235c\263\377\213K\243\365\222N\264\312"
|
||||
"\206A\244\206\225O\266\063\217M\267T\205G\255\375z>\242\377\202A\247\377\202"
|
||||
"H\237\377[\060~\377M%uM\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\246^\273\000\253h\300\231\251b\274\377\246Z"
|
||||
"\270\377\263t\312\377\265u\313\377\260p\307\223\315\214\332\000\000\000\000\000\006\002"
|
||||
"\010\000\243a\301\000\254o\310\013\302\214\332\254\315\233\342\377\317\233\342"
|
||||
"\377\313\227\337\377\264y\316\377\271\207\320\255\306\230\321\013\222L\265"
|
||||
"\000\004\001\006\000\000\000\000\000\216L\266\000z=\237\222k\061\213\377q\067\224\377{B\227\377"
|
||||
"h<\204\377Y\063z\231J#p\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\013\003\016\000\256o\305\007\252d\275z\247]\271\363\257"
|
||||
"o\306\377\264r\310\313\257h\301\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\313\227\343\205\316\232\346\377\305\216\337\377\305\216\337\377\304\216"
|
||||
"\335\377\272\201\326\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000n\062\217"
|
||||
"\010g.\201\312r\066\224\377w\071\225\363f.\207zS%v\007\002\001\005\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\246`\271\000\247b\275\034\253k\301\217\265u\312%\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\312\227\344g\312\225\343\377\303\215\340\377\304\217"
|
||||
"\340\377\311\224\340\377\307\221\336h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000g.\201$q\063\216\217p\064\220\034z\070\226\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\323\245\347I\323\242\350\377\316\233\345\377\310\224"
|
||||
"\341\377\311\224\340\377\310\222\336I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\322\242\350'\322\243\350\361\312\230\344\375\275\207\333\375"
|
||||
"\253n\307\361\257t\312(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
|
||||
|
||||
static const struct GLFWimage LOGO = {48, 48, (unsigned char*)LOGO_DATA};
|
|
@ -12,11 +12,8 @@
|
|||
using namespace render::gl;
|
||||
|
||||
constexpr auto GL_MAJOR = 4;
|
||||
#if GL_OLD
|
||||
constexpr auto GL_MINOR = 2;
|
||||
#else
|
||||
constexpr auto GL_MINOR = 6;
|
||||
#endif
|
||||
constexpr auto GL_MINOR_MIN = 2;
|
||||
constexpr auto GL_MINOR_BEST = 6;
|
||||
|
||||
#define CONTENT_DIR "content/"
|
||||
#define TEXTURES_DIR CONTENT_DIR "textures/"
|
||||
|
@ -50,7 +47,7 @@ void framebuffer_size_callback(GLFWwindow *, int width, int height) {
|
|||
bool Renderer::Load(Window& window, const render::renderOptions& opt, const windowOptions& windOpt) {
|
||||
Window::CreateInfo windowInfo;
|
||||
windowInfo.pfnResize = framebuffer_size_callback;
|
||||
windowInfo.client = {Window::CreateInfo::Client::Type::GL, GL_MAJOR, GL_MINOR};
|
||||
windowInfo.client = {Window::CreateInfo::Client::Type::GL, GL_MAJOR, GL_MINOR_MIN};
|
||||
windowInfo.samples = windOpt.getSamples();
|
||||
windowInfo.fps = windOpt.targetFPS;
|
||||
windowInfo.fullscreen = windOpt.fullscreen;
|
||||
|
@ -62,9 +59,13 @@ bool Renderer::Load(Window& window, const render::renderOptions& opt, const wind
|
|||
LOG_E("Failed to initialize OpenGL");
|
||||
return false;
|
||||
}
|
||||
if (!gl3wIsSupported(GL_MAJOR, GL_MINOR)) {
|
||||
LOG_E("OpenGL " << GL_MAJOR << "." << GL_MINOR << " not supported");
|
||||
return false;
|
||||
if (!gl3wIsSupported(GL_MAJOR, GL_MINOR_BEST)) {
|
||||
if (gl3wIsSupported(GL_MAJOR, GL_MINOR_MIN)) {
|
||||
LOG_W("OpenGL " << GL_MAJOR << "." << GL_MINOR_BEST << " not supported. Some feature like texture sharpness may not work");
|
||||
} else {
|
||||
LOG_E("OpenGL " << GL_MAJOR << "." << GL_MINOR_MIN << " not supported");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
LOG_D("OpenGL " << glGetString(GL_VERSION) << ", GLSL " << glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
|
|
|
@ -76,9 +76,8 @@ void applySampler(GLuint textureID, const Texture::sampling& props) {
|
|||
glTextureParameteri(textureID, GL_TEXTURE_MAG_FILTER, getFilter(props.magLinear, props.mipmap));
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MIN_FILTER, getFilter(props.minLinear, props.mipmap));
|
||||
glTextureParameterf(textureID, GL_TEXTURE_LOD_BIAS, props.mipmapLod);
|
||||
#if !GL_OLD
|
||||
glTextureParameterf(textureID, GL_TEXTURE_MAX_ANISOTROPY, props.anisotropy);
|
||||
#endif
|
||||
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_T, wrap);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_R, wrap);
|
||||
|
|
|
@ -128,6 +128,19 @@ void DistantUniverse::update(voxel_pos pos, float deltaTime) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (options.movePrediction) {
|
||||
entities.remove([&](size_t eId, Entity &entity) {
|
||||
entity.instances.remove([&](size_t iId, Universe::Entity::Instance &inst) {
|
||||
if (eId == PLAYER_ENTITY_ID.index && iId == playerId)
|
||||
return false;
|
||||
|
||||
// MAYBE: leap after entities packet
|
||||
inst.pos += inst.velocity * deltaTime;
|
||||
return false;
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
contouring->update(pos, areas);
|
||||
}
|
||||
|
@ -172,7 +185,7 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
}
|
||||
|
||||
case server_packet_type::COMPRESSION: {
|
||||
const auto remain = packet.readAll();
|
||||
const auto remain = packet.readRemaining();
|
||||
dict.emplace(remain.data(), remain.size());
|
||||
LOG_T("Compression dictionnary loaded");
|
||||
mayQueryChunks = true;
|
||||
|
@ -187,13 +200,13 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
}
|
||||
|
||||
case server_packet_type::MESSAGE: {
|
||||
const auto remain = packet.readAll();
|
||||
const auto remain = packet.readRemaining();
|
||||
onMessage(std::string((const char*)remain.data(), remain.size()));
|
||||
break;
|
||||
}
|
||||
|
||||
case server_packet_type::AREAS: {
|
||||
while(!packet.isFull()) {
|
||||
while(!packet.isDone()) {
|
||||
area_id id;
|
||||
world::Area::params p;
|
||||
if(!packet.read(id) || !packet.read(p))
|
||||
|
@ -228,7 +241,7 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
// MAYBE: then create virtual or non chunk of single material
|
||||
uint16_t full = 0;
|
||||
uint16_t total = 0;
|
||||
while (!packet.isFull()) {
|
||||
while (!packet.isDone()) {
|
||||
region_chunk_pos cpos;
|
||||
Voxel voxel;
|
||||
if (!packet.read(cpos) || !packet.read(voxel))
|
||||
|
@ -247,7 +260,7 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
if (!dict.has_value())
|
||||
break;
|
||||
|
||||
if (packet.isFull()) {
|
||||
if (packet.isDone()) {
|
||||
mayQueryChunks = true;
|
||||
break;
|
||||
}
|
||||
|
@ -267,7 +280,7 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
}
|
||||
|
||||
std::vector<char> buffer;
|
||||
if(auto err = dict.value().decompress(packet.readAll(), buffer)) {
|
||||
if(auto err = dict.value().decompress(packet.readRemaining(), buffer)) {
|
||||
LOG_E("Corrupted chunk packet " << err.value());
|
||||
break;
|
||||
}
|
||||
|
@ -313,14 +326,14 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
break;
|
||||
}
|
||||
|
||||
while(!packet.isFull()) {
|
||||
while(!packet.isDone()) {
|
||||
chunk_pos pos = chunk_pos(INT_MAX);
|
||||
packet.read(pos);
|
||||
chunk_voxel_idx count = 0;
|
||||
packet.read(count);
|
||||
if (auto ptr = it->second->setChunks().findInRange(pos)) {
|
||||
auto chunk = std::dynamic_pointer_cast<Chunk>(ptr.value());
|
||||
for (auto i = 0; i < count && !packet.isFull(); i++) {
|
||||
for (auto i = 0; i < count && !packet.isDone(); i++) {
|
||||
Chunk::Edit edit;
|
||||
packet.read(edit);
|
||||
chunk->apply(edit);
|
||||
|
@ -334,7 +347,7 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
|
||||
case server_packet_type::ENTITY_TYPES: {
|
||||
entities.clear();
|
||||
while(!packet.isFull()) {
|
||||
while(!packet.isDone()) {
|
||||
size_t index;
|
||||
glm::usvec3 size;
|
||||
glm::vec3 scale;
|
||||
|
@ -351,7 +364,7 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
|
||||
case server_packet_type::ENTITIES: {
|
||||
entities.remove([](size_t, Entity &entity) { entity.instances.clear(); return false; });
|
||||
while(!packet.isFull()) {
|
||||
while(!packet.isDone()) {
|
||||
size_t entity_idx;
|
||||
size_t count;
|
||||
if (!(packet.read(entity_idx) && packet.read(count)))
|
||||
|
@ -360,7 +373,7 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
if (auto entity = entities.get(entity_idx)) {
|
||||
if (count == 0)
|
||||
continue;
|
||||
for (size_t i = 0; i < count && !packet.isFull(); i++) {
|
||||
for (size_t i = 0; i < count && !packet.isDone(); i++) {
|
||||
size_t idx;
|
||||
glm::ifvec3 pos;
|
||||
glm::vec3 vel;
|
||||
|
@ -410,15 +423,9 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
auto area = std::get_if<Universe::Entity::area_t>(&it->shape);
|
||||
assert(area);
|
||||
area->clear();
|
||||
glm::i64 i = 0;
|
||||
while (!packet.isFull()) {
|
||||
i++;
|
||||
size_t size = 0;
|
||||
if (!packet.read(size))
|
||||
break;
|
||||
|
||||
while (!packet.isDone()) {
|
||||
std::vector<char> buffer;
|
||||
if(auto err = dict.value().decompress(packet.readPart(size), buffer)) {
|
||||
if(auto err = dict.value().decompress(packet.readSizedPart(), buffer)) {
|
||||
LOG_E("Corrupted entity chunk packet " << err.value());
|
||||
break;
|
||||
}
|
||||
|
@ -427,15 +434,15 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
area->push_back(std::make_shared<Chunk>(iss));
|
||||
}
|
||||
auto scale = glm::lvec3(1) + glm::divide(it->size);
|
||||
if (i != scale.x * scale.y * scale.z) {
|
||||
LOG_E("Corrupted entity area");
|
||||
if ((long)area->size() != scale.x * scale.y * scale.z) {
|
||||
LOG_E("Corrupted entity area " << area->size() << "!=" << (scale.x * scale.y * scale.z));
|
||||
break;
|
||||
}
|
||||
contouring->onEntityLoad(id, scale, *area);
|
||||
} else {
|
||||
auto model = std::get_if<Universe::Entity::model_t>(&it->shape);
|
||||
assert(model);
|
||||
auto remain = packet.readAll();
|
||||
auto remain = packet.readRemaining();
|
||||
model->resize(remain.size());
|
||||
//MAYBE: avoid storing model
|
||||
memcpy(model->data(), remain.data(), remain.size());
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace world::client {
|
|||
bool editPrediction = true;
|
||||
/// Get only edits commands and compute locally
|
||||
bool editHandling = true;
|
||||
/// Apply velocity locally. Smooth entities positions
|
||||
bool movePrediction = true;
|
||||
/// Check for entities collisions
|
||||
bool moveCollision = false;
|
||||
};
|
||||
struct connection: net::address {
|
||||
connection(): net::address{"127.0.0.1", 4242} { }
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace glm {
|
|||
}
|
||||
inline ifvec3 operator+(const offset_t& v) const { return ifvec3(raw, offset + v); }
|
||||
inline ifvec3 operator-(const offset_t &v) const { return ifvec3(raw, offset - v); }
|
||||
inline ifvec3 operator-(const ifvec3 &v) const { return ifvec3(raw - v.raw, offset - v.offset); }
|
||||
inline ifvec3 operator/(int i) const { return ifvec3(raw / i, offset / (i * 1.f), false); }
|
||||
inline ifvec3 operator*(int i) const { return ifvec3(raw * i, offset * (i * 1.f)); }
|
||||
};
|
||||
|
|
|
@ -76,7 +76,8 @@ namespace glm {
|
|||
constexpr T inline max_axis(const vec<3, T> &v) {
|
||||
return std::max({v.x, v.y, v.z});
|
||||
}
|
||||
ivec3 inline inormalize(const ivec3 &v) {
|
||||
template <typename T>
|
||||
ivec3 inline inormalize(const vec<3, T> &v) {
|
||||
const auto a = glm::abs(v);
|
||||
return a.x >= a.y ? (a.x >= a.z ? ivec3(glm::sign(v.x), 0, 0) : ivec3(0, 0, glm::sign(v.z))) :
|
||||
(a.y >= a.z ? ivec3(0, glm::sign(v.y), 0) : ivec3(0, 0, glm::sign(v.z)));
|
||||
|
|
|
@ -24,6 +24,131 @@ struct view {
|
|||
constexpr size_t size() const { return siz; }
|
||||
constexpr bool isDone() const { return cur >= siz; }
|
||||
};
|
||||
// Abstract data writer
|
||||
struct in_view: view {
|
||||
in_view(uint8_t *ptr, size_t size): view(size), ptr(ptr) {
|
||||
assert(ptr != nullptr);
|
||||
}
|
||||
|
||||
uint8_t* ptr;
|
||||
uint8_t* writeTo(size_t len) {
|
||||
assert(cur + len <= siz);
|
||||
auto p = ptr + cur;
|
||||
cur += len;
|
||||
return p;
|
||||
}
|
||||
void write(const uint8_t* data, size_t len) {
|
||||
memcpy(writeTo(len), data, len);
|
||||
}
|
||||
};
|
||||
/// Writer with Dynamic allocation and subparts
|
||||
struct in_writer: public in_view {
|
||||
private:
|
||||
static constexpr auto EMPTY_OFFSET = 0x1000;
|
||||
static uint8_t* alloc(size_t size) { return (uint8_t*)(size > 0 ? ::malloc(size) : reinterpret_cast<uint8_t*>(EMPTY_OFFSET)); }
|
||||
static uint8_t* realloc(uint8_t* ptr, size_t size) { return (uint8_t*)::realloc(ptr, size); }
|
||||
static void free(uint8_t* ptr) { ::free(ptr); }
|
||||
|
||||
inline void auto_size(size_t len) {
|
||||
if (cur + len > siz)
|
||||
resize(cur + len);
|
||||
}
|
||||
|
||||
public:
|
||||
in_writer(size_t init_size = 0): in_view(alloc(init_size), init_size), vis_siz(init_size) { }
|
||||
~in_writer() { if (ptr != reinterpret_cast<uint8_t*>(EMPTY_OFFSET)) free(ptr); }
|
||||
|
||||
size_t vis_siz = 0;
|
||||
|
||||
uint8_t* data() { return ptr; }
|
||||
constexpr size_t size() const { return vis_siz; }
|
||||
|
||||
void write(const void* data, size_t len) {
|
||||
in_view::write((uint8_t*)data, len);
|
||||
}
|
||||
/// Write without resize
|
||||
template<typename D>
|
||||
void write(const D& d) {
|
||||
write(&d, sizeof(d));
|
||||
}
|
||||
|
||||
uint8_t* pushTo(size_t len) {
|
||||
auto_size(len);
|
||||
return writeTo(len);
|
||||
}
|
||||
void push(const void* data, size_t len) {
|
||||
auto_size(len);
|
||||
in_view::write((uint8_t*)data, len);
|
||||
}
|
||||
template<typename D>
|
||||
void push(const D& d) {
|
||||
push(&d, sizeof(d));
|
||||
}
|
||||
|
||||
size_t getCursor() const { return cur; }
|
||||
void writeAt(size_t pos, const void* data, size_t len) {
|
||||
assert(pos + len <= vis_siz);
|
||||
memcpy(ptr + pos, data, len);
|
||||
}
|
||||
template<typename D>
|
||||
void writeAt(size_t pos, const D& d) {
|
||||
writeAt(pos, &d, sizeof(d));
|
||||
}
|
||||
|
||||
void reserve(size_t target) {
|
||||
if (target >= siz) {
|
||||
ptr = realloc(ptr, target);
|
||||
siz = target;
|
||||
}
|
||||
}
|
||||
void resize(size_t target) {
|
||||
reserve(target);
|
||||
vis_siz = target;
|
||||
}
|
||||
|
||||
bool isFull() const {
|
||||
return cur >= vis_siz;
|
||||
}
|
||||
|
||||
// Must take ptr ownership before
|
||||
void reset() {
|
||||
ptr = reinterpret_cast<uint8_t*>(EMPTY_OFFSET);
|
||||
cur = 0;
|
||||
siz = 0;
|
||||
vis_siz = 0;
|
||||
}
|
||||
|
||||
struct part {
|
||||
part(in_writer* parent): up(parent), start(parent->cur) { }
|
||||
in_writer* up;
|
||||
size_t start;
|
||||
|
||||
uint8_t* data() { return up->data() + start; }
|
||||
constexpr size_t size() const { return up->size() - start; }
|
||||
|
||||
void reserve(size_t size) {
|
||||
up->reserve(start + size);
|
||||
}
|
||||
void resize(size_t size) {
|
||||
up->resize(start + size);
|
||||
}
|
||||
};
|
||||
template<typename CB>
|
||||
size_t pushPart(const CB& callback) {
|
||||
const auto prev = cur;
|
||||
callback(part(this));
|
||||
cur = vis_siz;
|
||||
return cur - prev;
|
||||
}
|
||||
template<typename CB>
|
||||
size_t pushSizedPart(const CB& callback) {
|
||||
const auto size_cur = cur;
|
||||
push<size_t>(0);
|
||||
const size_t size = pushPart(callback);
|
||||
writeAt(size_cur, size);
|
||||
return size;
|
||||
}
|
||||
};
|
||||
/// Vector with in_view interface
|
||||
struct in_vector {
|
||||
/// 512 Mébibits
|
||||
|
@ -44,23 +169,6 @@ struct in_vector {
|
|||
memcpy(writeTo(len), data, len);
|
||||
}
|
||||
};
|
||||
// Abstract data writer
|
||||
struct in_view: view {
|
||||
in_view(uint8_t *ptr, size_t size): view(size), ptr(ptr) {
|
||||
assert(ptr != nullptr);
|
||||
}
|
||||
|
||||
uint8_t* ptr;
|
||||
uint8_t* writeTo(size_t len) {
|
||||
assert(cur + len <= siz);
|
||||
auto p = ptr + cur;
|
||||
cur += len;
|
||||
return p;
|
||||
}
|
||||
void write(const uint8_t* data, size_t len) {
|
||||
memcpy(writeTo(len), data, len);
|
||||
}
|
||||
};
|
||||
/// Abstract data reader
|
||||
struct out_view: view {
|
||||
out_view(): out_view(nullptr, 0) { }
|
||||
|
@ -80,6 +188,42 @@ struct out_view: view {
|
|||
constexpr const uint8_t* data() const { return ptr; }
|
||||
constexpr size_t remaining() const { return size() - cur; }
|
||||
};
|
||||
/// Helper to read from out_view
|
||||
struct out_reader: public out_view {
|
||||
out_reader(const out_view& buf): out_view(buf.ptr, buf.siz) { cur = buf.cur; }
|
||||
|
||||
template<typename D>
|
||||
const D* read() {
|
||||
return cur + sizeof(D) <= size() ?
|
||||
(const D*)readFrom(sizeof(D)) : nullptr;
|
||||
}
|
||||
template<typename D>
|
||||
bool read(D& out) {
|
||||
const auto ptr = read<D>();
|
||||
if (ptr == nullptr)
|
||||
return false;
|
||||
|
||||
out = *ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool skip(size_t size) {
|
||||
readFrom(size);
|
||||
return !isDone();
|
||||
}
|
||||
|
||||
data::out_view readPart(size_t size) {
|
||||
return data::out_view(readFrom(size), size);
|
||||
}
|
||||
data::out_view readSizedPart() {
|
||||
size_t size = 0;
|
||||
read(size);
|
||||
return readPart(size);
|
||||
}
|
||||
data::out_view readRemaining() {
|
||||
return readPart(remaining());
|
||||
}
|
||||
};
|
||||
/// Pointer to opaque owned memory
|
||||
using handle_t = std::shared_ptr<const void>;
|
||||
/// out_view with owned data
|
||||
|
@ -92,6 +236,9 @@ struct out_buffer: out_view {
|
|||
out_buffer(view, std::shared_ptr<const void>(view.ptr)) { }
|
||||
/// Take ptr ownership
|
||||
out_buffer(const uint8_t *ptr, size_t size): out_buffer(out_view(ptr, size)) { }
|
||||
/// Take ptr ownership (release writer)
|
||||
out_buffer(in_writer& writer):
|
||||
out_buffer(writer.data(), writer.size()) { writer.reset(); }
|
||||
|
||||
handle_t handle = nullptr;
|
||||
};
|
||||
|
|
|
@ -8,100 +8,19 @@ namespace net {
|
|||
//TODO: preallocate static data pool
|
||||
|
||||
/// Helper to write allocated packets
|
||||
class PacketWriter final {
|
||||
class PacketWriter final: public data::in_writer {
|
||||
public:
|
||||
PacketWriter(size_t size): buffer((uint8_t*)malloc(size), size), visible_size(size) { }
|
||||
PacketWriter(size_t size): data::in_writer(size) { }
|
||||
PacketWriter(uint8_t type, size_t data_size): PacketWriter(sizeof(type) + data_size) {
|
||||
write(type);
|
||||
}
|
||||
PacketWriter(net::client_packet_type type, size_t data_size): PacketWriter((uint8_t)type, data_size) { }
|
||||
PacketWriter(net::server_packet_type type, size_t data_size): PacketWriter((uint8_t)type, data_size) { }
|
||||
~PacketWriter() {
|
||||
if (buffer.ptr != nullptr)
|
||||
free(buffer.ptr);
|
||||
}
|
||||
|
||||
void write(const void* data, size_t len) {
|
||||
buffer.write((uint8_t*)data, len);
|
||||
}
|
||||
template<typename D>
|
||||
void write(const D& d) {
|
||||
write(&d, sizeof(d));
|
||||
}
|
||||
|
||||
constexpr size_t getCursor() const { return buffer.cur; }
|
||||
void writeAt(size_t pos, const void* data, size_t len) {
|
||||
assert(pos + len <= buffer.siz);
|
||||
memcpy(buffer.ptr + pos, data, len);
|
||||
}
|
||||
template<typename D>
|
||||
void writeAt(size_t pos, const D& d) {
|
||||
writeAt(pos, &d, sizeof(d));
|
||||
}
|
||||
|
||||
void reserve(size_t target) {
|
||||
if (target >= buffer.siz - buffer.cur) {
|
||||
const auto size = target + buffer.cur;
|
||||
buffer.ptr = (uint8_t *)realloc(buffer.ptr, size);
|
||||
buffer.siz = size;
|
||||
}
|
||||
}
|
||||
void resize(size_t target) {
|
||||
reserve(target);
|
||||
visible_size = target;
|
||||
}
|
||||
|
||||
void writePush(const void* data, size_t len) {
|
||||
if (buffer.cur + len > buffer.siz)
|
||||
resize(buffer.cur + len);
|
||||
write(data, len);
|
||||
}
|
||||
template<typename D>
|
||||
void writePush(const D& d) {
|
||||
writePush(&d, sizeof(d));
|
||||
}
|
||||
|
||||
struct varying_part {
|
||||
varying_part(data::in_view &buffer, size_t& p_size): buffer(buffer), parent_size(p_size), visible_size(0) { }
|
||||
~varying_part() {
|
||||
buffer.cur += visible_size;
|
||||
parent_size += visible_size;
|
||||
}
|
||||
|
||||
data::in_view &buffer;
|
||||
size_t &parent_size;
|
||||
size_t visible_size;
|
||||
|
||||
constexpr size_t size() const { return visible_size; }
|
||||
void* data() { return buffer.writeTo(0); }
|
||||
void reserve(size_t target) {
|
||||
if (target >= buffer.siz - buffer.cur) {
|
||||
const auto size = target + buffer.cur;
|
||||
buffer.ptr = (uint8_t *)realloc(buffer.ptr, size);
|
||||
buffer.siz = size;
|
||||
}
|
||||
}
|
||||
void resize(size_t target) {
|
||||
reserve(target);
|
||||
visible_size = target;
|
||||
}
|
||||
};
|
||||
/// Only from resize, write, resize down
|
||||
varying_part varying() {
|
||||
return varying_part(buffer, visible_size);
|
||||
}
|
||||
|
||||
bool isFull() const {
|
||||
return buffer.cur >= visible_size;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
data::out_buffer finish() {
|
||||
assert(isFull());
|
||||
data::out_buffer cpy(buffer.ptr, visible_size);
|
||||
buffer.ptr = nullptr;
|
||||
buffer.siz = 0;
|
||||
return cpy;
|
||||
return data::out_buffer(*this);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
@ -126,50 +45,12 @@ public:
|
|||
static data::out_buffer Of(net::server_packet_type type, const D& data) {
|
||||
return Of(type, &data, sizeof(data));
|
||||
}
|
||||
|
||||
private:
|
||||
data::in_view buffer;
|
||||
size_t visible_size;
|
||||
};
|
||||
|
||||
/// Helper to read out_view
|
||||
class PacketReader final {
|
||||
class PacketReader final: public data::out_reader {
|
||||
public:
|
||||
PacketReader(const data::out_view& buf): buffer(buf) { }
|
||||
|
||||
template<typename D>
|
||||
const D* read() {
|
||||
return buffer.cur + sizeof(D) <= buffer.size() ?
|
||||
(const D*)buffer.readFrom(sizeof(D)) : nullptr;
|
||||
}
|
||||
template<typename D>
|
||||
bool read(D& out) {
|
||||
const auto ptr = read<D>();
|
||||
if (ptr == nullptr)
|
||||
return false;
|
||||
|
||||
out = *ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool skip(size_t size) {
|
||||
buffer.readFrom(size);
|
||||
return !isFull();
|
||||
}
|
||||
|
||||
data::out_view readPart(size_t size) {
|
||||
return data::out_view(buffer.readFrom(size), size);
|
||||
}
|
||||
data::out_view readAll() {
|
||||
return readPart(buffer.size() - buffer.cur);
|
||||
}
|
||||
|
||||
bool isFull() const {
|
||||
return buffer.isDone();
|
||||
}
|
||||
|
||||
private:
|
||||
data::out_view buffer;
|
||||
PacketReader(const data::out_view& buf): data::out_reader(buf) { }
|
||||
};
|
||||
|
||||
}
|
|
@ -30,6 +30,8 @@ namespace world::server {
|
|||
std::optional<double> getCurvature() const override { return GetCurvature(generator_properties); }
|
||||
static std::optional<double> GetCurvature(const generator::params &);
|
||||
|
||||
inline const glm::vec3 getGravity(const voxel_pos& p) const { return generator->getGravity(p); }
|
||||
|
||||
private:
|
||||
shared_guarded<regions_t> regions;
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ void Universe::update(float deltaTime) {
|
|||
const auto areaDiff = glm::divide(it->second->getOffset().as_voxel());
|
||||
|
||||
std::vector<chunk_pos> inAreaPlayers;
|
||||
players.iter([&](entity_id, Entity::Instance player) {
|
||||
players.iter([&](const entity_id&, const Entity::Instance& player) {
|
||||
const chunk_pos diff = glm::divide(player.pos.as_voxel() - it->second->getOffset().as_voxel());
|
||||
if (glm::length2(diff) <= areaRange)
|
||||
inAreaPlayers.push_back(diff);
|
||||
|
@ -414,6 +414,9 @@ void Universe::update(float deltaTime) {
|
|||
ZoneScopedN("Entities");
|
||||
size_t item_count = 0;
|
||||
entities.remove([&](entity_id type, Entity &val) {
|
||||
//TODO: find mass center
|
||||
const auto OFFSET = glm::vec3(val.size) * val.scale / 2.f;
|
||||
const auto DIST2 = glm::pow2(loadDistance); //NOTE: must be < keepDistance + glm::length(OFFSET) to avoid collision miss
|
||||
val.instances.remove([&](entity_id, Entity::Instance &inst) {
|
||||
if (type == PLAYER_ENTITY_ID) {
|
||||
//MAYBE: update players ?
|
||||
|
@ -421,14 +424,25 @@ void Universe::update(float deltaTime) {
|
|||
return false;
|
||||
}
|
||||
|
||||
inst.pos += inst.velocity * deltaTime;
|
||||
if (true /*FIXME: remove far entities ? glm::length2(glm::divide(pos - inst.pos.as_voxel())) <= glm::pow2(keepDistance);*/) {
|
||||
//TODO: partition space
|
||||
auto pos = inst.pos + OFFSET;
|
||||
for(const auto& area: areas) {
|
||||
//NOTE: consider entity mass negligible
|
||||
inst.velocity += area.second->getGravity((pos - area.second->getOffset()).as_voxel()) * deltaTime;
|
||||
}
|
||||
//MAYBE: friction
|
||||
if (move(pos, inst.velocity, 1, glm::max_axis(OFFSET))) {
|
||||
inst.velocity = glm::vec3(0);
|
||||
}
|
||||
inst.pos = pos - OFFSET;
|
||||
if (entities.at(PLAYER_ENTITY_ID).instances.contains([&](const entity_id&, const Entity::Instance& player) {
|
||||
return glm::length2(glm::divide((player.pos - inst.pos).as_voxel())) <= DIST2;
|
||||
})) {
|
||||
item_count++;
|
||||
return false;
|
||||
}
|
||||
//TODO: Save to files if !temporary
|
||||
return true;
|
||||
//MAYBE: Store in region ?
|
||||
//MAYBE: Save to files
|
||||
});
|
||||
return !val.permanant && val.instances.empty();
|
||||
});
|
||||
|
@ -558,7 +572,7 @@ bool Universe::onPacket(net::server::Peer *peer, const data::out_view &buf, net:
|
|||
break;
|
||||
}
|
||||
case client_packet_type::MESSAGE: {
|
||||
const auto ref = packet.readAll();
|
||||
const auto ref = packet.readRemaining();
|
||||
broadcastMessage("Player" + std::to_string(peer->getCtx<net_client>()->instanceId.index)
|
||||
+ ": " + std::string((const char*)ref.data(), ref.size()));
|
||||
break;
|
||||
|
@ -573,7 +587,7 @@ bool Universe::onPacket(net::server::Peer *peer, const data::out_view &buf, net:
|
|||
break;
|
||||
if (auto area = areas.find(id); area != areas.end()) {
|
||||
const chunk_pos areaOffset = glm::divide(pos - area->second->getOffset().as_voxel());
|
||||
while (!packet.isFull()) {
|
||||
while (!packet.isDone()) {
|
||||
region_pos rpos;
|
||||
if (!packet.read(rpos))
|
||||
break;
|
||||
|
@ -582,10 +596,8 @@ bool Universe::onPacket(net::server::Peer *peer, const data::out_view &buf, net:
|
|||
if (glm::length2(areaOffset - glm::lvec3(it_r->first) * glm::lvec3(REGION_LENGTH)) <= glm::pow2(loadDistance + REGION_LENGTH * 2)) {
|
||||
auto packet = PacketWriter(server_packet_type::REGION, sizeof(area_<region_pos>));
|
||||
packet.write<area_<region_pos>>(std::make_pair(id, rpos));
|
||||
{
|
||||
auto vec = packet.varying();
|
||||
it_r->second->averages(vec);
|
||||
}
|
||||
packet.pushPart([&](PacketWriter::part part) {
|
||||
it_r->second->averages(part); });
|
||||
peer->send(packet.finish(), net::server::CHUNK);
|
||||
} else {
|
||||
LOG_T("Request out of range region");
|
||||
|
@ -611,7 +623,7 @@ bool Universe::onPacket(net::server::Peer *peer, const data::out_view &buf, net:
|
|||
auto &chunks = area->second->getChunks();
|
||||
const chunk_pos areaOffset = glm::divide(pos - area->second->getOffset().as_voxel());
|
||||
|
||||
for (size_t i = 0; !packet.isFull() && i < MAX_PENDING_CHUNK_COUNT; i++) {
|
||||
for (size_t i = 0; !packet.isDone() && i < MAX_PENDING_CHUNK_COUNT; i++) {
|
||||
chunk_pos cpos;
|
||||
if (!packet.read(cpos))
|
||||
break;
|
||||
|
@ -642,15 +654,8 @@ bool Universe::onPacket(net::server::Peer *peer, const data::out_view &buf, net:
|
|||
for (auto it = area->begin(); it != area->end(); ++it) {
|
||||
std::ostringstream out;
|
||||
std::dynamic_pointer_cast<Chunk>(*it)->write(out);
|
||||
auto size_pos = packet.getCursor();
|
||||
size_t size = 0;
|
||||
packet.writePush(size);
|
||||
{
|
||||
auto vec = packet.varying();
|
||||
dict_write_ctx.compress(out.str(), vec);
|
||||
size = vec.size();
|
||||
}
|
||||
packet.writeAt(size_pos, size);
|
||||
packet.pushSizedPart([&](PacketWriter::part part) {
|
||||
dict_write_ctx.compress(out.str(), part); });
|
||||
}
|
||||
peer->send(packet.finish(), net::server::CHUNK);
|
||||
} else {
|
||||
|
@ -691,10 +696,8 @@ data::out_buffer Universe::serializeChunk(area_<chunk_pos> id, const std::shared
|
|||
data->write(out);
|
||||
auto packet = net::PacketWriter(net::server_packet_type::CHUNK, sizeof(id));
|
||||
packet.write(id);
|
||||
{
|
||||
auto vec = packet.varying();
|
||||
dict_write_ctx.compress(out.str(), vec);
|
||||
}
|
||||
packet.pushPart([&](net::PacketWriter::part part){
|
||||
dict_write_ctx.compress(out.str(), part); });
|
||||
return packet.finish();
|
||||
}
|
||||
void Universe::broadcastMessage(const std::string& text) {
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace world::generator {
|
|||
/// Generate chunk voxels
|
||||
/// MAYBE: use template to avoid virtual
|
||||
virtual void generate(const chunk_pos &at, std::array<Voxel, CHUNK_SIZE> &out) = 0;
|
||||
/// Get gravity vector at given point
|
||||
virtual glm::vec3 getGravity(const voxel_pos& point) const = 0;
|
||||
};
|
||||
|
||||
// Generate empty space
|
||||
|
@ -24,6 +26,7 @@ namespace world::generator {
|
|||
void generate(const chunk_pos &, std::array<Voxel, CHUNK_SIZE> &out) override {
|
||||
out.fill(Voxel());
|
||||
}
|
||||
glm::vec3 getGravity(const voxel_pos&) const override { return glm::vec3(0); }
|
||||
};
|
||||
|
||||
/// Endless cave network
|
||||
|
@ -51,6 +54,7 @@ namespace world::generator {
|
|||
out[i] = Voxel(material, density);
|
||||
}
|
||||
}
|
||||
glm::vec3 getGravity(const voxel_pos&) const override { return glm::vec3(-1, 0, 0); }
|
||||
private:
|
||||
Params params;
|
||||
Noise density;
|
||||
|
@ -110,6 +114,12 @@ namespace world::generator {
|
|||
}();
|
||||
}
|
||||
}
|
||||
glm::vec3 getGravity(const voxel_pos& pos) const override {
|
||||
const auto heightRatio = static_cast<float>((getHeight(pos) - params.height) / params.height);
|
||||
const auto scale = params.height >> 7;
|
||||
const auto mass = scale * scale * scale; //FIXME: average material density
|
||||
return -getSurfaceDir(pos) * std::max(0.f, 1.f - heightRatio * heightRatio) * glm::vec3(mass);
|
||||
}
|
||||
private:
|
||||
static constexpr PlanetShape shape = PS;
|
||||
static constexpr glm::f64 getHeight(const voxel_pos &p) {
|
||||
|
@ -119,6 +129,15 @@ namespace world::generator {
|
|||
return glm::length(glm::dvec3(p));
|
||||
}
|
||||
}
|
||||
/// Centre inverse direction
|
||||
// NOTE: So center point is consider mass center
|
||||
static constexpr glm::vec3 getSurfaceDir(const voxel_pos &p) {
|
||||
if constexpr(shape == PlanetShape::Cube) {
|
||||
return glm::inormalize(p);
|
||||
} else {
|
||||
return glm::normalize(glm::dvec3(p));
|
||||
}
|
||||
}
|
||||
Params params;
|
||||
Noise density;
|
||||
Noise displacement;
|
||||
|
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
Binary file not shown.
|
@ -0,0 +1,28 @@
|
|||
|
||||
UNIVERXEL ICON "univerxel.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,0,1,0
|
||||
PRODUCTVERSION 0,0,1,0
|
||||
|
||||
EGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Shu"
|
||||
VALUE "FileVersion", "0,0,1,0"
|
||||
VALUE "LegalCopyright", "MIT"
|
||||
VALUE "ProductName", "Univerxel"
|
||||
VALUE "ProductVersion", "0,0,1,0"
|
||||
VER_SPECIAL_BUILD_LINE
|
||||
VER_PRIVATE_BUILD_LINE
|
||||
END
|
||||
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 0x04B0
|
||||
END
|
||||
END
|
Loading…
Reference in New Issue