# Headless checks of the walkable area and the sounds, built natively on Linux (WSL) from the shared loader:
#   walktest <apk...>            spawns / seats / hotspots stand on the baked area; seat colliders
#   walkviz <apk[+vista]> out.png [cell r radius r gap g]   top-down picture (PX=6 for sub-cell edges, PROBE="w x,z;...")
#   walkfeel <apk[+vista]>       simulated stick walking: leaving the area (must be 0), kept distance, judder
#   walkcompat save|check <apk> <file>   a saved area (FWG1 from an older build, or FWG2) against a fresh bake
#   audiotest <file|apk...>      decodes sounds (WAV, MP3, FLAC, Ogg Vorbis / Opus) and homes' ambience
#   walkgaps <apk>               floors left out of the area and what's between them and it
#   listcolliders <apk>          the world's box / sphere / capsule colliders
#   animcheck <apk> <fenv> [sweep s]   a Clay / glTF home's animation from the APK against the baked .fenv (bit for bit)
#   animrender <home> <prefix> <size> <t,t,...>   the home drawn at those animation times (APK against .fenv)
#   wallcheck <home> [drawn]    invisible walls at every angle: no walkable area inside them (exit 2 if there is)
#   bakecmp <home> <home>        both baked as they load, byte for byte (a .fenv's scene re-baked against its APK's bake)
#   fenv-tool report <apk[+vista]|fenv>   the home report (home_report.h), as Frame Studio and Frame Home make it
#   worldrender <apk> <prefix> <size> [seats|spots|cams x,y,z,yaw,pitch ...] [view=N hide=bits world]: the home rendered with the area and
#                                Auto-generate's items. Lavapipe can't run the renderer: build it with the MinGW
#                                toolchain (-DCMAKE_TOOLCHAIN_FILE=~/.local/opt/mingw/toolchain.cmake) and run the .exe
#                                from WSL on the PC's GPU (no window opens)
# cmake -S tools/walktest -B <build> -G Ninja && ninja -C <build>   (WALK_THREADS=n sets the bake's threads)
cmake_minimum_required(VERSION 3.16)
project(walktest C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Release)
set(R ${CMAKE_CURRENT_SOURCE_DIR}/../..)
set(TP ${R}/third_party)
add_library(miniz STATIC ${TP}/miniz/miniz.c ${TP}/miniz/miniz_tdef.c ${TP}/miniz/miniz_tinfl.c ${TP}/miniz/miniz_zip.c)
target_include_directories(miniz PUBLIC ${TP}/miniz)
target_compile_definitions(miniz PRIVATE MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS)
add_library(smolv STATIC ${TP}/smolv/smolv.cpp)
target_include_directories(smolv PUBLIC ${TP}/smolv)
set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
set(ASTCENC_CLI OFF CACHE BOOL "" FORCE)
set(ASTCENC_DECOMPRESSOR OFF CACHE BOOL "" FORCE)
set(ASTCENC_UNIVERSAL_BUILD OFF CACHE BOOL "" FORCE)
set(ASTCENC_ISA_SSE41 ON CACHE BOOL "" FORCE)
add_subdirectory(${TP}/astcenc astcenc EXCLUDE_FROM_ALL)
add_library(lzma STATIC ${TP}/lzma/LzmaEnc.c ${TP}/lzma/LzmaDec.c ${TP}/lzma/LzFind.c ${TP}/lzma/LzFindOpt.c ${TP}/lzma/LzFindMt.c ${TP}/lzma/Threads.c ${TP}/lzma/CpuArch.c)
target_include_directories(lzma PUBLIC ${TP}/lzma)
add_library(frame-scene STATIC ${R}/src/hsl_scene.cpp ${R}/src/scene_bake.cpp ${R}/src/anim_bake.cpp ${R}/src/fenv_lzma.cpp ${R}/src/model_import.cpp
    ${TP}/ufbx/ufbx.c ${TP}/qhe/cook/hzanim_acl.cpp ${TP}/stb/stb_image_impl.c)
target_include_directories(frame-scene PUBLIC ${R}/src ${TP}/stb ${TP}/qhe ${TP}/miniz ${TP}/cgltf ${TP}/ufbx ${TP}/acl/includes ${TP}/rtm/includes ${TP}/astcenc/Source)
set_source_files_properties(${TP}/qhe/cook/hzanim_acl.cpp PROPERTIES COMPILE_OPTIONS "-flax-vector-conversions")
target_link_libraries(frame-scene PUBLIC miniz lzma smolv astcenc-sse4.1-static pthread)
foreach(t walktest walkviz walkfeel walkcompat)
    add_executable(${t} ${t}.cpp)
    target_link_libraries(${t} frame-scene)
endforeach()
set(OPUS_BUILD_PROGRAMS OFF CACHE BOOL "" FORCE)
set(OPUS_BUILD_TESTING OFF CACHE BOOL "" FORCE)
set(OPUS_INSTALL_PKG_CONFIG_MODULE OFF CACHE BOOL "" FORCE)
set(OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF CACHE BOOL "" FORCE)
add_subdirectory(${TP}/opus opus EXCLUDE_FROM_ALL)
add_library(ogg STATIC ${TP}/ogg/src/bitwise.c ${TP}/ogg/src/framing.c)
target_include_directories(ogg PUBLIC ${TP}/ogg/include)
add_library(opusfile STATIC ${TP}/opusfile/src/info.c ${TP}/opusfile/src/internal.c ${TP}/opusfile/src/opusfile.c ${TP}/opusfile/src/stream.c)
target_include_directories(opusfile PUBLIC ${TP}/opusfile/include PRIVATE ${TP}/opusfile/src)
target_compile_definitions(opusfile PRIVATE OP_DISABLE_HTTP)
target_link_libraries(opusfile PUBLIC opus ogg)
add_executable(audiotest audiotest.cpp ${TP}/miniaudio/miniaudio_impl.c ${TP}/stb/stb_vorbis_impl.c)
target_include_directories(audiotest PRIVATE ${TP}/miniaudio)
target_link_libraries(audiotest frame-scene opusfile dl m)
add_executable(walkgaps walkgaps.cpp)
target_link_libraries(walkgaps frame-scene)
add_executable(listcolliders listcolliders.cpp)
target_link_libraries(listcolliders frame-scene)
add_executable(listmeshes listmeshes.cpp)
target_link_libraries(listmeshes frame-scene)
add_executable(filecheck filecheck.cpp)
target_link_libraries(filecheck frame-scene)
add_executable(teleportfeel teleportfeel.cpp)
target_link_libraries(teleportfeel frame-scene)
add_executable(edgecheck edgecheck.cpp)
target_link_libraries(edgecheck frame-scene)
add_executable(animcost animcost.cpp)
target_link_libraries(animcost frame-scene)
add_executable(scenestats scenestats.cpp)
target_link_libraries(scenestats frame-scene)
add_executable(fenv-tool ${R}/src/fenv_tool.cpp)   # (fenv-tool report: the home report, headless)
target_link_libraries(fenv-tool frame-scene)
# worldrender: the home drawn headlessly (lavapipe) with the walkable area and Auto-generate's items
find_package(Vulkan QUIET)
add_executable(worldrender worldrender.cpp ${R}/src/hsl_renderer.cpp ${TP}/volk/volk.c)
target_compile_definitions(worldrender PRIVATE FH_USE_VOLK)
target_include_directories(worldrender PRIVATE ${TP}/volk ${TP}/vulkan-headers/include)
target_link_libraries(worldrender frame-scene)
if(WIN32)   # (MinGW from WSL: run it on the PC's GPU; lavapipe can't run the renderer)
    target_compile_definitions(worldrender PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS)
    target_link_options(worldrender PRIVATE -static)
else()
    target_link_libraries(worldrender dl)
endif()
# animcheck <home.apk> <home.fenv>: a Clay / glTF home's animation from its APK and from the baked .fenv, step by step
add_executable(animcheck animcheck.cpp)
target_link_libraries(animcheck frame-scene)
# animrender <home> <prefix> <size> <t,t,...>: the home drawn at those animation times (APK against .fenv, picture for picture)
add_executable(animrender animrender.cpp ${R}/src/hsl_renderer.cpp ${TP}/volk/volk.c)
target_compile_definitions(animrender PRIVATE FH_USE_VOLK)
target_include_directories(animrender PRIVATE ${TP}/volk ${TP}/vulkan-headers/include)
target_link_libraries(animrender frame-scene)
# wallcheck <home> [drawn]: invisible walls at every angle never have walkable area inside them
add_executable(wallcheck wallcheck.cpp)
target_link_libraries(wallcheck frame-scene)
# bakecmp <home> <home>: both baked as loaded, byte for byte (a .fenv re-baked against its APK's bake)
add_executable(bakecmp bakecmp.cpp)
target_link_libraries(bakecmp frame-scene)
