add entities raycast
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "../data/dynamic_util.hpp"
|
||||
#include "../assets/Assets.hpp"
|
||||
#include "../world/Level.hpp"
|
||||
#include "../maths/rays.hpp"
|
||||
#include "../content/Content.hpp"
|
||||
#include "../physics/Hitbox.hpp"
|
||||
#include "../physics/PhysicsSolver.hpp"
|
||||
@@ -185,6 +186,37 @@ void Entities::loadEntity(const dynamic::Map_sptr& map, Entity entity) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Entities::RaycastResult> Entities::rayCast(
|
||||
glm::vec3 start, glm::vec3 dir, float maxDistance, entityid_t ignore
|
||||
) {
|
||||
Ray ray(start, dir);
|
||||
auto view = registry.view<EntityId, Transform, Rigidbody>();
|
||||
|
||||
entityid_t foundUID = 0;
|
||||
glm::ivec3 foundNormal;
|
||||
|
||||
for (auto [entity, eid, transform, body] : view.each()) {
|
||||
if (eid.uid == ignore) {
|
||||
continue;
|
||||
}
|
||||
auto& hitbox = body.hitbox;
|
||||
glm::ivec3 normal;
|
||||
double distance;
|
||||
if (ray.intersectAABB(
|
||||
glm::vec3(), hitbox.getAABB(), maxDistance, normal, distance) > RayRelation::None) {
|
||||
|
||||
foundUID = eid.uid;
|
||||
foundNormal = normal;
|
||||
maxDistance = static_cast<float>(distance);
|
||||
}
|
||||
}
|
||||
if (foundUID) {
|
||||
return Entities::RaycastResult {foundUID, foundNormal, maxDistance};
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void Entities::loadEntities(dynamic::Map_sptr root) {
|
||||
auto list = root->list("data");
|
||||
for (size_t i = 0; i < list->size(); i++) {
|
||||
|
||||
@@ -160,6 +160,12 @@ class Entities {
|
||||
|
||||
void preparePhysics();
|
||||
public:
|
||||
struct RaycastResult {
|
||||
entityid_t entity;
|
||||
glm::ivec3 normal;
|
||||
float distance;
|
||||
};
|
||||
|
||||
Entities(Level* level);
|
||||
|
||||
void clean();
|
||||
@@ -184,6 +190,16 @@ public:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/// @brief Entities raycast. No blocks check included, use combined with
|
||||
/// Chunks.rayCast
|
||||
/// @param start Ray start
|
||||
/// @param dir Ray direction normalized vector
|
||||
/// @param maxDistance Max ray length
|
||||
/// @param ignore Ignored entity ID
|
||||
/// @return An optional structure containing entity, normal and distance
|
||||
std::optional<RaycastResult> rayCast(
|
||||
glm::vec3 start, glm::vec3 dir, float maxDistance, entityid_t ignore=-1);
|
||||
|
||||
void loadEntities(dynamic::Map_sptr map);
|
||||
void loadEntity(const dynamic::Map_sptr& map);
|
||||
void loadEntity(const dynamic::Map_sptr& map, Entity entity);
|
||||
|
||||
@@ -60,6 +60,7 @@ Hitbox* Player::getHitbox() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#include "EntityDef.hpp"
|
||||
void Player::updateInput(PlayerInput& input, float delta) {
|
||||
auto hitbox = getHitbox();
|
||||
if (hitbox == nullptr) {
|
||||
|
||||
@@ -33,12 +33,13 @@ struct PlayerInput {
|
||||
bool flight : 1;
|
||||
};
|
||||
|
||||
struct BlockSelection {
|
||||
voxel vox {0, {}};
|
||||
struct CursorSelection {
|
||||
voxel vox {BLOCK_VOID, {}};
|
||||
glm::ivec3 position {};
|
||||
glm::ivec3 actualPosition {};
|
||||
glm::ivec3 normal {};
|
||||
glm::vec3 hitPosition;
|
||||
entityid_t entity = ENTITY_NONE;
|
||||
};
|
||||
|
||||
class Player : public Object, public Serializable {
|
||||
@@ -56,7 +57,7 @@ public:
|
||||
std::shared_ptr<Camera> currentCamera;
|
||||
bool debug = false;
|
||||
glm::vec3 cam {};
|
||||
BlockSelection selection {};
|
||||
CursorSelection selection {};
|
||||
|
||||
Player(Level* level, glm::vec3 position, float speed,
|
||||
std::shared_ptr<Inventory> inv, entityid_t eid);
|
||||
|
||||
Reference in New Issue
Block a user