Compare commits
85 Commits
f58402921f
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c860152f9b | |||
| da4c1fee0e | |||
| 4cf0ea5321 | |||
| 8320b14358 | |||
| 1d358d206e | |||
| cd91174f5d | |||
| 4b24d85123 | |||
| f86e7fd96c | |||
| 272e202774 | |||
| 80fba23cd2 | |||
| c031056e17 | |||
| 49fc547295 | |||
| d6d61229f8 | |||
| 5bb529bc31 | |||
| d3c93c5c18 | |||
| 9bb9e2c09b | |||
| 3f99099919 | |||
| 81a78990ce | |||
| 33fc237793 | |||
| 44896ed0d9 | |||
| e0db570581 | |||
| 6eed5063e6 | |||
| 5b014dcb65 | |||
| cd82fb0eed | |||
| 3f0484e87c | |||
| 9c4bea5983 | |||
| 3645557520 | |||
| 19a1275a8a | |||
| 25280a9cbe | |||
| 7e06da700a | |||
| 9e5d08bfc6 | |||
| a62d781aa0 | |||
| fea7c71788 | |||
| e967844558 | |||
| 62e14cf075 | |||
| 4249a0238b | |||
| cfd9ed8708 | |||
| 1977a12d8b | |||
| 190318e5c4 | |||
| 1aa002d8ba | |||
| 1bc0f298fc | |||
| e6463fc264 | |||
| 7621607152 | |||
| 82ac145e87 | |||
| ff780c34b3 | |||
| 5c03f0cd2c | |||
| 4d0fb8f60f | |||
| 3f59a384e4 | |||
| d42cf2854a | |||
| 92ec3e9497 | |||
| 25816c5658 | |||
| 1c56387c35 | |||
| aca04ff621 | |||
| 847aab6ed0 | |||
| b434e516f0 | |||
| e0045ffeb1 | |||
| 6ec256195b | |||
| 228eafb7d8 | |||
| 338ffe2661 | |||
| 657107b4ae | |||
| 503db60c60 | |||
| c730ca5222 | |||
| 2349bbc77e | |||
| d3b2ae30d5 | |||
| 52de5b16a8 | |||
| 5c05f6b8e0 | |||
| 9ef3194cde | |||
| 0c27405da7 | |||
| 51c25ac6a6 | |||
| db46a3a7a7 | |||
| f7db2130a8 | |||
| 99b711f42f | |||
| 912f3e5368 | |||
| cb4229905d | |||
| 4a3315e104 | |||
| 79d27bd7ab | |||
| f67d0c9ccb | |||
| 7fa48cab21 | |||
| 8d1345a532 | |||
| 8d95fcc97e | |||
| 4c9990b4da | |||
| 4a790a060a | |||
| c72b1cf35e | |||
| 52d6d31241 | |||
| b2e010bdb4 |
7
.gitattributes
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
*.blend filter=lfs diff=lfs merge=lfs -text
|
||||
*.kra filter=lfs diff=lfs merge=lfs -text
|
||||
*.vrm filter=lfs diff=lfs merge=lfs -text
|
||||
*.vroid filter=lfs diff=lfs merge=lfs -text
|
||||
*.fbx filter=lfs diff=lfs merge=lfs -text
|
||||
*.wav filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
5
.gitignore
vendored
@@ -1,4 +1,9 @@
|
||||
*~
|
||||
build/*
|
||||
build-vscode/*
|
||||
characters/*
|
||||
resources/buildings/*
|
||||
assets/blender/scripts/*.blend
|
||||
__pycache__/
|
||||
*.blend[1-9]
|
||||
./characters/
|
||||
|
||||
73
.vscode/settings.json
vendored
@@ -1,7 +1,76 @@
|
||||
{
|
||||
"cmake.generator": "Unix Makefiles",
|
||||
"cmake.configureSettings": {
|
||||
"CMAKE_PREFIX_PATH": "/media/slapin/library/ogre/ogre-sdk"
|
||||
"CMAKE_PREFIX_PATH": "/media/slapin/library/ogre3/ogre-sdk",
|
||||
"CMAKE_VERBOSE_MAKEFILE": "ON"
|
||||
},
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build-vscode"
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build-vscode",
|
||||
"files.associations": {
|
||||
"istream": "cpp",
|
||||
"variant": "cpp",
|
||||
"tuple": "cpp",
|
||||
"iostream": "cpp",
|
||||
"string_view": "cpp",
|
||||
"atomic": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"random": "cpp",
|
||||
"future": "cpp",
|
||||
"array": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"span": "cpp",
|
||||
"chrono": "cpp",
|
||||
"format": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"charconv": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"optional": "cpp",
|
||||
"ratio": "cpp",
|
||||
"system_error": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"numeric": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
||||
18
.vscode/tasks.json
vendored
@@ -13,7 +13,8 @@
|
||||
"label": "CMake: clean rebuild",
|
||||
"command": "build",
|
||||
"targets": [
|
||||
"GuiTest",
|
||||
"Editor",
|
||||
"Game",
|
||||
"0_Bootstrap",
|
||||
"TerrainTest",
|
||||
"Procedural"
|
||||
@@ -27,7 +28,8 @@
|
||||
"label": "CMake: clean rebuild",
|
||||
"command": "cleanRebuild",
|
||||
"targets": [
|
||||
"GuiTest",
|
||||
"Editor",
|
||||
"Game",
|
||||
"0_Bootstrap",
|
||||
"TerrainTest",
|
||||
"Procedural"
|
||||
@@ -57,6 +59,18 @@
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "CMake clean rebuild task"
|
||||
},
|
||||
{
|
||||
"type": "cmake",
|
||||
"label": "CMake: build",
|
||||
"command": "build",
|
||||
"targets": [
|
||||
"Editor",
|
||||
"Game"
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "CMake build task"
|
||||
}
|
||||
]
|
||||
}
|
||||
846
Bootstrap.cpp
344
CMakeLists.txt
@@ -1,38 +1,46 @@
|
||||
project(world2)
|
||||
cmake_minimum_required(VERSION 3.13.0)
|
||||
project(world2)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(BLENDER /home/slapin/blender-3.6.20-linux-x64/blender)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(BLENDER "${CMAKE_SOURCE_DIR}/../../blender-bin/bin/blender" CACHE STRING "Blender path")
|
||||
set(CREATE_DIRECTORIES
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/shapes/male
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/shapes/female
|
||||
${CMAKE_SOURCE_DIR}/characters/shapes/male/chibi
|
||||
${CMAKE_SOURCE_DIR}/characters/shapes/female/chibi
|
||||
${CMAKE_SOURCE_DIR}/characters/male
|
||||
${CMAKE_SOURCE_DIR}/characters/female)
|
||||
set(CREATE_SCENES
|
||||
${CMAKE_SOURCE_DIR}/characters/female/vroid-normal-female.scene
|
||||
${CMAKE_SOURCE_DIR}/characters/male/vroid-normal-male.scene
|
||||
)
|
||||
|
||||
${CMAKE_BINARY_DIR}/assets/blender/shapes/male
|
||||
${CMAKE_BINARY_DIR}/assets/blender/shapes/female
|
||||
${CMAKE_BINARY_DIR}/assets/blender/scripts
|
||||
${CMAKE_BINARY_DIR}/characters/shapes/male/chibi
|
||||
${CMAKE_BINARY_DIR}/characters/shapes/female/chibi
|
||||
${CMAKE_BINARY_DIR}/characters/male
|
||||
${CMAKE_BINARY_DIR}/characters/female)
|
||||
#set(CREATE_SCENES
|
||||
# ${CMAKE_SOURCE_DIR}/characters/female/vroid-normal-female.scene
|
||||
# ${CMAKE_SOURCE_DIR}/characters/male/vroid-normal-male.scene
|
||||
# )
|
||||
|
||||
# workaround horribly broken assimp cmake, fixed with assimp 5.1
|
||||
add_library(fix::assimp INTERFACE IMPORTED)
|
||||
set_target_properties(fix::assimp PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "${ASSIMP_LIBRARIES};pugixml"
|
||||
INTERFACE_LINK_DIRECTORIES "${ASSIMP_LIBRARY_DIRS}"
|
||||
)
|
||||
file(GLOB TERRAIN_SRC ${CMAKE_SOURCE_DIR}/src/terrain/*.cpp)
|
||||
#add_library(assimp INTERFACE IMPORTED)
|
||||
#set_target_properties(assimp PROPERTIES
|
||||
# INTERFACE_LINK_LIBRARIES "assimp;pugixml"
|
||||
# # INTERFACE_LINK_DIRECTORIES "${ASSIMP_LIBRARY_DIRS}"
|
||||
# INTERFACE_LINK_DIRECTORIES "${CMAKE_PREFIX_PATH}/lib"
|
||||
#)
|
||||
file(GLOB WATER_SRC ${CMAKE_SOURCE_DIR}/water/*.cpp)
|
||||
|
||||
# The COMPONENTS part checks that OGRE was built the way we need it
|
||||
# The CONFIG flag makes sure we get OGRE instead of OGRE-next
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging CONFIG)
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Paging Terrain CONFIG)
|
||||
find_package(ZLIB)
|
||||
find_package(SDL2)
|
||||
find_package(assimp)
|
||||
find_package(Bullet)
|
||||
find_package(assimp REQUIRED CONFIG)
|
||||
find_package(OgreProcedural REQUIRED CONFIG)
|
||||
find_package(pugixml REQUIRED CONFIG)
|
||||
find_package(flecs REQUIRED CONFIG)
|
||||
|
||||
add_library(fix::assimp INTERFACE IMPORTED)
|
||||
set_target_properties(fix::assimp PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "${ASSIMP_LIBRARIES};pugixml"
|
||||
INTERFACE_LINK_DIRECTORIES "${ASSIMP_LIBRARY_DIRS}"
|
||||
# INTERFACE_LINK_DIRECTORIES "${CMAKE_PREFIX_PATH}/lib"
|
||||
)
|
||||
|
||||
add_library(fix::OgreProcedural INTERFACE IMPORTED)
|
||||
set_target_properties(fix::OgreProcedural PROPERTIES
|
||||
@@ -40,27 +48,74 @@ set_target_properties(fix::OgreProcedural PROPERTIES
|
||||
INTERFACE_LINK_DIRECTORIES "${CMAKE_PREFIX_PATH}/lib"
|
||||
)
|
||||
|
||||
if(OGRE_STATIC)
|
||||
add_library(OgreGLSupportStatic INTERFACE IMPORTED)
|
||||
set_target_properties(OgreGLSupportStatic PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "OgreGLSupportStatic"
|
||||
INTERFACE_LINK_DIRECTORIES "${CMAKE_PREFIX_PATH}/lib"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(fix::pugixml INTERFACE IMPORTED)
|
||||
set_target_properties(fix::pugixml PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "pugixml"
|
||||
INTERFACE_LINK_DIRECTORIES "${CMAKE_PREFIX_PATH}/lib"
|
||||
)
|
||||
|
||||
|
||||
|
||||
add_subdirectory(src/lua)
|
||||
add_subdirectory(src/gamedata)
|
||||
add_subdirectory(src/miniaudio)
|
||||
add_subdirectory(src/sound)
|
||||
add_subdirectory(src/sceneloader)
|
||||
add_subdirectory(audio/gui)
|
||||
add_subdirectory(lua-scripts)
|
||||
add_subdirectory(morph)
|
||||
add_subdirectory(src/world)
|
||||
add_subdirectory(src/tests)
|
||||
add_subdirectory(src/physics)
|
||||
add_subdirectory(src/editor)
|
||||
add_subdirectory(assets/blender/buildings/parts)
|
||||
add_subdirectory(resources)
|
||||
|
||||
# add the source files as usual
|
||||
add_executable(0_Bootstrap Bootstrap.cpp)
|
||||
|
||||
# this also sets the includes and pulls third party dependencies
|
||||
target_link_libraries(0_Bootstrap OgreBites OgreBullet OgrePaging ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
|
||||
target_include_directories(0_Bootstrap PUBLIC OgreBites OgrePaging OgreBullet)
|
||||
add_dependencies(0_Bootstrap stage_files)
|
||||
add_executable(Game Game.cpp ${WATER_SRC})
|
||||
target_include_directories(Game PRIVATE src/gamedata)
|
||||
target_link_libraries(Game OgreBites OgrePaging OgreTerrain OgreMeshLodGenerator
|
||||
OgreProcedural::OgreProcedural
|
||||
GameData
|
||||
sound
|
||||
sceneloader physics
|
||||
flecs::flecs_static
|
||||
-Wl,--as-needed
|
||||
)
|
||||
if(OGRE_STATIC)
|
||||
target_link_options(Game PRIVATE -static-libstdc++ -static-libgcc)
|
||||
endif()
|
||||
add_dependencies(Game stage_files import_buildings import_water_stuff import_vehicles import_vrm audio_data_gui)
|
||||
|
||||
add_executable(GuiTest GuiTest.cpp ${TERRAIN_SRC} ${WATER_SRC})
|
||||
target_link_libraries(GuiTest OgreBites OgreBullet OgrePaging OgreTerrain OgreMeshLodGenerator ${OgreProcedural_LIBRARIES} ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
|
||||
target_include_directories(GuiTest PUBLIC OgreBites OgrePaging OgreBullet OgreTerrain OgreMeshLodGenerator ${OgreProcedural_INCLUDE_DIRS})
|
||||
add_dependencies(GuiTest stage_files import_buildings)
|
||||
|
||||
add_executable(Procedural Procedural.cpp ${TERRAIN_SRC})
|
||||
target_link_libraries(Procedural OgreBites OgreBullet OgrePaging OgreTerrain OgreProcedural::OgreProcedural ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
|
||||
target_include_directories(Procedural PUBLIC OgreBites OgrePaging OgreBullet OgreTerrain OgreProcedural::OgreProcedural ${CMAKE_PREFIX_PATH}/include/OgreProcedural)
|
||||
add_executable(Procedural Procedural.cpp)
|
||||
target_link_libraries(Procedural OgreBites OgrePaging OgreTerrain
|
||||
OgreProcedural::OgreProcedural
|
||||
-Wl,--as-needed
|
||||
)
|
||||
if(OGRE_STATIC)
|
||||
target_link_options(Procedural PRIVATE -static-libstdc++ -static-libgcc)
|
||||
endif()
|
||||
add_dependencies(Procedural stage_files import_buildings)
|
||||
|
||||
file(GLOB FONTS_SRC ${CMAKE_SOURCE_DIR}/assets/fonts/*.ttf)
|
||||
set(FONT_OUTPUT_FILES)
|
||||
foreach(FONT_FILE ${FONTS_SRC})
|
||||
get_filename_component(FILE_NAME ${FONT_FILE} NAME_WE)
|
||||
set(FONT_OUTPUT_FILE ${CMAKE_BINARY_DIR}/resources/fonts/${FILE_NAME}.ttf)
|
||||
add_custom_command(
|
||||
OUTPUT ${FONT_OUTPUT_FILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/resources/fonts
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${FONT_FILE} ${FONT_OUTPUT_FILE}
|
||||
DEPENDS ${FONT_FILE})
|
||||
list(APPEND FONT_OUTPUT_FILES ${FONT_OUTPUT_FILE})
|
||||
endforeach()
|
||||
add_custom_target(fonts ALL DEPENDS ${FONT_OUTPUT_FILES})
|
||||
file(GLOB BUILDINGS_SRC ${CMAKE_SOURCE_DIR}/assets/blender/buildings/*.blend)
|
||||
set(BUILDING_OUTPUT_FILES)
|
||||
foreach(BUILDING_FILE ${BUILDINGS_SRC})
|
||||
@@ -79,56 +134,78 @@ foreach(BUILDING_FILE ${BUILDINGS_SRC})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(import_buildings ALL DEPENDS ${BUILDING_OUTPUT_FILES})
|
||||
|
||||
add_executable(TerrainTest terrain.cpp ${TERRAIN_SRC})
|
||||
target_link_libraries(TerrainTest OgreBites OgreBullet OgrePaging OgreTerrain lua ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY})
|
||||
target_include_directories(TerrainTest PUBLIC OgreBites OgrePaging OgreTerrain OgreBullet PRIVATE . src/terrain src/lua src/lua/lua-5.4.8/src)
|
||||
|
||||
file(GLOB LUA_SCRIPTS_SRC ${CMAKE_SOURCE_DIR}/lua-scripts/*.lua)
|
||||
set(LUA_SCRIPTS_OUTPUT)
|
||||
foreach(LUA_SCRIPT_FILE ${LUA_SCRIPTS_SRC})
|
||||
get_filename_component(FILE_NAME ${LUA_SCRIPT_FILE} NAME_WE)
|
||||
set(LUA_SCRIPT_OUTPUT_FILE ${CMAKE_BINARY_DIR}/lua-scripts/${FILE_NAME}.lua)
|
||||
add_custom_command(OUTPUT ${LUA_SCRIPT_OUTPUT_FILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LUA_SCRIPT_FILE} ${LUA_SCRIPT_OUTPUT_FILE}
|
||||
DEPENDS ${LUA_SCRIPT_FILE})
|
||||
list(APPEND LUA_SCRIPTS_OUTPUT ${LUA_SCRIPT_OUTPUT_FILE})
|
||||
file(GLOB VEHICLES_SRC ${CMAKE_SOURCE_DIR}/assets/blender/vehicles/*.blend)
|
||||
set(VEHICLE_OUTPUT_FILES)
|
||||
foreach(VEHICLE_FILE ${VEHICLES_SRC})
|
||||
get_filename_component(FILE_NAME ${VEHICLE_FILE} NAME_WE)
|
||||
set(VEHICLE_OUTPUT_FILE ${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.glb)
|
||||
add_custom_command(
|
||||
OUTPUT ${VEHICLE_OUTPUT_FILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/resources/vehicles
|
||||
COMMAND ${BLENDER} ${VEHICLE_FILE}
|
||||
-b -Y -P
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_buildings.py
|
||||
-- ${VEHICLE_OUTPUT_FILE}
|
||||
COMMAND touch ${VEHICLE_OUTPUT_FILE}
|
||||
DEPENDS ${VEHICLE_FILE})
|
||||
list(APPEND VEHICLE_OUTPUT_FILES ${VEHICLE_OUTPUT_FILE})
|
||||
endforeach()
|
||||
add_custom_target(stage_lua_scripts ALL DEPENDS ${LUA_SCRIPTS_OUTPUT})
|
||||
add_custom_target(import_vehicles ALL DEPENDS ${VEHICLE_OUTPUT_FILES})
|
||||
|
||||
set(CHARACTER_SHAPES_SRC edited-normal-male-base.blend edited-shape-test-male.blend)
|
||||
set(CHARACTER_SHAPES_OUTPUT_FILES)
|
||||
foreach(CHARACTER_SHAPE_FILE ${CHARACTER_SHAPES_SRC})
|
||||
get_filename_component(FILE_NAME ${CHARACTER_SHAPE_FILE} NAME_WE)
|
||||
set(CHARACTER_SHAPE_OUTPUT_FILE ${CMAKE_BINARY_DIR}/characters/shapes/male/${FILE_NAME}/${FILE_NAME}.scene)
|
||||
add_custom_command(
|
||||
OUTPUT ${CHARACTER_SHAPE_OUTPUT_FILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/assets/blender
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/characters/shapes/male/${FILE_NAME}
|
||||
COMMAND ${BLENDER} ${CMAKE_SOURCE_DIR}/assets/blender/${CHARACTER_SHAPE_FILE}
|
||||
-b -Y -P
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_characters_ogre.py
|
||||
-- ${CHARACTER_SHAPE_OUTPUT_FILE}
|
||||
COMMAND touch ${CHARACTER_SHAPE_OUTPUT_FILE}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/${CHARACTER_SHAPE_FILE})
|
||||
list(APPEND CHARACTER_SHAPES_OUTPUT_FILES ${CHARACTER_SHAPE_OUTPUT_FILE})
|
||||
endforeach()
|
||||
add_custom_target(import_character_shapes ALL DEPENDS ${CHARACTER_SHAPES_OUTPUT_FILES})
|
||||
|
||||
set(WATER_STUFF)
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/water/sea.glb
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/water
|
||||
COMMAND ${BLENDER} ${CMAKE_SOURCE_DIR}/assets/blender/sea.blend
|
||||
-b -Y -P
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_buildings.py
|
||||
-- ${CMAKE_BINARY_DIR}/water/sea.glb
|
||||
COMMAND touch ${CMAKE_BINARY_DIR}/water/sea.glb
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/sea.blend)
|
||||
list(APPEND WATER_STUFF ${CMAKE_BINARY_DIR}/water/sea.glb)
|
||||
add_custom_target(import_water_stuff ALL DEPENDS ${WATER_STUFF})
|
||||
|
||||
add_executable(TerrainTest terrain.cpp)
|
||||
target_link_libraries(TerrainTest OgreBites OgrePaging OgreTerrain lua
|
||||
-Wl,--as-needed
|
||||
)
|
||||
target_include_directories(TerrainTest PRIVATE . src/terrain src/lua src/lua/lua-5.4.8/src)
|
||||
if(OGRE_STATIC)
|
||||
target_link_libraries(TerrainTest fix::assimp pugixml)
|
||||
target_link_options(TerrainTest PRIVATE -static-libstdc++ -static-libgcc)
|
||||
target_link_libraries(Procedural fix::assimp pugixml)
|
||||
endif()
|
||||
|
||||
add_dependencies(TerrainTest stage_lua_scripts stage_files)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/stories
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lua-scripts/stories ${CMAKE_BINARY_DIR}/stories
|
||||
DEPENDS ${CMAKE_BINARY_DIR}/lua-scripts/stories
|
||||
)
|
||||
add_custom_target(stage_stories ALL DEPENDS stage_lua_scripts ${CMAKE_BINARY_DIR}/stories)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/resources.cfg
|
||||
COMMAND cp ${CMAKE_SOURCE_DIR}/resources.cfg ${CMAKE_BINARY_DIR}/resources.cfg
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/resources/main
|
||||
${CMAKE_BINARY_DIR}/resources/main
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/resources/shaderlib
|
||||
${CMAKE_BINARY_DIR}/resources/shaderlib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/resources/terrain
|
||||
${CMAKE_BINARY_DIR}/resources/terrain
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/characters
|
||||
${CMAKE_BINARY_DIR}/characters
|
||||
# COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/lua-scripts
|
||||
# ${CMAKE_BINARY_DIR}/lua-scripts
|
||||
# COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/skybox
|
||||
# ${CMAKE_BINARY_DIR}/skybox
|
||||
# COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/resources/debug
|
||||
# ${CMAKE_BINARY_DIR}/resources/debug
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/resources.cfg ${CMAKE_BINARY_DIR}/resources.cfg
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/resources.cfg)
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/resources/terrain/world_map.png
|
||||
COMMAND unzip -o ${CMAKE_SOURCE_DIR}/world_map.kra mergedimage.png -d ${CMAKE_BINARY_DIR}/world_map
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_BINARY_DIR}/world_map/mergedimage.png
|
||||
${CMAKE_BINARY_DIR}/resources/terrain/world_map.png
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/world_map
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/world_map.kra)
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/resources/terrain/brushes.png
|
||||
COMMAND unzip -o ${CMAKE_SOURCE_DIR}/brushes.kra mergedimage.png -d ${CMAKE_BINARY_DIR}/brushes
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_BINARY_DIR}/brushes/mergedimage.png
|
||||
${CMAKE_BINARY_DIR}/resources/terrain/brushes.png
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/brushes
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/brushes.kra)
|
||||
|
||||
set(SKYBOX_SRC
|
||||
early_morning_bk.jpg
|
||||
@@ -150,6 +227,8 @@ set(WATER_SRC
|
||||
water.program
|
||||
water.frag
|
||||
water.vert
|
||||
depth.frag
|
||||
depth.vert
|
||||
water.compositor
|
||||
waves2.png
|
||||
)
|
||||
@@ -176,28 +255,93 @@ foreach(MATERIAL_FILE ${MATERIAL_FILES})
|
||||
list(APPEND MATERIALS_OUTPUT ${OUTPUT_FILE})
|
||||
endforeach()
|
||||
|
||||
file(GLOB VRM_FILES RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/assets/vroid/*.vrm)
|
||||
file(GLOB MIXAMO_FILES RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/assets/blender/mixamo/**/*.fbx)
|
||||
set(VRM_SOURCE)
|
||||
foreach(VRM_FILE ${VRM_FILES} ${MIXAMO_FILES})
|
||||
set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/${VRM_FILE}")
|
||||
set(INPUT_FILE "${CMAKE_SOURCE_DIR}/${VRM_FILE}")
|
||||
add_custom_command(OUTPUT "${OUTPUT_FILE}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${INPUT_FILE}" "${OUTPUT_FILE}"
|
||||
DEPENDS "${INPUT_FILE}" VERBATIM)
|
||||
list(APPEND VRM_SOURCE "${OUTPUT_FILE}")
|
||||
endforeach()
|
||||
|
||||
set(VRM_IMPORTED_BLENDS
|
||||
${CMAKE_BINARY_DIR}/assets/blender/vrm-vroid-normal-female.blend
|
||||
${CMAKE_BINARY_DIR}/assets/blender/vrm-vroid-normal-male.blend
|
||||
${CMAKE_BINARY_DIR}/assets/blender/shapes/male/vrm-vroid-normal-male-chibi.blend
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${VRM_IMPORTED_BLENDS}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CREATE_DIRECTORIES}
|
||||
COMMAND ${BLENDER} -b -Y -P ${CMAKE_SOURCE_DIR}/assets/blender/scripts/import_vrm.py
|
||||
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${VRM_IMPORTED_BLENDS}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/scripts/import_vrm.py
|
||||
${VRM_SOURCE}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
set(EDITED_BLENDS_LIST
|
||||
male
|
||||
female
|
||||
)
|
||||
set(EDITED_BLEND_TARGETS)
|
||||
set(CHARACTER_GLBS)
|
||||
foreach(EDITED_BLEND ${EDITED_BLENDS_LIST})
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_SOURCE_DIR}/characters/female/vroid-normal-female.scene
|
||||
${CMAKE_SOURCE_DIR}/characters/male/vroid-normal-male.scene
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/vrm-vroid-normal-female.blend
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/vrm-vroid-normal-male.blend
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/shapes/male/vrm-vroid-normal-male-chibi.blend
|
||||
COMMAND mkdir -p ${CREATE_DIRECTORIES}
|
||||
COMMAND ${BLENDER} -b -Y -P ${CMAKE_SOURCE_DIR}/assets/blender/scripts/import_vrm.py
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend
|
||||
${CMAKE_BINARY_DIR}/assets/blender/vrm-vroid-normal-${EDITED_BLEND}.blend
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-E copy ${CMAKE_SOURCE_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend
|
||||
${CMAKE_BINARY_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend
|
||||
COMMAND ${BLENDER} -b -Y
|
||||
${CMAKE_BINARY_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend
|
||||
-P ${CMAKE_SOURCE_DIR}/assets/blender/scripts/copy_animations.py --
|
||||
${CMAKE_BINARY_DIR}/assets/blender/vrm-vroid-normal-${EDITED_BLEND}.blend ${EDITED_BLEND}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
list(APPEND EDITED_BLEND_TARGETS ${CMAKE_BINARY_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend)
|
||||
list(APPEND CHARACTER_GLBS ${CMAKE_BINARY_DIR}/characters/${EDITED_BLEND}/normal-${EDITED_BLEND}.glb)
|
||||
endforeach()
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/characters/shapes/male/chibi/vroid-normal-male-chibi.glb
|
||||
DEPENDS ${CMAKE_BINARY_DIR}/assets/blender/characters/shapes/male/chibi/vroid-normal-male-chibi.glb
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/assets/blender/characters/shapes/male/chibi/vroid-normal-male-chibi.glb
|
||||
${CMAKE_BINARY_DIR}/characters/shapes/male/chibi/vroid-normal-male-chibi.glb)
|
||||
add_custom_target(morph ALL DEPENDS MorphTargetsResearch ${CMAKE_BINARY_DIR}/characters/shapes/male/chibi/vroid-normal-male-chibi.glb)
|
||||
|
||||
set(COPY_BLENDS edited-shape-test-male.blend edited-normal-male-base.blend)
|
||||
foreach (COPY_BLEND_FILE ${COPY_BLENDS})
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/assets/blender/${COPY_BLEND_FILE}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/${COPY_BLEND_FILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/${COPY_BLEND_FILE}
|
||||
${CMAKE_BINARY_DIR}/assets/blender/${COPY_BLEND_FILE}
|
||||
)
|
||||
list(APPEND EDITED_BLEND_TARGETS ${CMAKE_BINARY_DIR}/assets/blender/${COPY_BLEND_FILE})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(edited-blends ALL DEPENDS ${EDITED_BLEND_TARGETS})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CHARACTER_GLBS}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CREATE_DIRECTORIES}
|
||||
COMMAND ${BLENDER} -b -Y -P ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_models.py
|
||||
# COMMAND ${BLENDER} -b -Y -P ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_ogre_scene.py
|
||||
COMMAND echo rm -Rf ${CMAKE_SOURCE_DIR}/characters/male/*.material ${CMAKE_SOURCE_DIR}/characters/female/*.material
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_models.py ${CMAKE_SOURCE_DIR}/assets/blender/scripts/import_vrm.py
|
||||
${CMAKE_SOURCE_DIR}/assets/vroid/buch1.vrm
|
||||
${CMAKE_SOURCE_DIR}/assets/vroid/buch1-chibi.vrm
|
||||
${CMAKE_SOURCE_DIR}/assets/vroid/jane2-dress.vrm
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${CHARACTER_GLBS}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_models.py ${VRM_IMPORTED_BLENDS} ${EDITED_BLEND_TARGETS}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_custom_target(stage_files ALL DEPENDS ${CMAKE_BINARY_DIR}/resources.cfg ${MATERIALS_OUTPUT}
|
||||
${CMAKE_BINARY_DIR}/resources/terrain/world_map.png
|
||||
${CMAKE_BINARY_DIR}/resources/terrain/brushes.png)
|
||||
${CMAKE_BINARY_DIR}/resources/terrain/brushes.png
|
||||
edited-blends stage_resources)
|
||||
|
||||
add_custom_target(remove_scenes COMMAND rm -f ${CREATE_SCENES})
|
||||
add_custom_target(remove_scenes COMMAND rm -f ${VRM_SOURCE} ${VRM_IMPORTED_BLENDS} ${CHARACTER_GLBS})
|
||||
|
||||
add_custom_target(import_vrm DEPENDS ${CREATE_SCENES})
|
||||
add_custom_target(import_vrm DEPENDS ${CHARACTER_GLBS})
|
||||
target_compile_definitions(Game PRIVATE FLECS_CPP_NO_AUTO_REGISTRATION)
|
||||
|
||||
install(TARGETS Game DESTINATION bin)
|
||||
install(TARGETS Editor DESTINATION bin)
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <OgreTrays.h>
|
||||
#include <OgreTimer.h>
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
#include <OgreTerrain.h>
|
||||
|
||||
#include "src/terrain/terrain.h"
|
||||
#include "water/water.h"
|
||||
class App;
|
||||
class SkyRenderer : public Ogre::SceneManager::Listener {
|
||||
@@ -244,16 +244,12 @@ public:
|
||||
void initGui();
|
||||
};
|
||||
class App : public OgreBites::ApplicationContext {
|
||||
std::unique_ptr<Ogre::Bullet::DynamicsWorld> mDynWorld;
|
||||
std::unique_ptr<Ogre::Bullet::DebugDrawer> mDbgDraw;
|
||||
Ogre::SceneNode *mCameraNode, *mCameraPivot, *mCameraGoal;
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::Real mPivotPitch;
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
OgreBites::InputListenerChain mInput;
|
||||
Ogre::Viewport *mViewport;
|
||||
EditUI m_edit_ui;
|
||||
TerrainSetup m_terrain;
|
||||
Ogre::Light *mSun;
|
||||
SkyBoxRenderer *sky;
|
||||
Water m_water;
|
||||
@@ -285,6 +281,8 @@ class App : public OgreBites::ApplicationContext {
|
||||
// Ogre::Root::getSingleton().queueEndRendering();
|
||||
mApp->setWindowGrab(false);
|
||||
}
|
||||
if (evt.keysym.sym == OgreBites::SDLK_SPACE)
|
||||
mApp->dump_water();
|
||||
if (evt.keysym.sym == 'w')
|
||||
motion.z = -1.0f;
|
||||
if (evt.keysym.sym == 's')
|
||||
@@ -364,6 +362,7 @@ class App : public OgreBites::ApplicationContext {
|
||||
mApp->updateCamera(evt.timeSinceLastFrame);
|
||||
mApp->updateSun(evt.timeSinceLastFrame);
|
||||
mApp->updateTerrain(evt.timeSinceLastFrame);
|
||||
mApp->updateWater(evt.timeSinceLastFrame);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -371,12 +370,9 @@ class App : public OgreBites::ApplicationContext {
|
||||
|
||||
public:
|
||||
App()
|
||||
: OgreBites::ApplicationContext("GuiTest")
|
||||
: OgreBites::ApplicationContext("ChoroEditor")
|
||||
, mKbd(this)
|
||||
, m_edit_ui(this)
|
||||
, mDynWorld(new Ogre::Bullet::DynamicsWorld(
|
||||
Ogre::Vector3(0, -9.8, 0)))
|
||||
, m_terrain(mDynWorld->getBtWorld())
|
||||
{
|
||||
}
|
||||
virtual ~App()
|
||||
@@ -392,13 +388,18 @@ public:
|
||||
mScnMgr->addRenderQueueListener(pOverlaySystem);
|
||||
// mTrayMgr = new OgreBites::TrayManager("AppTrays",
|
||||
// getRenderWindow());
|
||||
mDbgDraw.reset(new Ogre::Bullet::DebugDrawer(
|
||||
mScnMgr->getRootSceneNode(), mDynWorld->getBtWorld()));
|
||||
}
|
||||
void locateResources()
|
||||
void locateResources() override
|
||||
{
|
||||
OgreBites::ApplicationContext::locateResources();
|
||||
}
|
||||
void loadResources() override
|
||||
{
|
||||
}
|
||||
void dump_water()
|
||||
{
|
||||
m_water.dump_textures();
|
||||
}
|
||||
|
||||
void initCamera()
|
||||
{
|
||||
@@ -429,8 +430,40 @@ public:
|
||||
// our model is quite small, so reduce the clipping planes
|
||||
mCamera->setNearClipDistance(0.1f);
|
||||
mCamera->setFarClipDistance(800);
|
||||
|
||||
mPivotPitch = 0;
|
||||
}
|
||||
void configure()
|
||||
{
|
||||
std::cout << "Startup" << "\n";
|
||||
initApp();
|
||||
std::cout << "Set up RTSS" << "\n";
|
||||
Ogre::Root *root = getRoot();
|
||||
Ogre::SceneManager *scnMgr = getSceneManager();
|
||||
|
||||
// register our scene with the RTSS
|
||||
Ogre::RTShader::ShaderGenerator *shadergen =
|
||||
Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
||||
shadergen->addSceneManager(scnMgr);
|
||||
setWindowGrab(true);
|
||||
std::cout << "Init camera" << "\n";
|
||||
initCamera();
|
||||
std::cout << "Set up water" << "\n";
|
||||
#if 0
|
||||
m_water.createWater(getRenderWindow(), mCamera,
|
||||
mDynWorld.get());
|
||||
#endif
|
||||
std::cout << "Set up cursor" << "\n";
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.initialiseAllResourceGroups();
|
||||
// OgreBites::ApplicationContext::loadResources();
|
||||
setupCursor();
|
||||
std::cout << "Create content" << "\n";
|
||||
createContent();
|
||||
std::cout << "Setup terrain" << "\n";
|
||||
m_water.init();
|
||||
}
|
||||
void setupCursor()
|
||||
{
|
||||
// mKeyDirection = Ogre::Vector3::ZERO;
|
||||
// mVerticalVelocity = 0;
|
||||
Ogre::ManualObject *mobj =
|
||||
@@ -473,6 +506,7 @@ public:
|
||||
}
|
||||
void updateMotion(float delta)
|
||||
{
|
||||
#if 0
|
||||
if (delta == 0.0f)
|
||||
return;
|
||||
Ogre::Vector3 move(mCameraNode->getOrientation().zAxis() *
|
||||
@@ -495,6 +529,7 @@ public:
|
||||
// mKbd.motion = Ogre::Vector3(0, 0, 0);
|
||||
// if (move.squaredLength() > 0)
|
||||
// std::cout << move << "\n";
|
||||
#endif
|
||||
}
|
||||
void updateCamera(Ogre::Real delta)
|
||||
{
|
||||
@@ -541,10 +576,12 @@ public:
|
||||
mCameraGoal->translate(0, 0, distChange,
|
||||
Ogre::Node::TS_LOCAL);
|
||||
Ogre::Vector3 mh = mCameraGoal->_getDerivedPosition();
|
||||
#if 0
|
||||
float h = m_terrain.get_height(mh);
|
||||
if (h + 10 > mh.y)
|
||||
mCameraGoal->translate(0, 10.0f * deltaZoom, distChange,
|
||||
Ogre::Node::TS_LOCAL);
|
||||
#endif
|
||||
}
|
||||
Ogre::SceneNode *mSunGoal;
|
||||
Ogre::SceneNode *mSunNode;
|
||||
@@ -600,7 +637,7 @@ public:
|
||||
Ogre::Timer mTerrainUpd;
|
||||
void updateTerrain(float delta)
|
||||
{
|
||||
mDbgDraw->update();
|
||||
// mDbgDraw->update();
|
||||
#if 0
|
||||
if (mTerrainUpd.getMilliseconds() > 1000) {
|
||||
m_terrain.create_colliders();
|
||||
@@ -608,15 +645,16 @@ public:
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void updateWater(float delta)
|
||||
{
|
||||
m_water.updateWater(delta);
|
||||
}
|
||||
void createContent()
|
||||
{
|
||||
int i;
|
||||
m_edit_ui.init_glb_list();
|
||||
m_edit_ui.initGui();
|
||||
createSun();
|
||||
mInput = OgreBites::InputListenerChain(
|
||||
{ getImGuiInputListener(), &mKbd });
|
||||
addInputListener(&mInput);
|
||||
getRoot()->addFrameListener(&mKbd);
|
||||
// mTrayMgr->showCursor();
|
||||
|
||||
@@ -641,8 +679,6 @@ public:
|
||||
"Skybox/Dynamic", "General");
|
||||
OgreAssert(m, "Sky box material not found.");
|
||||
m->load();
|
||||
m_water.createWater(mCamera);
|
||||
getRoot()->addFrameListener(&m_water);
|
||||
#endif
|
||||
}
|
||||
void create_entity_node(const Ogre::String &name, int key)
|
||||
@@ -674,11 +710,6 @@ public:
|
||||
{
|
||||
return mCamera;
|
||||
}
|
||||
void setupTerrain()
|
||||
{
|
||||
m_terrain.setupTerrain(mCamera, mSun, mDynWorld.get(),
|
||||
mDbgDraw.get());
|
||||
}
|
||||
};
|
||||
|
||||
void EditUI::buildings_editor()
|
||||
@@ -845,20 +876,9 @@ void EditUI::initGui()
|
||||
int main()
|
||||
{
|
||||
App ctx;
|
||||
ctx.initApp();
|
||||
ctx.configure();
|
||||
// ctx.runRenderingSettingsDialog();
|
||||
// get a pointer to the already created root
|
||||
Ogre::Root *root = ctx.getRoot();
|
||||
Ogre::SceneManager *scnMgr = ctx.getSceneManager();
|
||||
|
||||
// register our scene with the RTSS
|
||||
Ogre::RTShader::ShaderGenerator *shadergen =
|
||||
Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
||||
shadergen->addSceneManager(scnMgr);
|
||||
ctx.setWindowGrab(true);
|
||||
ctx.initCamera();
|
||||
ctx.createContent();
|
||||
ctx.setupTerrain();
|
||||
// register for input events
|
||||
// KeyHandler keyHandler;
|
||||
// ctx.addInputListener(&keyHandler);
|
||||
855
Game.cpp
Normal file
@@ -0,0 +1,855 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <Ogre.h>
|
||||
#include <OgreApplicationContext.h>
|
||||
#include <OgreOverlaySystem.h>
|
||||
#include <OgreOverlayManager.h>
|
||||
#include <OgreImGuiOverlay.h>
|
||||
#include <OgreImGuiInputListener.h>
|
||||
#include <OgreTrays.h>
|
||||
#include <OgreTimer.h>
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
|
||||
// #include "water/water.h"
|
||||
#include "GameData.h"
|
||||
#include "Components.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "GUIModuleCommon.h"
|
||||
#include "AppModule.h"
|
||||
#include "sound.h"
|
||||
class App;
|
||||
class SkyRenderer : public Ogre::SceneManager::Listener {
|
||||
protected:
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
virtual void _updateRenderQueue(Ogre::RenderQueue *queue) = 0;
|
||||
|
||||
public:
|
||||
enum BoxPlane {
|
||||
BP_FRONT = 0,
|
||||
BP_BACK = 1,
|
||||
BP_LEFT = 2,
|
||||
BP_RIGHT = 3,
|
||||
BP_UP = 4,
|
||||
BP_DOWN = 5
|
||||
};
|
||||
|
||||
SkyRenderer(Ogre::SceneManager *owner)
|
||||
: mSceneManager(owner)
|
||||
, mSceneNode(0)
|
||||
, mEnabled(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SkyRenderer()
|
||||
{
|
||||
setEnabled(false);
|
||||
if (mSceneNode)
|
||||
mSceneManager->destroySceneNode(mSceneNode);
|
||||
}
|
||||
|
||||
Ogre::SceneNode *mSceneNode;
|
||||
bool mEnabled;
|
||||
|
||||
void setEnabled(bool enable)
|
||||
{
|
||||
if (enable == mEnabled)
|
||||
return;
|
||||
mEnabled = enable;
|
||||
enable ? mSceneManager->addListener(this) :
|
||||
mSceneManager->removeListener(this);
|
||||
}
|
||||
void
|
||||
postFindVisibleObjects(Ogre::SceneManager *source,
|
||||
Ogre::SceneManager::IlluminationRenderStage irs,
|
||||
Ogre::Viewport *vp) override
|
||||
{
|
||||
// Queue skies, if viewport seems it
|
||||
if (!vp->getSkiesEnabled() ||
|
||||
irs == Ogre::SceneManager::IRS_RENDER_TO_TEXTURE)
|
||||
return;
|
||||
|
||||
if (!mEnabled || !mSceneNode)
|
||||
return;
|
||||
|
||||
// Update nodes
|
||||
// Translate the box by the camera position (constant distance)
|
||||
mSceneNode->setPosition(vp->getCamera()->getDerivedPosition());
|
||||
_updateRenderQueue(source->getRenderQueue());
|
||||
}
|
||||
};
|
||||
class SkyBoxRenderer : public SkyRenderer {
|
||||
std::unique_ptr<Ogre::ManualObject> mSkyBoxObj;
|
||||
|
||||
Ogre::Quaternion mSkyBoxOrientation;
|
||||
void _updateRenderQueue(Ogre::RenderQueue *queue) override
|
||||
{
|
||||
if (mSkyBoxObj->isVisible()) {
|
||||
mSkyBoxObj->_updateRenderQueue(queue);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
SkyBoxRenderer(Ogre::SceneManager *owner)
|
||||
: SkyRenderer(owner)
|
||||
{
|
||||
}
|
||||
Ogre::SceneManager::SkyBoxGenParameters mSkyBoxGenParameters;
|
||||
void create(const Ogre::String &materialName, Ogre::Real distance,
|
||||
uint8_t renderQueue, const Ogre::Quaternion &orientation,
|
||||
const Ogre::String &groupName)
|
||||
{
|
||||
Ogre::MaterialPtr m =
|
||||
Ogre::MaterialManager::getSingleton().getByName(
|
||||
materialName, groupName);
|
||||
OgreAssert(m, "Sky box material '" + materialName +
|
||||
"' not found.");
|
||||
// Ensure loaded
|
||||
m->load();
|
||||
|
||||
bool valid = m->getBestTechnique() &&
|
||||
m->getBestTechnique()->getNumPasses();
|
||||
#if 0
|
||||
if (valid) {
|
||||
Pass *pass = m->getBestTechnique()->getPass(0);
|
||||
valid = valid && pass->getNumTextureUnitStates() &&
|
||||
pass->getTextureUnitState(0)->getTextureType() ==
|
||||
TEX_TYPE_CUBE_MAP;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
LogManager::getSingleton().logWarning(
|
||||
"skybox material " + materialName +
|
||||
" is not supported, defaulting");
|
||||
m = MaterialManager::getSingleton().getDefaultSettings();
|
||||
}
|
||||
#endif
|
||||
OgreAssert(valid, "Bad material" + materialName);
|
||||
|
||||
// Create node
|
||||
mSceneNode = mSceneManager->createSceneNode();
|
||||
|
||||
// Create object
|
||||
mSkyBoxObj = std::make_unique<Ogre::ManualObject>("SkyBox");
|
||||
mSkyBoxObj->setCastShadows(false);
|
||||
mSceneNode->attachObject(mSkyBoxObj.get());
|
||||
|
||||
mSkyBoxObj->setRenderQueueGroup(renderQueue);
|
||||
mSkyBoxObj->begin(materialName,
|
||||
Ogre::RenderOperation::OT_TRIANGLE_STRIP,
|
||||
groupName);
|
||||
|
||||
// rendering cube, only using 14 vertices
|
||||
const Ogre::Vector3 cube_strip[14] = {
|
||||
{ -1.f, 1.f, 1.f }, // Front-top-left
|
||||
{ 1.f, 1.f, 1.f }, // Front-top-right
|
||||
{ -1.f, -1.f, 1.f }, // Front-bottom-left
|
||||
{ 1.f, -1.f, 1.f }, // Front-bottom-right
|
||||
{ 1.f, -1.f, -1.f }, // Back-bottom-right
|
||||
{ 1.f, 1.f, 1.f }, // Front-top-right
|
||||
{ 1.f, 1.f, -1.f }, // Back-top-right
|
||||
{ -1.f, 1.f, 1.f }, // Front-top-left
|
||||
{ -1.f, 1.f, -1.f }, // Back-top-left
|
||||
{ -1.f, -1.f, 1.f }, // Front-bottom-left
|
||||
{ -1.f, -1.f, -1.f }, // Back-bottom-left
|
||||
{ 1.f, -1.f, -1.f }, // Back-bottom-right
|
||||
{ -1.f, 1.f, -1.f }, // Back-top-left
|
||||
{ 1.f, 1.f, -1.f } // Back-top-right
|
||||
};
|
||||
|
||||
for (const auto &vtx : cube_strip) {
|
||||
mSkyBoxObj->position(orientation * (vtx * distance));
|
||||
// Note UVs mirrored front/back
|
||||
mSkyBoxObj->textureCoord(vtx.normalisedCopy() *
|
||||
Ogre::Vector3(1, 1, -1));
|
||||
}
|
||||
|
||||
mSkyBoxObj->end();
|
||||
mSkyBoxGenParameters.skyBoxDistance = distance;
|
||||
}
|
||||
};
|
||||
class App;
|
||||
class KeyboardListener : public OgreBites::InputListener {
|
||||
App *mApp;
|
||||
|
||||
uint32_t control;
|
||||
ECS::Vector2 mouse;
|
||||
ECS::Vector2 mouse_abs;
|
||||
float wheel_y;
|
||||
bool mouse_moved, wheel_moved;
|
||||
float mInitDelay;
|
||||
|
||||
public:
|
||||
Ogre::Timer fps_timer;
|
||||
bool fast;
|
||||
KeyboardListener(App *app)
|
||||
: OgreBites::InputListener()
|
||||
, mApp(app)
|
||||
, fast(false)
|
||||
, control(0)
|
||||
, mouse({ 0, 0 })
|
||||
, mouse_abs({ 0, 0 })
|
||||
, wheel_y(0.0f)
|
||||
, mouse_moved(false)
|
||||
, wheel_moved(false)
|
||||
, mInitDelay(1.0)
|
||||
{
|
||||
}
|
||||
bool isGuiEnabled()
|
||||
{
|
||||
if (!ECS::get().has<ECS::GUI>())
|
||||
return false;
|
||||
return (ECS::get().get<ECS::GUI>().enabled);
|
||||
}
|
||||
void setGuiEnabled(bool value)
|
||||
{
|
||||
if (!ECS::get().has<ECS::GUI>())
|
||||
return;
|
||||
ECS::get().get_mut<ECS::GUI>().enabled = value;
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
}
|
||||
bool keyPressed(const OgreBites::KeyboardEvent &evt) override
|
||||
{
|
||||
bool updated = false;
|
||||
if (isGuiEnabled())
|
||||
return false;
|
||||
if (evt.keysym.sym == OgreBites::SDLK_ESCAPE) {
|
||||
OgreAssert(ECS::get().has<ECS::GUI>(), "");
|
||||
setGuiEnabled(true);
|
||||
if (ECS::get().has<ECS::GUI>())
|
||||
ECS::get<ECS::GUI>().setWindowGrab(false);
|
||||
return true;
|
||||
}
|
||||
OgreBites::Keycode key = evt.keysym.sym;
|
||||
if (key == 'w')
|
||||
control |= 1;
|
||||
else if (key == 'a')
|
||||
control |= 2;
|
||||
else if (key == 's')
|
||||
control |= 4;
|
||||
else if (key == 'd')
|
||||
control |= 8;
|
||||
else if (key == OgreBites::SDLK_LSHIFT)
|
||||
control |= 16;
|
||||
else if (key == 'e')
|
||||
control |= 32;
|
||||
else if (key == 'f')
|
||||
control |= 64;
|
||||
if (key == 'w' || key == 'a' || key == 's' || key == 'd' ||
|
||||
key == 'e' || key == OgreBites::SDLK_LSHIFT || key == 'e' ||
|
||||
key == 'f')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool keyReleased(const OgreBites::KeyboardEvent &evt) override
|
||||
{
|
||||
OgreBites::Keycode key = evt.keysym.sym;
|
||||
if (key == 'w')
|
||||
control &= ~1;
|
||||
else if (key == 'a')
|
||||
control &= ~2;
|
||||
else if (key == 's')
|
||||
control &= ~4;
|
||||
else if (key == 'd')
|
||||
control &= ~8;
|
||||
else if (key == OgreBites::SDLK_LSHIFT)
|
||||
control &= ~16;
|
||||
else if (key == 'e')
|
||||
control &= ~32;
|
||||
else if (key == 'f')
|
||||
control &= ~64;
|
||||
if (isGuiEnabled())
|
||||
return false;
|
||||
if (key == 'w' || key == 'a' || key == 's' || key == 'd' ||
|
||||
key == OgreBites::SDLK_LSHIFT || key == 'e' || key == 'f')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool mouseMoved(const OgreBites::MouseMotionEvent &evt) override
|
||||
{
|
||||
if (isGuiEnabled())
|
||||
return false;
|
||||
mouse.x = evt.xrel;
|
||||
mouse.y = evt.yrel;
|
||||
mouse_abs.x = evt.x;
|
||||
mouse_abs.y = evt.y;
|
||||
mouse_moved = true;
|
||||
/* no special mouse handling */
|
||||
return true;
|
||||
}
|
||||
bool mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) override
|
||||
{
|
||||
if (isGuiEnabled())
|
||||
return false;
|
||||
/* no special mouse wheel handling */
|
||||
wheel_y = evt.y;
|
||||
wheel_moved = true;
|
||||
return true;
|
||||
}
|
||||
bool mousePressed(const OgreBites::MouseButtonEvent &evt) override
|
||||
{
|
||||
std::cout << "Mouse press " << (int)evt.button << " "
|
||||
<< (int)evt.clicks << "\n";
|
||||
if ((int)evt.button == 1)
|
||||
control |= 256;
|
||||
else
|
||||
control &= ~256;
|
||||
return false;
|
||||
}
|
||||
void frameRendered(const Ogre::FrameEvent &evt) override;
|
||||
};
|
||||
class App : public OgreBites::ApplicationContext {
|
||||
Ogre::SceneNode *mCameraNode, *mCameraPivot, *mCameraGoal;
|
||||
Ogre::Camera *mCamera, *mCameraInterior, *mCameraInventory;
|
||||
Ogre::Real mPivotPitch;
|
||||
Ogre::SceneManager *mScnMgr, *mScnMgrInterior, *mScnMgrInventory;
|
||||
Ogre::Viewport *mViewport;
|
||||
SkyBoxRenderer *sky;
|
||||
bool mGrab;
|
||||
KeyboardListener mKbd;
|
||||
|
||||
public:
|
||||
App()
|
||||
: OgreBites::ApplicationContext("ChoroGame")
|
||||
, mKbd(this)
|
||||
, mGrab(false)
|
||||
{
|
||||
}
|
||||
virtual ~App()
|
||||
{
|
||||
}
|
||||
void setup() override
|
||||
{
|
||||
OgreBites::ApplicationContext::setup();
|
||||
Ogre::Root *root = getRoot();
|
||||
Ogre::SceneManager *scnMgr = root->createSceneManager();
|
||||
mScnMgr = scnMgr;
|
||||
mScnMgrInterior = root->createSceneManager();
|
||||
mScnMgrInventory = root->createSceneManager();
|
||||
Ogre::OverlaySystem *pOverlaySystem = getOverlaySystem();
|
||||
mScnMgr->addRenderQueueListener(pOverlaySystem);
|
||||
mScnMgrInterior->addRenderQueueListener(pOverlaySystem);
|
||||
mScnMgrInventory->addRenderQueueListener(pOverlaySystem);
|
||||
// mTrayMgr = new OgreBites::TrayManager("AppTrays",
|
||||
// getRenderWindow());
|
||||
}
|
||||
bool isWindowGrab()
|
||||
{
|
||||
return mGrab;
|
||||
}
|
||||
void locateResources() override
|
||||
{
|
||||
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(
|
||||
"Water", true);
|
||||
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(
|
||||
"LuaScripts", false);
|
||||
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
|
||||
"./lua-scripts", "FileSystem", "LuaScripts", true,
|
||||
true);
|
||||
OgreBites::ApplicationContext::locateResources();
|
||||
}
|
||||
void loadResources() override
|
||||
{
|
||||
}
|
||||
void setWindowGrab(bool grab = true)
|
||||
{
|
||||
mGrab = grab;
|
||||
ApplicationContextBase::setWindowGrab(grab);
|
||||
}
|
||||
void initInteriorCamera()
|
||||
{
|
||||
Ogre::SceneNode *cameraNode =
|
||||
mScnMgrInterior->getRootSceneNode()
|
||||
->createChildSceneNode("InteriorCameraNode");
|
||||
cameraNode->setPosition(0, 2, 3);
|
||||
cameraNode->lookAt(Ogre::Vector3(0, 1, -1),
|
||||
Ogre::Node::TS_PARENT);
|
||||
mCameraInterior = mScnMgr->createCamera("interior_camera");
|
||||
mCameraInterior->setNearClipDistance(0.05f);
|
||||
mCameraInterior->setAutoAspectRatio(true);
|
||||
cameraNode->attachObject(mCameraInterior);
|
||||
}
|
||||
void initInventoryCamera()
|
||||
{
|
||||
Ogre::SceneNode *cameraNode =
|
||||
mScnMgrInventory->getRootSceneNode()
|
||||
->createChildSceneNode("InteriorCameraNode");
|
||||
cameraNode->setPosition(0, 2, 3);
|
||||
cameraNode->lookAt(Ogre::Vector3(0, 1, -1),
|
||||
Ogre::Node::TS_PARENT);
|
||||
mCameraInventory = mScnMgr->createCamera("inventory_camera");
|
||||
mCameraInventory->setNearClipDistance(0.05f);
|
||||
mCameraInventory->setAutoAspectRatio(true);
|
||||
cameraNode->attachObject(mCameraInventory);
|
||||
}
|
||||
void initCamera()
|
||||
{
|
||||
mCameraNode = mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"CameraNode");
|
||||
mCameraNode->setPosition(0, 2, 3);
|
||||
mCameraNode->lookAt(Ogre::Vector3(0, 1, -1),
|
||||
Ogre::Node::TS_PARENT);
|
||||
|
||||
// create the camera
|
||||
mCamera = mScnMgr->createCamera("fps_camera");
|
||||
mCamera->setNearClipDistance(0.05f);
|
||||
mCamera->setAutoAspectRatio(true);
|
||||
mCameraNode->attachObject(mCamera);
|
||||
|
||||
// and tell it to render into the main window
|
||||
mViewport = getRenderWindow()->addViewport(mCamera);
|
||||
mCameraPivot =
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"FPSCameraPivot");
|
||||
mCameraGoal = mCameraPivot->createChildSceneNode(
|
||||
"FPSCameraGoal", Ogre::Vector3(0, 2, 3));
|
||||
mCameraNode->setPosition(mCameraPivot->getPosition() +
|
||||
mCameraGoal->getPosition());
|
||||
mCameraPivot->setFixedYawAxis(true);
|
||||
mCameraGoal->setFixedYawAxis(true);
|
||||
mCameraNode->setFixedYawAxis(true);
|
||||
// our model is quite small, so reduce the clipping planes
|
||||
mCamera->setNearClipDistance(0.1f);
|
||||
mCamera->setFarClipDistance(800);
|
||||
mPivotPitch = 0;
|
||||
initInteriorCamera();
|
||||
initInventoryCamera();
|
||||
}
|
||||
void configure()
|
||||
{
|
||||
std::cout << "Startup"
|
||||
<< "\n";
|
||||
initApp();
|
||||
std::cout << "Set up RTSS"
|
||||
<< "\n";
|
||||
Ogre::Root *root = getRoot();
|
||||
Ogre::SceneManager *scnMgr = getSceneManager();
|
||||
|
||||
// register our scene with the RTSS
|
||||
Ogre::RTShader::ShaderGenerator *shadergen =
|
||||
Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
||||
shadergen->addSceneManager(scnMgr);
|
||||
setWindowGrab(true);
|
||||
std::cout << "Init camera"
|
||||
<< "\n";
|
||||
initCamera();
|
||||
std::cout << "Set up water"
|
||||
<< "\n";
|
||||
std::cout << "Set up cursor"
|
||||
<< "\n";
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.initialiseAllResourceGroups();
|
||||
// OgreBites::ApplicationContext::loadResources();
|
||||
// setupCursor();
|
||||
std::cout << "Setup input"
|
||||
<< "\n";
|
||||
setupInput();
|
||||
std::cout << "Create content"
|
||||
<< "\n";
|
||||
createContent();
|
||||
std::cout << "Setup done"
|
||||
<< "\n";
|
||||
#if 0
|
||||
mDbgDraw->setDebugMode(mDbgDraw->getDebugMode() |
|
||||
btIDebugDraw::DBG_DrawContactPoints);
|
||||
#endif
|
||||
Ogre::LogManager::getSingleton().setMinLogLevel(
|
||||
Ogre::LML_CRITICAL);
|
||||
}
|
||||
Ogre::SceneManager *getSceneManager()
|
||||
{
|
||||
return mScnMgr;
|
||||
}
|
||||
Ogre::Timer mTerrainUpd;
|
||||
bool isTerrainReady()
|
||||
{
|
||||
if (ECS::get().has<ECS::Terrain>())
|
||||
return ECS::get().get<ECS::Terrain>().mTerrainReady;
|
||||
return false;
|
||||
}
|
||||
// TODO: implement rough water level calculation
|
||||
float getWaterLevel(const Ogre::Vector3 &position)
|
||||
{
|
||||
Ogre::Vector3::UNIT_Y;
|
||||
float etime =
|
||||
Ogre::ControllerManager::getSingleton().getElapsedTime();
|
||||
return 0.0f;
|
||||
}
|
||||
void updateWorld(float delta)
|
||||
{
|
||||
#if 0
|
||||
mDynWorld->getBtWorld()->stepSimulation(delta, 3);
|
||||
#endif
|
||||
if (!ECS::get().has<ECS::GUI>())
|
||||
goto end;
|
||||
{
|
||||
/* Update window grab */
|
||||
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
|
||||
if (gui.grabChanged) {
|
||||
setWindowGrab(gui.grab);
|
||||
gui.grabChanged = false;
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
std::cout << "updateWorld " << gui.grabChanged
|
||||
<< " " << gui.grab << std::endl;
|
||||
}
|
||||
}
|
||||
end:
|
||||
ECS::update(delta);
|
||||
|
||||
#if 0
|
||||
if (ECS::get<ECS::EngineData>().enableDbgDraw)
|
||||
mDbgDraw->update();
|
||||
#endif
|
||||
}
|
||||
class InputListenerChainFlexible : public OgreBites::InputListener {
|
||||
protected:
|
||||
std::vector<OgreBites::InputListener *> mListenerChain;
|
||||
|
||||
public:
|
||||
InputListenerChainFlexible()
|
||||
{
|
||||
}
|
||||
InputListenerChainFlexible(std::vector<InputListener *> chain)
|
||||
: mListenerChain(chain)
|
||||
{
|
||||
}
|
||||
|
||||
void add(OgreBites::InputListener *listener)
|
||||
{
|
||||
mListenerChain.push_back(listener);
|
||||
}
|
||||
void erase(OgreBites::InputListener *listener)
|
||||
{
|
||||
mListenerChain.erase(std::find(mListenerChain.begin(),
|
||||
mListenerChain.end(),
|
||||
listener));
|
||||
}
|
||||
bool empty() const
|
||||
{
|
||||
return mListenerChain.empty();
|
||||
}
|
||||
|
||||
InputListenerChainFlexible &
|
||||
operator=(const InputListenerChainFlexible &o)
|
||||
{
|
||||
mListenerChain = o.mListenerChain;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void frameRendered(const Ogre::FrameEvent &evt) override
|
||||
{
|
||||
for (auto listener : mListenerChain)
|
||||
listener->frameRendered(evt);
|
||||
}
|
||||
|
||||
bool keyPressed(const OgreBites::KeyboardEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->keyPressed(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool keyReleased(const OgreBites::KeyboardEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->keyReleased(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool touchMoved(const OgreBites::TouchFingerEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->touchMoved(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
touchPressed(const OgreBites::TouchFingerEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->touchPressed(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
touchReleased(const OgreBites::TouchFingerEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->touchReleased(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool mouseMoved(const OgreBites::MouseMotionEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->mouseMoved(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->mouseWheelRolled(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
mousePressed(const OgreBites::MouseButtonEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->mousePressed(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
mouseReleased(const OgreBites::MouseButtonEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->mouseReleased(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool textInput(const OgreBites::TextInputEvent &evt) override
|
||||
{
|
||||
for (auto listner : mListenerChain) {
|
||||
if (listner->textInput(evt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
flecs::entity input_update;
|
||||
flecs::entity find_wait_gui;
|
||||
void setupInput()
|
||||
{
|
||||
}
|
||||
void createContent()
|
||||
{
|
||||
int i;
|
||||
sky = new SkyBoxRenderer(getSceneManager());
|
||||
bool drawFirst = true;
|
||||
uint8_t renderQueue = drawFirst ?
|
||||
Ogre::RENDER_QUEUE_SKIES_EARLY :
|
||||
Ogre::RENDER_QUEUE_SKIES_LATE;
|
||||
sky->create("Skybox/Dynamic", 450, renderQueue,
|
||||
Ogre::Quaternion::IDENTITY,
|
||||
Ogre::ResourceGroupManager::
|
||||
AUTODETECT_RESOURCE_GROUP_NAME);
|
||||
sky->setEnabled(true);
|
||||
|
||||
Ogre::MaterialPtr m =
|
||||
Ogre::MaterialManager::getSingleton().getByName(
|
||||
"Skybox/Dynamic", "General");
|
||||
OgreAssert(m, "Sky box material not found.");
|
||||
m->load();
|
||||
ECS::setupExteriorScene(mScnMgr,
|
||||
/*mDynWorld.get(), */ mCameraNode,
|
||||
mCamera, getRenderWindow());
|
||||
ECS::get().set<ECS::RenderWindow>(
|
||||
{ getRenderWindow(), getDisplayDPI() });
|
||||
ECS::get()
|
||||
.observer<ECS::GUI>("UpdateGrab")
|
||||
.event(flecs::OnSet)
|
||||
.each([this](ECS::GUI &gui) {
|
||||
if (gui.grabChanged)
|
||||
setWindowGrab(gui.grab);
|
||||
std::cout << "grab: " << gui.grab << "\n";
|
||||
std::cout << "GUI enabled: " << gui.enabled
|
||||
<< "\n";
|
||||
});
|
||||
ECS::get()
|
||||
.observer<ECS::App>("UpdateInputListener")
|
||||
.event(flecs::OnSet)
|
||||
.each([this](ECS::App &app) {
|
||||
if (app.mInput)
|
||||
removeInputListener(app.mInput);
|
||||
delete app.mInput;
|
||||
app.mInput =
|
||||
OGRE_NEW OgreBites::InputListenerChain(
|
||||
app.listeners);
|
||||
addInputListener(app.mInput);
|
||||
});
|
||||
#if 0
|
||||
ECS::get()
|
||||
.observer<ECS::GUI, ECS::App>("SetInputListener2")
|
||||
.event(flecs::OnSet)
|
||||
.each([this](ECS::GUI &gui, ECS::App &app) {
|
||||
if (gui.mGuiInpitListener &&
|
||||
app.listeners.size() == 1) {
|
||||
app.listeners.clear();
|
||||
app.listeners.push_back(
|
||||
gui.mGuiInpitListener);
|
||||
app.listeners.push_back(&mKbd);
|
||||
ECS::modified<ECS::App>();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
input_update =
|
||||
ECS::get()
|
||||
.system<ECS::GUI, ECS::App>("SetInputListener")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([this](ECS::GUI &gui, ECS::App &app) {
|
||||
if (app.listeners.size() < 2 &&
|
||||
gui.mGuiInpitListener) {
|
||||
OgreBites::InputListener *guiListener =
|
||||
gui.mGuiInpitListener;
|
||||
if (guiListener) {
|
||||
app.listeners.clear();
|
||||
app.listeners.push_back(
|
||||
guiListener);
|
||||
app.listeners.push_back(
|
||||
&mKbd);
|
||||
std::cout
|
||||
<< "input update complete\n";
|
||||
gui.mGuiInpitListener =
|
||||
guiListener;
|
||||
if (app.mInput)
|
||||
removeInputListener(
|
||||
app.mInput);
|
||||
delete app.mInput;
|
||||
app.mInput = new OgreBites::
|
||||
InputListenerChain(
|
||||
app.listeners);
|
||||
addInputListener(
|
||||
app.mInput);
|
||||
std::cout
|
||||
<< "update listeners: "
|
||||
<< app.listeners
|
||||
.size()
|
||||
<< "\n";
|
||||
if (app.listeners
|
||||
.size() ==
|
||||
2)
|
||||
OgreAssert(
|
||||
app.listeners.size() ==
|
||||
2,
|
||||
"");
|
||||
input_update.disable();
|
||||
OgreAssert(false, "");
|
||||
} else {
|
||||
app.listeners.clear();
|
||||
app.listeners.push_back(
|
||||
&mKbd);
|
||||
}
|
||||
} else
|
||||
input_update.disable();
|
||||
std::cout << "input update "
|
||||
<< app.listeners.size()
|
||||
<< "\n";
|
||||
});
|
||||
#endif
|
||||
ECS::get().set<ECS::App>(
|
||||
{ initialiseImGui(),
|
||||
nullptr,
|
||||
{ getImGuiInputListener(), &mKbd } });
|
||||
Sound::setup();
|
||||
Sound::ding();
|
||||
}
|
||||
void create_entity_node(const Ogre::String &name, int key)
|
||||
{
|
||||
Ogre::Entity *ent = mScnMgr->createEntity(name);
|
||||
Ogre::SceneNode *pnode =
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"ent:" + name +
|
||||
Ogre::StringConverter::toString(key),
|
||||
mCameraPivot->getPosition(),
|
||||
mCameraPivot->getOrientation());
|
||||
pnode->attachObject(ent);
|
||||
Ogre::Quaternion q = pnode->getOrientation();
|
||||
Ogre::Radian yaw = q.getYaw();
|
||||
Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0));
|
||||
pnode->setOrientation(nq);
|
||||
set_gui_active(false);
|
||||
ECS::get<ECS::GUI>().setWindowGrab(true);
|
||||
}
|
||||
bool get_gui_active()
|
||||
{
|
||||
return ECS::get().get<ECS::GUI>().enabled;
|
||||
}
|
||||
void set_gui_active(bool active)
|
||||
{
|
||||
ECS::get().get_mut<ECS::GUI>().enabled = active;
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
}
|
||||
Ogre::Camera *getCamera()
|
||||
{
|
||||
return mCamera;
|
||||
}
|
||||
flecs::entity getPlayer() const
|
||||
{
|
||||
return ECS::player;
|
||||
}
|
||||
void enableDbgDraw(bool enable)
|
||||
{
|
||||
ECS::get_mut<ECS::EngineData>().enableDbgDraw = enable;
|
||||
ECS::modified<ECS::EngineData>();
|
||||
}
|
||||
bool isEnabledDbgDraw() const
|
||||
{
|
||||
return ECS::get<ECS::EngineData>().enableDbgDraw;
|
||||
}
|
||||
};
|
||||
void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt)
|
||||
{
|
||||
if (fps_timer.getMilliseconds() > 1000.0f) {
|
||||
std::cout << "FPS: "
|
||||
<< mApp->getRenderWindow()->getStatistics().lastFPS
|
||||
<< " ";
|
||||
std::cout << "Draw calls: "
|
||||
<< mApp->getRenderWindow()->getStatistics().batchCount
|
||||
<< " ";
|
||||
fps_timer.reset();
|
||||
std::cout << "Drops: "
|
||||
<< mApp->getRenderWindow()
|
||||
->getStatistics()
|
||||
.vBlankMissCount
|
||||
<< "\n";
|
||||
fps_timer.reset();
|
||||
}
|
||||
if (!isGuiEnabled() ||
|
||||
(isGuiEnabled() && ECS::get<ECS::GUI>().narrationBox)) {
|
||||
mApp->updateWorld(evt.timeSinceLastFrame);
|
||||
if (mInitDelay >= 0.0f)
|
||||
mInitDelay -= evt.timeSinceLastFrame;
|
||||
}
|
||||
|
||||
if (!isGuiEnabled() && ECS::get().has<ECS::Input>()) {
|
||||
ECS::Input &input = ECS::get().get_mut<ECS::Input>();
|
||||
input.control = control;
|
||||
input.mouse = mouse;
|
||||
input.mouse_abs = mouse_abs;
|
||||
mouse.x = 0;
|
||||
mouse.y = 0;
|
||||
input.wheel_y = wheel_y;
|
||||
wheel_y = 0;
|
||||
input.mouse_moved = mouse_moved;
|
||||
input.wheel_moved = wheel_moved;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
App ctx;
|
||||
ctx.configure();
|
||||
// ctx.runRenderingSettingsDialog();
|
||||
// get a pointer to the already created root
|
||||
// register for input events
|
||||
// KeyHandler keyHandler;
|
||||
// ctx.addInputListener(&keyHandler);
|
||||
ctx.enableDbgDraw(false);
|
||||
ctx.getRoot()->startRendering();
|
||||
ctx.setWindowGrab(false);
|
||||
ctx.closeApp();
|
||||
return 0;
|
||||
}
|
||||
212
Procedural.cpp
@@ -7,10 +7,6 @@
|
||||
|
||||
#include "Ogre.h"
|
||||
#include "OgreApplicationContext.h"
|
||||
#include "Bullet/OgreBullet.h"
|
||||
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
|
||||
#include "btKinematicCharacterController.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "OgrePageManager.h"
|
||||
#include "Procedural.h"
|
||||
|
||||
@@ -23,11 +19,8 @@ using Real = Ogre::Real;
|
||||
using Math = Ogre::Math;
|
||||
|
||||
class WorldData {
|
||||
std::unique_ptr<Ogre::Bullet::DynamicsWorld> mDynWorld;
|
||||
std::unique_ptr<Ogre::Bullet::DebugDrawer> mDbgDraw;
|
||||
std::unique_ptr<Ogre::Root> mRoot;
|
||||
std::unique_ptr<Ogre::SceneManager> mScnMgr;
|
||||
std::unique_ptr<btDynamicsWorld> mbtWorld;
|
||||
std::unique_ptr<Ogre::PageManager> mPageManager;
|
||||
Ogre::PagedWorld *mPagedWorld;
|
||||
|
||||
@@ -63,13 +56,8 @@ private:
|
||||
DummyPageProvider mDummyPageProvider;
|
||||
|
||||
WorldData(Ogre::Root *root, Ogre::SceneManager *scnMgr)
|
||||
: mDynWorld(new Ogre::Bullet::DynamicsWorld(
|
||||
Ogre::Vector3(0, -9.8, 0)))
|
||||
, mDbgDraw(new Ogre::Bullet::DebugDrawer(
|
||||
scnMgr->getRootSceneNode(), mDynWorld->getBtWorld()))
|
||||
, mRoot(root)
|
||||
: mRoot(root)
|
||||
, mScnMgr(scnMgr)
|
||||
, mbtWorld(mDynWorld->getBtWorld())
|
||||
, mPageManager(nullptr)
|
||||
, mPagedWorld(nullptr)
|
||||
{
|
||||
@@ -101,94 +89,8 @@ public:
|
||||
void createTrimesh(Ogre::Entity *entity)
|
||||
{
|
||||
}
|
||||
btPairCachingGhostObject *addGhostObject(Ogre::Entity *ent,
|
||||
btCollisionShape *shape,
|
||||
int group = 1,
|
||||
int mask = 0xFFFF)
|
||||
{
|
||||
btDynamicsWorld *world = mDynWorld->getBtWorld();
|
||||
Ogre::SceneNode *node = ent->getParentSceneNode();
|
||||
btPairCachingGhostObject *ghost =
|
||||
new btPairCachingGhostObject();
|
||||
ghost->setCollisionShape(shape);
|
||||
ghost->setCollisionFlags(
|
||||
ghost->getCollisionFlags() |
|
||||
btCollisionObject::CF_NO_CONTACT_RESPONSE |
|
||||
btCollisionObject::CF_CHARACTER_OBJECT);
|
||||
getWorld()->attachCollisionObject(ghost, ent, group, mask);
|
||||
#if 0
|
||||
getBtWorld()
|
||||
->getBroadphase()->getOverlappingPairCache()
|
||||
->setInternalGhostPairCallback(new btGhostPairCallback());
|
||||
ghost->setUserPointer(new EntityCollisionListener{ent, nullptr});
|
||||
#endif
|
||||
return ghost;
|
||||
}
|
||||
btRigidBody *addRigidBody(float mass, Ogre::Entity *ent,
|
||||
Ogre::Bullet::ColliderType ct, int group = 1,
|
||||
int mask = 0xFFFF)
|
||||
{
|
||||
btDynamicsWorld *world = mDynWorld->getBtWorld();
|
||||
Ogre::SceneNode *node = ent->getParentSceneNode();
|
||||
Ogre::Bullet::RigidBodyState *state =
|
||||
new Ogre::Bullet::RigidBodyState(node);
|
||||
btCollisionShape *cs;
|
||||
btCollisionShape *shape;
|
||||
btVector3 inertia(0, 0, 0);
|
||||
switch (ct) {
|
||||
case Ogre::Bullet::CT_TRIMESH: {
|
||||
cs = Ogre::Bullet::createTrimeshCollider(ent);
|
||||
if (mass != 0)
|
||||
cs->calculateLocalInertia(mass, inertia);
|
||||
} break;
|
||||
case Ogre::Bullet::CT_CAPSULE: {
|
||||
cs = new btCompoundShape();
|
||||
btScalar height = 1.0f;
|
||||
btScalar radius = 0.3f;
|
||||
shape = new btCapsuleShape(radius,
|
||||
2 * height - 2 * radius);
|
||||
btTransform transform;
|
||||
transform.setIdentity();
|
||||
transform.setOrigin(btVector3(0, 1, 0));
|
||||
static_cast<btCompoundShape *>(cs)->addChildShape(
|
||||
transform, shape);
|
||||
btScalar masses[1] = { mass };
|
||||
btTransform principal;
|
||||
static_cast<btCompoundShape *>(cs)
|
||||
->calculatePrincipalAxisTransform(
|
||||
masses, principal, inertia);
|
||||
} break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
btRigidBody *body = new btRigidBody(mass, state, cs, inertia);
|
||||
getWorld()->attachRigidBody(body, ent, nullptr, group, mask);
|
||||
#if 0
|
||||
body->setUserPointer(new EntityCollisionListener{ent, nullptr});
|
||||
// btRigidBody *body = mDynWorld->addRigidBody(0, ent, Ogre::Bullet::CT_TRIMESH);
|
||||
#endif
|
||||
return body;
|
||||
}
|
||||
btRigidBody *addKinematicRigidBody(float mass, Ogre::Entity *ent,
|
||||
Ogre::Bullet::ColliderType ct,
|
||||
int group = 1, int mask = 0xFFFF)
|
||||
{
|
||||
return mDynWorld->addKinematicRigidBody(ent, ct, group, mask);
|
||||
}
|
||||
btDynamicsWorld *getBtWorld()
|
||||
{
|
||||
return mDynWorld->getBtWorld();
|
||||
}
|
||||
Ogre::Bullet::DynamicsWorld *getWorld()
|
||||
{
|
||||
return mDynWorld.get();
|
||||
}
|
||||
void update(float delta)
|
||||
{
|
||||
WorldData::get_singleton()->getBtWorld()->stepSimulation(delta,
|
||||
10);
|
||||
mDbgDraw->update();
|
||||
}
|
||||
void initPagedWorld(Ogre::Camera *camera)
|
||||
{
|
||||
@@ -202,8 +104,6 @@ public:
|
||||
WorldData *WorldData::singleton = nullptr;
|
||||
|
||||
class MainWorld : public Ogre::FrameListener {
|
||||
btRigidBody *mFloorBody;
|
||||
|
||||
public:
|
||||
void setup()
|
||||
{
|
||||
@@ -221,13 +121,6 @@ public:
|
||||
WorldData::get_singleton()->getSceneManager();
|
||||
Ogre::Entity *floor = scnMgr->createEntity("Floor", "floor");
|
||||
scnMgr->getRootSceneNode()->attachObject(floor);
|
||||
mFloorBody = WorldData::get_singleton()->addRigidBody(
|
||||
0, floor, Ogre::Bullet::CT_TRIMESH);
|
||||
}
|
||||
btRigidBody *addCharacter(Ogre::Entity *ent, float mass)
|
||||
{
|
||||
return WorldData::get_singleton()->addKinematicRigidBody(
|
||||
mass, ent, Ogre::Bullet::CT_COMPOUND);
|
||||
}
|
||||
bool frameStarted(const Ogre::FrameEvent &evt) override;
|
||||
};
|
||||
@@ -267,9 +160,6 @@ class CharacterController : public OgreBites::InputListener,
|
||||
Ogre::Vector3 rootMotion;
|
||||
Ogre::Quaternion rootRotation;
|
||||
// btRigidBody *mRigidBody;
|
||||
btCompoundShape *mCollisionShape;
|
||||
btPairCachingGhostObject *mGhostObject;
|
||||
btKinematicCharacterController *mController;
|
||||
|
||||
public:
|
||||
CharacterController(Ogre::SceneNode *camNode, Ogre::Camera *cam,
|
||||
@@ -318,35 +208,6 @@ private:
|
||||
recoverResult *recover_result,
|
||||
const std::set<btCollisionObject *> &exclude);
|
||||
#endif
|
||||
inline btQuaternion convert(const Ogre::Quaternion &q)
|
||||
{
|
||||
return btQuaternion(q.x, q.y, q.z, q.w);
|
||||
}
|
||||
inline btVector3 convert(const Ogre::Vector3 &v)
|
||||
{
|
||||
return btVector3(v.x, v.y, v.z);
|
||||
}
|
||||
inline btTransform convert(const Ogre::Quaternion &q,
|
||||
const Ogre::Vector3 &v)
|
||||
{
|
||||
btQuaternion mq = convert(q);
|
||||
btVector3 mv = convert(v);
|
||||
return btTransform(mq, mv);
|
||||
}
|
||||
inline Ogre::Quaternion convert(const btQuaternion &q)
|
||||
{
|
||||
return Ogre::Quaternion(q.w(), q.x(), q.y(), q.z());
|
||||
}
|
||||
inline Ogre::Vector3 convert(const btVector3 &v)
|
||||
{
|
||||
return Ogre::Vector3(v.x(), v.y(), v.z());
|
||||
}
|
||||
inline void convert(const btTransform &from, Ogre::Quaternion &q,
|
||||
Ogre::Vector3 &v)
|
||||
{
|
||||
q = convert(from.getRotation());
|
||||
v = convert(from.getOrigin());
|
||||
}
|
||||
};
|
||||
CharacterController::CharacterController(Ogre::SceneNode *camNode,
|
||||
Ogre::Camera *cam,
|
||||
@@ -360,9 +221,6 @@ CharacterController::CharacterController(Ogre::SceneNode *camNode,
|
||||
, mAnimID(ANIM_NONE)
|
||||
, mRunning(false)
|
||||
, world(world)
|
||||
, mCollisionShape(nullptr)
|
||||
, mGhostObject(nullptr)
|
||||
, mController(nullptr)
|
||||
{
|
||||
setupBody();
|
||||
setupCamera();
|
||||
@@ -377,72 +235,6 @@ void CharacterController::setupBody()
|
||||
mBodyNode = mScnMgr->getRootSceneNode()->createChildSceneNode();
|
||||
mBodyNode->attachObject(mBodyEnt);
|
||||
mSkeleton = mBodyEnt->getSkeleton();
|
||||
// mRigidBody = world->addCharacter(mBodyEnt, 0);
|
||||
// mCollisionShape = static_cast<btCompoundShape *>(mRigidBody->getCollisionShape());
|
||||
mGhostObject = new btPairCachingGhostObject();
|
||||
mCollisionShape = new btCompoundShape;
|
||||
mGhostObject->setCollisionShape(mCollisionShape);
|
||||
|
||||
{
|
||||
btVector3 inertia(0, 0, 0);
|
||||
// mCollisionShape = new btCompoundShape();
|
||||
btScalar height = 1.0f;
|
||||
btScalar radius = 0.3f;
|
||||
btCapsuleShape *shape =
|
||||
new btCapsuleShape(radius, 2 * height - 2 * radius);
|
||||
btTransform transform;
|
||||
transform.setIdentity();
|
||||
transform.setOrigin(btVector3(0, 1, 0));
|
||||
static_cast<btCompoundShape *>(mCollisionShape)
|
||||
->addChildShape(transform, shape);
|
||||
btScalar masses[1] = { 0 };
|
||||
btTransform principal;
|
||||
static_cast<btCompoundShape *>(mCollisionShape)
|
||||
->calculatePrincipalAxisTransform(masses, principal,
|
||||
inertia);
|
||||
}
|
||||
mGhostObject->setCollisionFlags(
|
||||
btCollisionObject::CF_KINEMATIC_OBJECT |
|
||||
btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
mGhostObject->setActivationState(DISABLE_DEACTIVATION);
|
||||
Ogre::Bullet::KinematicMotionSimple *controller =
|
||||
new Ogre::Bullet::KinematicMotionSimple(mGhostObject,
|
||||
mBodyNode);
|
||||
WorldData::get_singleton()->getWorld()->attachCollisionObject(
|
||||
mGhostObject, mBodyEnt, btBroadphaseProxy::AllFilter,
|
||||
btBroadphaseProxy::AllFilter);
|
||||
WorldData::get_singleton()->getBtWorld()->addAction(controller);
|
||||
|
||||
assert(mCollisionShape);
|
||||
#if 0
|
||||
if (mRigidBody->getMass() == 0) {
|
||||
#if 0
|
||||
mRigidBody->setCollisionFlags(mRigidBody->getCollisionFlags()
|
||||
| btCollisionObject::CF_KINEMATIC_OBJECT
|
||||
| btCollisionObject::CF_NO_CONTACT_RESPONSE
|
||||
);
|
||||
#endif
|
||||
#if 0
|
||||
mGhostObject->setWorldTransform(mRigidBody->getWorldTransform());
|
||||
WorldData::get_singleton()->getBtWorld()
|
||||
->getBroadphase()->getOverlappingPairCache()
|
||||
->setInternalGhostPairCallback(new btGhostPairCallback());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
mRigidBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
#endif
|
||||
#if 0
|
||||
{
|
||||
Ogre::Entity *e2 = mScnMgr->createEntity("normal-male.glb");
|
||||
Ogre::SceneNode *e2node = mScnMgr->getRootSceneNode()->createChildSceneNode();
|
||||
e2node->attachObject(e2);
|
||||
mGhostObject = WorldData::get_singleton()->addGhostObject(e2, mCollisionShape);
|
||||
mController = new btKinematicCharacterController(mGhostObject, mCollisionShape, 0.5f);
|
||||
WorldData::get_singleton()->getBtWorld()->addAction(mController);
|
||||
}
|
||||
#endif
|
||||
assert(mSkeleton->hasBone("Root"));
|
||||
mRootBone = mSkeleton->getBone("Root");
|
||||
assert(mRootBone);
|
||||
@@ -743,8 +535,6 @@ void CharacterController::updateRootMotion(Real delta)
|
||||
Ogre::Vector3 velocity = rot * boneMotion / delta;
|
||||
velocity += gravity * delta;
|
||||
Ogre::Vector3 rotMotion = velocity * delta;
|
||||
btTransform from(convert(mBodyNode->getOrientation()),
|
||||
convert(mBodyNode->getPosition()));
|
||||
mBodyNode->setPosition(mBodyNode->getPosition() + rotMotion);
|
||||
// WorldData::get_singleton()->getWorld()->testBodyMotion(mRigidBody, from, Ogre::Bullet::convert(rotMotion), true,
|
||||
// nullptr, false, std::set<btCollisionObject *>());
|
||||
|
||||
BIN
assets/blender/altar.blend
LFS
Normal file
BIN
assets/blender/buildings/Atlas_00001.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/blender/buildings/Atlas_00002.png
Normal file
|
After Width: | Height: | Size: 341 B |
BIN
assets/blender/buildings/Atlas_00003.png
Normal file
|
After Width: | Height: | Size: 341 B |
BIN
assets/blender/buildings/Atlas_00004.png
Normal file
|
After Width: | Height: | Size: 341 B |
BIN
assets/blender/buildings/Atlas_00005.png
Normal file
|
After Width: | Height: | Size: 341 B |
BIN
assets/blender/buildings/Atlas_00006.png
Normal file
|
After Width: | Height: | Size: 276 B |
BIN
assets/blender/buildings/Atlas_00007.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/blender/buildings/Atlas_00008.png
Normal file
|
After Width: | Height: | Size: 345 B |
BIN
assets/blender/buildings/Atlas_00009.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/blender/buildings/Atlas_00010.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/blender/buildings/Atlas_12696.png
Normal file
|
After Width: | Height: | Size: 346 B |
BIN
assets/blender/buildings/Atlas_32944.png
Normal file
|
After Width: | Height: | Size: 431 B |
BIN
assets/blender/buildings/Atlas_36953.png
Normal file
|
After Width: | Height: | Size: 437 B |
BIN
assets/blender/buildings/Atlas_52716.png
Normal file
|
After Width: | Height: | Size: 517 B |
BIN
assets/blender/buildings/Atlas_73934.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
assets/blender/buildings/altar.blend
LFS
Normal file
BIN
assets/blender/buildings/atlas-gym-roughness.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
assets/blender/buildings/atlas-gym-specular.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
assets/blender/buildings/bus-stop.blend
LFS
Normal file
BIN
assets/blender/buildings/business-bar1.blend
LFS
Normal file
BIN
assets/blender/buildings/business-cafe1.blend
LFS
Normal file
BIN
assets/blender/buildings/business-office1.blend
LFS
Normal file
BIN
assets/blender/buildings/business-store1.blend
LFS
Normal file
BIN
assets/blender/buildings/dirt-road-corner.blend
LFS
Normal file
BIN
assets/blender/buildings/dirt-road-x.blend
LFS
Normal file
BIN
assets/blender/buildings/dirt-road.blend
LFS
Normal file
BIN
assets/blender/buildings/gym-exterior.blend
LFS
Normal file
BIN
assets/blender/buildings/home-exterior.blend
LFS
Normal file
BIN
assets/blender/buildings/joint-atlas-1-roughness.kra
LFS
Normal file
BIN
assets/blender/buildings/joint-atlas-1-roughness.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/blender/buildings/joint-atlas-1-specular.kra
LFS
Normal file
BIN
assets/blender/buildings/joint-atlas-1-specular.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/blender/buildings/joint-atlas-1.kra
LFS
Normal file
BIN
assets/blender/buildings/joint-atlas-1.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
assets/blender/buildings/logistics-center-exterior.blend
LFS
Normal file
BIN
assets/blender/buildings/lot-large1.blend
LFS
Normal file
BIN
assets/blender/buildings/lot-large2.blend
LFS
Normal file
BIN
assets/blender/buildings/lot-small-m0.blend
LFS
Normal file
BIN
assets/blender/buildings/lot-small0.blend
LFS
Normal file
BIN
assets/blender/buildings/lot-small1.blend
LFS
Normal file
BIN
assets/blender/buildings/lot-small2.blend
LFS
Normal file
BIN
assets/blender/buildings/material.blend
LFS
Normal file
BIN
assets/blender/buildings/office-exterior.blend
LFS
Normal file
31
assets/blender/buildings/parts/CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
project(building-parts)
|
||||
set(PARTS_FILES pier.blend)
|
||||
set(FURNITURE_FILES furniture.blend furniture-sofa.blend)
|
||||
set(PARTS_OUTPUT_DIRS)
|
||||
foreach(PARTS_FILE ${PARTS_FILES})
|
||||
get_filename_component(FILE_NAME ${PARTS_FILE} NAME_WE)
|
||||
set(PARTS_OUTPUT_DIR ${CMAKE_BINARY_DIR}/resources/buildings/parts/${FILE_NAME})
|
||||
add_custom_command(
|
||||
OUTPUT ${PARTS_OUTPUT_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PARTS_OUTPUT_DIR}
|
||||
COMMAND ${BLENDER} ${CMAKE_CURRENT_SOURCE_DIR}/${PARTS_FILE}
|
||||
-b -Y -P
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_building_parts.py
|
||||
-- ${PARTS_OUTPUT_DIR}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PARTS_FILE} ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_building_parts.py)
|
||||
list(APPEND PARTS_OUTPUT_DIRS ${PARTS_OUTPUT_DIR})
|
||||
endforeach()
|
||||
foreach(FURNITURE_FILE ${FURNITURE_FILES})
|
||||
get_filename_component(FILE_NAME ${FURNITURE_FILE} NAME_WE)
|
||||
set(PARTS_OUTPUT_DIR ${CMAKE_BINARY_DIR}/resources/buildings/parts/${FILE_NAME})
|
||||
add_custom_command(
|
||||
OUTPUT ${PARTS_OUTPUT_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PARTS_OUTPUT_DIR}
|
||||
COMMAND ${BLENDER} ${CMAKE_CURRENT_SOURCE_DIR}/${FURNITURE_FILE}
|
||||
-b -Y -P
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/export_furniture_parts.py
|
||||
-- ${PARTS_OUTPUT_DIR}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PARTS_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/export_furniture_parts.py)
|
||||
list(APPEND PARTS_OUTPUT_DIRS ${PARTS_OUTPUT_DIR})
|
||||
endforeach()
|
||||
add_custom_target(import_building_parts ALL DEPENDS ${PARTS_OUTPUT_DIRS})
|
||||
182
assets/blender/buildings/parts/export_furniture_parts.py
Normal file
@@ -0,0 +1,182 @@
|
||||
import bpy
|
||||
import os, sys, time
|
||||
import json
|
||||
from mathutils import Matrix, Quaternion
|
||||
argv = sys.argv
|
||||
argv = argv[argv.index("--") + 1:]
|
||||
|
||||
incpath = os.path.dirname(__file__)
|
||||
|
||||
sys.path.insert(0, incpath)
|
||||
outdir = argv[0]
|
||||
|
||||
basis_change = Matrix((
|
||||
(1, 0, 0, 0),
|
||||
(0, 0, 1, 0),
|
||||
(0, -1, 0, 0),
|
||||
(0, 0, 0, 1)
|
||||
))
|
||||
|
||||
def export_root_objects_to_gltf(output_dir):
|
||||
# Ensure the output directory exists
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
# Deselect all objects
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
# Iterate through all objects in the scene
|
||||
for obj in bpy.context.scene.objects:
|
||||
# Check if the object has no parent and has children
|
||||
# The original request specifies "objects having no parent with children".
|
||||
# This condition captures those that are explicitly root objects of a hierarchy.
|
||||
if obj.parent is None:
|
||||
# Select the root object and all its children
|
||||
|
||||
print(obj.name)
|
||||
if not obj.name.startswith("furniture-"):
|
||||
continue
|
||||
desc = {}
|
||||
desc["name"] = obj.name.replace("furniture-","")
|
||||
desc["mesh"] = obj.name + ".glb"
|
||||
if "furniture_tags" in obj:
|
||||
mtags = obj["furniture_tags"]
|
||||
if "," in mtags:
|
||||
atags = [m.strip() for m in mtags.split(",")]
|
||||
desc["tags"] = atags
|
||||
else:
|
||||
desc["tags"] = [mtags]
|
||||
else:
|
||||
desc["tags"] = []
|
||||
desc["sensors"] = []
|
||||
desc["actions"] = []
|
||||
desc["positions"] = []
|
||||
for child in obj.children:
|
||||
if child.name.startswith("action-"):
|
||||
if not "action" in child:
|
||||
continue
|
||||
if not "height" in child:
|
||||
continue
|
||||
if not "radius" in child:
|
||||
continue
|
||||
local_matrix = child.matrix_local
|
||||
ogre_local_matrix = basis_change @ local_matrix @ basis_change.inverted()
|
||||
local_pos_d = ogre_local_matrix.to_translation()
|
||||
local_rot_d = ogre_local_matrix.to_quaternion()
|
||||
local_pos = [round(x, 4) for x in local_pos_d]
|
||||
local_rot = [round(x, 4) for x in local_rot_d]
|
||||
action = {}
|
||||
action["position_x"] = local_pos[0]
|
||||
action["position_y"] = local_pos[1]
|
||||
action["position_z"] = local_pos[2]
|
||||
action["rotation_w"] = local_rot[0]
|
||||
action["rotation_x"] = local_rot[1]
|
||||
action["rotation_y"] = local_rot[2]
|
||||
action["rotation_z"] = local_rot[3]
|
||||
action["height"] = child["height"]
|
||||
action["radius"] = child["radius"]
|
||||
action["action"] = child["action"]
|
||||
if "action_text" in child:
|
||||
action["action_text"] = child["action_text"]
|
||||
else:
|
||||
action["action_text"] = child["action"].capitalize()
|
||||
if "name" in child:
|
||||
action["name"] = child["name"]
|
||||
else:
|
||||
action["name"] = desc["name"] + "_" + str(len(desc["actions"]))
|
||||
action["furniture"] = {}
|
||||
action["furniture"]["name"] = desc["name"]
|
||||
action["furniture"]["tags"] = desc["tags"]
|
||||
action["positions"] = []
|
||||
for schild in child.children:
|
||||
if schild.name.startswith("position-"):
|
||||
local_matrix = schild.matrix_local
|
||||
ogre_local_matrix = basis_change @ local_matrix @ basis_change.inverted()
|
||||
local_pos_d = ogre_local_matrix.to_translation()
|
||||
local_rot_d = ogre_local_matrix.to_quaternion()
|
||||
local_pos = [round(x, 4) for x in local_pos_d]
|
||||
local_rot = [round(x, 4) for x in local_rot_d]
|
||||
position = {}
|
||||
if "name" in schild:
|
||||
position["name"] = schild["name"]
|
||||
if "type" in schild:
|
||||
position["type"] = schild["type"]
|
||||
position["position_x"] = local_pos[0]
|
||||
position["position_y"] = local_pos[2]
|
||||
position["position_z"] = local_pos[1]
|
||||
position["rotation_w"] = local_rot[0]
|
||||
position["rotation_x"] = local_rot[1]
|
||||
position["rotation_y"] = local_rot[2]
|
||||
position["rotation_z"] = local_rot[3]
|
||||
action["positions"].append(position)
|
||||
desc["actions"].append(action)
|
||||
if child.name.startswith("position-"):
|
||||
local_matrix = child.matrix_local
|
||||
ogre_local_matrix = basis_change @ local_matrix @ basis_change.inverted()
|
||||
local_pos_d = ogre_local_matrix.to_translation()
|
||||
local_rot_d = ogre_local_matrix.to_quaternion()
|
||||
local_pos = [round(x, 4) for x in local_pos_d]
|
||||
local_rot = [round(x, 4) for x in local_rot_d]
|
||||
position = {}
|
||||
if "name" in child:
|
||||
position["name"] = child["name"]
|
||||
if "type" in child:
|
||||
position["type"] = child["type"]
|
||||
position["position_x"] = local_pos[0]
|
||||
position["position_y"] = local_pos[2]
|
||||
position["position_z"] = local_pos[1]
|
||||
position["rotation_w"] = local_rot[0]
|
||||
position["rotation_x"] = local_rot[1]
|
||||
position["rotation_y"] = local_rot[2]
|
||||
position["rotation_z"] = local_rot[3]
|
||||
desc["positions"].append(position)
|
||||
|
||||
obj.select_set(True)
|
||||
for child in obj.children_recursive:
|
||||
child.select_set(True)
|
||||
|
||||
obj.location = (0.0, 0.0, 0.0)
|
||||
|
||||
# Set the root object as the active object for the export operator
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
|
||||
# Define the output file path
|
||||
file_path = os.path.join(output_dir, f"{obj.name}.glb")
|
||||
|
||||
# Export the selected objects to a glTF file
|
||||
bpy.ops.export_scene.gltf(filepath=file_path,
|
||||
use_selection=True,
|
||||
check_existing=False,
|
||||
export_format='GLB',
|
||||
export_texture_dir='textures', export_texcoords=True,
|
||||
export_normals=True,
|
||||
export_tangents=True,
|
||||
export_materials='EXPORT',
|
||||
export_colors=True,
|
||||
use_mesh_edges=False,
|
||||
use_mesh_vertices=False,
|
||||
export_cameras=False,
|
||||
use_visible=False,
|
||||
use_renderable=False,
|
||||
export_yup=True,
|
||||
export_apply=True,
|
||||
export_animations=True,
|
||||
export_force_sampling=True,
|
||||
export_def_bones=False,
|
||||
export_current_frame=False,
|
||||
export_morph=True,
|
||||
export_morph_animation=False,
|
||||
export_morph_normal=True,
|
||||
export_morph_tangent=True,
|
||||
export_lights=False,
|
||||
export_skins=True)
|
||||
|
||||
# Deselect all objects for the next iteration
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
print(f"Exported {obj.name} and its children to {file_path}")
|
||||
with open(file_path + ".json", "w") as json_data:
|
||||
json.dump(desc, json_data)
|
||||
|
||||
export_root_objects_to_gltf(outdir)
|
||||
|
||||