Compare commits

...

2 Commits

Author SHA1 Message Date
bf25ef1a80 Fixed vehicles export 2026-02-10 00:49:19 +03:00
b01605d826 Cleanup 2026-02-09 12:40:38 +03:00
8 changed files with 258 additions and 61 deletions

View File

@@ -72,6 +72,7 @@ add_subdirectory(src/tests)
add_subdirectory(src/physics)
add_subdirectory(src/editor)
add_subdirectory(src/crowd)
add_subdirectory(assets/blender/vehicles)
add_subdirectory(assets/blender/buildings/parts)
add_subdirectory(assets/blender/characters)
add_subdirectory(resources)
@@ -132,23 +133,6 @@ foreach(BUILDING_FILE ${BUILDINGS_SRC})
endforeach()
add_custom_target(import_buildings ALL DEPENDS ${BUILDING_OUTPUT_FILES})
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(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)

View File

@@ -0,0 +1,112 @@
#!/usr/bin/env python
import os, sys, time
import bpy
from math import pi
import glob
import shutil
from mathutils import Vector, Matrix
from math import radians, pi
argv = sys.argv
argv = argv[argv.index("--") + 1:]
incpath = os.path.dirname(__file__)
sys.path.insert(0, incpath)
sys.path.insert(1, incpath + "/blender2ogre")
import io_ogre
try:
io_ogre.register()
except:
pass
gltf_file = argv[0]
print("Exporting to " + gltf_file)
basepath = incpath
# bpy.ops.export_scene.gltf(filepath="", check_existing=True,
# export_import_convert_lighting_mode='SPEC', gltf_export_id="",
# export_format='GLB', ui_tab='GENERAL', export_copyright="", export_image_format='AUTO',
# export_texture_dir="", export_jpeg_quality=75, export_keep_originals=False,
# export_texcoords=True, export_normals=True, export_draco_mesh_compression_enable=False,
# export_draco_mesh_compression_level=6, export_draco_position_quantization=14,
# export_draco_normal_quantization=10, export_draco_texcoord_quantization=12,
# export_draco_color_quantization=10, export_draco_generic_quantization=12, export_tangents=False,
# export_materials='EXPORT', export_original_specular=False, export_colors=True,
# export_attributes=False, use_mesh_edges=False, use_mesh_vertices=False, export_cameras=False,
# use_selection=False, use_visible=False, use_renderable=False,
# use_active_collection_with_nested=True, use_active_collection=False, use_active_scene=False,
# export_extras=False, export_yup=True, export_apply=False, export_animations=True,
# export_frame_range=False, export_frame_step=1, export_force_sampling=True, export_animation_mode='ACTIONS',
# export_nla_strips_merged_animation_name="Animation", export_def_bones=False,
# export_hierarchy_flatten_bones=False, export_optimize_animation_size=True,
# export_optimize_animation_keep_anim_armature=True, export_optimize_animation_keep_anim_object=False,
# export_negative_frame='SLIDE', export_anim_slide_to_zero=False, export_bake_animation=False,
# export_anim_single_armature=True, export_reset_pose_bones=True, export_current_frame=False,
# export_rest_position_armature=True, export_anim_scene_split_object=True, export_skins=True,
# export_all_influences=False, export_morph=True, export_morph_normal=True,
# export_morph_tangent=False, export_morph_animation=True, export_morph_reset_sk_data=True,
# export_lights=False, export_nla_strips=True, will_save_settings=False, filter_glob="*.glb")
for obj in bpy.data.objects:
if obj.name.endswith("-col"):
bpy.data.objects.remove(obj)
# Set the object as active and switch mode
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='OBJECT')
#bpy.context.view_layer.objects.active = None
scene_file = gltf_file.replace(".glb", "").replace(".gltf", "") + ".scene"
bpy.ops.ogre.export(filepath=scene_file,
EX_SWAP_AXIS='xz-y',
EX_V2_MESH_TOOL_VERSION='v2',
EX_EXPORT_XML_DELETE=True,
EX_SCENE=True,
EX_SELECTED_ONLY=False,
EX_EXPORT_HIDDEN=False,
EX_FORCE_CAMERA=False,
EX_FORCE_LIGHTS=False,
EX_NODE_ANIMATION=True,
EX_MATERIALS=True,
EX_SEPARATE_MATERIALS=True,
EX_COPY_SHADER_PROGRAMS=True,
EX_MESH=True,
EX_LOD_LEVELS=3,
EX_LOD_DISTANCE=100,
EX_LOD_PERCENT=40
)
bpy.ops.export_scene.gltf(filepath=gltf_file,
use_selection=False,
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)
bpy.ops.wm.read_homefile(use_empty=True)
time.sleep(2)
bpy.ops.wm.quit_blender()

View File

@@ -0,0 +1,25 @@
project(vehicles)
set(VEHICLES_SRC boat-big.blend boat.blend
boat-gobbot.blend boat-sails.blend
raft.blend tiny-boat.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} ${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.scene
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/resources/vehicles
COMMAND ${BLENDER} ${CMAKE_CURRENT_SOURCE_DIR}/${VEHICLE_FILE}
-b -Y -P
${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_vehicles.py
-- ${VEHICLE_OUTPUT_FILE}
COMMAND ${CMAKE_COMMAND} -D FILE=${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.glb -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/check_file_size.cmake
COMMAND ${CMAKE_COMMAND} -D FILE=${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.scene -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/check_file_size.cmake
COMMAND touch ${VEHICLE_OUTPUT_FILE}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${VEHICLE_FILE} ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_vehicles.py)
list(APPEND VEHICLE_OUTPUT_FILES ${VEHICLE_OUTPUT_FILE} ${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.scene)
endforeach()
add_custom_target(import_vehicles ALL DEPENDS ${VEHICLE_OUTPUT_FILES})

Binary file not shown.

View File

@@ -0,0 +1,11 @@
if(EXISTS "${FILE}")
file(SIZE "${FILE}" FILE_SIZE)
if(FILE_SIZE GREATER 0)
message(STATUS "Build-time check: ${FILE} exists and is not empty.")
else()
message(FATAL_ERROR "Build-time check: ${FILE} exists but is empty!")
endif()
else()
message(FATAL_ERROR "Build-time check: ${FILE} does not exist!")
endif()

View File

@@ -434,9 +434,9 @@ public:
createContent();
std::cout << "Setup done"
<< "\n";
Ogre::LogManager::getSingleton().setMinLogLevel(
Ogre::LML_TRIVIAL);
}
Ogre::LogManager::getSingleton().setMinLogLevel(
Ogre::LML_TRIVIAL);
}
Ogre::Timer mTerrainUpd;
// TODO: implement rough water level calculation
float getWaterLevel(const Ogre::Vector3 &position)
@@ -590,14 +590,14 @@ public:
{
}
bool switchWindow = false;
JoltPhysicsWrapper *mJolt;
void createContent()
JoltPhysicsWrapper *mJolt;
void createContent()
{
int i;
mJolt = new JoltPhysicsWrapper(
mEditorNormalScene.getSceneManager(),
mEditorNormalScene.mCameraNode);
sky = new SkyBoxRenderer(mEditorNormalScene.getSceneManager());
mJolt = new JoltPhysicsWrapper(
mEditorNormalScene.getSceneManager(),
mEditorNormalScene.mCameraNode);
sky = new SkyBoxRenderer(mEditorNormalScene.getSceneManager());
bool drawFirst = true;
uint8_t renderQueue = drawFirst ?
Ogre::RENDER_QUEUE_SKIES_EARLY :
@@ -617,12 +617,12 @@ public:
mEditorNormalScene.mScnMgr,
/*mDynWorld.get(), */ mEditorNormalScene.mCameraNode,
mEditorNormalScene.mCamera, getRenderWindow());
ECS::get().import <ECS::PhysicsModule>();
ECS::get().import <ECS::EditorGizmoModule>();
ECS::get().import <ECS::EditorInputModule>();
ECS::Physics &ph = ECS::get().ensure<ECS::Physics>();
ph.physics = mJolt;
ECS::modified<ECS::Physics>();
ECS::get().import <ECS::PhysicsModule>();
ECS::get().import <ECS::EditorGizmoModule>();
ECS::get().import <ECS::EditorInputModule>();
ECS::Physics &ph = ECS::get().ensure<ECS::Physics>();
ph.physics = mJolt;
ECS::modified<ECS::Physics>();
ECS::get().set<ECS::RenderWindow>(
{ getRenderWindow(), getDisplayDPI() });
ECS::get()

View File

@@ -51,11 +51,11 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
, command(COMMAND_NONE)
{
_midFont = createFont("midFont", "General",
"Jupiteroid-Regular.ttf", 18.0f);
"Jupiteroid-Regular.ttf", 24.0f);
_smallFont = createFont("smallFont", "General",
"Jupiteroid-Regular.ttf", 13.0f);
"Jupiteroid-Regular.ttf", 18.0f);
_bigFont = createFont("bigFont", "General", "Kenney Bold.ttf",
32.0f);
36.0f);
smallFont = overlay->addFont("smallFont", "General");
OgreAssert(smallFont, "Could not load font");
midFont = overlay->addFont("midFont", "General");
@@ -1398,8 +1398,9 @@ EditorGUIModule::EditorGUIModule(flecs::world &ecs)
.event(flecs::OnSet)
.without<EditorGUIData>()
.each([](const RenderWindow &window, const App &app, GUI &gui) {
float vpScale = window.dpi / 96 *
window.window->getWidth() / 1600.0f;
float vpScale = window.dpi / 96;
if (vpScale < 1.0f)
vpScale = 1.0f;
Ogre::OverlayManager::getSingleton().setPixelRatio(
vpScale);
std::cout << "Editor GUI configure\n";

View File

@@ -47,11 +47,11 @@ struct GUIListener : public Ogre::RenderTargetListener {
: Ogre::RenderTargetListener()
{
_midFont = createFont("midFont", "General",
"Jupiteroid-Regular.ttf", 18.0f);
"Jupiteroid-Regular.ttf", 24.0f);
_smallFont = createFont("smallFont", "General",
"Jupiteroid-Regular.ttf", 13.0f);
"Jupiteroid-Regular.ttf", 18.0f);
_bigFont = createFont("bigFont", "General", "Kenney Bold.ttf",
32.0f);
36.0f);
smallFont = ECS::get<GUIData>().mGuiOverlay->addFont(
"smallFont", "General");
OgreAssert(smallFont, "Could not load font");
@@ -370,12 +370,24 @@ struct GUIListener : public Ogre::RenderTargetListener {
ImGui::End();
} else if (ECS::get().get<GUI>().enabled) {
if (ECS::get().get<GUI>().mainMenu) {
ImVec2 size = ImGui::GetMainViewport()->Size;
ImGuiViewport *viewport =
ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos,
ImGuiCond_Always);
ImGui::SetNextWindowSize(viewport->WorkSize,
ImGuiCond_Always);
ImGui::PushStyleVar(
ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(
ImGuiStyleVar_WindowBorderSize, 0.0f);
#if 0
ImGui::SetNextWindowPos(ImVec2(0, 0),
ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(size.x + 4,
size.y + 1),
ImGuiCond_Always);
#endif
ImVec4 solidColor =
ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
ImGui::PushStyleColor(ImGuiCol_WindowBg,
@@ -388,31 +400,81 @@ struct GUIListener : public Ogre::RenderTargetListener {
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_NoBringToFrontOnFocus |
0);
ImGui::PushFont(bigFont);
struct buttons {
std::string label;
std::function<void(bool)> callback;
};
bool new_game = false, cont = false,
load_game = false, opts = false,
quit = false;
struct buttons buttons_data[] = {
{ "New Game",
[&](bool pressed) {
new_game = true;
} },
{ "Continue",
[&](bool pressed) { cont = true; } },
{ "Load Game",
[&](bool pressed) {
load_game = true;
} },
{ "Options",
[&](bool pressed) { opts = true; } },
{ "Quit###quit",
[&](bool pressed) { quit = true; } },
};
ImVec2 size = ImGui::GetWindowSize();
float window_width = size.x;
float window_height = size.y;
ImGui::PushFont(bigFont);
ImGui::TextWrapped("%s", "Booo!!!!");
bool pressed = false;
bool new_game = false, cont = false,
load_game = false, opts = false,
quit = false;
ImGui::SetCursorPosY(size.y / 2.0f - 300.0f);
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
new_game = ImGui::Button("New Game");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
cont = ImGui::Button("Continue");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
load_game = ImGui::Button("Load Game");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
opts = ImGui::Button("Options");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
quit = ImGui::Button("Quit###quit");
float extra_pixels = 20.0f;
float button_width = 0.0f;
float buttons_height = 0.0f;
for (const struct buttons &b : buttons_data) {
ImVec2 text_size = ImGui::CalcTextSize(
b.label.c_str());
float text_width = text_size.x;
float text_height = text_size.y;
float bwidth =
text_width +
(ImGui::GetStyle()
.FramePadding.x *
2.0f) +
extra_pixels;
if (button_width < bwidth)
button_width = bwidth;
buttons_height +=
text_height +
(ImGui::GetStyle()
.FramePadding.y *
2.0f);
}
ImGui::SetCursorPosY(
(window_height - buttons_height) *
0.5f);
for (const struct buttons &b : buttons_data) {
ImGui::SetCursorPosX(
(window_width - button_width) *
0.5f);
if (ImGui::Button(b.label.c_str(),
ImVec2(button_width,
0)))
b.callback(true);
}
bool pressed = false;
pressed = new_game || cont || load_game ||
opts || quit;
ImGui::PopFont();
ImGui::Spacing();
ImGui::End();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::PopStyleVar();
if (quit)
Ogre::Root::getSingleton()
.queueEndRendering();
@@ -686,7 +748,9 @@ void GUIModule::configure()
const App &app = ECS::get<App>();
if (gui.mGuiOverlay)
return;
float vpScale = window.dpi / 96 * window.window->getWidth() / 1600.0f;
float vpScale = window.dpi / 96;
if (vpScale < 1.0f)
vpScale = 1.0f;
Ogre::OverlayManager::getSingleton().setPixelRatio(vpScale);
std::cout << "GUI configure\n";
OgreAssert(app.mGuiOverlay, "No ImGUI overlay");