Action nodes support and lots of other updates

This commit is contained in:
2026-01-19 00:07:03 +03:00
parent f86e7fd96c
commit 4b24d85123
34 changed files with 7810 additions and 3488 deletions

View File

@@ -0,0 +1,114 @@
#include <nanoflann.hpp>
#include <vector>
#include <iostream>
#include "Components.h"
#include "GameData.h"
#include "PlayerActionModule.h"
namespace ECS
{
struct OgreVector3Adaptor {
const std::vector<ActionNodeList::ActionNode> &nodes;
OgreVector3Adaptor(const std::vector<ActionNodeList::ActionNode> &nodes)
: nodes(nodes)
{
}
// Required by nanoflann: Number of data points
inline size_t kdtree_get_point_count() const
{
return nodes.size();
}
// Required by nanoflann: Returns the distance between the vector and a point
// Using squared distance is standard for performance
inline float kdtree_get_pt(const size_t idx, const size_t dim) const
{
return nodes[idx].position[dim];
}
// Optional: bounding box optimization (return false if not implemented)
template <class BBOX> bool kdtree_get_bbox(BBOX & /*bb*/) const
{
return false;
}
};
typedef nanoflann::KDTreeSingleIndexAdaptor<
nanoflann::L2_Simple_Adaptor<float, OgreVector3Adaptor>,
OgreVector3Adaptor, 3 /* dimensionality */
>
OgreKDTree;
struct ActionNodeList::indexObject {
OgreVector3Adaptor adaptor;
OgreKDTree index;
indexObject(const std::vector<ActionNodeList::ActionNode> &nodes)
: adaptor(nodes)
, index(3, adaptor,
nanoflann::KDTreeSingleIndexAdaptorParams(10))
{
}
};
PlayerActionModule::PlayerActionModule(flecs::world &ecs)
{
ecs.module<PlayerActionModule>();
ecs.component<ActionNodeList>()
.on_add([](flecs::entity e, ActionNodeList &alist) {
alist.dirty = true;
alist.nodes.reserve(1000);
})
.add(flecs::Singleton);
#if 0
ecs.system<ActionNodeList>("testNodeList")
.kind(flecs::OnUpdate)
.each([](ActionNodeList &list) {
if (list.nodes.size() > 0) {
Ogre::Vector3 queryPos =
ECS::get<Camera>()
.mCameraNode
->_getDerivedPosition();
std::vector<size_t> points;
list.query(queryPos, points);
for (auto &p : points)
std::cout << p << std::endl
<< list.nodes[p].props.dump()
<< std::endl;
OgreAssert(points.size() == 0, "got result");
}
});
#endif
}
void ActionNodeList::build()
{
indexObj = std::make_shared<ActionNodeList::indexObject>(nodes);
indexObj->index.buildIndex();
dirty = false;
std::cout << "index built" << std::endl;
}
bool ActionNodeList::query(const Ogre::Vector3 &position,
std::vector<size_t> &points)
{
if (dirty)
build();
std::vector<size_t> tmppoints;
std::vector<float> tmpdistances;
points.clear();
points.reserve(4);
tmppoints.resize(4);
tmpdistances.resize(4);
nanoflann::KNNResultSet<float> resultSet(4);
resultSet.init(tmppoints.data(), tmpdistances.data());
bool ret = indexObj->index.findNeighbors(resultSet, &position.x,
nanoflann::SearchParameters());
int i;
for (i = 0; i < resultSet.size(); i++)
if (tmpdistances[i] < 25.0f)
points.push_back(tmppoints[i]);
return ret;
}
}