add entities raycast
This commit is contained in:
parent
638a0d9850
commit
c17f3fec54
@ -19,6 +19,7 @@ inline const std::string ENGINE_VERSION_STRING = "0.22";
|
||||
|
||||
inline constexpr blockid_t BLOCK_AIR = 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_H = 256;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "../logic/scripting/scripting.hpp"
|
||||
#include "../objects/Player.hpp"
|
||||
#include "../objects/Entities.hpp"
|
||||
#include "../objects/EntityDef.hpp"
|
||||
#include "../physics/Hitbox.hpp"
|
||||
#include "../util/stringutil.hpp"
|
||||
#include "../voxels/Block.hpp"
|
||||
@ -60,24 +61,24 @@ std::shared_ptr<UINode> create_debug_panel(
|
||||
fpsMin = 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);
|
||||
}));
|
||||
panel->add(create_label([](){
|
||||
panel->add(create_label([]() {
|
||||
int drawCalls = Mesh::drawCalls;
|
||||
Mesh::drawCalls = 0;
|
||||
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())+
|
||||
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());
|
||||
}));
|
||||
panel->add(create_label([=](){
|
||||
panel->add(create_label([=]() {
|
||||
auto& settings = engine->getSettings();
|
||||
bool culling = settings.graphics.frustumCulling.get();
|
||||
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: "+
|
||||
std::to_wstring(level->entities->peekNextID());
|
||||
}));
|
||||
panel->add(create_label([=](){
|
||||
panel->add(create_label([=]() {
|
||||
const auto& vox = player->selection.vox;
|
||||
std::wstringstream stream;
|
||||
stream << "r:" << vox.state.rotation << " s:"
|
||||
@ -103,6 +104,17 @@ std::shared_ptr<UINode> create_debug_panel(
|
||||
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([=](){
|
||||
auto* indices = level->content->getIndices();
|
||||
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) {
|
||||
updateInteraction();
|
||||
} else {
|
||||
player->selection.vox.id = BLOCK_VOID;
|
||||
player->selection.vox.state.rotation = 0;
|
||||
player->selection = {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,13 +364,25 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
||||
maxDistance,
|
||||
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, {}};
|
||||
return nullptr;
|
||||
}
|
||||
blockstate selectedState = vox->state;
|
||||
selection.vox = *vox;
|
||||
selection.actualPosition = iend;
|
||||
if (selectedState.segment) {
|
||||
selection.position = chunks->seekOrigin(
|
||||
iend, indices->blocks.get(selection.vox.id), selectedState
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -461,7 +461,8 @@ voxel* Chunks::rayCast(
|
||||
box.b += offset;
|
||||
scalar_t boxDistance;
|
||||
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;
|
||||
distance = boxDistance;
|
||||
norm = boxNorm;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user