add entities raycast
This commit is contained in:
@@ -19,6 +19,7 @@ inline const std::string ENGINE_VERSION_STRING = "0.22";
|
|||||||
|
|
||||||
inline constexpr blockid_t BLOCK_AIR = 0;
|
inline constexpr blockid_t BLOCK_AIR = 0;
|
||||||
inline constexpr itemid_t ITEM_EMPTY = 0;
|
inline constexpr itemid_t ITEM_EMPTY = 0;
|
||||||
|
inline constexpr entityid_t ENTITY_NONE = 0;
|
||||||
|
|
||||||
inline constexpr int CHUNK_W = 16;
|
inline constexpr int CHUNK_W = 16;
|
||||||
inline constexpr int CHUNK_H = 256;
|
inline constexpr int CHUNK_H = 256;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "../logic/scripting/scripting.hpp"
|
#include "../logic/scripting/scripting.hpp"
|
||||||
#include "../objects/Player.hpp"
|
#include "../objects/Player.hpp"
|
||||||
#include "../objects/Entities.hpp"
|
#include "../objects/Entities.hpp"
|
||||||
|
#include "../objects/EntityDef.hpp"
|
||||||
#include "../physics/Hitbox.hpp"
|
#include "../physics/Hitbox.hpp"
|
||||||
#include "../util/stringutil.hpp"
|
#include "../util/stringutil.hpp"
|
||||||
#include "../voxels/Block.hpp"
|
#include "../voxels/Block.hpp"
|
||||||
@@ -60,24 +61,24 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
fpsMin = fps;
|
fpsMin = fps;
|
||||||
fpsMax = fps;
|
fpsMax = fps;
|
||||||
});
|
});
|
||||||
panel->add(create_label([](){ return L"fps: "+fpsString;}));
|
panel->add(create_label([]() { return L"fps: "+fpsString;}));
|
||||||
|
|
||||||
panel->add(create_label([](){
|
panel->add(create_label([]() {
|
||||||
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([](){
|
panel->add(create_label([]() {
|
||||||
int drawCalls = Mesh::drawCalls;
|
int drawCalls = Mesh::drawCalls;
|
||||||
Mesh::drawCalls = 0;
|
Mesh::drawCalls = 0;
|
||||||
return L"draw-calls: " + std::to_wstring(drawCalls);
|
return L"draw-calls: " + std::to_wstring(drawCalls);
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([](){
|
panel->add(create_label([]() {
|
||||||
return L"speakers: " + std::to_wstring(audio::count_speakers())+
|
return L"speakers: " + std::to_wstring(audio::count_speakers())+
|
||||||
L" streams: " + std::to_wstring(audio::count_streams());
|
L" streams: " + std::to_wstring(audio::count_streams());
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([](){
|
panel->add(create_label([]() {
|
||||||
return L"lua-stack: " + std::to_wstring(scripting::get_values_on_stack());
|
return L"lua-stack: " + std::to_wstring(scripting::get_values_on_stack());
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([=](){
|
panel->add(create_label([=]() {
|
||||||
auto& settings = engine->getSettings();
|
auto& settings = engine->getSettings();
|
||||||
bool culling = settings.graphics.frustumCulling.get();
|
bool culling = settings.graphics.frustumCulling.get();
|
||||||
return L"frustum-culling: "+std::wstring(culling ? L"on" : L"off");
|
return L"frustum-culling: "+std::wstring(culling ? L"on" : L"off");
|
||||||
@@ -90,7 +91,7 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
return L"entities: "+std::to_wstring(level->entities->size())+L" next: "+
|
return L"entities: "+std::to_wstring(level->entities->size())+L" next: "+
|
||||||
std::to_wstring(level->entities->peekNextID());
|
std::to_wstring(level->entities->peekNextID());
|
||||||
}));
|
}));
|
||||||
panel->add(create_label([=](){
|
panel->add(create_label([=]() {
|
||||||
const auto& vox = player->selection.vox;
|
const auto& vox = player->selection.vox;
|
||||||
std::wstringstream stream;
|
std::wstringstream stream;
|
||||||
stream << "r:" << vox.state.rotation << " s:"
|
stream << "r:" << vox.state.rotation << " s:"
|
||||||
@@ -103,6 +104,17 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
L" "+stream.str();
|
L" "+stream.str();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
panel->add(create_label([=]() {
|
||||||
|
const auto& selection = player->selection;
|
||||||
|
if (selection.entity == ENTITY_NONE) {
|
||||||
|
return std::wstring {L"entity: -"};
|
||||||
|
} else if (auto entity = level->entities->get(selection.entity)) {
|
||||||
|
return L"entity: "+util::str2wstr_utf8(entity->getDef().name)+
|
||||||
|
L" uid: "+std::to_wstring(entity->getUID());
|
||||||
|
} else {
|
||||||
|
return std::wstring {L"entity: error (invalid UID)"};
|
||||||
|
}
|
||||||
|
}));
|
||||||
panel->add(create_label([=](){
|
panel->add(create_label([=](){
|
||||||
auto* indices = level->content->getIndices();
|
auto* indices = level->content->getIndices();
|
||||||
if (auto def = indices->blocks.get(player->selection.vox.id)) {
|
if (auto def = indices->blocks.get(player->selection.vox.id)) {
|
||||||
|
|||||||
@@ -264,8 +264,7 @@ void PlayerController::postUpdate(float delta, bool input, bool pause) {
|
|||||||
if (input) {
|
if (input) {
|
||||||
updateInteraction();
|
updateInteraction();
|
||||||
} else {
|
} else {
|
||||||
player->selection.vox.id = BLOCK_VOID;
|
player->selection = {};
|
||||||
player->selection.vox.state.rotation = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,13 +364,25 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
|||||||
maxDistance,
|
maxDistance,
|
||||||
end, norm, iend
|
end, norm, iend
|
||||||
);
|
);
|
||||||
if (vox == nullptr) {
|
if (vox) {
|
||||||
|
maxDistance = glm::distance(camera->position, end);
|
||||||
|
}
|
||||||
|
selection.entity = ENTITY_NONE;
|
||||||
|
selection.actualPosition = iend;
|
||||||
|
if (auto result = level->entities->rayCast(
|
||||||
|
camera->position, camera->front, maxDistance, player->getEntity())) {
|
||||||
|
selection.entity = result->entity;
|
||||||
|
selection.hitPosition = camera->position + camera->front * result->distance;
|
||||||
|
selection.position = selection.hitPosition;
|
||||||
|
selection.actualPosition = selection.position;
|
||||||
|
selection.normal = result->normal;
|
||||||
|
}
|
||||||
|
if (vox == nullptr || selection.entity) {
|
||||||
selection.vox = {BLOCK_VOID, {}};
|
selection.vox = {BLOCK_VOID, {}};
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
blockstate selectedState = vox->state;
|
blockstate selectedState = vox->state;
|
||||||
selection.vox = *vox;
|
selection.vox = *vox;
|
||||||
selection.actualPosition = iend;
|
|
||||||
if (selectedState.segment) {
|
if (selectedState.segment) {
|
||||||
selection.position = chunks->seekOrigin(
|
selection.position = chunks->seekOrigin(
|
||||||
iend, indices->blocks.get(selection.vox.id), selectedState
|
iend, indices->blocks.get(selection.vox.id), selectedState
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "../data/dynamic_util.hpp"
|
#include "../data/dynamic_util.hpp"
|
||||||
#include "../assets/Assets.hpp"
|
#include "../assets/Assets.hpp"
|
||||||
#include "../world/Level.hpp"
|
#include "../world/Level.hpp"
|
||||||
|
#include "../maths/rays.hpp"
|
||||||
#include "../content/Content.hpp"
|
#include "../content/Content.hpp"
|
||||||
#include "../physics/Hitbox.hpp"
|
#include "../physics/Hitbox.hpp"
|
||||||
#include "../physics/PhysicsSolver.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) {
|
void Entities::loadEntities(dynamic::Map_sptr root) {
|
||||||
auto list = root->list("data");
|
auto list = root->list("data");
|
||||||
for (size_t i = 0; i < list->size(); i++) {
|
for (size_t i = 0; i < list->size(); i++) {
|
||||||
|
|||||||
@@ -160,6 +160,12 @@ class Entities {
|
|||||||
|
|
||||||
void preparePhysics();
|
void preparePhysics();
|
||||||
public:
|
public:
|
||||||
|
struct RaycastResult {
|
||||||
|
entityid_t entity;
|
||||||
|
glm::ivec3 normal;
|
||||||
|
float distance;
|
||||||
|
};
|
||||||
|
|
||||||
Entities(Level* level);
|
Entities(Level* level);
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
@@ -184,6 +190,16 @@ public:
|
|||||||
return std::nullopt;
|
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 loadEntities(dynamic::Map_sptr map);
|
||||||
void loadEntity(const dynamic::Map_sptr& map);
|
void loadEntity(const dynamic::Map_sptr& map);
|
||||||
void loadEntity(const dynamic::Map_sptr& map, Entity entity);
|
void loadEntity(const dynamic::Map_sptr& map, Entity entity);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ Hitbox* Player::getHitbox() {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "EntityDef.hpp"
|
||||||
void Player::updateInput(PlayerInput& input, float delta) {
|
void Player::updateInput(PlayerInput& input, float delta) {
|
||||||
auto hitbox = getHitbox();
|
auto hitbox = getHitbox();
|
||||||
if (hitbox == nullptr) {
|
if (hitbox == nullptr) {
|
||||||
|
|||||||
@@ -33,12 +33,13 @@ struct PlayerInput {
|
|||||||
bool flight : 1;
|
bool flight : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockSelection {
|
struct CursorSelection {
|
||||||
voxel vox {0, {}};
|
voxel vox {BLOCK_VOID, {}};
|
||||||
glm::ivec3 position {};
|
glm::ivec3 position {};
|
||||||
glm::ivec3 actualPosition {};
|
glm::ivec3 actualPosition {};
|
||||||
glm::ivec3 normal {};
|
glm::ivec3 normal {};
|
||||||
glm::vec3 hitPosition;
|
glm::vec3 hitPosition;
|
||||||
|
entityid_t entity = ENTITY_NONE;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Player : public Object, public Serializable {
|
class Player : public Object, public Serializable {
|
||||||
@@ -56,7 +57,7 @@ public:
|
|||||||
std::shared_ptr<Camera> currentCamera;
|
std::shared_ptr<Camera> currentCamera;
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
glm::vec3 cam {};
|
glm::vec3 cam {};
|
||||||
BlockSelection selection {};
|
CursorSelection selection {};
|
||||||
|
|
||||||
Player(Level* level, glm::vec3 position, float speed,
|
Player(Level* level, glm::vec3 position, float speed,
|
||||||
std::shared_ptr<Inventory> inv, entityid_t eid);
|
std::shared_ptr<Inventory> inv, entityid_t eid);
|
||||||
|
|||||||
@@ -461,7 +461,8 @@ voxel* Chunks::rayCast(
|
|||||||
box.b += offset;
|
box.b += offset;
|
||||||
scalar_t boxDistance;
|
scalar_t boxDistance;
|
||||||
glm::ivec3 boxNorm;
|
glm::ivec3 boxNorm;
|
||||||
if (ray.intersectAABB(iend, box, maxDist, boxNorm, boxDistance) > RayRelation::None && boxDistance < distance) {
|
if (ray.intersectAABB(iend, box, maxDist, boxNorm, boxDistance) > RayRelation::None &&
|
||||||
|
boxDistance < distance) {
|
||||||
hit = true;
|
hit = true;
|
||||||
distance = boxDistance;
|
distance = boxDistance;
|
||||||
norm = boxNorm;
|
norm = boxNorm;
|
||||||
|
|||||||
Reference in New Issue
Block a user