3.2.4 release.

This commit is contained in:
harfang3dadmin 2022-09-26 12:07:03 +02:00
parent c4acab3698
commit e8b03fe5e9
27 changed files with 810 additions and 143 deletions

View File

@ -27,6 +27,7 @@ option(HG_ENABLE_ASAN "Harfang: Enable ASAN" OFF)
# -----------------------------------------------------------------------------
# Build options
# -----------------------------------------------------------------------------
option(HG_BUILD_HARFANG_STATIC "Harfang: Build Harfang static" OFF)
option(HG_BUILD_ASSIMP_CONVERTER "Harfang: Build Assimp converter" ON)
option(HG_BUILD_FBX_CONVERTER "Harfang: Build FBX converter" ON)
option(HG_BUILD_GLTF_EXPORTER "Harfang: Build GLTF exporter" ON)
@ -74,7 +75,7 @@ endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
message(STATUS "! Disabling GLFW since building for Emscripten")
set(HG_USE_GLFW OFF FORCE)
set(HG_USE_GLFW OFF CACHE BOOL "Harfang: Use GLFW backend" FORCE)
endif()
if(HG_ENABLE_SRANIPAL_API AND MSVC)
@ -105,18 +106,20 @@ if(MSVC)
# Don't forget to remove this as soon as CMake is fixed.
# Tells MSVC to update __cplusplus value, otherwise it will be stuck to 199711L and libraries like bx (if updated) won't compile anymore even if we set CMAKE_CXX_STANDARD to C++14.
add_compile_options(/Zc:__cplusplus)
elseif(MINGW)
add_compile_options(-fpermissive -lstdc++ -lstdc++fs)
elseif(ANDROID)
add_compile_definitions(ANDROID)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
message(STATUS "Emscripten sets")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --bind -fPIC -DEMSCRIPTEN -s USE_SDL=2 -s USE_WEBGL2=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -s OFFSCREENCANVAS_SUPPORT=1 -s LLD_REPORT_UNDEFINED -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s FORCE_FILESYSTEM=1 -DBGFX_CONFIG_RENDERER_OPENGLES_MIN_VERSION=30")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --bind -fPIC -DEMSCRIPTEN -s USE_SDL=2 -s USE_WEBGL2=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -s OFFSCREENCANVAS_SUPPORT=1 -s LLD_REPORT_UNDEFINED -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s FORCE_FILESYSTEM=1 -DBGFX_CONFIG_RENDERER_OPENGLES_MIN_VERSION=30")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --bind -fPIC -DEMSCRIPTEN -s MAX_WEBGL_VERSION=2 -s USE_SDL=2 -s USE_WEBGL2=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -s OFFSCREENCANVAS_SUPPORT=1 -s LLD_REPORT_UNDEFINED -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s FORCE_FILESYSTEM=1 -DBGFX_CONFIG_RENDERER_OPENGLES_MIN_VERSION=30")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --bind -fPIC -DEMSCRIPTEN -s MAX_WEBGL_VERSION=2 -s USE_SDL=2 -s USE_WEBGL2=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -s OFFSCREENCANVAS_SUPPORT=1 -s LLD_REPORT_UNDEFINED -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s FORCE_FILESYSTEM=1 -DBGFX_CONFIG_RENDERER_OPENGLES_MIN_VERSION=30")
# without pthread and with wasm
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -s WASM=1 -Oz -DNDEBUG -s DISABLE_EXCEPTION_CATCHING=0 -s FORCE_FILESYSTEM=1")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s WASM=1 -Oz -DNDEBUG -s DISABLE_EXCEPTION_CATCHING=0 -s FORCE_FILESYSTEM=1")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -s WASM=1 -O0 -DNDEBUG -g4 -s ASSERTIONS=2 -s DEMANGLE_SUPPORT=1 -s FORCE_FILESYSTEM=1")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -s WASM=1 -O0 -DNDEBUG -g4 -s ASSERTIONS=2 -s DEMANGLE_SUPPORT=1 -s FORCE_FILESYSTEM=1")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -s STANDALONE_WASM=1 -s WASM=1 -Oz -DNDEBUG -s DISABLE_EXCEPTION_CATCHING=0 -s FORCE_FILESYSTEM=1")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s STANDALONE_WASM=1 -s WASM=1 -Oz -DNDEBUG -s DISABLE_EXCEPTION_CATCHING=0 -s FORCE_FILESYSTEM=1")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -s STANDALONE_WASM=1 -s WASM=1 -O0 -DNDEBUG -g4 -s ASSERTIONS=2 -s DEMANGLE_SUPPORT=1 -s FORCE_FILESYSTEM=1")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -s STANDALONE_WASM=1 -s WASM=1 -O0 -DNDEBUG -g4 -s ASSERTIONS=2 -s DEMANGLE_SUPPORT=1 -s FORCE_FILESYSTEM=1")
else()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(NOT APPLE)
@ -293,14 +296,16 @@ function(install_cppsdk_dependencies Destination)
set(ComponentName ${Destination})
endif()
if(HG_USE_GLFW)
install(FILES $<TARGET_FILE:glfw> DESTINATION ${Destination} COMPONENT ${ComponentName})
endif()
if(NOT HG_BUILD_HARFANG_STATIC)
if(HG_USE_GLFW)
install(FILES $<TARGET_FILE:glfw> DESTINATION ${Destination} COMPONENT ${ComponentName})
endif()
install(FILES $<TARGET_FILE:libluadll> DESTINATION ${Destination} COMPONENT ${ComponentName})
if(HG_ENABLE_OPENVR_API)
get_target_property(OpenVRTargetFiles OpenVR IMPORTED_LOCATION)
install(FILES ${OpenVRTargetFiles} DESTINATION ${Destination} COMPONENT ${ComponentName})
install(FILES $<TARGET_FILE:libluadll> DESTINATION ${Destination} COMPONENT ${ComponentName})
if(HG_ENABLE_OPENVR_API)
get_target_property(OpenVRTargetFiles OpenVR IMPORTED_LOCATION)
install(FILES ${OpenVRTargetFiles} DESTINATION ${Destination} COMPONENT ${ComponentName})
endif()
endif()
if(HG_ENABLE_SRANIPAL_API)
@ -407,7 +412,9 @@ message(STATUS "")
# -----------------------------------------------------------------------------
# [WARNING] Don't forget to add any new shared library target to this list!
set(HG_SHARED_LIBRARY_TARGETS "hg::glfw;hg::libluadll")
if(NOT HG_BUILD_HARFANG_STATIC)
set(HG_SHARED_LIBRARY_TARGETS "hg::glfw;hg::libluadll")
endif()
if(HG_ENABLE_OPENVR_API)
list(APPEND HG_SHARED_LIBRARY_TARGETS OpenVR)
if(HG_ENABLE_SRANIPAL_API)

View File

@ -600,6 +600,7 @@ def bind_platform(gen):
# hg::FileFilter
file_filter = gen.begin_class('hg::FileFilter')
gen.bind_constructor(file_filter, [])
gen.bind_members(file_filter, ['std::string name', 'std::string pattern'])
gen.end_class(file_filter)
@ -1574,7 +1575,7 @@ def bind_bullet3_physics(gen):
gen.bind_method(bullet, 'StepSimulation', 'void', ['hg::time_ns display_dt', '?hg::time_ns step_dt', '?int max_step'])
gen.bind_method(bullet, 'CollectCollisionEvents', 'void', ['const hg::Scene &scene', 'hg::NodePairContacts &node_pair_contacts'])
gen.bind_method(bullet, 'CollectCollisionEvents', 'void', ['const hg::Scene &scene', 'hg::NodePairContacts &node_pair_contacts'], {'arg_out': ['node_pair_contacts']})
gen.bind_method(bullet, 'SyncTransformsFromScene', 'void', ['const hg::Scene &scene'])
gen.bind_method(bullet, 'SyncTransformsToScene', 'void', ['hg::Scene &scene'])
@ -4389,6 +4390,11 @@ def bind(gen):
if not gen.embedded:
insert_non_embedded_setup_free_code(gen)
if gen.get_language() == 'Go':
gen.set_compilation_directives("// #cgo linux pkg-config: gtk+-3.0\n" \
"// #cgo linux LDFLAGS: -L${SRCDIR}/linux -lhg_go -lharfang -lm -lstdc++ -Wl,--no-as-needed -ldl -lGL -lXrandr -lXext -lX11 -lglib-2.0\n" \
"// #cgo windows LDFLAGS: -L${SRCDIR}/windows -lhg_go -lharfang -lGdi32 -lDbghelp -lshell32 -loleaut32 -luuid -lcomdlg32 -lOle32 -lWinmm -lstdc++\n")
void_ptr = gen.bind_ptr('void *', bound_name='VoidPointer')
gen.insert_binding_code('static void * _int_to_VoidPointer(intptr_t ptr) { return reinterpret_cast<void *>(ptr); }')
gen.bind_function('int_to_VoidPointer', 'void *', ['intptr_t ptr'], {'route': route_lambda('_int_to_VoidPointer')})

View File

@ -23,7 +23,7 @@ The rigid body intertia tensor is computed from its collision shape properties.
## Simulating Physics
Create a physics backend such as [SceneNewtonPhysics] and call [SceneBullet3Physics_SceneCreatePhysicsFromAssets] to create the physics states corresponding to the scene declaration.
Create a physics backend such as [SceneBullet3Physics] and call [SceneBullet3Physics_SceneCreatePhysicsFromAssets] to create the physics states corresponding to the scene declaration.
*Note:* [SceneBullet3Physics_SceneCreatePhysicsFromAssets] means that if setting up the physics states requires access to an external resource, such as a mesh, it should be loaded from the assets system. If you are working from the filesystem, use [SceneBullet3Physics_SceneCreatePhysicsFromFile].
@ -33,9 +33,9 @@ This involves 3 steps on each update:
1. Synchronize physics state with the scene declaration using [SceneBullet3Physics_SceneCreatePhysicsFromAssets]. Alternatively, you can use a more fine-grained approach using [SceneBullet3Physics_NodeCreatePhysicsFromAssets] to improve performance.
2. Step the simulation using [SceneBullet3Physics_StepSimulation].
3. Synchronize the updated physics transformations to the scene using [SceneBullet3Physics_SyncDynamicBodiesToScene].
3. Synchronize the updated physics transformations to the scene using [SceneBullet3Physics_SyncTransformsToScene].
*Note:* If you are using kinematic bodies you will also need to synchronize them from their node transformation on each update using [SceneBullet3Physics_SyncKinematicBodiesFromScene].
*Note:* If you are using kinematic bodies you will also need to synchronize them from their node transformation on each update using [SceneBullet3Physics_SyncTransformsFromScene].
### The Easy Way

View File

@ -33,9 +33,9 @@ Views with no queued draw commands are skipped. If you need to force the process
Draw commands queued on a view are processed according to the view mode, they are executed:
- In submission order if the view mode is [VM_Sequential].
- In ascending depth order if the view mode is [VM_Ascending].
- In descending depth order if the view mode is [VM_Descending].
- In ascending depth order if the view mode is [VM_DepthAscending].
- In descending depth order if the view mode is [VM_DepthDescending].
When the view mode is [VM_Ascending] or [VM_Descending], the depth value used to sort draw commands is derived from the draw call *depth* parameter.
When the view mode is [VM_DepthAscending] or [VM_DepthDescending], the depth value used to sort draw commands is derived from the draw call *depth* parameter.
When no depth is specified, 0 is implied.

22
extern/CMakeLists.txt vendored
View File

@ -71,7 +71,11 @@ if(HG_USE_GLFW)
if(HG_REBUILD_GLFW)
# build it from sources
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries" FORCE)
if(HG_BUILD_HARFANG_STATIC)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
else()
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries" FORCE)
endif()
set(GLFW_INSTALL OFF CACHE BOOL "")
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "")
set(GLFW_BUILD_TESTS OFF CACHE BOOL "")
@ -121,7 +125,7 @@ install_cppsdk_external_target(nvtt)
install_cppsdk_external_target(pvrtc)
# Lua
if(UNIX AND NOT APPLE)
if(UNIX AND NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Emscripten"))
# lua links against libreadline but does not check for its availability.
find_package(readline REQUIRED)
endif()
@ -204,6 +208,7 @@ if(HG_BUILD_CPP_SDK)
endif()
# OpenAL soft
if(NOT (CMAKE_SYSTEM_NAME STREQUAL "Emscripten"))
message("Configuring OpenAL soft")
set(ALSOFT_UTILS OFF CACHE BOOL "OpenAL soft: Build and install utility programs")
@ -225,6 +230,8 @@ set_property(TARGET OpenAL PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OpenAL_inclu
install_cppsdk_external_target(OpenAL)
endif()
# json.hpp
add_library(jsonhpp INTERFACE)
target_include_directories(jsonhpp
@ -334,6 +341,7 @@ if(HG_ENABLE_RECAST_DETOUR_API)
endif()
# CMFT
if(NOT MINGW)
add_executable(cmft
cmft/src/cmft/common/stb_image.cpp
cmft/src/cmft/common/print.cpp
@ -350,6 +358,7 @@ if(UNIX)
target_compile_definitions(cmft PRIVATE linux)
target_link_libraries(cmft pthread dl)
endif()
endif()
# meshoptimizer
set(CMAKE_INSTALL_INCLUDEDIR ${CppSdkHeadersDestination}/extern)
@ -357,6 +366,15 @@ add_subdirectory(meshoptimizer EXCLUDE_FROM_ALL)
set_target_properties(meshoptimizer PROPERTIES FOLDER "harfang/3rdparty")
install_cppsdk_external_target(meshoptimizer)
# meshoptimizer: in emscripten remove some compile options flag
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
get_target_property(_target_cxx_flags meshoptimizer COMPILE_OPTIONS)
if(_target_cxx_flags)
list(REMOVE_ITEM _target_cxx_flags -Wall -Wextra -Wshadow -Werror)
set_target_properties(meshoptimizer PROPERTIES COMPILE_OPTIONS "${_target_cxx_flags}")
endif()
endif()
# mikktspace
add_library(mikktspace STATIC mikktspace/mikktspace.c mikktspace/mikktspace.h)
target_include_directories(mikktspace PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mikktspace>)

View File

@ -12,7 +12,7 @@ set( BGFX_SRCS
bgfx/src/renderer_d3d12.cpp bgfx/src/topology.cpp
bgfx/src/renderer_d3d9.cpp bgfx/src/vertexlayout.cpp
bgfx/src/renderer_nvn.cpp bgfx/src/renderer_webgpu.cpp
bgfx/src/renderer_agc.cpp
bgfx/src/glcontext_html5.cpp bgfx/src/renderer_agc.cpp
)
set( BGFX_HDRS
@ -35,6 +35,7 @@ set( BGFX_HDRS
bgfx/src/glcontext_glx.h bgfx/src/vs_clear.bin.h
bgfx/src/glcontext_nsgl.h bgfx/src/vs_debugfont.bin.h
bgfx/src/glcontext_wgl.h bgfx/src/renderer_webgpu.h
bgfx/src/glcontext_html5.h
bgfx/include/bgfx/bgfx.h bgfx/include/bgfx/embedded_shader.h
bgfx/include/bgfx/defines.h bgfx/include/bgfx/platform.h
@ -46,6 +47,7 @@ add_library( bgfx ${BGFX_SRCS} ${BGFX_HDRS} )
set_property( TARGET bgfx PROPERTY PUBLIC_HEADER
${CMAKE_CURRENT_SOURCE_DIR}/bgfx/include/bgfx/bgfx.h
${CMAKE_CURRENT_SOURCE_DIR}/bgfx/include/bgfx/defines.h
${CMAKE_CURRENT_SOURCE_DIR}/bgfx/include/bgfx/platform.h
)
target_include_directories( bgfx
PRIVATE
@ -56,6 +58,8 @@ target_include_directories( bgfx
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/bgfx/include>
)
target_compile_definitions( bgfx PRIVATE BGFX_GL_CONFIG_TEXTURE_READ_BACK_EMULATION=1 )
target_compile_definitions( bgfx PRIVATE BGFX_GL_CONFIG_BLIT_EMULATION=1 )
if( MSVC )
target_compile_definitions( bgfx PRIVATE "_CRT_SECURE_NO_WARNINGS" )
endif()

View File

@ -21,9 +21,11 @@ list( APPEND SPIRV_OPT_SRCS
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/opcode.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/operand.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/parsed_operand.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/pch_source.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/print.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/software_version.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/spirv_endian.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/spirv_fuzzer_options.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/spirv_optimizer_options.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/spirv_reducer_options.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/spirv_target_env.cpp
@ -34,6 +36,7 @@ list( APPEND SPIRV_OPT_SRCS
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/util/bit_vector.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/util/parse_number.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/util/string_utils.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/util/timer.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/val/basic_block.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/val/construct.cpp
${CMAKE_CURRENT_LIST_DIR}/bgfx/3rdparty/spirv-tools/source/val/function.cpp

View File

@ -85,7 +85,11 @@ if (WIN32)
target_compile_definitions(liblua PUBLIC _CRT_SECURE_NO_WARNINGS)
endif()
if(HG_BUILD_HARFANG_STATIC)
add_library(libluadll STATIC ${SRC_CORE} ${SRC_LIB})
else()
add_library(libluadll SHARED ${SRC_CORE} ${SRC_LIB})
endif()
target_include_directories(libluadll
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
@ -96,7 +100,7 @@ if(WIN32)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
target_compile_definitions(libluadll PUBLIC LUA_USE_LINUX)
endif()
set_target_properties(libluadll PROPERTIES OUTPUT_NAME lua53)
set_target_properties(libluadll PROPERTIES OUTPUT_NAME lua54)
if(NOT WIN32)
set(EXE_LIBS m readline dl)

View File

@ -10,6 +10,7 @@
#include "engine/ogg_audio_stream.h"
#include "engine/wav_audio_stream.h"
#ifndef EMSCRIPTEN
#include <AL/alc.h>
#include <AL/alext.h>
@ -624,3 +625,4 @@ void StopAllSources() {
}
} // namespace hg
#endif

View File

@ -188,22 +188,23 @@ Model CreateConeModel(const bgfx::VertexLayout &decl, float radius, float height
subdiv_x = 3;
}
const float z = height / 2.f;
std::vector<VtxIdxType> ref(subdiv_x + 2);
for (int i = 0; i < subdiv_x; i++) {
float t = 2.f * Pi * i / static_cast<float>(subdiv_x);
float cs = Cos(t);
float sn = Sin(t);
float x = radius * cs, y = radius * sn;
ref[i + 1] = builder.AddVertex({{x, 0, y}, {cs, 0.f, sn}});
ref[i + 1] = builder.AddVertex({{x, -z, y}, {cs, 0.f, sn}});
}
ref[subdiv_x + 1] = ref[0];
ref[0] = builder.AddVertex({{0, height, 0}, {0, 1, 0}});
ref[0] = builder.AddVertex({{0, z, 0}, {0, 1, 0}});
builder.AddPolygon(ref);
std::reverse(ref.begin() + 1, ref.end());
ref[0] = builder.AddVertex({{0, 0, 0}, {0, -1, 0}});
ref[0] = builder.AddVertex({{0, -z, 0}, {0, -1, 0}});
builder.AddPolygon(ref);
builder.EndList(0);
@ -217,14 +218,14 @@ Model CreateCapsuleModel(const bgfx::VertexLayout &decl, float radius, float hei
if (subdiv_y < 1)
subdiv_y = 1;
if (height < (2.f * radius))
if (height <= 0.f)
return CreateSphereModel(decl, radius, subdiv_x, subdiv_y);
ModelBuilder builder;
// cylinder
std::vector<VtxIdxType> ref(subdiv_x * 2);
const float z = height / 2.f - radius;
const float z = height / 2.f;
for (int i = 0; i < subdiv_x; i++) {
float t = 2.f * Pi * i / static_cast<float>(subdiv_x);
float cs = Cos(t);
@ -245,8 +246,8 @@ Model CreateCapsuleModel(const bgfx::VertexLayout &decl, float radius, float hei
b0 = c0;
}
VtxIdxType top = builder.AddVertex({{0.f, height / 2.f, 0.f}, {0.f, 1.f, 0.f}});
VtxIdxType bottom = builder.AddVertex({{0.f, -height / 2.f, 0.f}, {0.f, -1.f, 0.f}});
VtxIdxType top = builder.AddVertex({{0.f, height / 2.f + radius, 0.f}, {0.f, 1.f, 0.f}});
VtxIdxType bottom = builder.AddVertex({{0.f, -height / 2.f - radius, 0.f}, {0.f, -1.f, 0.f}});
std::vector<VtxIdxType> fan(2 + subdiv_x);

View File

@ -179,7 +179,10 @@ static void DrawText(bgfx::ViewId view_id, const Font &font, const std::vector<u
const auto &glyph = j->second;
stbtt_aligned_quad quad;
stbtt_packedchar pc = {glyph.pc.box.sx, glyph.pc.box.sy, glyph.pc.box.ex, glyph.pc.box.ey, glyph.pc.offsets[0].x, glyph.pc.offsets[0].y,
stbtt_packedchar pc = {(unsigned short)glyph.pc.box.sx, (unsigned short)glyph.pc.box.sy, (unsigned short)glyph.pc.box.ex,
(unsigned short)glyph.pc.box.ey,
glyph.pc.offsets[0].x,
glyph.pc.offsets[0].y,
glyph.pc.advance, glyph.pc.offsets[1].x, glyph.pc.offsets[1].y};
stbtt_GetPackedQuad(&pc, font.resolution, font.resolution, 0, &pos.x, &pos.y, &quad, 1);

View File

@ -230,6 +230,7 @@ void SceneBullet3Physics::NodeCreatePhysics(const Node &node, const Reader &ir,
auto &_node = nodes[node.ref];
if (_node.body) {
world->removeRigidBody(_node.body);
__DeleteRigidBody(_node.body);
_node.body = nullptr;
}
@ -261,6 +262,8 @@ void SceneBullet3Physics::NodeCreatePhysics(const Node &node, const Reader &ir,
} else if (type == CT_Mesh) {
if (auto tree = LoadCollisionTree(ir, ip, col.GetCollisionResource().c_str()))
shapes.push_back(tree);
} else {
error(format("Collision Type not implemented: %1").arg(type));
}
shapes.back()->setUserIndex(node.ref.idx); // ref back to node

View File

@ -18,7 +18,7 @@ class Scene;
//
struct Bullet3Node {
btRigidBody *body{};
btRigidBody *body{nullptr};
Vec3 scl{Vec3::One};
Mat4 ref_mtx{Mat4::Identity};
};

View File

@ -164,7 +164,9 @@ set_property(TARGET foundation PROPERTY PUBLIC_HEADER "${HDRS}")
set_target_properties(foundation PROPERTIES FOLDER "harfang")
if(NOT WIN32)
find_package(uuid REQUIRED)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
find_package(uuid REQUIRED)
endif()
target_link_libraries(foundation PUBLIC uuid)
else()
target_link_libraries(foundation PUBLIC Iphlpapi)

View File

@ -12,10 +12,10 @@
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#else
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <cstdio>
#include <mutex>
@ -216,7 +216,12 @@ FileInfo GetFileInfo(const char *path) {
if (stat(path, &info) != 0)
return {false, 0, 0, 0};
#endif
#if defined __CYGWIN__
return {S_ISREG(info.st_mode) ? true : false, size_t(info.st_size), time_ns(info.st_ctime), time_ns(info.st_mtime)};
#else
return {info.st_mode & S_IFREG ? true : false, size_t(info.st_size), time_ns(info.st_ctime), time_ns(info.st_mtime)};
#endif
}
//
@ -231,8 +236,11 @@ bool IsFile(const char *path) {
if (stat(path, &info) != 0)
return false;
#endif
#if defined __CYGWIN__
if (S_ISREG(info.st_mode))
#else
if (info.st_mode & S_IFREG)
#endif
return true;
return false;
}

View File

@ -66,8 +66,10 @@ else()
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
list(APPEND SRCS
sdl/input_system.cpp
sdl/input_system_sdl.cpp
sdl/input_system_sdl.h
sdl/window_system.cpp
sdl/platform_sdl.cpp
)
else()
list(APPEND SRCS
@ -91,7 +93,7 @@ elseif(ANDROID)
target_include_directories(platform PRIVATE ${ANDROID_NDK}/sources/android/native_app_glue)
target_link_libraries(platform foundation android log)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
target_link_libraries(platform foundation GL drm dl)
target_link_libraries(platform foundation GL dl)
else()
target_include_directories(platform PUBLIC ${GLFW_INCLUDE_DIRS})
target_link_libraries(platform foundation glfw)

View File

@ -0,0 +1,328 @@
// HARFANG(R) Copyright (C) 2019 Emmanuel Julien, Movida Production. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.
#include "platform/sdl/input_system_sdl.h"
#include "platform/input_system.h"
#include "foundation/cext.h"
#include "foundation/log.h"
#include "foundation/format.h"
#include "foundation/utf8.h"
#include "platform/window_system.h"
#include <SDL.h>
#include <array>
#include <memory>
#include <map>
namespace hg {
static double wheel = 0, hwheel = 0;
static int inhibit_click = 0;
MouseState previous_state;
static MouseState ReadMouse() {
MouseState state = previous_state;
state.wheel = 0;
int w, h;
auto win = GetWindowInFocus();
if (!GetWindowClientSize(win, w, h)) {
inhibit_click = 3;
return {};
}
// ...and update it
SDL_Event event;
while (SDL_PollEvent(&event))
switch (event.type) {
case SDL_FINGERMOTION: {
// use only if there is one finger
if (SDL_GetTouchFinger(event.tfinger.touchId, 1))
break;
state.x = float(event.tfinger.x) * w;
state.y = float(1.f - event.tfinger.y) * h;
} break;
case SDL_FINGERDOWN: {
// use only if there is one finger
if (SDL_GetTouchFinger(event.tfinger.touchId, 1))
break;
state.button[0] = true;
state.x = float(event.tfinger.x) * w;
state.y = float(1.f - event.tfinger.y) * h;
} break;
case SDL_MULTIGESTURE: // use this for pinch
{
if (fabs(event.mgesture.dDist) > 0.002f) {
//Pinch open
if (event.mgesture.dDist > 0) {
state.wheel = 1;
}
//Pinch close
else {
state.wheel = -1;
}
}
} break;
case SDL_FINGERUP:
// use only if there is one finger
if (SDL_GetTouchFinger(event.tfinger.touchId, 1))
break;
state.button[0] = false;
break;
case SDL_MOUSEMOTION: {
state.x = float(event.motion.x);
state.y = float(h - event.motion.y);
} break;
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
switch (event.button.button) {
case SDL_BUTTON_LEFT:
state.button[0] = (event.button.state == SDL_PRESSED);
break;
case SDL_BUTTON_MIDDLE:
state.button[2] = (event.button.state == SDL_PRESSED);
break;
case SDL_BUTTON_RIGHT:
state.button[1] = (event.button.state == SDL_PRESSED);
break;
}
break;
case SDL_MOUSEWHEEL:
if (event.wheel.y >= 1) // scroll up
state.wheel = 1;
else if (event.wheel.y <= -1) // scroll down
state.wheel = -1;
break;
}
previous_state = state;
return state;
}
// Keyboard
static KeyboardState ReadKeyboard() {
auto handle = GetWindowHandle(GetWindowInFocus());
if (!handle)
return {};
KeyboardState state;
// ...and update it.
const Uint8 *keys = SDL_GetKeyboardState(nullptr);
state.key[K_Up] = keys[SDL_SCANCODE_UP];
state.key[K_Down] = keys[SDL_SCANCODE_DOWN];
state.key[K_Left] = keys[SDL_SCANCODE_LEFT];
state.key[K_Right] = keys[SDL_SCANCODE_RIGHT];
state.key[K_Escape] = keys[SDL_SCANCODE_ESCAPE];
state.key[K_Add] = keys[SDL_SCANCODE_KP_PLUS];
state.key[K_Sub] = keys[SDL_SCANCODE_KP_MINUS];
state.key[K_Mul] = keys[SDL_SCANCODE_KP_MULTIPLY];
state.key[K_Div] = keys[SDL_SCANCODE_KP_DIVIDE];
state.key[K_Enter] = keys[SDL_SCANCODE_KP_ENTER];
state.key[K_PrintScreen] = keys[SDL_SCANCODE_PRINTSCREEN];
state.key[K_ScrollLock] = keys[SDL_SCANCODE_SCROLLLOCK];
state.key[K_Pause] = keys[SDL_SCANCODE_PAUSE];
state.key[K_NumLock] = keys[SDL_SCANCODE_NUMLOCKCLEAR];
state.key[K_Return] = keys[SDL_SCANCODE_RETURN];
state.key[K_LShift] = keys[SDL_SCANCODE_LSHIFT];
state.key[K_RShift] = keys[SDL_SCANCODE_RSHIFT];
state.key[K_LCtrl] = keys[SDL_SCANCODE_LCTRL];
state.key[K_RCtrl] = keys[SDL_SCANCODE_RCTRL];
state.key[K_LAlt] = keys[SDL_SCANCODE_LALT];
state.key[K_RAlt] = keys[SDL_SCANCODE_RALT];
state.key[K_LWin] = keys[SDL_SCANCODE_LGUI];
state.key[K_RWin] = keys[SDL_SCANCODE_RGUI];
state.key[K_Tab] = keys[SDL_SCANCODE_TAB];
state.key[K_CapsLock] = keys[SDL_SCANCODE_CAPSLOCK];
state.key[K_Space] = keys[SDL_SCANCODE_SPACE];
state.key[K_Backspace] = keys[SDL_SCANCODE_BACKSPACE];
state.key[K_Insert] = keys[SDL_SCANCODE_INSERT];
state.key[K_Suppr] = keys[SDL_SCANCODE_DELETE];
state.key[K_Home] = keys[SDL_SCANCODE_HOME];
state.key[K_End] = keys[SDL_SCANCODE_END];
state.key[K_PageUp] = keys[SDL_SCANCODE_PAGEUP];
state.key[K_PageDown] = keys[SDL_SCANCODE_PAGEDOWN];
state.key[K_F1] = keys[SDL_SCANCODE_F1];
state.key[K_F2] = keys[SDL_SCANCODE_F2];
state.key[K_F3] = keys[SDL_SCANCODE_F3];
state.key[K_F4] = keys[SDL_SCANCODE_F4];
state.key[K_F5] = keys[SDL_SCANCODE_F5];
state.key[K_F6] = keys[SDL_SCANCODE_F6];
state.key[K_F7] = keys[SDL_SCANCODE_F7];
state.key[K_F8] = keys[SDL_SCANCODE_F8];
state.key[K_F9] = keys[SDL_SCANCODE_F9];
state.key[K_F10] = keys[SDL_SCANCODE_F10];
state.key[K_F11] = keys[SDL_SCANCODE_F11];
state.key[K_F12] = keys[SDL_SCANCODE_F12];
state.key[K_Numpad0] = keys[SDL_SCANCODE_KP_0];
state.key[K_Numpad1] = keys[SDL_SCANCODE_KP_1];
state.key[K_Numpad2] = keys[SDL_SCANCODE_KP_2];
state.key[K_Numpad3] = keys[SDL_SCANCODE_KP_3];
state.key[K_Numpad4] = keys[SDL_SCANCODE_KP_4];
state.key[K_Numpad5] = keys[SDL_SCANCODE_KP_5];
state.key[K_Numpad6] = keys[SDL_SCANCODE_KP_6];
state.key[K_Numpad7] = keys[SDL_SCANCODE_KP_7];
state.key[K_Numpad8] = keys[SDL_SCANCODE_KP_8];
state.key[K_Numpad9] = keys[SDL_SCANCODE_KP_9];
state.key[K_A] = keys[SDL_SCANCODE_A];
state.key[K_B] = keys[SDL_SCANCODE_B];
state.key[K_C] = keys[SDL_SCANCODE_C];
state.key[K_D] = keys[SDL_SCANCODE_D];
state.key[K_E] = keys[SDL_SCANCODE_E];
state.key[K_F] = keys[SDL_SCANCODE_F];
state.key[K_G] = keys[SDL_SCANCODE_G];
state.key[K_H] = keys[SDL_SCANCODE_H];
state.key[K_I] = keys[SDL_SCANCODE_I];
state.key[K_J] = keys[SDL_SCANCODE_J];
state.key[K_K] = keys[SDL_SCANCODE_K];
state.key[K_L] = keys[SDL_SCANCODE_L];
state.key[K_M] = keys[SDL_SCANCODE_M];
state.key[K_N] = keys[SDL_SCANCODE_N];
state.key[K_O] = keys[SDL_SCANCODE_O];
state.key[K_P] = keys[SDL_SCANCODE_P];
state.key[K_Q] = keys[SDL_SCANCODE_Q];
state.key[K_R] = keys[SDL_SCANCODE_R];
state.key[K_S] = keys[SDL_SCANCODE_S];
state.key[K_T] = keys[SDL_SCANCODE_T];
state.key[K_U] = keys[SDL_SCANCODE_U];
state.key[K_V] = keys[SDL_SCANCODE_V];
state.key[K_W] = keys[SDL_SCANCODE_W];
state.key[K_X] = keys[SDL_SCANCODE_X];
state.key[K_Y] = keys[SDL_SCANCODE_Y];
state.key[K_Z] = keys[SDL_SCANCODE_Z];
return state;
}
static const char *GetKeyName(Key key) {
static std::map<Key, int> key_to_sdl = {
{K_LShift, SDL_SCANCODE_LSHIFT},
{K_RShift, SDL_SCANCODE_RSHIFT},
{K_LCtrl, SDL_SCANCODE_LCTRL},
{K_RCtrl, SDL_SCANCODE_RCTRL},
{K_LAlt, SDL_SCANCODE_LALT},
{K_RAlt, SDL_SCANCODE_RALT},
{K_LWin, SDL_SCANCODE_LGUI},
{K_RWin, SDL_SCANCODE_RGUI},
{K_Tab, SDL_SCANCODE_TAB},
{K_CapsLock, SDL_SCANCODE_CAPSLOCK},
{K_Space, SDL_SCANCODE_SPACE},
{K_Backspace, SDL_SCANCODE_BACKSPACE},
{K_Insert, SDL_SCANCODE_INSERT},
{K_Suppr, SDL_SCANCODE_DELETE},
{K_Home, SDL_SCANCODE_HOME},
{K_End, SDL_SCANCODE_END},
{K_PageUp, SDL_SCANCODE_PAGEUP},
{K_PageDown, SDL_SCANCODE_PAGEDOWN},
{K_Up, SDL_SCANCODE_UP},
{K_Down, SDL_SCANCODE_DOWN},
{K_Left, SDL_SCANCODE_LEFT},
{K_Right, SDL_SCANCODE_RIGHT},
{K_Escape, SDL_SCANCODE_ESCAPE},
{K_F1, SDL_SCANCODE_F1},
{K_F2, SDL_SCANCODE_F2},
{K_F3, SDL_SCANCODE_F3},
{K_F4, SDL_SCANCODE_F4},
{K_F5, SDL_SCANCODE_F5},
{K_F6, SDL_SCANCODE_F6},
{K_F7, SDL_SCANCODE_F7},
{K_F8, SDL_SCANCODE_F8},
{K_F9, SDL_SCANCODE_F9},
{K_F10, SDL_SCANCODE_F10},
{K_F11, SDL_SCANCODE_F11},
{K_F12, SDL_SCANCODE_F12},
{K_PrintScreen, SDL_SCANCODE_PRINTSCREEN},
{K_ScrollLock, SDL_SCANCODE_SCROLLLOCK},
{K_Pause, SDL_SCANCODE_PAUSE},
{K_NumLock, SDL_SCANCODE_NUMLOCKCLEAR},
{K_Return, SDL_SCANCODE_RETURN},
{K_0, SDL_SCANCODE_0},
{K_1, SDL_SCANCODE_1},
{K_2, SDL_SCANCODE_2},
{K_3, SDL_SCANCODE_3},
{K_4, SDL_SCANCODE_4},
{K_5, SDL_SCANCODE_5},
{K_6, SDL_SCANCODE_6},
{K_7, SDL_SCANCODE_7},
{K_8, SDL_SCANCODE_8},
{K_9, SDL_SCANCODE_9},
{K_Numpad0, SDL_SCANCODE_KP_0},
{K_Numpad1, SDL_SCANCODE_KP_1},
{K_Numpad2, SDL_SCANCODE_KP_2},
{K_Numpad3, SDL_SCANCODE_KP_3},
{K_Numpad4, SDL_SCANCODE_KP_4},
{K_Numpad5, SDL_SCANCODE_KP_5},
{K_Numpad6, SDL_SCANCODE_KP_6},
{K_Numpad7, SDL_SCANCODE_KP_7},
{K_Numpad8, SDL_SCANCODE_KP_8},
{K_Numpad9, SDL_SCANCODE_KP_9},
{K_Add, SDL_SCANCODE_KP_PLUS},
{K_Sub, SDL_SCANCODE_KP_MINUS},
{K_Mul, SDL_SCANCODE_KP_MULTIPLY},
{K_Div, SDL_SCANCODE_KP_DIVIDE},
{K_Enter, SDL_SCANCODE_KP_ENTER},
{K_A, SDL_SCANCODE_A},
{K_B, SDL_SCANCODE_B},
{K_C, SDL_SCANCODE_C},
{K_D, SDL_SCANCODE_D},
{K_E, SDL_SCANCODE_E},
{K_F, SDL_SCANCODE_F},
{K_G, SDL_SCANCODE_G},
{K_H, SDL_SCANCODE_H},
{K_I, SDL_SCANCODE_I},
{K_J, SDL_SCANCODE_J},
{K_K, SDL_SCANCODE_K},
{K_L, SDL_SCANCODE_L},
{K_M, SDL_SCANCODE_M},
{K_N, SDL_SCANCODE_N},
{K_O, SDL_SCANCODE_O},
{K_P, SDL_SCANCODE_P},
{K_Q, SDL_SCANCODE_Q},
{K_R, SDL_SCANCODE_R},
{K_S, SDL_SCANCODE_S},
{K_T, SDL_SCANCODE_T},
{K_U, SDL_SCANCODE_U},
{K_V, SDL_SCANCODE_V},
{K_W, SDL_SCANCODE_W},
{K_X, SDL_SCANCODE_X},
{K_Y, SDL_SCANCODE_Y},
{K_Z, SDL_SCANCODE_Z},
{K_Plus, SDL_SCANCODE_EQUALS},
{K_Comma, SDL_SCANCODE_COMMA},
{K_Minus, SDL_SCANCODE_MINUS},
{K_Period, SDL_SCANCODE_PERIOD},
};
const auto i = key_to_sdl.find(key);
if (i != std::end(key_to_sdl))
return SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)i->second));
return nullptr;
}
static Signal<void(const Window *)>::Connection on_new_window_connection;
void InputInit() {
AddMouseReader("default", ReadMouse);
AddKeyboardReader("default", ReadKeyboard, GetKeyName);
}
void InputShutdown() { new_window_signal.Disconnect(on_new_window_connection); }
} // namespace hg

View File

@ -0,0 +1,10 @@
// HARFANG(R) Copyright (C) 2019 Emmanuel Julien, Movida Production. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.
#pragma once
namespace hg {
void RegisterSDLInputSystem();
void UnregisterSDLInputSystem();
} // namespace hg

View File

@ -0,0 +1,35 @@
// HARFANG(R) Copyright (C) 2019 Emmanuel Julien, Movida Production. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.
#include "foundation/assert.h"
#include "foundation/format.h"
#include "foundation/log.h"
#include "foundation/path_tools.h"
#include "foundation/string.h"
#include "platform/input_system.h"
namespace hg {
bool InitPlatform() {
return true;
}
std::string GetPlatformLocale() {
return "fr";
}
bool OpenFolderDialog(const std::string &title, std::string &OUTPUT, const std::string &initial_dir) {
return false;
}
bool OpenFileDialog(const std::string &title, const std::string &filter, std::string &OUTPUT, const std::string &initial_dir) {
return false;
}
bool SaveFileDialog(const std::string &title, const std::string &filter, std::string &OUTPUT, const std::string &initial_dir) {
return false;
}
void DebugBreak() { }
} // namespace hg

View File

@ -1,2 +1,2 @@
SDL based input system module for the GS framework.
SDL based input system module for the Harfang framework.
Emmanuel Julien 2013

View File

@ -1,6 +1,7 @@
// HARFANG(R) Copyright (C) 2021 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.
#include "platform/window_system.h"
#include "foundation/format.h"
#include "foundation/log.h"
#include <SDL.h>
#include <iostream>
@ -8,174 +9,170 @@
namespace hg {
//-- Monitor
struct Monitor::Impl {
struct Monitor {
std::string id;
iRect rect;
bool primary;
};
Monitor::Monitor() : impl_(new Monitor::Impl()) {}
Monitor::~Monitor() = default;
Monitor::Monitor(const Monitor &m) : impl_(new Monitor::Impl(*m.impl_)) {}
Monitor::Monitor(Monitor &&) noexcept = default;
Monitor &Monitor::operator=(const Monitor &m) {
if (this != &m) {
impl_.reset(new Monitor::Impl(*m.impl_));
}
return *this;
}
Monitor &Monitor::operator=(Monitor &&) noexcept = default;
std::vector<Monitor> GetMonitors() {
std::vector<Monitor> monitors;
std::vector<Monitor *> GetMonitors() {
std::vector<Monitor *> monitors;
return monitors;
}
iRect GetMonitorRect(const Monitor &m) { return m.impl_->rect; }
iRect GetMonitorRect(const Monitor *m) { return m->rect; }
bool IsPrimaryMonitor(const Monitor &m) { return m.impl_->primary; }
bool IsPrimaryMonitor(const Monitor *m) { return m->primary; }
// TODO Return true if the monitor is connected.
bool IsMonitorConnected(const Monitor &monitor) { return true; }
bool IsMonitorConnected(const Monitor *monitor) { return true; }
// TODO Return monitor name.
std::string GetMonitorName(const Monitor &monitor) { return "TODO IN SDL"; }
std::string GetMonitorName(const Monitor *monitor) { return "TODO IN SDL"; }
// TODO Return monitor size in millimeters.
iVec2 GetMonitorSizeMM(const Monitor &monitor) { return iVec2(0, 0); }
hg::iVec2 GetMonitorSizeMM(const Monitor *monitor) { return hg::iVec2(0, 0); }
// TODO Get the list of screen modes for a given monitor.
bool GetMonitorModes(const Monitor &monitor, std::vector<MonitorMode> &modes) { return true; }
bool GetMonitorModes(const Monitor *monitor, std::vector<MonitorMode> &modes) { return true; }
//-- Window
//
struct SDLWindow {
struct Window {
SDL_Window *w{0};
bool is_foreign{false};
};
void WindowSystemInit() { SDL_Init(SDL_INIT_VIDEO); }
static Window *window_in_focus;
Window NewWindow(int width, int height, int bpp, Window::Visibility visibility) {
Signal<void(const Window *)> new_window_signal;
Signal<void(const Window *, bool)> window_focus_signal;
Signal<bool(const Window *)> close_window_signal;
Signal<void(const Window *)> destroy_window_signal;
Window w;
static_assert(sizeof(SDLWindow) <= sizeof(Window), "Window OS object size exceeds generic object size");
auto data = reinterpret_cast<SDLWindow *>(w.data.data());
void WindowSystemInit() {
SDL_Init(SDL_INIT_VIDEO);
uint window_flag = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
// DISABLE ALL TEXT KEYBOARD
SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
SDL_EventState(SDL_KEYDOWN, SDL_DISABLE);
SDL_EventState(SDL_KEYUP, SDL_DISABLE);
}
Window *NewWindow(int width, int height, int bpp, WindowVisibility visibility) {
Window *w = new Window();
int window_flag = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN;
switch (visibility) {
case Window::Fullscreen:
case WV_Fullscreen:
window_flag |= SDL_WINDOW_FULLSCREEN;
break;
case Window::Undecorated:
case WV_Undecorated:
window_flag |= SDL_WINDOW_BORDERLESS;
break;
default:
case Window::Windowed:
case WV_Windowed:
break;
}
data->w = SDL_CreateWindow("Harfang", 0, 0, width, height, window_flag);
SetWindowTitle(w, "Harfang");
w->w = SDL_CreateWindow(nullptr, 0, 0, width, height, window_flag);
UpdateWindow(w);
debug(format("NewWindow: %1").arg((void *)data->w));
debug(format("NewWindow: %1").arg((void *)w->w));
return w;
}
Window NewWindowFrom(void *handle) {
Window w;
auto data = reinterpret_cast<SDLWindow *>(w.data.data());
Window *NewWindow(const char *title, int width, int height, int bpp, WindowVisibility visibility) {
auto win = NewWindow(width, height, bpp, visibility);
SetWindowTitle(win, title);
return win;
}
data->is_foreign = true;
data->w = reinterpret_cast<SDL_Window *>(handle);
Window *NewWindowFrom(void *handle) {
Window *w = new Window();
SDL_CreateWindowFrom(data->w);
w->is_foreign = true;
w->w = reinterpret_cast<SDL_Window *>(handle);
SDL_CreateWindowFrom(w->w);
return w;
}
// TODO Create a new fullscreen window on a specified monitor.
Window NewFullscreenWindow(const Monitor &monitor, int mode_index, MonitorRotation rotation) { return NewWindow(512, 512, 32, Window::Windowed); }
Window *NewFullscreenWindow(const Monitor *monitor, int mode_index, MonitorRotation rotation) { return NewWindow(512, 512, 32, WV_Windowed); }
void *GetDisplay() { return nullptr; }
void *GetWindowHandle(const Window &w) { return reinterpret_cast<void *>(reinterpret_cast<const SDLWindow *>(w.data.data())->w); }
static const char *canvas_name = "canvas";
void *GetWindowHandle(const Window *w) {
return (void *)canvas_name;
// return reinterpret_cast<void *>(w->w);
}
Window GetWindowInFocus() { return g_window_system.get().window_in_focus; }
Window *GetWindowInFocus() { return window_in_focus; }
bool DestroyWindow(Window &w) {
auto data = reinterpret_cast<SDLWindow *>(w.data.data());
debug(format("DestroyWindow: %1").arg((void *)data->w));
g_window_system.get().window_focus_signal.Emit(w, false);
SDL_DestroyWindow(data->w);
data->w = 0;
bool DestroyWindow(Window *w) {
debug(format("DestroyWindow: %1").arg((void *)w->w));
window_focus_signal.Emit(w, false);
SDL_DestroyWindow(w->w);
w->w = 0;
delete w;
return true;
}
//
bool UpdateWindow(const Window &w) {
bool UpdateWindow(const Window *w) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
if (SDL_GetWindowFlags(data->w) & SDL_WINDOW_INPUT_FOCUS) {
if (SDL_GetWindowFlags(w->w) & SDL_WINDOW_INPUT_FOCUS) {
// in focus
if (!(g_window_system.get().window_in_focus == w)) {
if (!(window_in_focus == w)) {
g_window_system.get().window_in_focus = w;
g_window_system.get().window_focus_signal.Emit(w, true);
window_in_focus = (Window *)w;
window_focus_signal.Emit(w, true);
}
} else if (g_window_system.get().window_in_focus == w) {
} else if (window_in_focus == w) {
// not in focus
g_window_system.get().window_in_focus = Window(); // blank window
g_window_system.get().window_focus_signal.Emit(w, false);
window_in_focus = new Window(); // blank window
window_focus_signal.Emit(w, false);
}
return true;
}
//
bool GetWindowClientSize(const Window &w, int &width, int &height) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
SDL_GetWindowSize(data->w, &width, &height);
bool GetWindowClientSize(const Window *w, int &width, int &height) {
if (!w)
return false;
SDL_GetWindowSize(w->w, &width, &height);
return true;
}
bool SetWindowClientSize(const Window &w, int width, int height) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
SDL_SetWindowSize(data->w, width, height);
bool SetWindowClientSize(Window *w, int width, int height) {
if (!w)
return false;
SDL_SetWindowSize(w->w, width, height);
return true;
}
bool GetWindowTitle(const Window &w, std::string &title) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
return true;
}
bool GetWindowTitle(const Window *w, std::string &title) { return true; }
bool SetWindowTitle(const Window &w, const std::string &title) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
return true;
}
bool SetWindowTitle(Window *w, const std::string &title) { return true; }
bool WindowHasFocus(const Window &w) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
return true;
}
bool WindowHasFocus(const Window *w) { return true; }
bool SetWindowPos(const Window &w, const iVec2 &v) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
SDL_SetWindowPosition(data->w, v.x, v.y);
bool SetWindowPos(const Window *w, const hg::iVec2 &v) {
SDL_SetWindowPosition(w->w, v.x, v.y);
UpdateWindow(w); // process messages on the spot
return true;
}
iVec2 GetWindowPos(const Window &w) {
auto data = reinterpret_cast<const SDLWindow *>(w.data.data());
hg::iVec2 GetWindowPos(const Window *w) {
UpdateWindow(w);
iVec2 pos;
SDL_GetWindowPosition(data->w, &pos.x, &pos.y);
hg::iVec2 pos;
SDL_GetWindowPosition(w->w, &pos.x, &pos.y);
return pos;
}

View File

@ -1 +1 @@
3.2.3
3.2.4

View File

@ -9,22 +9,24 @@ add_custom_command(
${CMAKE_CURRENT_BINARY_DIR}/binding/fabgen.h
${CMAKE_CURRENT_BINARY_DIR}/binding/go.mod
COMMAND
${Python3_EXECUTABLE} bind.py ${CMAKE_CURRENT_SOURCE_DIR}/../../binding/bind_harfang.py --go --out ${CMAKE_CURRENT_BINARY_DIR}/binding ${HG_BINDING_DEFINES}
${Python3_EXECUTABLE} bind.py ${CMAKE_CURRENT_SOURCE_DIR}/../../binding/bind_harfang.py --go --out ${CMAKE_CURRENT_BINARY_DIR}/binding --doc_md_folder ${CMAKE_CURRENT_SOURCE_DIR}/../../doc/doc ${HG_BINDING_DEFINES}
MAIN_DEPENDENCY
${CMAKE_CURRENT_SOURCE_DIR}/../../binding/bind_harfang.py
WORKING_DIRECTORY
${HG_FABGEN_PATH}
COMMENT
"Generating Harfang binding for Go: go fabgen=${HG_FABGEN_PATH} srcdir=${CMAKE_SOURCE_DIR} dstdir=${CMAKE_CURRENT_BINARY_DIR}")
"Generating Harfang binding for Go: go fabgen=${HG_FABGEN_PATH} srcdir=${CMAKE_SOURCE_DIR} dstdir=${CMAKE_CURRENT_BINARY_DIR}"
DEPENDS ${static_libs})
add_library(hg_go SHARED
add_library(hg_go STATIC
${CMAKE_CURRENT_BINARY_DIR}/binding/wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/binding/wrapper.h
${CMAKE_CURRENT_BINARY_DIR}/binding/fabgen.h)
target_link_libraries(hg_go script engine foundation platform)
target_link_libraries(hg_go PUBLIC script engine foundation platform)
set_target_properties(hg_go PROPERTIES FOLDER "harfang/languages")
set_target_properties(hg_go PROPERTIES OUTPUT_NAME "harfang" )
install(TARGETS hg_go
RUNTIME DESTINATION hg_go
@ -42,6 +44,105 @@ install(FILES
COMPONENT go
)
add_dependencies(hg_go bind_hg_lua)
install_cppsdk_dependencies(hg_go go)
function(bundle_static_library tgt_name bundled_tgt_name)
list(APPEND static_libs ${tgt_name})
function(_recursively_collect_dependencies input_target)
set(_input_link_libraries LINK_LIBRARIES)
get_target_property(_input_type ${input_target} TYPE)
if (${_input_type} STREQUAL "INTERFACE_LIBRARY")
set(_input_link_libraries INTERFACE_LINK_LIBRARIES)
endif()
get_target_property(public_dependencies ${input_target} ${_input_link_libraries})
foreach(dependency IN LISTS public_dependencies)
if(TARGET ${dependency})
get_target_property(alias ${dependency} ALIASED_TARGET)
if (TARGET ${alias})
set(dependency ${alias})
endif()
get_target_property(_type ${dependency} TYPE)
if (${_type} STREQUAL "STATIC_LIBRARY")
list(APPEND static_libs ${dependency})
endif()
get_property(library_already_added
GLOBAL PROPERTY _${tgt_name}_static_bundle_${dependency})
if (NOT library_already_added)
set_property(GLOBAL PROPERTY _${tgt_name}_static_bundle_${dependency} ON)
_recursively_collect_dependencies(${dependency})
endif()
endif()
endforeach()
set(static_libs ${static_libs} PARENT_SCOPE)
endfunction()
_recursively_collect_dependencies(${tgt_name})
list(REMOVE_DUPLICATES static_libs)
set(bundled_tgt_full_name ${CMAKE_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${bundled_tgt_name}${CMAKE_STATIC_LIBRARY_SUFFIX})
set(bundled_tgt_full_name ${bundled_tgt_full_name} PARENT_SCOPE)
if (CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU)$")
file(WRITE ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in
"CREATE ${bundled_tgt_full_name}\n" )
foreach(tgt IN LISTS static_libs)
file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in
"ADDLIB $<TARGET_FILE:${tgt}>\n")
endforeach()
file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in "SAVE\n")
file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in "END\n")
file(GENERATE
OUTPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar
INPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in)
set(ar_tool ${CMAKE_AR})
if (CMAKE_INTERPROCEDURAL_OPTIMIZATION)
set(ar_tool ${CMAKE_CXX_COMPILER_AR})
endif()
add_custom_command(
COMMAND ${ar_tool} -M < ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar
OUTPUT ${bundled_tgt_full_name}
COMMENT "Bundling ${bundled_tgt_name}"
VERBATIM)
elseif(MSVC)
find_program(lib_tool lib)
foreach(tgt IN LISTS static_libs)
list(APPEND static_libs_full_names $<TARGET_FILE:${tgt}>)
endforeach()
add_custom_command(
COMMAND ${lib_tool} /NOLOGO /OUT:${bundled_tgt_full_name} ${static_libs_full_names}
OUTPUT ${bundled_tgt_full_name}
COMMENT "Bundling ${bundled_tgt_name}"
VERBATIM)
else()
message(FATAL_ERROR "Unknown bundle scenario!")
endif()
add_custom_target(bundling_target ALL DEPENDS ${bundled_tgt_full_name})
add_dependencies(bundling_target ${tgt_name})
add_library(${bundled_tgt_name} STATIC IMPORTED)
set_target_properties(${bundled_tgt_name}
PROPERTIES
IMPORTED_LOCATION ${bundled_tgt_full_name}
INTERFACE_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:${tgt_name},INTERFACE_INCLUDE_DIRECTORIES>)
add_dependencies(${bundled_tgt_name} bundling_target)
set_target_properties(bundling_target PROPERTIES FOLDER "harfang/languages")
endfunction()
bundle_static_library(hg_go harfang)
install(FILES ${bundled_tgt_full_name} DESTINATION hg_go COMPONENT go)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF)

View File

@ -1,3 +1,53 @@
# [3.2.4] - 2022-09-27
This minor release provides minor corrections and fixes to specific issues:
- Fixed the OpenGL support of the rendering pipeline (see https://github.com/harfang3d/harfang-core-package).
- Improved the support of the Go language (see https://pkg.go.dev/github.com/harfang3d/harfang-go).
- Improved the Emscripten build.
### Framework integration and source code maintenance
- Ongoing effort to support the WASM / Emscripten target.
- Added a series of flags improve the compilation to WASM.
- Updated the SDL calls to support the latest inputs/windows system.
- :warning: Audio is disabled for now.
### Binding / Golang support
- Proper package of the Go binding.
- Added a _mingw_ build stage for the Windows lib part of HARFANG.
- Added a cmake flag `HG_BUILD_HARFANG_STATIC` to build HAFANG in static mode.
- Added a Go directive (based on FabGen merge request https://github.com/ejulien/FABGen/pull/60).
- Removed the non-mingw Go build from the Windows target.
- Updated cmake to build HARFANG Go as a monolithic lib.
- Reinstated the script support (to embed Lua in a Go project).
- The support for the _OpenVR_ API was (temporarily) removed.
### Toolchain
- **GLTF importer:**
- support for camera and lights (:warning: experimental)
- support for _point_, _directional_ and _spot_ types.
- support for the diffuse color and intensity (specular is not supported by the GLTF standard).
- Fixed a mislabelled _usage_.
- **Assetc:** added `jpeg` to the textures checklist.
- Fix #16 (lua53.dll should be lua54.dll).
### Binding
- Added a constructor to `FileFilter`.
- Fixed the arg out for `CollectCollisionEvents` to return a `NodePairContacts` properly.
### Physics
- Improved the ability of a node to change its collision shape component multiple times during runtime.
- Fix #17 Capsule / Cone model fix.
### Documentation
- Fixed a mention to `ViewMode` enums in the manual.
- Fixed the reference to 3 physics functions in the manual, `Bullet3Physics`, `SyncTransformsFromScene` and `SyncTransformsToScene`.
# [3.2.3] - 2022-07-13
This minor release brings several fixes to the rendering, physics, engine, foundation and tools.

View File

@ -1507,7 +1507,7 @@ struct AssetConfig {
};
static AssetType GetAssetFileType(std::string path, const std::vector<std::string> &all_files, std::vector<std::string> &out_files) {
static const std::set<std::string> texture_exts = {"bmp", "exr", "gif", "jpg", "hdr", "png", "psd", "tga"};
static const std::set<std::string> texture_exts = {"bmp", "exr", "gif", "jpg", "jpeg", "hdr", "png", "psd", "tga"};
static const std::set<std::string> ignored_exts = {"tmp"};
const auto ext = tolower(GetFileExtension(path));

View File

@ -917,6 +917,49 @@ static const size_t ExportObject(Model &model, const hg::Object &object, const C
return id_mesh;
}
static size_t ExportCamera(Model& model, const hg::Camera& cam) {
Camera gltf_camera;
if (cam.GetIsOrthographic()) {
gltf_camera.type = "orthographic";
gltf_camera.orthographic.znear = cam.GetZNear();
gltf_camera.orthographic.zfar = cam.GetZFar();
} else {
gltf_camera.type = "perspective";
gltf_camera.perspective.znear = cam.GetZNear();
gltf_camera.perspective.zfar = cam.GetZFar();
gltf_camera.perspective.yfov = (double)cam.GetFov();
}
model.cameras.push_back(gltf_camera);
return model.cameras.size() - 1;
}
static int ExportLight(Model &model, const hg::Light &light) {
Light gltf_light;
gltf_light.color.push_back(light.GetDiffuseColor().r);
gltf_light.color.push_back(light.GetDiffuseColor().g);
gltf_light.color.push_back(light.GetDiffuseColor().b);
gltf_light.intensity = light.GetDiffuseIntensity();
gltf_light.spot.innerConeAngle = light.GetInnerAngle();
gltf_light.spot.outerConeAngle = light.GetOuterAngle();
gltf_light.range = light.GetRadius();
if (light.GetType() == hg::LT_Point) {
gltf_light.type = "point";
} else if (light.GetType() == hg::LT_Linear) {
gltf_light.type = "directional";
} else if (light.GetType() == hg::LT_Spot) {
gltf_light.type = "spot";
}
model.lights.push_back(gltf_light);
return model.lights.size() - 1;
}
//
static const int ExportNode(Model &model, const hg::NodeRef nodeRef, const std::vector<hg::NodeRef> &children, const hg::NodesChildren &nodes_children,
const hg::Scene &scene, const Config &config, hg::PipelineResources &resources) {
@ -957,12 +1000,19 @@ static const int ExportNode(Model &model, const hg::NodeRef nodeRef, const std::
n.scale.push_back(s.y);
n.scale.push_back(s.z);
}
/*
// is it a camera
if (gltf_node.camera >= 0)
ExportCamera(model, gltf_node, node, scene, config, resources);
*/
if (node.HasCamera()) {
n.camera = ExportCamera(model, node.GetCamera());
}
// is it a light
if (node.HasLight()) {
if (std::find(model.extensionsUsed.begin(), model.extensionsUsed.end(), "KHR_lights_punctual") == model.extensionsUsed.end())
model.extensionsUsed.push_back("KHR_lights_punctual");
n.extensions["KHR_lights_punctual"] = Value({{"light", Value(ExportLight(model, node.GetLight()))}});
}
//
if (node.HasObject()) {
auto id_mesh = ExportObject(model, node.GetObject(), config, resources);

View File

@ -735,7 +735,7 @@ static hg::Material ExportMaterial(const Model &model, const Material &gltf_mat,
hg::debug(hg::format(" - Using pipeline shader '%1'").arg(shader));
mat.program = resources.programs.Add(shader.c_str(), {});
// FinalizeMaterial(mat, fbx_material->GetName(), geo_name);
// FinalizeMaterial(mat, gltf_material->GetName(), geo_name);
return mat;
}
@ -1313,7 +1313,6 @@ static void ExportObject(const Model &model, const Node &gltf_node, hg::Node &no
static void ExportCamera(const Model &model, const Node &gltf_node, hg::Node &node, hg::Scene &scene, const Config &config, hg::PipelineResources &resources) {
auto camera = scene.CreateCamera();
node.SetCamera(camera);
auto gltf_camera = model.cameras[gltf_node.camera];
@ -1327,6 +1326,31 @@ static void ExportCamera(const Model &model, const Node &gltf_node, hg::Node &no
camera.SetZFar(gltf_camera.orthographic.zfar);
camera.SetIsOrthographic(true);
}
node.SetCamera(camera);
}
static void ExportLight(const Model &model, const size_t &id_light, hg::Node &node, hg::Scene &scene, const Config &config, hg::PipelineResources &resources) {
auto light = scene.CreateLight();
auto gltf_light = model.lights[id_light];
light.SetDiffuseColor(hg::Color(gltf_light.color[0], gltf_light.color[1], gltf_light.color[2]));
light.SetDiffuseIntensity(gltf_light.intensity);
light.SetInnerAngle(gltf_light.spot.innerConeAngle);
light.SetOuterAngle(gltf_light.spot.outerConeAngle);
light.SetRadius(gltf_light.range);
if (gltf_light.type == "point") {
light.SetType(hg::LT_Point);
} else if (gltf_light.type == "directional") {
light.SetType(hg::LT_Linear);
} else if (gltf_light.type == "spot") {
light.SetType(hg::LT_Spot);
}
node.SetLight(light);
}
//
@ -1378,6 +1402,15 @@ static hg::Node ExportNode(const Model &model, const int &gltf_id_node, hg::Scen
if (gltf_node.camera >= 0)
ExportCamera(model, gltf_node, node, scene, config, resources);
// is it a light
auto KHR_lights_punctual = gltf_node.extensions.find("KHR_lights_punctual");
if (KHR_lights_punctual != gltf_node.extensions.end()) {
if (KHR_lights_punctual->second.Has("light")) {
auto id_light = KHR_lights_punctual->second.Get("light").Get<int>();
ExportLight(model, id_light, node, scene, config, resources);
}
}
// is it a mesh
if (gltf_node.mesh >= 0 || gltf_node.skin >= 0) {
// if the node doesn't have a name, give the geo name, if there is one
@ -1610,7 +1643,7 @@ int main(int argc, const char **argv) {
{"-shader", "Material pipeline shader [default=core/shader/pbr.hps]", true},
},
{
{"input", "Input FBX file to convert"},
{"input", "Input GLTF file to convert"},
},
{
{"-o", "-out"},