diff --git a/Game.cpp b/Game.cpp index 6b68874..1cafb76 100644 --- a/Game.cpp +++ b/Game.cpp @@ -174,6 +174,7 @@ class KeyboardListener : public OgreBites::InputListener { uint32_t control; ECS::Vector2 mouse; + ECS::Vector2 mouse_abs; float wheel_y; bool mouse_moved, wheel_moved; float mInitDelay; @@ -187,6 +188,7 @@ public: , fast(false) , control(0) , mouse({ 0, 0 }) + , mouse_abs({ 0, 0 }) , wheel_y(0.0f) , mouse_moved(false) , wheel_moved(false) @@ -264,6 +266,8 @@ public: 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; @@ -604,7 +608,7 @@ public: ECS::get() .observer("UpdateGrab") .event(flecs::OnSet) - .each([this](flecs::entity e, ECS::GUI &gui) { + .each([this](ECS::GUI &gui) { if (gui.grabChanged) setWindowGrab(gui.grab); std::cout << "grab: " << gui.grab << "\n"; @@ -614,7 +618,7 @@ public: ECS::get() .observer("UpdateInputListener") .event(flecs::OnSet) - .each([this](flecs::entity e, ECS::App &app) { + .each([this](ECS::App &app) { if (app.mInput) removeInputListener(app.mInput); delete app.mInput; @@ -774,6 +778,7 @@ void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt) ECS::Input &input = ECS::get().get_mut(); input.control = control; input.mouse = mouse; + input.mouse_abs = mouse_abs; mouse.x = 0; mouse.y = 0; input.wheel_y = wheel_y; diff --git a/src/editor/CMakeLists.txt b/src/editor/CMakeLists.txt index ad9d5b1..198d7ad 100644 --- a/src/editor/CMakeLists.txt +++ b/src/editor/CMakeLists.txt @@ -30,6 +30,7 @@ target_link_libraries(editor PRIVATE OgreMain GameData ) +target_include_directories(editor PUBLIC .) add_executable(Editor main.cpp) target_link_libraries(Editor PRIVATE diff --git a/src/editor/EditorGizmoModule.cpp b/src/editor/EditorGizmoModule.cpp index a2397a3..7028d84 100644 --- a/src/editor/EditorGizmoModule.cpp +++ b/src/editor/EditorGizmoModule.cpp @@ -21,6 +21,8 @@ createVertexColorNoDepthMaterial(const std::string &materialName) // Disable dynamic lighting, so only vertex colors are used pass->setLightingEnabled(false); pass->setCullingMode(Ogre::CULL_NONE); + pass->setPolygonModeOverrideable(false); + pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); // Set the material to use vertex colors for diffuse, ambient, and specular components pass->setVertexColourTracking(Ogre::TVC_DIFFUSE | Ogre::TVC_AMBIENT | @@ -28,11 +30,11 @@ createVertexColorNoDepthMaterial(const std::string &materialName) // Disable depth checking (so it renders regardless of what's already in the depth buffer) // pass->setDepthCheckEnabled(false); - pass->setDepthCheckEnabled(true); + pass->setDepthCheckEnabled(false); // Disable depth writing (so subsequent objects are not occluded by this one) // pass->setDepthWriteEnabled(false); - pass->setDepthWriteEnabled(true); + pass->setDepthWriteEnabled(false); // Optional: Set scene blending to alpha blending if you use vertex alpha // pass->setSceneBlending(Ogre::SBT_ALPHA_BLEND); @@ -56,19 +58,21 @@ EditorGizmoModule::EditorGizmoModule(flecs::world &ecs) ecs.observer("SetupGizmo") .event(flecs::OnSet) .each([](const EditorDebugMaterial &mdbg, EditorGizmo &gizmo) { + const int size = 20; + gizmo.gizmo->setBufferUsage(Ogre::HBU_CPU_TO_GPU); gizmo.gizmo->begin(mdbg.material, Ogre::RenderOperation::OT_LINE_LIST); gizmo.gizmo->position(Ogre::Vector3(0, 0, 0)); gizmo.gizmo->colour(Ogre::ColourValue(0, 0, 1, 1)); - gizmo.gizmo->position(Ogre::Vector3(0, 0, 1)); + gizmo.gizmo->position(Ogre::Vector3(0, 0, size)); gizmo.gizmo->colour(Ogre::ColourValue(0, 0, 1, 1)); gizmo.gizmo->position(Ogre::Vector3(0, 0, 0)); gizmo.gizmo->colour(Ogre::ColourValue(0, 1, 0, 1)); - gizmo.gizmo->position(Ogre::Vector3(0, 1, 0)); + gizmo.gizmo->position(Ogre::Vector3(0, size, 0)); gizmo.gizmo->colour(Ogre::ColourValue(0, 1, 0, 1)); gizmo.gizmo->position(Ogre::Vector3(0, 0, 0)); gizmo.gizmo->colour(Ogre::ColourValue(1, 0, 0, 1)); - gizmo.gizmo->position(Ogre::Vector3(1, 0, 0)); + gizmo.gizmo->position(Ogre::Vector3(size, 0, 0)); gizmo.gizmo->colour(Ogre::ColourValue(1, 0, 0, 1)); gizmo.gizmo->end(); }); diff --git a/src/editor/EditorInputModule.cpp b/src/editor/EditorInputModule.cpp index ba9cbea..8dc9234 100644 --- a/src/editor/EditorInputModule.cpp +++ b/src/editor/EditorInputModule.cpp @@ -2,6 +2,8 @@ #include #include "Components.h" #include "GameData.h" +#include "PhysicsModule.h" +#include "EditorGizmoModule.h" #include "EditorInputModule.h" namespace ECS @@ -115,6 +117,73 @@ EditorInputModule::EditorInputModule(flecs::world &ecs) input.fast = true; else input.fast = false; + if (input.control & 256) { + /* click */ + std::vector objects; + Ogre::Viewport *viewport = + ECS::get() + .mCamera->getViewport(); + Ogre::Real nx = + static_cast( + input.mouse_abs.x) / + (float)viewport->getActualWidth(); + Ogre::Real ny = + static_cast( + input.mouse_abs.y) / + (float)viewport->getActualHeight(); + Ogre::Ray ray = + ECS::get() + .mCamera->getCameraToViewportRay( + nx, ny); + + Ogre::Vector3 position; + Ogre::Plane horizontalZeroPlane( + Ogre::Vector3::UNIT_Y, 0.0f); + std::cout << "ray: " << ray.getOrigin() << " " + << ray.getDirection() << std::endl; + Ogre::RayTestResult ogreResult = + ray.intersects(horizontalZeroPlane); + if (ogreResult.first) { + position = + ray.getPoint(ogreResult.second); + Ogre::Vector3 position2; + bool hit = PhysicsModule::raycastQuery( + ray.getOrigin(), + ray.getPoint(2000.0f), + position2); + if (hit) { + float d1 = + ray.getOrigin() + .squaredDistance( + position); + float d2 = + ray.getOrigin() + .squaredDistance( + position2); + if (d2 < d1) + position = position2; + } + std::cout << "HIT!: " << position + << std::endl; + ECS::get() + .sceneNode->_setDerivedPosition( + position); + } else { + bool hit = PhysicsModule::raycastQuery( + ray.getOrigin(), + ray.getPoint(2000.0f), + position); + if (hit) { + std::cout + << "HIT!: " << position + << std::endl; + ECS::get() + .sceneNode + ->_setDerivedPosition( + position); + } + } + } if (input.control & 512) { if (input.mouse_moved) { updateCameraGoal(camera, diff --git a/src/editor/main.cpp b/src/editor/main.cpp index 44843c8..b07b9af 100644 --- a/src/editor/main.cpp +++ b/src/editor/main.cpp @@ -162,7 +162,7 @@ class KeyboardListener : public OgreBites::InputListener { App *mApp; uint32_t control; - ECS::Vector2 mouse; + ECS::Vector2 mouse, mouse_abs; float wheel_y; bool mouse_moved, wheel_moved; float mInitDelay; @@ -176,6 +176,7 @@ public: , fast(false) , control(0) , mouse({ 0, 0 }) + , mouse_abs({ 0, 0 }) , wheel_y(0.0f) , mouse_moved(false) , wheel_moved(false) @@ -255,6 +256,8 @@ public: { 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; @@ -627,6 +630,7 @@ public: mScnMgr->getRootSceneNode()->createChildSceneNode( "EditorGizmoNode"); gizmoNode->attachObject(manualObj.get()); + manualObj->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); ECS::get().set({ manualObj, gizmoNode }); #if 0 ECS::get() @@ -758,6 +762,7 @@ void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt) ECS::Input &input = ECS::get().get_mut(); input.control = control; input.mouse = mouse; + input.mouse_abs = mouse_abs; mouse.x = 0; mouse.y = 0; input.wheel_y = wheel_y; @@ -769,6 +774,7 @@ void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt) ECS::Input &input = ECS::get().get_mut(); input.control = control; input.mouse = mouse; + input.mouse_abs = mouse_abs; mouse.x = 0; mouse.y = 0; input.wheel_y = wheel_y; diff --git a/src/gamedata/CMakeLists.txt b/src/gamedata/CMakeLists.txt index 436d214..f5c3668 100644 --- a/src/gamedata/CMakeLists.txt +++ b/src/gamedata/CMakeLists.txt @@ -8,6 +8,6 @@ add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp Sun VehicleManagerModule.cpp AppModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp) target_link_libraries(GameData PUBLIC lua flecs::flecs_static OgreMain OgreBites OgrePaging OgreTerrain OgreOverlay - PRIVATE sceneloader world-build physics) + PRIVATE sceneloader world-build physics editor) target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${BULLET_INCLUDE_DIR} ../luaaa) target_compile_definitions(GameData PRIVATE FLECS_CPP_NO_AUTO_REGISTRATION) diff --git a/src/gamedata/Components.h b/src/gamedata/Components.h index d29b4a1..d2839db 100644 --- a/src/gamedata/Components.h +++ b/src/gamedata/Components.h @@ -39,6 +39,7 @@ struct Input { uint32_t control_prev; Vector3 motion; Vector2 mouse; + Vector2 mouse_abs; float wheel_y; bool mouse_moved; bool wheel_moved; diff --git a/src/gamedata/GUIModule.cpp b/src/gamedata/GUIModule.cpp index c997ce8..3180433 100644 --- a/src/gamedata/GUIModule.cpp +++ b/src/gamedata/GUIModule.cpp @@ -14,6 +14,7 @@ #include "LuaData.h" #include "AppModule.h" #include "TerrainModule.h" +#include "EditorGizmoModule.h" #include "GUIModule.h" namespace ECS { @@ -480,7 +481,6 @@ struct EditorGUIListener : public Ogre::RenderTargetListener { EditorGUIListener(Ogre::ImGuiOverlay *overlay) : Ogre::RenderTargetListener() { - std::cout << "WAAAAAAA!!!!!" << std::endl; _midFont = createFont("midFont", "General", "Jupiteroid-Regular.ttf", 18.0f); _smallFont = createFont("smallFont", "General", @@ -741,13 +741,11 @@ struct EditorGUIListener : public Ogre::RenderTargetListener { x + j, y + i); if (terrain && terrain->isLoaded()) { terrain->dirty(); - terrain->updateDerivedData(true); - terrain->updateGeometry(); + terrain->update(true); + terrain->waitForDerivedProcesses(); } } - ECS::get().mTerrainGroup->updateDerivedData(true); - ECS::get().mTerrainGroup->updateGeometry(); ECS::get().mTerrainGroup->update(true); } void setCameraPos() @@ -770,12 +768,7 @@ struct EditorGUIListener : public Ogre::RenderTargetListener { cameraPos = ECS::get().mCameraGoal->_getDerivedPosition(); ECS::get().mCameraNode->_setDerivedPosition(cameraPos); - std::cout << cameraPos << std::endl; - std::cout << worldPos << std::endl; - std::cout << selected_x << " " << selected_y << std::endl; - ECS::get().mTerrainGroup->updateDerivedData(true); - ECS::get().mTerrainGroup->updateGeometry(); - ECS::get().mTerrainGroup->update(true); + updateHeightmap(); } void worldMapView() { @@ -798,9 +791,6 @@ struct EditorGUIListener : public Ogre::RenderTargetListener { selected_x = TerrainModule::get_img_x(worldPos.x); selected_y = TerrainModule::get_img_y(worldPos.z); locationSelected = true; - std::cout << worldPos << std::endl; - std::cout << selected_x << " " << selected_y - << std::endl; OgreAssert(selected_x >= 0 && selected_x < worldMap->getWidth(), "mix width"); @@ -830,10 +820,6 @@ struct EditorGUIListener : public Ogre::RenderTargetListener { top_x = item_absolute_pos.x + 5; top_y = item_absolute_pos.y + 5; bool hovered = false; -#if 0 - pos_x = mouse_absolute_pos.x - item_absolute_pos.x - 5; - pos_y = mouse_absolute_pos.y - item_absolute_pos.y - 5; -#endif if (ImGui::IsItemHovered()) { ImVec2 mouse_absolute_pos = ImGui::GetMousePos(); ImVec2 item_absolute_pos = ImGui::GetItemRectMin(); @@ -893,9 +879,6 @@ struct EditorGUIListener : public Ogre::RenderTargetListener { worldMapImage.getColourAt(selected_x, selected_y, 0).r); if (ImGui::Button("Update terrain")) { ECS::get().mTerrainGroup->update(true); - ECS::get().mTerrainGroup->updateDerivedData( - true); - ECS::get().mTerrainGroup->updateGeometry(); } ImGui::SliderFloat("Strength...", &strength, 0.0f, 0.2f); ImGui::SliderInt("Size", &size, 0, 8); diff --git a/src/gamedata/PhysicsModule.cpp b/src/gamedata/PhysicsModule.cpp index 092a8cb..e4686f3 100644 --- a/src/gamedata/PhysicsModule.cpp +++ b/src/gamedata/PhysicsModule.cpp @@ -748,6 +748,13 @@ void PhysicsModule::controlPhysics(flecs::entity e, bool enable) e.remove(); } } +bool PhysicsModule::raycastQuery(const Ogre::Vector3 &startPos, + const Ogre::Vector3 &endPos, + Ogre::Vector3 &position) +{ + return JoltPhysicsWrapper::getSingleton().raycastQuery(startPos, endPos, + position); +} bool WaterBody::isInWater(const JPH::BodyID &id) const { flecs::entity e = diff --git a/src/gamedata/PhysicsModule.h b/src/gamedata/PhysicsModule.h index 527ddbb..9bc63f0 100644 --- a/src/gamedata/PhysicsModule.h +++ b/src/gamedata/PhysicsModule.h @@ -57,6 +57,9 @@ struct PhysicsModule { const Ogre::Vector3 &scale, int sampleCount); static void controlPhysics(flecs::entity e, bool enable); + static bool raycastQuery(const Ogre::Vector3 &startPos, + const Ogre::Vector3 &endPos, + Ogre::Vector3 &position); }; } #endif diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 7d2235c..e5aa843 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -1463,6 +1466,22 @@ public: #endif } } + bool raycastQuery(Ogre::Vector3 startPoint, Ogre::Vector3 endPoint, + Ogre::Vector3 &position) + { + int i; + Ogre::Vector3 direction = endPoint - startPoint; + JPH::RRayCast ray{ JoltPhysics::convert(startPoint), + JoltPhysics::convert(direction) }; + JPH::RayCastResult hit; + bool hadHit = physics_system.GetNarrowPhaseQuery().CastRay( + ray, hit, {}, + JPH::SpecifiedObjectLayerFilter(Layers::NON_MOVING)); + if (hadHit) + position = JoltPhysics::convert( + ray.GetPointOnRay(hit.mFraction)); + return hadHit; + } }; void physics() @@ -1742,5 +1761,11 @@ void JoltPhysicsWrapper::removeContactListener(const JPH::BodyID &id) { contacts.removeListener(id); } +bool JoltPhysicsWrapper::raycastQuery(Ogre::Vector3 startPoint, + Ogre::Vector3 endPoint, + Ogre::Vector3 &position) +{ + return phys->raycastQuery(startPoint, endPoint, position); +} template <> JoltPhysicsWrapper *Ogre::Singleton::msSingleton = 0; diff --git a/src/physics/physics.h b/src/physics/physics.h index 8e9996b..68fed6d 100644 --- a/src/physics/physics.h +++ b/src/physics/physics.h @@ -204,5 +204,7 @@ public: ContactReport &report)> listener); void removeContactListener(const JPH::BodyID &id); + bool raycastQuery(Ogre::Vector3 startPoint, Ogre::Vector3 endPoint, + Ogre::Vector3 &position); }; #endif