diff --git a/.vscode/tasks.json b/.vscode/tasks.json index a08321a..0c5f9a3 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -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" } ] } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2590a54..72a6d1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,10 @@ option(OGRE_DYNAMIC "Build against dynamic ogre" ON) #) file(GLOB TERRAIN_SRC ${CMAKE_SOURCE_DIR}/src/terrain/*.cpp) file(GLOB WATER_SRC ${CMAKE_SOURCE_DIR}/water/*.cpp) +set(CHARACTERS_SRC + ${CMAKE_SOURCE_DIR}/src/characters/character.cpp + ${CMAKE_SOURCE_DIR}/src/characters/controller.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 @@ -76,14 +80,14 @@ target_link_libraries(0_Bootstrap OgreBites OgreBullet OgrePaging ${BULLET_DYNAM target_include_directories(0_Bootstrap PUBLIC OgreBites OgrePaging OgreBullet) add_dependencies(0_Bootstrap stage_files) -add_executable(Editor Editor.cpp ${TERRAIN_SRC} ${WATER_SRC}) +add_executable(Editor Editor.cpp ${TERRAIN_SRC} ${WATER_SRC} ${CHARACTERS_SRC}) target_link_libraries(Editor OgreBites OgreBullet OgrePaging OgreTerrain OgreMeshLodGenerator ${OgreProcedural_LIBRARIES} ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY}) target_include_directories(Editor PUBLIC OgreBites OgrePaging OgreBullet OgreTerrain OgreMeshLodGenerator ${OgreProcedural_INCLUDE_DIRS}) -add_dependencies(Editor stage_files import_buildings import_water_stuff) -add_executable(Game Game.cpp ${TERRAIN_SRC} ${WATER_SRC}) +add_dependencies(Editor stage_files import_buildings import_water_stuff import_vehicles) +add_executable(Game Game.cpp ${TERRAIN_SRC} ${WATER_SRC} ${CHARACTERS_SRC}) target_link_libraries(Game OgreBites OgreBullet OgrePaging OgreTerrain OgreMeshLodGenerator ${OgreProcedural_LIBRARIES} ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY}) target_include_directories(Game PUBLIC OgreBites OgrePaging OgreBullet OgreTerrain OgreMeshLodGenerator ${OgreProcedural_INCLUDE_DIRS}) -add_dependencies(Game stage_files import_buildings import_water_stuff) +add_dependencies(Game stage_files import_buildings import_water_stuff import_vehicles) 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}) @@ -106,10 +110,29 @@ foreach(BUILDING_FILE ${BUILDINGS_SRC}) list(APPEND BUILDING_OUTPUT_FILES ${BUILDING_OUTPUT_FILE}) 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(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 diff --git a/Game.cpp b/Game.cpp index 3442898..0d1589b 100644 --- a/Game.cpp +++ b/Game.cpp @@ -12,6 +12,7 @@ #include "src/terrain/terrain.h" #include "water/water.h" +#include "src/characters/controller.h" class App; class SkyRenderer : public Ogre::SceneManager::Listener { protected: @@ -248,6 +249,7 @@ class App : public OgreBites::ApplicationContext { std::unique_ptr mDbgDraw; Ogre::SceneNode *mCameraNode, *mCameraPivot, *mCameraGoal; Ogre::Camera *mCamera; + CharacterController *mCharacterController; Ogre::Real mPivotPitch; Ogre::SceneManager *mScnMgr; OgreBites::InputListenerChain mInput; @@ -284,9 +286,12 @@ class App : public OgreBites::ApplicationContext { // std::cout << "Escape!\n"; // Ogre::Root::getSingleton().queueEndRendering(); mApp->setWindowGrab(false); + return true; } - if (evt.keysym.sym == OgreBites::SDLK_SPACE) + return 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') @@ -304,6 +309,7 @@ class App : public OgreBites::ApplicationContext { { if (gui_active) return false; + return false; if (evt.keysym.sym == 'w' && motion.z < 0.0f) motion.z = 0.0f; if (evt.keysym.sym == 's' && motion.z > 0.0f) @@ -320,6 +326,7 @@ class App : public OgreBites::ApplicationContext { { if (gui_active) return false; + return false; // update camera goal based on mouse movement mApp->updateCameraGoal(-0.18f * evt.xrel, -0.12f * evt.yrel, 0); @@ -329,6 +336,7 @@ class App : public OgreBites::ApplicationContext { { if (gui_active) return false; + return false; // update camera goal based on mouse movement mApp->updateCameraGoal(0, 0, -0.15f * evt.y); return true; @@ -380,6 +388,7 @@ public: , mDynWorld(new Ogre::Bullet::DynamicsWorld( Ogre::Vector3(0, -9.8, 0))) , m_terrain(mDynWorld->getBtWorld()) + , mCharacterController(nullptr) { } virtual ~App() @@ -459,18 +468,30 @@ public: std::cout << "Set up water" << "\n"; m_water.createWater(getRenderWindow(), mCamera); std::cout << "Set up cursor" << "\n"; - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + Ogre::ResourceGroupManager::getSingleton() + .initialiseAllResourceGroups(); // OgreBites::ApplicationContext::loadResources(); - setupCursor(); + // setupCursor(); + setupPlayer(); std::cout << "Create content" << "\n"; createContent(); std::cout << "Setup terrain" << "\n"; setupTerrain(); m_water.init(); } + void setupPlayer() + { + mCharacterController = new CharacterController( + mCameraNode, mCamera, mScnMgr, mDynWorld.get()); +#if 0 + /* FIXME: make proper player setup */ + Ogre::Entity *ent = + mScnMgr->createEntity("PlayerBoat", "boat.glb"); + mCameraPivot->attachObject(ent); +#endif + } void setupCursor() { - // mKeyDirection = Ogre::Vector3::ZERO; // mVerticalVelocity = 0; Ogre::ManualObject *mobj = @@ -515,6 +536,7 @@ public: { if (delta == 0.0f) return; +#if 0 Ogre::Vector3 move(mCameraNode->getOrientation().zAxis() * mKbd.motion.z); move += Ogre::Vector3(mCameraNode->getOrientation().xAxis() * @@ -535,11 +557,13 @@ public: // mKbd.motion = Ogre::Vector3(0, 0, 0); // if (move.squaredLength() > 0) // std::cout << move << "\n"; +#endif } void updateCamera(Ogre::Real delta) { if (delta == 0.0f) return; +#if 0 // place the camera pivot roughly at the character's shoulder // mCameraPivot->setPosition(mBodyNode->getPosition() + // Ogre::Vector3::UNIT_Y * CAM_HEIGHT); @@ -555,10 +579,12 @@ public: // always look at the pivot mCameraNode->lookAt(mCameraPivot->_getDerivedPosition(), Ogre::Node::TS_PARENT); +#endif } void updateCameraGoal(Ogre::Real deltaYaw, Ogre::Real deltaPitch, Ogre::Real deltaZoom) { +#if 0 mCameraPivot->yaw(Ogre::Degree(deltaYaw), Ogre::Node::TS_PARENT); if (!(mPivotPitch + deltaPitch > 25 && deltaPitch > 0) && @@ -585,6 +611,7 @@ public: if (h + 10 > mh.y) mCameraGoal->translate(0, 10.0f * deltaZoom, distChange, Ogre::Node::TS_LOCAL); +#endif } Ogre::SceneNode *mSunGoal; Ogre::SceneNode *mSunNode; @@ -659,7 +686,8 @@ public: m_edit_ui.initGui(); createSun(); mInput = OgreBites::InputListenerChain( - { getImGuiInputListener(), &mKbd }); + { getImGuiInputListener(), &mKbd, + mCharacterController }); addInputListener(&mInput); getRoot()->addFrameListener(&mKbd); // mTrayMgr->showCursor(); diff --git a/resources.cfg b/resources.cfg index 1a5dd85..2db23a7 100644 --- a/resources.cfg +++ b/resources.cfg @@ -20,6 +20,7 @@ FileSystem=resources/terrain [General] FileSystem=skybox FileSystem=resources/buildings +FileSystem=resources/vehicles FileSystem=resources/debug FileSystem=water # PBR media must come before the scripts that reference it diff --git a/src/vehicles/vehicle.h b/src/vehicles/vehicle.h new file mode 100644 index 0000000..d5196b2 --- /dev/null +++ b/src/vehicles/vehicle.h @@ -0,0 +1,2 @@ +class Vehicle { +};