Working on web, change python to lua
This commit is contained in:
parent
90e2a369f4
commit
178f69967b
@ -48,5 +48,8 @@ check_and_download("https://download.savannah.gnu.org/releases/freetype/freetype
|
|||||||
# 8) SDL_ttf
|
# 8) SDL_ttf
|
||||||
check_and_download("https://github.com/libsdl-org/SDL_ttf/archive/refs/tags/release-2.24.0.zip" "release-2.24.0.zip" "SDL_ttf-release-2.24.0" "CMakeLists.txt")
|
check_and_download("https://github.com/libsdl-org/SDL_ttf/archive/refs/tags/release-2.24.0.zip" "release-2.24.0.zip" "SDL_ttf-release-2.24.0" "CMakeLists.txt")
|
||||||
|
|
||||||
# 9) pybind11
|
# 9) Lua
|
||||||
check_and_download("https://github.com/pybind/pybind11/archive/refs/tags/v3.0.3.zip" "pybind11-v3.0.3.zip" "pybind11-3.0.3" "CMakeLists.txt")
|
check_and_download("https://github.com/lua/lua/archive/refs/tags/v5.4.8.zip" "lua-v5.4.8.zip" "lua-5.4.8" "lapi.c")
|
||||||
|
|
||||||
|
# 10) sol2 (header-only C++ bindings for Lua)
|
||||||
|
check_and_download("https://github.com/ThePhD/sol2/archive/refs/tags/v3.3.0.zip" "sol2-v3.3.0.zip" "sol2-3.3.0" "include/sol/sol.hpp")
|
||||||
|
|||||||
@ -8,6 +8,11 @@ endmacro()
|
|||||||
|
|
||||||
set(BUILD_CONFIGS Debug Release)
|
set(BUILD_CONFIGS Debug Release)
|
||||||
|
|
||||||
|
# Map MinSizeRel and RelWithDebInfo to Release libs for all imported targets.
|
||||||
|
# Without this CMake warns that IMPORTED_LOCATION is missing for those configs.
|
||||||
|
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL Release)
|
||||||
|
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release)
|
||||||
|
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# 1) ZLIB (zlib131.zip → zlib-1.3.2) - без изменений
|
# 1) ZLIB (zlib131.zip → zlib-1.3.2) - без изменений
|
||||||
@ -549,12 +554,57 @@ if(NOT TARGET boost_external_lib)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# 9) pybind11 (3.0.3) - Python embedding
|
# 9) Lua (5.5.0) - embedded scripting language
|
||||||
# ===========================================
|
# ===========================================
|
||||||
set(PYBIND11_SRC_DIR "${THIRDPARTY_DIR}/pybind11-3.0.3")
|
set(LUA_SRC_DIR "${THIRDPARTY_DIR}/lua-5.4.8")
|
||||||
|
|
||||||
if(NOT TARGET pybind11::headers)
|
if(NOT TARGET lua_static)
|
||||||
# pybind11 is header-only; add_subdirectory gives us pybind11::embed which
|
file(GLOB LUA_SOURCES "${LUA_SRC_DIR}/*.c")
|
||||||
# also locates and links the Python interpreter and development libraries.
|
# Exclude the standalone interpreter, compiler, and unity-build wrapper.
|
||||||
add_subdirectory("${PYBIND11_SRC_DIR}" "${CMAKE_BINARY_DIR}/pybind11_build" EXCLUDE_FROM_ALL)
|
# onelua.c #includes all other .c files — compiling it alongside them
|
||||||
|
# causes every symbol to be defined twice.
|
||||||
|
list(REMOVE_ITEM LUA_SOURCES
|
||||||
|
"${LUA_SRC_DIR}/lua.c"
|
||||||
|
"${LUA_SRC_DIR}/luac.c"
|
||||||
|
"${LUA_SRC_DIR}/onelua.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(lua_static STATIC ${LUA_SOURCES})
|
||||||
|
target_include_directories(lua_static PUBLIC "${LUA_SRC_DIR}")
|
||||||
|
target_compile_definitions(lua_static PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# 10) sol2 (3.3.0) - header-only C++ bindings for Lua
|
||||||
|
# ===========================================
|
||||||
|
set(SOL2_SRC_DIR "${THIRDPARTY_DIR}/sol2-3.3.0")
|
||||||
|
|
||||||
|
# Apply patch for Clang/Emscripten compatibility in optional<T&>::emplace().
|
||||||
|
# The sentinel file prevents re-applying on subsequent cmake runs.
|
||||||
|
set(_sol2_sentinel "${SOL2_SRC_DIR}/.patched")
|
||||||
|
if(NOT EXISTS "${_sol2_sentinel}")
|
||||||
|
find_package(Git QUIET)
|
||||||
|
if(GIT_FOUND)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} apply --ignore-whitespace
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/patches/sol2-3.3.0-clang-optional.patch"
|
||||||
|
WORKING_DIRECTORY "${SOL2_SRC_DIR}"
|
||||||
|
RESULT_VARIABLE _sol2_patch_res
|
||||||
|
)
|
||||||
|
if(_sol2_patch_res EQUAL 0)
|
||||||
|
file(WRITE "${_sol2_sentinel}" "patched\n")
|
||||||
|
message(STATUS "Applied sol2 Clang optional patch")
|
||||||
|
else()
|
||||||
|
message(WARNING "sol2 patch failed (exit ${_sol2_patch_res}) — Clang/Emscripten builds may not compile")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "Git not found — cannot apply sol2 patch automatically. "
|
||||||
|
"Apply cmake/patches/sol2-3.3.0-clang-optional.patch manually.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT TARGET sol2_external_lib)
|
||||||
|
add_library(sol2_external_lib INTERFACE)
|
||||||
|
target_include_directories(sol2_external_lib INTERFACE "${SOL2_SRC_DIR}/include")
|
||||||
|
target_link_libraries(sol2_external_lib INTERFACE lua_static)
|
||||||
endif()
|
endif()
|
||||||
14
cmake/patches/sol2-3.3.0-clang-optional.patch
Normal file
14
cmake/patches/sol2-3.3.0-clang-optional.patch
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
--- a/include/sol/optional_implementation.hpp
|
||||||
|
+++ b/include/sol/optional_implementation.hpp
|
||||||
|
@@ -2189,7 +2189,10 @@
|
||||||
|
template <class... Args>
|
||||||
|
T& emplace(Args&&... args) noexcept {
|
||||||
|
static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
|
||||||
|
|
||||||
|
*this = nullopt;
|
||||||
|
- this->construct(std::forward<Args>(args)...);
|
||||||
|
+ // Reference specialization stores a pointer; set it directly.
|
||||||
|
+ // construct() only exists in the non-reference specialization.
|
||||||
|
+ m_value = std::addressof(std::forward<Args>(args)...);
|
||||||
|
+ return *m_value;
|
||||||
|
}
|
||||||
@ -8,7 +8,7 @@ if(NOT CMAKE_MAKE_PROGRAM AND WIN32)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(space-game001 CXX)
|
project(space-game001 LANGUAGES C CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@ -17,11 +17,52 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/FetchDependencies.cmake")
|
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/FetchDependencies.cmake")
|
||||||
# Теперь гарантированно есть папка ../thirdparty со всеми исходниками
|
# Теперь гарантированно есть папка ../thirdparty со всеми исходниками
|
||||||
|
|
||||||
# Список исходных файлов (без изменений)
|
# ===========================================
|
||||||
|
# Lua (5.5.0) - embedded scripting, pure C, compiles with Emscripten
|
||||||
|
# ===========================================
|
||||||
|
set(LUA_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/lua-5.4.8")
|
||||||
|
file(GLOB LUA_SOURCES "${LUA_SRC_DIR}/*.c")
|
||||||
|
list(REMOVE_ITEM LUA_SOURCES
|
||||||
|
"${LUA_SRC_DIR}/lua.c"
|
||||||
|
"${LUA_SRC_DIR}/luac.c"
|
||||||
|
"${LUA_SRC_DIR}/onelua.c"
|
||||||
|
)
|
||||||
|
add_library(lua_static STATIC ${LUA_SOURCES})
|
||||||
|
target_include_directories(lua_static PUBLIC "${LUA_SRC_DIR}")
|
||||||
|
|
||||||
|
# sol2 (header-only)
|
||||||
|
set(SOL2_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/sol2-3.3.0")
|
||||||
|
|
||||||
|
# Apply patch for Clang/Emscripten compatibility in optional<T&>::emplace().
|
||||||
|
set(_sol2_sentinel "${SOL2_SRC_DIR}/.patched")
|
||||||
|
if(NOT EXISTS "${_sol2_sentinel}")
|
||||||
|
find_package(Git QUIET)
|
||||||
|
if(GIT_FOUND)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} apply --ignore-whitespace
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake/patches/sol2-3.3.0-clang-optional.patch"
|
||||||
|
WORKING_DIRECTORY "${SOL2_SRC_DIR}"
|
||||||
|
RESULT_VARIABLE _sol2_patch_res
|
||||||
|
)
|
||||||
|
if(_sol2_patch_res EQUAL 0)
|
||||||
|
file(WRITE "${_sol2_sentinel}" "patched\n")
|
||||||
|
message(STATUS "Applied sol2 Clang optional patch")
|
||||||
|
else()
|
||||||
|
message(WARNING "sol2 patch failed (exit ${_sol2_patch_res}) — Clang/Emscripten builds may not compile")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "Git not found — cannot apply sol2 patch automatically. "
|
||||||
|
"Apply cmake/patches/sol2-3.3.0-clang-optional.patch manually.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Список исходных файлов (синхронизирован с proj-windows/CMakeLists.txt)
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
../src/main.cpp
|
../src/main.cpp
|
||||||
../src/Game.cpp
|
../src/Game.cpp
|
||||||
../src/Game.h
|
../src/Game.h
|
||||||
|
../src/Character.cpp
|
||||||
|
../src/Character.h
|
||||||
../src/Environment.cpp
|
../src/Environment.cpp
|
||||||
../src/Environment.h
|
../src/Environment.h
|
||||||
../src/render/Renderer.cpp
|
../src/render/Renderer.cpp
|
||||||
@ -42,39 +83,41 @@ set(SOURCES
|
|||||||
../src/utils/Utils.h
|
../src/utils/Utils.h
|
||||||
../src/SparkEmitter.cpp
|
../src/SparkEmitter.cpp
|
||||||
../src/SparkEmitter.h
|
../src/SparkEmitter.h
|
||||||
../src/planet/PlanetObject.cpp
|
# ../src/planet/PlanetObject.cpp
|
||||||
../src/planet/PlanetObject.h
|
# ../src/planet/PlanetObject.h
|
||||||
../src/planet/PlanetData.cpp
|
# ../src/planet/PlanetData.cpp
|
||||||
../src/planet/PlanetData.h
|
# ../src/planet/PlanetData.h
|
||||||
../src/utils/Perlin.cpp
|
../src/utils/Perlin.cpp
|
||||||
../src/utils/Perlin.h
|
../src/utils/Perlin.h
|
||||||
../src/utils/TaskManager.cpp
|
../src/utils/TaskManager.cpp
|
||||||
../src/utils/TaskManager.h
|
../src/utils/TaskManager.h
|
||||||
../src/planet/StoneObject.cpp
|
# ../src/planet/StoneObject.cpp
|
||||||
../src/planet/StoneObject.h
|
# ../src/planet/StoneObject.h
|
||||||
../src/render/FrameBuffer.cpp
|
../src/render/FrameBuffer.cpp
|
||||||
../src/render/FrameBuffer.h
|
../src/render/FrameBuffer.h
|
||||||
../src/UiManager.cpp
|
../src/UiManager.cpp
|
||||||
../src/UiManager.h
|
../src/UiManager.h
|
||||||
../src/Projectile.h
|
../src/Projectile.h
|
||||||
../src/Projectile.cpp
|
../src/Projectile.cpp
|
||||||
../src/network/NetworkInterface.h
|
# ../src/network/NetworkInterface.h
|
||||||
../src/network/LocalClient.h
|
# ../src/network/LocalClient.h
|
||||||
../src/network/LocalClient.cpp
|
# ../src/network/LocalClient.cpp
|
||||||
../src/network/ClientState.h
|
# ../src/network/ClientState.h
|
||||||
../src/network/ClientState.cpp
|
# ../src/network/ClientState.cpp
|
||||||
../src/network/WebSocketClientBase.h
|
# ../src/network/WebSocketClientBase.h
|
||||||
../src/network/WebSocketClientBase.cpp
|
# ../src/network/WebSocketClientBase.cpp
|
||||||
../src/network/WebSocketClientEmscripten.h
|
# ../src/network/WebSocketClientEmscripten.h
|
||||||
../src/network/WebSocketClientEmscripten.cpp
|
# ../src/network/WebSocketClientEmscripten.cpp
|
||||||
../src/render/TextRenderer.h
|
../src/render/TextRenderer.h
|
||||||
../src/render/TextRenderer.cpp
|
../src/render/TextRenderer.cpp
|
||||||
../src/MenuManager.h
|
../src/MenuManager.h
|
||||||
../src/MenuManager.cpp
|
../src/MenuManager.cpp
|
||||||
../src/Space.h
|
# ../src/Space.h
|
||||||
../src/Space.cpp
|
# ../src/Space.cpp
|
||||||
../src/GameConstants.h
|
../src/GameConstants.h
|
||||||
../src/GameConstants.cpp
|
../src/GameConstants.cpp
|
||||||
|
../src/ScriptEngine.h
|
||||||
|
../src/ScriptEngine.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(space-game001 ${SOURCES})
|
add_executable(space-game001 ${SOURCES})
|
||||||
@ -84,10 +127,10 @@ target_include_directories(space-game001 PRIVATE
|
|||||||
../src
|
../src
|
||||||
../thirdparty/eigen-5.0.0
|
../thirdparty/eigen-5.0.0
|
||||||
../thirdparty/boost_1_90_0
|
../thirdparty/boost_1_90_0
|
||||||
|
"${SOL2_SRC_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Сборка libzip через add_subdirectory (Emscripten соберет её из исходников)
|
# Сборка libzip через add_subdirectory (Emscripten соберет её из исходников)
|
||||||
# Опции для либзипа, чтобы он не искал лишнего в системе
|
|
||||||
set(ENABLE_GNUTLS OFF CACHE BOOL "" FORCE)
|
set(ENABLE_GNUTLS OFF CACHE BOOL "" FORCE)
|
||||||
set(ENABLE_OPENSSL OFF CACHE BOOL "" FORCE)
|
set(ENABLE_OPENSSL OFF CACHE BOOL "" FORCE)
|
||||||
set(ENABLE_WINDOWS_CRYPTO OFF CACHE BOOL "" FORCE)
|
set(ENABLE_WINDOWS_CRYPTO OFF CACHE BOOL "" FORCE)
|
||||||
@ -95,7 +138,7 @@ set(ENABLE_COMMONCRYPTO OFF CACHE BOOL "" FORCE)
|
|||||||
|
|
||||||
add_subdirectory("../thirdparty/libzip-1.11.4" libzip-build)
|
add_subdirectory("../thirdparty/libzip-1.11.4" libzip-build)
|
||||||
|
|
||||||
target_link_libraries(space-game001 PRIVATE zip z websocket.js)
|
target_link_libraries(space-game001 PRIVATE zip z lua_static websocket.js)
|
||||||
|
|
||||||
# Эмскриптен-флаги
|
# Эмскриптен-флаги
|
||||||
set(EMSCRIPTEN_FLAGS
|
set(EMSCRIPTEN_FLAGS
|
||||||
@ -107,7 +150,7 @@ set(EMSCRIPTEN_FLAGS
|
|||||||
#"-pthread"
|
#"-pthread"
|
||||||
#"-sUSE_PTHREADS=1"
|
#"-sUSE_PTHREADS=1"
|
||||||
"-fexceptions"
|
"-fexceptions"
|
||||||
"-DNETWORK"
|
"-DNETWORK"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(space-game001 PRIVATE ${EMSCRIPTEN_FLAGS} "-O2")
|
target_compile_options(space-game001 PRIVATE ${EMSCRIPTEN_FLAGS} "-O2")
|
||||||
@ -119,9 +162,10 @@ set(EMSCRIPTEN_LINK_FLAGS
|
|||||||
"-O2"
|
"-O2"
|
||||||
#"-sPTHREAD_POOL_SIZE=4"
|
#"-sPTHREAD_POOL_SIZE=4"
|
||||||
"-sALLOW_MEMORY_GROWTH=1"
|
"-sALLOW_MEMORY_GROWTH=1"
|
||||||
"-sFULL_ES3=1"
|
"-sFULL_ES3=1"
|
||||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/loading.png@resources/loading.png"
|
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/loading.png@resources/loading.png"
|
||||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/shaders@resources/shaders"
|
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/shaders@resources/shaders"
|
||||||
|
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start.lua@resources/start.lua"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Применяем настройки линковки
|
# Применяем настройки линковки
|
||||||
@ -159,7 +203,6 @@ install(TARGETS space-game001
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 2. Устанавливаем сопутствующие файлы (JS, WASM и сгенерированный архив данных)
|
# 2. Устанавливаем сопутствующие файлы (JS, WASM и сгенерированный архив данных)
|
||||||
# Emscripten создает их в той же папке, что и таргет
|
|
||||||
install(FILES
|
install(FILES
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/space-game001.js"
|
"${CMAKE_CURRENT_BINARY_DIR}/space-game001.js"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/space-game001.wasm"
|
"${CMAKE_CURRENT_BINARY_DIR}/space-game001.wasm"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
project(space-game001 LANGUAGES CXX)
|
project(space-game001 LANGUAGES C CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@ -111,7 +111,7 @@ target_link_libraries(space-game001 PRIVATE
|
|||||||
SDL2_ttf_external_lib
|
SDL2_ttf_external_lib
|
||||||
eigen_external_lib
|
eigen_external_lib
|
||||||
boost_external_lib
|
boost_external_lib
|
||||||
pybind11::embed
|
sol2_external_lib
|
||||||
)
|
)
|
||||||
|
|
||||||
# Линкуем OpenGL (Windows)
|
# Линкуем OpenGL (Windows)
|
||||||
|
|||||||
16
resources/start.lua
Normal file
16
resources/start.lua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-- Chain of waypoints for NPC 0.
|
||||||
|
-- Each on_arrived callback issues the next walk command.
|
||||||
|
|
||||||
|
local function step3()
|
||||||
|
game_api.npc_walk_to(0, 0.0, 0.0, -30.0, step1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function step2()
|
||||||
|
game_api.npc_walk_to(0, -2.0, 0.0, -2.0, step3)
|
||||||
|
end
|
||||||
|
|
||||||
|
function step1()
|
||||||
|
game_api.npc_walk_to(0, 2.0, 0.0, -2.0, step2)
|
||||||
|
end
|
||||||
|
|
||||||
|
step1()
|
||||||
@ -1,15 +0,0 @@
|
|||||||
import game_api
|
|
||||||
|
|
||||||
# Chain of waypoints for NPC 0.
|
|
||||||
# Each on_arrived callback issues the next walk command.
|
|
||||||
|
|
||||||
def step3():
|
|
||||||
game_api.npc_walk_to(0, 0.0, 0.0, -30.0, on_arrived=step1)
|
|
||||||
|
|
||||||
def step2():
|
|
||||||
game_api.npc_walk_to(0, -2.0, 0.0, -2.0, on_arrived=step3)
|
|
||||||
|
|
||||||
def step1():
|
|
||||||
game_api.npc_walk_to(0, 2.0, 0.0, -2.0, on_arrived=step2)
|
|
||||||
|
|
||||||
step1()
|
|
||||||
@ -18,6 +18,10 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "Bone name not found: " << name << std::endl;
|
||||||
|
throw std::runtime_error("Bone name not found: " + name);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,22 +182,34 @@ namespace ZL
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "bone names count : " << boneNames.size() << std::endl;
|
||||||
|
|
||||||
//Now process all the bones:
|
//Now process all the bones:
|
||||||
for (int i = 0; i < numberBones; i++)
|
for (int i = 0; i < numberBones; i++)
|
||||||
{
|
{
|
||||||
std::string boneName = boneNames[i];
|
std::string boneName = boneNames[i];
|
||||||
std::string boneParent = boneParentNames[i];
|
std::string boneParent = boneParentNames[i];
|
||||||
if (boneParent == "")
|
if (boneParent == "" || boneParent == "None")
|
||||||
{
|
{
|
||||||
bones[i].parent = -1;
|
bones[i].parent = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*std::cout << "-Processing bone: " << boneName << ", parent: " << boneParent << " " << "sizeof:" << boneParent.size() << " " << strlen("None") <<
|
||||||
|
int(boneParent[0])<<","<<
|
||||||
|
int(boneParent[1]) << ","<<
|
||||||
|
int(boneParent[2]) << ","<<
|
||||||
|
int(boneParent[3]) << ","<<
|
||||||
|
int(boneParent[4]) << "," <<
|
||||||
|
int(boneParent[5]) << ","
|
||||||
|
<< std::endl;*/
|
||||||
bones[i].parent = getIndexByValue(boneParent, boneNames);
|
bones[i].parent = getIndexByValue(boneParent, boneNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < boneChildren[boneName].size(); j++)
|
for (int j = 0; j < boneChildren[boneName].size(); j++)
|
||||||
{
|
{
|
||||||
|
//std::cout << "Enumerating bones:" << j << " " << boneName << " " << boneChildren[boneName][j] << std::endl;
|
||||||
|
|
||||||
bones[i].children.push_back(getIndexByValue(boneChildren[boneName][j], boneNames));
|
bones[i].children.push_back(getIndexByValue(boneChildren[boneName][j], boneNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +257,7 @@ namespace ZL
|
|||||||
|
|
||||||
//==== process uv and normals begin
|
//==== process uv and normals begin
|
||||||
|
|
||||||
std::cout << "Hello x1" << std::endl;
|
//std::cout << "Hello x1" << std::endl;
|
||||||
|
|
||||||
std::getline(f, tempLine); //===UV Coordinates:
|
std::getline(f, tempLine); //===UV Coordinates:
|
||||||
|
|
||||||
@ -310,7 +326,7 @@ namespace ZL
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Hello eee" << std::endl;
|
//std::cout << "Hello eee" << std::endl;
|
||||||
|
|
||||||
std::getline(f, tempLine); //===Normals:
|
std::getline(f, tempLine); //===Normals:
|
||||||
|
|
||||||
@ -395,10 +411,9 @@ namespace ZL
|
|||||||
{
|
{
|
||||||
std::getline(f, tempLine); //Group: 'Bone', Weight: 0.9929084181785583
|
std::getline(f, tempLine); //Group: 'Bone', Weight: 0.9929084181785583
|
||||||
if (std::regex_search(tempLine, match, pattern_bone_weight)) {
|
if (std::regex_search(tempLine, match, pattern_bone_weight)) {
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
||||||
std::string word = match.str(1);
|
std::string word = match.str(1);
|
||||||
double weight = std::stod(match.str(2));
|
double weight = std::stod(match.str(2));
|
||||||
|
//std::cout << "Bone name: " << word << ", weight: " << weight << std::endl;
|
||||||
int boneNumber = getIndexByValue(word, boneNames);
|
int boneNumber = getIndexByValue(word, boneNames);
|
||||||
localVerticesBoneWeight[i][j].boneIndex = boneNumber;
|
localVerticesBoneWeight[i][j].boneIndex = boneNumber;
|
||||||
localVerticesBoneWeight[i][j].weight = weight;
|
localVerticesBoneWeight[i][j].weight = weight;
|
||||||
@ -450,10 +465,10 @@ namespace ZL
|
|||||||
throw std::runtime_error("No number found in the input string.");
|
throw std::runtime_error("No number found in the input string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 0)
|
/*if (i == 0)
|
||||||
{
|
{
|
||||||
startingFrame == numberFrame;
|
startingFrame = numberFrame;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
animations[0].keyFrames[i].frame = numberFrame;
|
animations[0].keyFrames[i].frame = numberFrame;
|
||||||
|
|
||||||
@ -463,6 +478,7 @@ namespace ZL
|
|||||||
{
|
{
|
||||||
std::getline(f, tempLine);
|
std::getline(f, tempLine);
|
||||||
std::string boneName = tempLine.substr(8);
|
std::string boneName = tempLine.substr(8);
|
||||||
|
//std::cout << "Processing keyframe " << i << ", bone: " << j << " " << boneName << std::endl;
|
||||||
int boneNumber = getIndexByValue(boneName, boneNames);
|
int boneNumber = getIndexByValue(boneName, boneNames);
|
||||||
animations[0].keyFrames[i].bones[boneNumber] = startBones[boneNumber];
|
animations[0].keyFrames[i].bones[boneNumber] = startBones[boneNumber];
|
||||||
|
|
||||||
@ -588,6 +604,7 @@ namespace ZL
|
|||||||
|
|
||||||
if (startingFrame == -1)
|
if (startingFrame == -1)
|
||||||
{
|
{
|
||||||
|
std::cout << "Exception here: frame number is out of range of keyframes. Frame: " << frame << std::endl;
|
||||||
throw std::runtime_error("Exception here");
|
throw std::runtime_error("Exception here");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,7 +618,6 @@ namespace ZL
|
|||||||
std::vector<Bone>& nextFrameBones = animations[0].keyFrames[startingFrame+1].bones;
|
std::vector<Bone>& nextFrameBones = animations[0].keyFrames[startingFrame+1].bones;
|
||||||
|
|
||||||
std::vector<Matrix4f> skinningMatrixForEachBone;
|
std::vector<Matrix4f> skinningMatrixForEachBone;
|
||||||
//std::vector<Matrix3f> skinningMatrixForEachBone;
|
|
||||||
skinningMatrixForEachBone.resize(currentBones.size());
|
skinningMatrixForEachBone.resize(currentBones.size());
|
||||||
|
|
||||||
|
|
||||||
@ -646,6 +662,13 @@ namespace ZL
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*std::cout << "m=" << skinningMatrixForEachBone[5] << std::endl;
|
||||||
|
|
||||||
|
std::cout << "Start Mesh data " << std::endl;
|
||||||
|
std::cout << startMesh.PositionData[0] << std::endl;
|
||||||
|
std::cout << startMesh.PositionData[10] << std::endl;
|
||||||
|
std::cout << startMesh.PositionData[100] << std::endl;
|
||||||
|
*/
|
||||||
for (int i = 0; i < mesh.PositionData.size(); i++)
|
for (int i = 0; i < mesh.PositionData.size(); i++)
|
||||||
{
|
{
|
||||||
Vector4f originalPos = {
|
Vector4f originalPos = {
|
||||||
@ -661,16 +684,36 @@ namespace ZL
|
|||||||
{
|
{
|
||||||
if (verticesBoneWeight[i][j].weight != 0)
|
if (verticesBoneWeight[i][j].weight != 0)
|
||||||
{
|
{
|
||||||
|
if (verticesBoneWeight[i][j].boneIndex == -1)
|
||||||
|
{
|
||||||
|
std::cout << "Exception here: bone index is -1 but weight is > 0" << std::endl;
|
||||||
|
throw std::runtime_error("Bones loaded incorrectly - bone index is -1 but weight is > 0");
|
||||||
|
}
|
||||||
vMoved = true;
|
vMoved = true;
|
||||||
//finalPos = finalPos + MultVectorMatrix(originalPos, skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex]) * verticesBoneWeight[i][j].weight;
|
|
||||||
finalPos = finalPos + (skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex] * originalPos) * verticesBoneWeight[i][j].weight;
|
finalPos = finalPos + (skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex] * originalPos) * verticesBoneWeight[i][j].weight;
|
||||||
|
|
||||||
|
/*if (i == 100)
|
||||||
|
{
|
||||||
|
std::cout << "bone index=" << verticesBoneWeight[i][j].boneIndex << std::endl;
|
||||||
|
std::cout << "weight=" << verticesBoneWeight[i][j].weight << std::endl;
|
||||||
|
std::cout << "skinning matrix=" << skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex] << std::endl;
|
||||||
|
std::cout << "original pos=" << originalPos.transpose() << std::endl;
|
||||||
|
std::cout << "final pos=" << finalPos.transpose() << std::endl;
|
||||||
|
std::cout << "-----------------" << std::endl;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(finalPos(0) - originalPos(0)) > 1 || abs(finalPos(1) - originalPos(1)) > 1 || abs(finalPos(2) - originalPos(2)) > 1)
|
/*if (i == 100)
|
||||||
|
{
|
||||||
|
std::cout << originalPos << std::endl;
|
||||||
|
std::cout << finalPos << std::endl;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*if (abs(finalPos(0) - originalPos(0)) > 1 || abs(finalPos(1) - originalPos(1)) > 1 || abs(finalPos(2) - originalPos(2)) > 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (!vMoved)
|
if (!vMoved)
|
||||||
{
|
{
|
||||||
@ -682,9 +725,6 @@ namespace ZL
|
|||||||
mesh.PositionData[i](2) = finalPos(2);
|
mesh.PositionData[i](2) = finalPos(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "Character.h"
|
#include "Character.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ AnimationState Character::resolveActiveState() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Character::update(int64_t deltaMs) {
|
void Character::update(int64_t deltaMs) {
|
||||||
|
//std::cout << "update called with deltaMs: " << deltaMs << std::endl;
|
||||||
// Move toward walk target on the XZ plane
|
// Move toward walk target on the XZ plane
|
||||||
Eigen::Vector3f toTarget = walkTarget - position;
|
Eigen::Vector3f toTarget = walkTarget - position;
|
||||||
toTarget.y() = 0.f;
|
toTarget.y() = 0.f;
|
||||||
@ -72,6 +74,7 @@ void Character::update(int64_t deltaMs) {
|
|||||||
|
|
||||||
auto& anim = it->second;
|
auto& anim = it->second;
|
||||||
anim.currentFrame += static_cast<float>(deltaMs) / 24.f;
|
anim.currentFrame += static_cast<float>(deltaMs) / 24.f;
|
||||||
|
//std::cout << "Current animation frame: " << anim.currentFrame << " / " << anim.totalFrames << " -- " << anim.lastFrame << std::endl;
|
||||||
if (static_cast<int>(anim.currentFrame) >= anim.totalFrames-1) {
|
if (static_cast<int>(anim.currentFrame) >= anim.totalFrames-1) {
|
||||||
anim.currentFrame = anim.model.startingFrame;
|
anim.currentFrame = anim.model.startingFrame;
|
||||||
}
|
}
|
||||||
@ -82,6 +85,7 @@ void Character::update(int64_t deltaMs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Character::draw(Renderer& renderer) {
|
void Character::draw(Renderer& renderer) {
|
||||||
|
//std::cout << "draw called for Character at position: " << position.transpose() << std::endl;
|
||||||
AnimationState drawState = resolveActiveState();
|
AnimationState drawState = resolveActiveState();
|
||||||
auto it = animations.find(drawState);
|
auto it = animations.find(drawState);
|
||||||
if (it == animations.end() || !texture) return;
|
if (it == animations.end() || !texture) return;
|
||||||
|
|||||||
@ -9,6 +9,12 @@
|
|||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
using std::min;
|
||||||
|
using std::max;
|
||||||
|
#endif
|
||||||
|
|
||||||
constexpr float DEFAULT_ZOOM = 36.f;
|
constexpr float DEFAULT_ZOOM = 36.f;
|
||||||
|
|
||||||
class Environment {
|
class Environment {
|
||||||
|
|||||||
33
src/Game.cpp
33
src/Game.cpp
@ -39,6 +39,7 @@ namespace ZL
|
|||||||
Game* Game::s_instance = nullptr;
|
Game* Game::s_instance = nullptr;
|
||||||
|
|
||||||
void Game::onResourcesZipLoaded(const char* /*filename*/) {
|
void Game::onResourcesZipLoaded(const char* /*filename*/) {
|
||||||
|
std::cout << "Resources.zip loaded successfully" << std::endl;
|
||||||
if (s_instance) {
|
if (s_instance) {
|
||||||
s_instance->mainThreadHandler.EnqueueMainThreadTask([&]() {
|
s_instance->mainThreadHandler.EnqueueMainThreadTask([&]() {
|
||||||
s_instance->setupPart2();
|
s_instance->setupPart2();
|
||||||
@ -47,7 +48,7 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Game::onResourcesZipError(const char* /*filename*/) {
|
void Game::onResourcesZipError(const char* /*filename*/) {
|
||||||
std::cerr << "Failed to download resources.zip" << std::endl;
|
std::cout << "Failed to download resources.zip" << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ namespace ZL
|
|||||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "resources/shaders/defaultColor.vertex", "resources/shaders/defaultColor_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultColor", "resources/shaders/defaultColor.vertex", "resources/shaders/defaultColor_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("default", "resources/shaders/default.vertex", "resources/shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("default", "resources/shaders/default.vertex", "resources/shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
||||||
#endif
|
#endif
|
||||||
loadingTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/loading.png", CONST_ZIP_FILE));
|
loadingTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/loading.png", ""));
|
||||||
|
|
||||||
float minDimension;
|
float minDimension;
|
||||||
float width = Environment::projectionWidth;
|
float width = Environment::projectionWidth;
|
||||||
@ -139,22 +140,28 @@ namespace ZL
|
|||||||
renderer.shaderManager.AddShaderFromFiles("spark", "resources/shaders/spark.vertex", "resources/shaders/spark_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("spark", "resources/shaders/spark.vertex", "resources/shaders/spark_desktop.fragment", CONST_ZIP_FILE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 4" << std::endl;
|
||||||
|
|
||||||
roomTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/room005.png", CONST_ZIP_FILE));
|
roomTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/room005.png", CONST_ZIP_FILE));
|
||||||
roomMesh.data = LoadFromTextFile02("resources/w/room001.txt", CONST_ZIP_FILE);
|
roomMesh.data = LoadFromTextFile02("resources/w/room001.txt", CONST_ZIP_FILE);
|
||||||
roomMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI*0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
roomMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI*0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||||
roomMesh.RefreshVBO();
|
roomMesh.RefreshVBO();
|
||||||
|
std::cout << "Load resurces step 5" << std::endl;
|
||||||
fireboxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/Cube001.png", CONST_ZIP_FILE));
|
fireboxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/Cube001.png", CONST_ZIP_FILE));
|
||||||
fireboxMesh.data = LoadFromTextFile02("resources/w/firebox.txt", CONST_ZIP_FILE);
|
fireboxMesh.data = LoadFromTextFile02("resources/w/firebox.txt", CONST_ZIP_FILE);
|
||||||
fireboxMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
fireboxMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||||
fireboxMesh.RefreshVBO();
|
fireboxMesh.RefreshVBO();
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 6" << std::endl;
|
||||||
inaiTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/inai001.png", CONST_ZIP_FILE));
|
inaiTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/inai001.png", CONST_ZIP_FILE));
|
||||||
|
std::cout << "Load resurces step 6.1" << std::endl;
|
||||||
inaiMesh.data = LoadFromTextFile02("resources/w/inai001.txt", CONST_ZIP_FILE);
|
inaiMesh.data = LoadFromTextFile02("resources/w/inai001.txt", CONST_ZIP_FILE);
|
||||||
inaiMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
inaiMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||||
inaiMesh.data.Move({ 2.5, 1.4, -9.9 });
|
inaiMesh.data.Move({ 2.5, 1.4, -9.9 });
|
||||||
inaiMesh.RefreshVBO();
|
inaiMesh.RefreshVBO();
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 7" << std::endl;
|
||||||
benchTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/bench001opt.png", CONST_ZIP_FILE));
|
benchTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/bench001opt.png", CONST_ZIP_FILE));
|
||||||
benchMesh.data = LoadFromTextFile02("resources/w/bench002opt.txt", CONST_ZIP_FILE);
|
benchMesh.data = LoadFromTextFile02("resources/w/bench002opt.txt", CONST_ZIP_FILE);
|
||||||
benchMesh.data.Scale(3.f);
|
benchMesh.data.Scale(3.f);
|
||||||
@ -162,6 +169,8 @@ namespace ZL
|
|||||||
benchMesh.data.Move({ -2.1, 0.5, -7.9 });
|
benchMesh.data.Move({ -2.1, 0.5, -7.9 });
|
||||||
benchMesh.RefreshVBO();
|
benchMesh.RefreshVBO();
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 8" << std::endl;
|
||||||
|
|
||||||
auto violaTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/viola.png", CONST_ZIP_FILE));
|
auto violaTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/viola.png", CONST_ZIP_FILE));
|
||||||
|
|
||||||
// Player (Viola)
|
// Player (Viola)
|
||||||
@ -176,39 +185,51 @@ namespace ZL
|
|||||||
Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5f, Eigen::Vector3f::UnitX())) *
|
Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5f, Eigen::Vector3f::UnitX())) *
|
||||||
Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitZ()));
|
Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitZ()));
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 9" << std::endl;
|
||||||
auto defaultTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/default_skin001.png", CONST_ZIP_FILE));
|
auto defaultTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/default_skin001.png", CONST_ZIP_FILE));
|
||||||
|
|
||||||
auto npc01 = std::make_unique<Character>();
|
auto npc01 = std::make_unique<Character>();
|
||||||
npc01->loadAnimation(AnimationState::IDLE, "resources/w/default_idle002.txt", CONST_ZIP_FILE);
|
npc01->loadAnimation(AnimationState::IDLE, "resources/w/default_idle002.txt", CONST_ZIP_FILE);
|
||||||
npc01->loadAnimation(AnimationState::WALK, "resources/w/default_walk001.txt", CONST_ZIP_FILE);
|
npc01->loadAnimation(AnimationState::WALK, "resources/w/default_walk001.txt", CONST_ZIP_FILE);
|
||||||
|
//npc01->loadAnimation(AnimationState::IDLE, "resources/idleviola_uv010.txt", CONST_ZIP_FILE);
|
||||||
|
//npc01->loadAnimation(AnimationState::WALK, "resources/walkviola_uv010.txt", CONST_ZIP_FILE);
|
||||||
npc01->setTexture(defaultTexture);
|
npc01->setTexture(defaultTexture);
|
||||||
npc01->walkSpeed = 1.5f;
|
npc01->walkSpeed = 1.5f;
|
||||||
npc01->rotationSpeed = 8.0f;
|
npc01->rotationSpeed = 8.0f;
|
||||||
npc01->modelScale = 0.01f;
|
npc01->modelScale = 0.01f;
|
||||||
|
//npc01->modelScale = 0.1f;
|
||||||
npc01->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
npc01->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||||
|
|
||||||
npc01->position = Eigen::Vector3f(0.f, 0.f, -45.f);
|
std::cout << "Load resurces step 10" << std::endl;
|
||||||
|
npc01->position = Eigen::Vector3f(0.f, 0.f, -10.f);
|
||||||
npc01->setTarget(npc01->position);
|
npc01->setTarget(npc01->position);
|
||||||
npcs.push_back(std::move(npc01));
|
npcs.push_back(std::move(npc01));
|
||||||
|
|
||||||
auto ghostTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/ghost_skin001.png", CONST_ZIP_FILE));
|
auto ghostTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/ghost_skin001.png", CONST_ZIP_FILE));
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 11" << std::endl;
|
||||||
auto npc02 = std::make_unique<Character>();
|
auto npc02 = std::make_unique<Character>();
|
||||||
//npc02->loadAnimation(AnimationState::IDLE, "resources/w/default_float001.txt", CONST_ZIP_FILE);
|
npc02->loadAnimation(AnimationState::IDLE, "resources/w/default_float001.txt", CONST_ZIP_FILE);
|
||||||
npc02->loadAnimation(AnimationState::IDLE, "resources/w/float_attack003.txt", CONST_ZIP_FILE);
|
//npc02->loadAnimation(AnimationState::IDLE, "resources/w/float_attack003.txt", CONST_ZIP_FILE);
|
||||||
|
//npc02->loadAnimation(AnimationState::IDLE, "resources/idleviola_uv010.txt", CONST_ZIP_FILE);
|
||||||
npc02->setTexture(ghostTexture);
|
npc02->setTexture(ghostTexture);
|
||||||
npc02->walkSpeed = 1.5f;
|
npc02->walkSpeed = 1.5f;
|
||||||
npc02->rotationSpeed = 8.0f;
|
npc02->rotationSpeed = 8.0f;
|
||||||
npc02->modelScale = 0.01f;
|
npc02->modelScale = 0.01f;
|
||||||
|
//npc02->modelScale = 0.1f;
|
||||||
npc02->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
npc02->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
|
||||||
|
|
||||||
npc02->position = Eigen::Vector3f(0.f, 0.f, -20.f);
|
npc02->position = Eigen::Vector3f(0.f, 0.f, -20.f);
|
||||||
npc02->setTarget(npc02->position);
|
npc02->setTarget(npc02->position);
|
||||||
npcs.push_back(std::move(npc02));
|
npcs.push_back(std::move(npc02));
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 12" << std::endl;
|
||||||
|
|
||||||
loadingCompleted = true;
|
loadingCompleted = true;
|
||||||
|
|
||||||
scriptEngine.init(this);
|
scriptEngine.init(this);
|
||||||
|
|
||||||
|
std::cout << "Load resurces step 13" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,74 +1,60 @@
|
|||||||
#include "ScriptEngine.h"
|
#include "ScriptEngine.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include <pybind11/embed.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace py = pybind11;
|
#define SOL_ALL_SAFETIES_ON 1
|
||||||
|
#include <sol/sol.hpp>
|
||||||
// Static pointer used by the embedded module (set before interpreter starts).
|
|
||||||
static ZL::Game* s_game = nullptr;
|
|
||||||
|
|
||||||
// The embedded module must be defined at file scope before the interpreter
|
|
||||||
// is started. It exposes a minimal surface: one function per scripting command.
|
|
||||||
PYBIND11_EMBEDDED_MODULE(game_api, m) {
|
|
||||||
m.doc() = "Game scripting API";
|
|
||||||
|
|
||||||
// npc_walk_to(index, x, y, z, on_arrived=None)
|
|
||||||
// Tells the NPC at `index` to walk to (x,y,z).
|
|
||||||
// on_arrived is an optional Python callable invoked once when the NPC arrives.
|
|
||||||
// It can call npc_walk_to again (or anything else) to chain behaviour.
|
|
||||||
m.def("npc_walk_to", [](int index, float x, float y, float z, py::object on_arrived) {
|
|
||||||
if (!s_game) {
|
|
||||||
std::cerr << "[script] game_api.npc_walk_to: engine not ready\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto& npcs = s_game->npcs;
|
|
||||||
if (index < 0 || index >= static_cast<int>(npcs.size())) {
|
|
||||||
std::cerr << "[script] game_api.npc_walk_to: index " << index
|
|
||||||
<< " out of range (0.." << npcs.size() - 1 << ")\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::function<void()> cb;
|
|
||||||
if (!on_arrived.is_none()) {
|
|
||||||
cb = [on_arrived]() {
|
|
||||||
try {
|
|
||||||
on_arrived();
|
|
||||||
} catch (const py::error_already_set& e) {
|
|
||||||
std::cerr << "[script] on_arrived callback error:\n" << e.what() << "\n";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
npcs[index]->setTarget(Eigen::Vector3f(x, y, z), std::move(cb));
|
|
||||||
},
|
|
||||||
py::arg("index"), py::arg("x"), py::arg("y"), py::arg("z"),
|
|
||||||
py::arg("on_arrived") = py::none(),
|
|
||||||
"Command NPC[index] to walk to (x,y,z). on_arrived is called when the NPC arrives.");
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
|
struct ScriptEngine::Impl {
|
||||||
|
sol::state lua;
|
||||||
|
};
|
||||||
|
|
||||||
ScriptEngine::ScriptEngine() = default;
|
ScriptEngine::ScriptEngine() = default;
|
||||||
ScriptEngine::~ScriptEngine() = default;
|
ScriptEngine::~ScriptEngine() = default;
|
||||||
|
|
||||||
void ScriptEngine::init(Game* game) {
|
void ScriptEngine::init(Game* game) {
|
||||||
s_game = game;
|
impl = std::make_unique<Impl>();
|
||||||
interpreter = std::make_unique<py::scoped_interpreter>();
|
sol::state& lua = impl->lua;
|
||||||
runScript("resources/start.py");
|
|
||||||
|
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string, sol::lib::table);
|
||||||
|
|
||||||
|
auto api = lua.create_named_table("game_api");
|
||||||
|
|
||||||
|
// npc_walk_to(index, x, y, z [, on_arrived])
|
||||||
|
// on_arrived is an optional Lua function called when the NPC reaches the target.
|
||||||
|
// It can call npc_walk_to again (or anything else) to chain behaviour.
|
||||||
|
api.set_function("npc_walk_to",
|
||||||
|
[game](int index, float x, float y, float z, sol::object on_arrived) {
|
||||||
|
auto& npcs = game->npcs;
|
||||||
|
if (index < 0 || index >= static_cast<int>(npcs.size())) {
|
||||||
|
std::cerr << "[script] npc_walk_to: index " << index
|
||||||
|
<< " out of range (0.." << npcs.size() - 1 << ")\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::function<void()> cb;
|
||||||
|
if (on_arrived.is<sol::protected_function>()) {
|
||||||
|
sol::protected_function fn = on_arrived.as<sol::protected_function>();
|
||||||
|
cb = [fn]() mutable {
|
||||||
|
auto result = fn();
|
||||||
|
if (!result.valid()) {
|
||||||
|
sol::error err = result;
|
||||||
|
std::cerr << "[script] on_arrived error: " << err.what() << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
npcs[index]->setTarget(Eigen::Vector3f(x, y, z), std::move(cb));
|
||||||
|
});
|
||||||
|
|
||||||
|
runScript("resources/start.lua");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::runScript(const std::string& path) {
|
void ScriptEngine::runScript(const std::string& path) {
|
||||||
std::ifstream file(path);
|
auto result = impl->lua.safe_script_file(path, sol::script_pass_on_error);
|
||||||
if (!file.is_open()) {
|
if (!result.valid()) {
|
||||||
std::cerr << "[script] Could not open script: " << path << "\n";
|
sol::error err = result;
|
||||||
return;
|
std::cerr << "[script] Error in " << path << ": " << err.what() << "\n";
|
||||||
}
|
|
||||||
std::string source((std::istreambuf_iterator<char>(file)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
try {
|
|
||||||
py::exec(source);
|
|
||||||
} catch (const py::error_already_set& e) {
|
|
||||||
std::cerr << "[script] Error in " << path << ":\n" << e.what() << "\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
// Forward-declare the heavy pybind11 type so including this header stays cheap.
|
|
||||||
namespace pybind11 { class scoped_interpreter; }
|
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
class Game;
|
class Game;
|
||||||
@ -17,11 +14,12 @@ public:
|
|||||||
// Must be called once, after the Game's NPCs are ready.
|
// Must be called once, after the Game's NPCs are ready.
|
||||||
void init(Game* game);
|
void init(Game* game);
|
||||||
|
|
||||||
// Execute a Python script file. Logs errors to stderr.
|
// Execute a Lua script file. Logs errors to stderr.
|
||||||
void runScript(const std::string& path);
|
void runScript(const std::string& path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<pybind11::scoped_interpreter> interpreter;
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
|
|||||||
@ -51,6 +51,7 @@ namespace ZL
|
|||||||
numberVertices = std::stoi(number_str);
|
numberVertices = std::stoi(number_str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
std::cout << "No number found in the input string: " << tempLine << std::endl;
|
||||||
throw std::runtime_error("No number found in the input string.");
|
throw std::runtime_error("No number found in the input string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +86,8 @@ namespace ZL
|
|||||||
numberTriangles = std::stoi(number_str);
|
numberTriangles = std::stoi(number_str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw std::runtime_error("No number found in the input string.");
|
std::cout << "-No number found in the input string: " << tempLine << std::endl;
|
||||||
|
throw std::runtime_error("-No number found in the input string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -105,11 +107,13 @@ namespace ZL
|
|||||||
uvCount = std::stoi(number_str);
|
uvCount = std::stoi(number_str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw std::runtime_error("No number found in the input string.");
|
std::cout << "2 No number found in the input string: " << tempLine << std::endl;
|
||||||
|
throw std::runtime_error("2 No number found in the input string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uvCount != 3)
|
if (uvCount != 3)
|
||||||
{
|
{
|
||||||
|
std::cout << "UV count is not 3 for triangle " << i << ": " << uvCount << std::endl;
|
||||||
throw std::runtime_error("more than 3 uvs");
|
throw std::runtime_error("more than 3 uvs");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +133,7 @@ namespace ZL
|
|||||||
|
|
||||||
if (floatValues.size() != 2)
|
if (floatValues.size() != 2)
|
||||||
{
|
{
|
||||||
|
std::cout << "UV count is not 2: " << j << " " << floatValues.size() << std::endl;
|
||||||
throw std::runtime_error("more than 2 uvs---");
|
throw std::runtime_error("more than 2 uvs---");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +141,7 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Normals go" << std::endl;
|
//std::cout << "Normals go" << std::endl;
|
||||||
|
|
||||||
std::getline(f, tempLine); //===Normals:
|
std::getline(f, tempLine); //===Normals:
|
||||||
|
|
||||||
@ -160,7 +165,7 @@ namespace ZL
|
|||||||
normals[i] = Vector3f{ floatValues[0], floatValues[1], floatValues[2] };
|
normals[i] = Vector3f{ floatValues[0], floatValues[1], floatValues[2] };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Triangles go:" << std::endl;
|
//std::cout << "Triangles go:" << std::endl;
|
||||||
|
|
||||||
std::getline(f, tempLine); //===Triangles: 3974
|
std::getline(f, tempLine); //===Triangles: 3974
|
||||||
|
|
||||||
@ -198,11 +203,6 @@ namespace ZL
|
|||||||
result.PositionData.push_back(vertices[triangles[i][1]]);
|
result.PositionData.push_back(vertices[triangles[i][1]]);
|
||||||
result.PositionData.push_back(vertices[triangles[i][2]]);
|
result.PositionData.push_back(vertices[triangles[i][2]]);
|
||||||
|
|
||||||
/*
|
|
||||||
result.NormalData.push_back(normals[triangles[i][0]]);
|
|
||||||
result.NormalData.push_back(normals[triangles[i][1]]);
|
|
||||||
result.NormalData.push_back(normals[triangles[i][2]]);
|
|
||||||
*/
|
|
||||||
result.TexCoordData.push_back(uvCoords[i][0]);
|
result.TexCoordData.push_back(uvCoords[i][0]);
|
||||||
result.TexCoordData.push_back(uvCoords[i][1]);
|
result.TexCoordData.push_back(uvCoords[i][1]);
|
||||||
result.TexCoordData.push_back(uvCoords[i][2]);
|
result.TexCoordData.push_back(uvCoords[i][2]);
|
||||||
@ -280,6 +280,7 @@ namespace ZL
|
|||||||
numberVertices = std::stoi(match.str());
|
numberVertices = std::stoi(match.str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
std::cout << "Vertices header not found or invalid: " << tempLine << std::endl;
|
||||||
throw std::runtime_error("Vertices header not found or invalid.");
|
throw std::runtime_error("Vertices header not found or invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,14 +315,10 @@ namespace ZL
|
|||||||
// UV - [7], [8]
|
// UV - [7], [8]
|
||||||
|
|
||||||
if (floatValues.size() < 9) {
|
if (floatValues.size() < 9) {
|
||||||
|
std::cout << "Malformed vertex line at index " << i << ": " << tempLine << std::endl;
|
||||||
throw std::runtime_error("Malformed vertex line at index " + std::to_string(i));
|
throw std::runtime_error("Malformed vertex line at index " + std::to_string(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (floatValues[2] > 1.f)
|
|
||||||
{
|
|
||||||
std::cout << "got" << std::endl;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
tempPositions[i] = Vector3f{ floatValues[1], floatValues[2], floatValues[3] };
|
tempPositions[i] = Vector3f{ floatValues[1], floatValues[2], floatValues[3] };
|
||||||
tempNormals[i] = Vector3f{ floatValues[4], floatValues[5], floatValues[6] };
|
tempNormals[i] = Vector3f{ floatValues[4], floatValues[5], floatValues[6] };
|
||||||
tempUVs[i] = Vector2f{ floatValues[7], floatValues[8] };
|
tempUVs[i] = Vector2f{ floatValues[7], floatValues[8] };
|
||||||
@ -339,6 +336,7 @@ namespace ZL
|
|||||||
numberTriangles = std::stoi(match.str());
|
numberTriangles = std::stoi(match.str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
std::cout << "Triangles header not found or invalid: " << tempLine << std::endl;
|
||||||
throw std::runtime_error("Triangles header not found.");
|
throw std::runtime_error("Triangles header not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,6 +361,7 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (indices.size() != 3) {
|
if (indices.size() != 3) {
|
||||||
|
std::cout << "Malformed triangle line at index " << i << ": " << tempLine << std::endl;
|
||||||
throw std::runtime_error("Malformed triangle line at index " + std::to_string(i));
|
throw std::runtime_error("Malformed triangle line at index " + std::to_string(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user