Made cursor work

This commit is contained in:
2025-12-07 20:09:41 +03:00
parent 44896ed0d9
commit 33fc237793
12 changed files with 136 additions and 30 deletions

View File

@@ -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<ECS::GUI>("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<ECS::App>("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<ECS::Input>();
input.control = control;
input.mouse = mouse;
input.mouse_abs = mouse_abs;
mouse.x = 0;
mouse.y = 0;
input.wheel_y = wheel_y;

View File

@@ -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

View File

@@ -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<const EditorDebugMaterial, EditorGizmo>("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();
});

View File

@@ -2,6 +2,8 @@
#include <Ogre.h>
#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<Ogre::MovableObject *> objects;
Ogre::Viewport *viewport =
ECS::get<Camera>()
.mCamera->getViewport();
Ogre::Real nx =
static_cast<Ogre::Real>(
input.mouse_abs.x) /
(float)viewport->getActualWidth();
Ogre::Real ny =
static_cast<Ogre::Real>(
input.mouse_abs.y) /
(float)viewport->getActualHeight();
Ogre::Ray ray =
ECS::get<Camera>()
.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<EditorGizmo>()
.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<EditorGizmo>()
.sceneNode
->_setDerivedPosition(
position);
}
}
}
if (input.control & 512) {
if (input.mouse_moved) {
updateCameraGoal(camera,

View File

@@ -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<ECS::EditorGizmo>({ manualObj, gizmoNode });
#if 0
ECS::get()
@@ -758,6 +762,7 @@ void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt)
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;
@@ -769,6 +774,7 @@ void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt)
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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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<Terrain>().mTerrainGroup->updateDerivedData(true);
ECS::get<Terrain>().mTerrainGroup->updateGeometry();
ECS::get<Terrain>().mTerrainGroup->update(true);
}
void setCameraPos()
@@ -770,12 +768,7 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
cameraPos =
ECS::get<Camera>().mCameraGoal->_getDerivedPosition();
ECS::get<Camera>().mCameraNode->_setDerivedPosition(cameraPos);
std::cout << cameraPos << std::endl;
std::cout << worldPos << std::endl;
std::cout << selected_x << " " << selected_y << std::endl;
ECS::get<Terrain>().mTerrainGroup->updateDerivedData(true);
ECS::get<Terrain>().mTerrainGroup->updateGeometry();
ECS::get<Terrain>().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<Terrain>().mTerrainGroup->update(true);
ECS::get<Terrain>().mTerrainGroup->updateDerivedData(
true);
ECS::get<Terrain>().mTerrainGroup->updateGeometry();
}
ImGui::SliderFloat("Strength...", &strength, 0.0f, 0.2f);
ImGui::SliderInt("Size", &size, 0, 8);

View File

@@ -748,6 +748,13 @@ void PhysicsModule::controlPhysics(flecs::entity e, bool enable)
e.remove<InWater>();
}
}
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 =

View File

@@ -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

View File

@@ -30,6 +30,9 @@
#include <Jolt/Physics/Collision/Shape/HeightFieldShape.h>
#include <Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h>
#include <Jolt/Physics/Collision/ContactListener.h>
#include <Jolt/Physics/Collision/RayCast.h>
#include <Jolt/Physics/Collision/CastResult.h>
#include <Jolt/Physics/Collision/CollisionCollectorImpl.h>
#include <Jolt/Physics/Body/BodyCreationSettings.h>
#include <Jolt/Physics/Body/BodyActivationListener.h>
#include <Jolt/Renderer/DebugRendererSimple.h>
@@ -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<JoltPhysicsWrapper>::msSingleton = 0;

View File

@@ -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