This commit is contained in:
MihailRis
2024-05-06 17:35:05 +03:00
parent b3a1cad0e1
commit 3c6089225f
16 changed files with 633 additions and 638 deletions
+43 -43
View File
@@ -1,43 +1,43 @@
#include "core_defs.hpp" #include "core_defs.hpp"
#include "items/ItemDef.hpp" #include "items/ItemDef.hpp"
#include "content/Content.hpp" #include "content/Content.hpp"
#include "window/Window.hpp" #include "window/Window.hpp"
#include "window/Events.hpp" #include "window/Events.hpp"
#include "window/input.hpp" #include "window/input.hpp"
#include "voxels/Block.hpp" #include "voxels/Block.hpp"
// All in-game definitions (blocks, items, etc..) // All in-game definitions (blocks, items, etc..)
void corecontent::setup(ContentBuilder* builder) { void corecontent::setup(ContentBuilder* builder) {
Block& block = builder->createBlock("core:air"); Block& block = builder->createBlock("core:air");
block.replaceable = true; block.replaceable = true;
block.drawGroup = 1; block.drawGroup = 1;
block.lightPassing = true; block.lightPassing = true;
block.skyLightPassing = true; block.skyLightPassing = true;
block.obstacle = false; block.obstacle = false;
block.selectable = false; block.selectable = false;
block.model = BlockModel::none; block.model = BlockModel::none;
block.pickingItem = "core:empty"; block.pickingItem = "core:empty";
ItemDef& item = builder->createItem("core:empty"); ItemDef& item = builder->createItem("core:empty");
item.iconType = item_icon_type::none; item.iconType = item_icon_type::none;
} }
void corecontent::setup_bindings() { void corecontent::setup_bindings() {
Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W); Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W);
Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S); Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S);
Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D); Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D);
Events::bind(BIND_MOVE_LEFT, inputtype::keyboard, keycode::A); Events::bind(BIND_MOVE_LEFT, inputtype::keyboard, keycode::A);
Events::bind(BIND_MOVE_JUMP, inputtype::keyboard, keycode::SPACE); Events::bind(BIND_MOVE_JUMP, inputtype::keyboard, keycode::SPACE);
Events::bind(BIND_MOVE_SPRINT, inputtype::keyboard, keycode::LEFT_CONTROL); Events::bind(BIND_MOVE_SPRINT, inputtype::keyboard, keycode::LEFT_CONTROL);
Events::bind(BIND_MOVE_CROUCH, inputtype::keyboard, keycode::LEFT_SHIFT); Events::bind(BIND_MOVE_CROUCH, inputtype::keyboard, keycode::LEFT_SHIFT);
Events::bind(BIND_MOVE_CHEAT, inputtype::keyboard, keycode::R); Events::bind(BIND_MOVE_CHEAT, inputtype::keyboard, keycode::R);
Events::bind(BIND_CAM_ZOOM, inputtype::keyboard, keycode::C); Events::bind(BIND_CAM_ZOOM, inputtype::keyboard, keycode::C);
Events::bind(BIND_CAM_MODE, inputtype::keyboard, keycode::F4); Events::bind(BIND_CAM_MODE, inputtype::keyboard, keycode::F4);
Events::bind(BIND_PLAYER_NOCLIP, inputtype::keyboard, keycode::N); Events::bind(BIND_PLAYER_NOCLIP, inputtype::keyboard, keycode::N);
Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F); Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F);
Events::bind(BIND_PLAYER_ATTACK, inputtype::mouse, mousecode::BUTTON_1); Events::bind(BIND_PLAYER_ATTACK, inputtype::mouse, mousecode::BUTTON_1);
Events::bind(BIND_PLAYER_BUILD, inputtype::mouse, mousecode::BUTTON_2); Events::bind(BIND_PLAYER_BUILD, inputtype::mouse, mousecode::BUTTON_2);
Events::bind(BIND_PLAYER_PICK, inputtype::mouse, mousecode::BUTTON_3); Events::bind(BIND_PLAYER_PICK, inputtype::mouse, mousecode::BUTTON_3);
Events::bind(BIND_HUD_INVENTORY, inputtype::keyboard, keycode::TAB); Events::bind(BIND_HUD_INVENTORY, inputtype::keyboard, keycode::TAB);
} }
+1 -1
View File
@@ -25,7 +25,7 @@ Lighting::~Lighting(){
} }
void Lighting::clear(){ void Lighting::clear(){
for (unsigned int index = 0; index < chunks->volume; index++){ for (size_t index = 0; index < chunks->volume; index++){
auto chunk = chunks->chunks[index]; auto chunk = chunks->chunks[index];
if (chunk == nullptr) if (chunk == nullptr)
continue; continue;
+83 -83
View File
@@ -6,113 +6,113 @@
class Frustum class Frustum
{ {
public: public:
Frustum() {}; Frustum() {};
void update(glm::mat4 projview); void update(glm::mat4 projview);
bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const; bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
private: private:
enum Planes enum Planes
{ {
Left = 0, Left = 0,
Right, Right,
Bottom, Bottom,
Top, Top,
Near, Near,
Far, Far,
Count, Count,
Combinations = Count * (Count - 1) / 2 Combinations = Count * (Count - 1) / 2
}; };
template<Planes i, Planes j> template<Planes i, Planes j>
struct ij2k struct ij2k
{ {
enum { k = i * (9 - i) / 2 + j - 1 }; enum { k = i * (9 - i) / 2 + j - 1 };
}; };
template<Planes a, Planes b, Planes c> template<Planes a, Planes b, Planes c>
glm::vec3 intersection(const glm::vec3* crosses) const; glm::vec3 intersection(const glm::vec3* crosses) const;
glm::vec4 m_planes[Count]; glm::vec4 m_planes[Count];
glm::vec3 m_points[8]; glm::vec3 m_points[8];
}; };
inline void Frustum::update(glm::mat4 m) inline void Frustum::update(glm::mat4 m)
{ {
m = glm::transpose(m); m = glm::transpose(m);
m_planes[Left] = m[3] + m[0]; m_planes[Left] = m[3] + m[0];
m_planes[Right] = m[3] - m[0]; m_planes[Right] = m[3] - m[0];
m_planes[Bottom] = m[3] + m[1]; m_planes[Bottom] = m[3] + m[1];
m_planes[Top] = m[3] - m[1]; m_planes[Top] = m[3] - m[1];
m_planes[Near] = m[3] + m[2]; m_planes[Near] = m[3] + m[2];
m_planes[Far] = m[3] - m[2]; m_planes[Far] = m[3] - m[2];
glm::vec3 crosses[Combinations] = { glm::vec3 crosses[Combinations] = {
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Right])), glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Right])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Bottom])), glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Bottom])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Top])), glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Near])), glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Far])), glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Bottom])), glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Bottom])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Top])), glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Near])), glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Far])), glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Top])), glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Top])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Near])), glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Far])), glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Near])), glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Near])),
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Far])), glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Far])),
glm::cross(glm::vec3(m_planes[Near]), glm::vec3(m_planes[Far])) glm::cross(glm::vec3(m_planes[Near]), glm::vec3(m_planes[Far]))
}; };
m_points[0] = intersection<Left, Bottom, Near>(crosses); m_points[0] = intersection<Left, Bottom, Near>(crosses);
m_points[1] = intersection<Left, Top, Near>(crosses); m_points[1] = intersection<Left, Top, Near>(crosses);
m_points[2] = intersection<Right, Bottom, Near>(crosses); m_points[2] = intersection<Right, Bottom, Near>(crosses);
m_points[3] = intersection<Right, Top, Near>(crosses); m_points[3] = intersection<Right, Top, Near>(crosses);
m_points[4] = intersection<Left, Bottom, Far>(crosses); m_points[4] = intersection<Left, Bottom, Far>(crosses);
m_points[5] = intersection<Left, Top, Far>(crosses); m_points[5] = intersection<Left, Top, Far>(crosses);
m_points[6] = intersection<Right, Bottom, Far>(crosses); m_points[6] = intersection<Right, Bottom, Far>(crosses);
m_points[7] = intersection<Right, Top, Far>(crosses); m_points[7] = intersection<Right, Top, Far>(crosses);
} }
inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const
{ {
// check box outside/inside of frustum // check box outside/inside of frustum
for (int i = 0; i < Count; i++) for (int i = 0; i < Count; i++)
{ {
if ((glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, minp.z, 1.0f)) < 0.0) && if ((glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, minp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, minp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, minp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, maxp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, maxp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, maxp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, maxp.z, 1.0f)) < 0.0) &&
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, maxp.z, 1.0f)) < 0.0)) (glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, maxp.z, 1.0f)) < 0.0))
{ {
return false; return false;
} }
} }
// check frustum outside/inside box // check frustum outside/inside box
int out; int out;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x > maxp.x) ? 1 : 0); if (out == 8) return false; out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x > maxp.x) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x < minp.x) ? 1 : 0); if (out == 8) return false; out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].x < minp.x) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y > maxp.y) ? 1 : 0); if (out == 8) return false; out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y > maxp.y) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y < minp.y) ? 1 : 0); if (out == 8) return false; out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].y < minp.y) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z > maxp.z) ? 1 : 0); if (out == 8) return false; out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z > maxp.z) ? 1 : 0); if (out == 8) return false;
out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z < minp.z) ? 1 : 0); if (out == 8) return false; out = 0; for (int i = 0; i < 8; i++) out += ((m_points[i].z < minp.z) ? 1 : 0); if (out == 8) return false;
return true; return true;
} }
template<Frustum::Planes a, Frustum::Planes b, Frustum::Planes c> template<Frustum::Planes a, Frustum::Planes b, Frustum::Planes c>
inline glm::vec3 Frustum::intersection(const glm::vec3* crosses) const inline glm::vec3 Frustum::intersection(const glm::vec3* crosses) const
{ {
float D = glm::dot(glm::vec3(m_planes[a]), crosses[ij2k<b, c>::k]); float D = glm::dot(glm::vec3(m_planes[a]), crosses[ij2k<b, c>::k]);
glm::vec3 res = glm::mat3(crosses[ij2k<b, c>::k], -crosses[ij2k<a, c>::k], crosses[ij2k<a, b>::k]) * glm::vec3 res = glm::mat3(crosses[ij2k<b, c>::k], -crosses[ij2k<a, c>::k], crosses[ij2k<a, b>::k]) *
glm::vec3(m_planes[a].w, m_planes[b].w, m_planes[c].w); glm::vec3(m_planes[a].w, m_planes[b].w, m_planes[c].w);
return res * (-1.0f / D); return res * (-1.0f / D);
} }
#endif // MATHS_FRUSTUM_CULLING_HPP_ #endif // MATHS_FRUSTUM_CULLING_HPP_
+7 -7
View File
@@ -2,15 +2,15 @@
#define MATHS_UVREGION_HPP_ #define MATHS_UVREGION_HPP_
struct UVRegion { struct UVRegion {
float u1; float u1;
float v1; float v1;
float u2; float u2;
float v2; float v2;
UVRegion(float u1, float v1, float u2, float v2) UVRegion(float u1, float v1, float u2, float v2)
: u1(u1), v1(v1), u2(u2), v2(v2){} : u1(u1), v1(v1), u2(u2), v2(v2){}
UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){} UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){}
}; };
#endif // MATHS_UVREGION_HPP_ #endif // MATHS_UVREGION_HPP_
+1 -1
View File
@@ -5,7 +5,7 @@
// Axis Aligned Bounding Box // Axis Aligned Bounding Box
struct AABB { struct AABB {
glm::vec3 a {0.0f}; glm::vec3 a {0.0f};
glm::vec3 b {1.0f}; glm::vec3 b {1.0f};
/* Get AABB point with minimal x,y,z */ /* Get AABB point with minimal x,y,z */
+194 -194
View File
@@ -10,249 +10,249 @@ Ray::Ray(const rayvec3& origin, const rayvec3& dir) : origin(origin), dir(dir) {
//make faces from AABB //make faces from AABB
AABBFaces::AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox){ AABBFaces::AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox){
rayvec3 pbMin = parentBox.min(), // every face is min-point and opposite corner point rayvec3 pbMin = parentBox.min(), // every face is min-point and opposite corner point
pbMax = parentBox.max(), pbMax = parentBox.max(),
pbRealPos = parentBoxPos + pbMin; pbRealPos = parentBoxPos + pbMin;
rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ), rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ),
xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ), xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ),
xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y ); xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y );
faces[0] = { parentBoxPos + rayvec3(pbMax.x, pbMin.y, pbMin.z), yzMax }; faces[0] = { parentBoxPos + rayvec3(pbMax.x, pbMin.y, pbMin.z), yzMax };
faces[1] = {pbRealPos, yzMax}; faces[1] = {pbRealPos, yzMax};
faces[2] = { parentBoxPos + rayvec3(pbMin.x, pbMax.y, pbMin.z), xzMax }; faces[2] = { parentBoxPos + rayvec3(pbMin.x, pbMax.y, pbMin.z), xzMax };
faces[3] = {pbRealPos, xzMax}; faces[3] = {pbRealPos, xzMax};
faces[4] = { parentBoxPos + rayvec3(pbMin.x, pbMin.y, pbMax.z), xyMax }; faces[4] = { parentBoxPos + rayvec3(pbMin.x, pbMin.y, pbMax.z), xyMax };
faces[5] = {pbRealPos, xyMax}; faces[5] = {pbRealPos, xyMax};
} }
RayRelation Ray::intersectYZFace( RayRelation Ray::intersectYZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //y and z global coords of opposite corner const rayvec2& faceOppositeCorner, //y and z global coords of opposite corner
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret //sinonym of rayCoef scalar_t& distance_ret //sinonym of rayCoef
){ ){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8){ //precision if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel; return RayRelation::Parallel;
} }
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);// equivalent to distance if dir normalized scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None; if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = {faceMin.x, rayvec3 intersectPoint = {faceMin.x,
rayCoef*dir.y + origin.y, rayCoef*dir.y + origin.y,
rayCoef*dir.z + origin.z}; rayCoef*dir.z + origin.z};
if (intersectPoint.y >= faceMin.y if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0] && intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z && intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]){ && intersectPoint.z <= faceOppositeCorner[1]){
distance_ret = rayCoef; // believe that dir normalized distance_ret = rayCoef; // believe that dir normalized
if (dir.x > 0) normal_ret = -X_AXIS; if (dir.x > 0) normal_ret = -X_AXIS;
else normal_ret = X_AXIS; else normal_ret = X_AXIS;
return RayRelation::Intersect; return RayRelation::Intersect;
} }
return RayRelation::None; return RayRelation::None;
} }
RayRelation Ray::intersectXZFace( RayRelation Ray::intersectXZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and z global coords of opposite corner const rayvec2& faceOppositeCorner, //x and z global coords of opposite corner
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret scalar_t& distance_ret
){ ){
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8){ //precision if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel; return RayRelation::Parallel;
} }
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);// equivalent to distance if dir normalized scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None; if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x, rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
faceMin.y, faceMin.y,
rayCoef*dir.z + origin.z}; rayCoef*dir.z + origin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0] && intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z && intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1] ){ && intersectPoint.z <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized distance_ret = rayCoef; // believe that dir normalized
if (dir.y > 0) normal_ret = -Y_AXIS; if (dir.y > 0) normal_ret = -Y_AXIS;
else normal_ret = Y_AXIS; else normal_ret = Y_AXIS;
return RayRelation::Intersect; return RayRelation::Intersect;
} }
return RayRelation::None; return RayRelation::None;
} }
RayRelation Ray::intersectXYFace( RayRelation Ray::intersectXYFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and y global coords of opposite corner const rayvec2& faceOppositeCorner, //x and y global coords of opposite corner
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret scalar_t& distance_ret
){ ){
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8){ //precision if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel; return RayRelation::Parallel;
} }
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z); // equivalent to distance if dir normalized scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z); // equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None; if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x, rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
rayCoef*dir.y + origin.y, rayCoef*dir.y + origin.y,
faceMin.z}; faceMin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0] && intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y && intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1] ){ && intersectPoint.y <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized distance_ret = rayCoef; // believe that dir normalized
if (dir.z > 0) normal_ret = -Z_AXIS; if (dir.z > 0) normal_ret = -Z_AXIS;
else normal_ret = Z_AXIS; else normal_ret = Z_AXIS;
return RayRelation::Intersect; return RayRelation::Intersect;
} }
return RayRelation::None; return RayRelation::None;
} }
RayRelation Ray::isIntersectsYZFace( RayRelation Ray::isIntersectsYZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner const rayvec2& faceOppositeCorner
){ ){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8) { //precision of "parallelity" if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel; return RayRelation::Parallel;
} }
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x); scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);
if (rayCoef < 0) return RayRelation::None; if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { faceMin.x, rayvec3 intersectPoint = { faceMin.x,
rayCoef * dir.y + origin.y, rayCoef * dir.y + origin.y,
rayCoef * dir.z + origin.z }; rayCoef * dir.z + origin.z };
if (intersectPoint.y >= faceMin.y if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0] && intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z && intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) { && intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect; return RayRelation::Intersect;
} }
return RayRelation::None; return RayRelation::None;
} }
RayRelation Ray::isIntersectsXZFace( RayRelation Ray::isIntersectsXZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner const rayvec2& faceOppositeCorner
) { ) {
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8) { //precision of "parallelity" if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel; return RayRelation::Parallel;
} }
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y); scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);
if (rayCoef < 0) return RayRelation::None; if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x, rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
faceMin.y, faceMin.y,
rayCoef * dir.z + origin.z }; rayCoef * dir.z + origin.z };
if (intersectPoint.x >= faceMin.x //Face-hit check if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0] && intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z && intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) { && intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect; return RayRelation::Intersect;
} }
return RayRelation::None; return RayRelation::None;
} }
RayRelation Ray::isIntersectsXYFace( RayRelation Ray::isIntersectsXYFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner const rayvec2& faceOppositeCorner
) { ) {
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8) { //precision of "parallelity" if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel; return RayRelation::Parallel;
} }
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z); scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z);
if (rayCoef < 0) return RayRelation::None; if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x, rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
rayCoef * dir.y + origin.y, rayCoef * dir.y + origin.y,
faceMin.z }; faceMin.z };
if (intersectPoint.x >= faceMin.x //Face-hit check if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0] && intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y && intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1]) { && intersectPoint.y <= faceOppositeCorner[1]) {
return RayRelation::Intersect; return RayRelation::Intersect;
} }
return RayRelation::None; return RayRelation::None;
} }
RayRelation Ray::intersectAABB( RayRelation Ray::intersectAABB(
const rayvec3& boxPos, const rayvec3& boxPos,
const AABB& box, const AABB& box,
float maxDist, float maxDist,
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret){ scalar_t& distance_ret){
const AABBFaces& boxFaces = AABBFaces(boxPos, box); const AABBFaces& boxFaces = AABBFaces(boxPos, box);
return intersectAABBFaces(boxFaces, maxDist, normal_ret, distance_ret); return intersectAABBFaces(boxFaces, maxDist, normal_ret, distance_ret);
} }
RayRelation Ray::intersectAABBFaces( RayRelation Ray::intersectAABBFaces(
const AABBFaces& boxFaces, const AABBFaces& boxFaces,
float maxDist, float maxDist,
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret){ scalar_t& distance_ret){
scalar_t faceDist; scalar_t faceDist;
distance_ret = maxDist; distance_ret = maxDist;
glm::ivec3 bufNormal; glm::ivec3 bufNormal;
//unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT! //unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT!
bool isIntersect = false; bool isIntersect = false;
if (intersectYZFace( if (intersectYZFace(
boxFaces.faces[0].first, boxFaces.faces[0].second, bufNormal, faceDist boxFaces.faces[0].first, boxFaces.faces[0].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret){ ) > RayRelation::None && faceDist < distance_ret){
isIntersect = true; isIntersect = true;
normal_ret = bufNormal; normal_ret = bufNormal;
distance_ret = faceDist; distance_ret = faceDist;
} }
if (intersectYZFace( if (intersectYZFace(
boxFaces.faces[1].first, boxFaces.faces[1].second, bufNormal, faceDist boxFaces.faces[1].first, boxFaces.faces[1].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) { ) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true; isIntersect = true;
normal_ret = bufNormal; normal_ret = bufNormal;
distance_ret = faceDist; distance_ret = faceDist;
} }
if (intersectXZFace( if (intersectXZFace(
boxFaces.faces[2].first, boxFaces.faces[2].second, bufNormal, faceDist boxFaces.faces[2].first, boxFaces.faces[2].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) { ) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true; isIntersect = true;
normal_ret = bufNormal; normal_ret = bufNormal;
distance_ret = faceDist; distance_ret = faceDist;
} }
if (intersectXZFace( if (intersectXZFace(
boxFaces.faces[3].first, boxFaces.faces[3].second, bufNormal, faceDist boxFaces.faces[3].first, boxFaces.faces[3].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) { ) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true; isIntersect = true;
normal_ret = bufNormal; normal_ret = bufNormal;
distance_ret = faceDist; distance_ret = faceDist;
} }
if (intersectXYFace( if (intersectXYFace(
boxFaces.faces[4].first, boxFaces.faces[4].second, bufNormal, faceDist boxFaces.faces[4].first, boxFaces.faces[4].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) { ) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true; isIntersect = true;
normal_ret = bufNormal; normal_ret = bufNormal;
distance_ret = faceDist; distance_ret = faceDist;
} }
if (intersectXYFace( if (intersectXYFace(
boxFaces.faces[5].first, boxFaces.faces[5].second, bufNormal, faceDist boxFaces.faces[5].first, boxFaces.faces[5].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) { ) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true; isIntersect = true;
normal_ret = bufNormal; normal_ret = bufNormal;
distance_ret = faceDist; distance_ret = faceDist;
} }
if (isIntersect) return RayRelation::Intersect; if (isIntersect) return RayRelation::Intersect;
return RayRelation::None; return RayRelation::None;
} }
+43 -43
View File
@@ -17,61 +17,61 @@ enum class RayRelation {
}; };
class AABBFaces { class AABBFaces {
static const unsigned char AABBFACES_COUNT = 6; static const unsigned char AABBFACES_COUNT = 6;
public: public:
std::array<std::pair<rayvec3, rayvec2>, AABBFACES_COUNT> faces; // every face is min-point and opposite corner point std::array<std::pair<rayvec3, rayvec2>, AABBFACES_COUNT> faces; // every face is min-point and opposite corner point
AABBFaces(){}; AABBFaces(){};
AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox); AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox);
}; };
class Ray { class Ray {
public: public:
rayvec3 origin; rayvec3 origin;
rayvec3 dir; rayvec3 dir;
Ray(const rayvec3& rayOrigin, Ray(const rayvec3& rayOrigin,
const rayvec3& rayDir); const rayvec3& rayDir);
RayRelation isIntersectsYZFace( RayRelation isIntersectsYZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner); const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXZFace( RayRelation isIntersectsXZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner); const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXYFace( RayRelation isIntersectsXYFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner); const rayvec2& faceOppositeCorner);
///returns normal and distance ///returns normal and distance
RayRelation intersectYZFace( RayRelation intersectYZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret); scalar_t& distance_ret);
RayRelation intersectXZFace( RayRelation intersectXZFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret); scalar_t& distance_ret);
RayRelation intersectXYFace( RayRelation intersectXYFace(
const rayvec3& faceMin, const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret); scalar_t& distance_ret);
RayRelation intersectAABB( RayRelation intersectAABB(
const rayvec3& boxPos, const rayvec3& boxPos,
const AABB& box, const AABB& box,
float maxDist, float maxDist,
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret); scalar_t& distance_ret);
RayRelation intersectAABBFaces( // calculates only normal and distance RayRelation intersectAABBFaces( // calculates only normal and distance
const AABBFaces& boxFaces, const AABBFaces& boxFaces,
float maxDist, float maxDist,
glm::ivec3& normal_ret, glm::ivec3& normal_ret,
scalar_t& distance_ret); scalar_t& distance_ret);
}; };
#endif // SRC_VOXNATHS_HPP_ #endif // SRC_VOXNATHS_HPP_
+16 -16
View File
@@ -4,48 +4,48 @@
#include "../typedefs.hpp" #include "../typedefs.hpp"
inline int floordiv(int a, int b) { inline int floordiv(int a, int b) {
if (a < 0 && a % b) { if (a < 0 && a % b) {
return (a / b) - 1; return (a / b) - 1;
} }
return a / b; return a / b;
} }
inline int ceildiv(int a, int b) { inline int ceildiv(int a, int b) {
if (a > 0 && a % b) { if (a > 0 && a % b) {
return a / b + 1; return a / b + 1;
} }
return a / b; return a / b;
} }
inline int max(int a, int b) { inline int max(int a, int b) {
return (a > b) ? a : b; return (a > b) ? a : b;
} }
inline int min(int a, int b) { inline int min(int a, int b) {
return (a < b) ? a : b; return (a < b) ? a : b;
} }
inline int64_t max(int64_t a, int64_t b) { inline int64_t max(int64_t a, int64_t b) {
return (a > b) ? a : b; return (a > b) ? a : b;
} }
inline int64_t min(int64_t a, int64_t b) { inline int64_t min(int64_t a, int64_t b) {
return (a < b) ? a : b; return (a < b) ? a : b;
} }
static unsigned int g_seed; static unsigned int g_seed;
inline void fast_srand(int seed) { inline void fast_srand(int seed) {
g_seed = seed; g_seed = seed;
} }
inline int fast_rand(void) { inline int fast_rand(void) {
g_seed = (214013 * g_seed + 2531011); g_seed = (214013 * g_seed + 2531011);
return (g_seed >> 16) & 0x7FFF; return (g_seed >> 16) & 0x7FFF;
} }
inline light_t light_pack(ubyte r, ubyte g, ubyte b, ubyte s) { inline light_t light_pack(ubyte r, ubyte g, ubyte b, ubyte s) {
return r | (g << 4) | (b << 8) | (s << 12); return r | (g << 4) | (b << 8) | (s << 12);
} }
#endif // VOXNATHS_HPP_ #endif // VOXNATHS_HPP_
+6 -6
View File
@@ -5,13 +5,13 @@
class Hitbox { class Hitbox {
public: public:
glm::vec3 position; glm::vec3 position;
glm::vec3 halfsize; glm::vec3 halfsize;
glm::vec3 velocity; glm::vec3 velocity;
float linear_damping; float linear_damping;
bool grounded = false; bool grounded = false;
Hitbox(glm::vec3 position, glm::vec3 halfsize); Hitbox(glm::vec3 position, glm::vec3 halfsize);
}; };
#endif /* PHYSICS_HITBOX_HPP_ */ #endif /* PHYSICS_HITBOX_HPP_ */
+176 -176
View File
@@ -15,77 +15,77 @@ PhysicsSolver::PhysicsSolver(vec3 gravity) : gravity(gravity) {
} }
void PhysicsSolver::step( void PhysicsSolver::step(
Chunks* chunks, Chunks* chunks,
Hitbox* hitbox, Hitbox* hitbox,
float delta, float delta,
uint substeps, uint substeps,
bool shifting, bool shifting,
float gravityScale, float gravityScale,
bool collisions) bool collisions)
{ {
float dt = delta / float(substeps); float dt = delta / float(substeps);
float linear_damping = hitbox->linear_damping; float linear_damping = hitbox->linear_damping;
float s = 2.0f/BLOCK_AABB_GRID; float s = 2.0f/BLOCK_AABB_GRID;
bool prevGrounded = hitbox->grounded; bool prevGrounded = hitbox->grounded;
hitbox->grounded = false; hitbox->grounded = false;
for (uint i = 0; i < substeps; i++) { for (uint i = 0; i < substeps; i++) {
vec3& pos = hitbox->position; vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize; vec3& half = hitbox->halfsize;
vec3& vel = hitbox->velocity; vec3& vel = hitbox->velocity;
float px = pos.x; float px = pos.x;
float pz = pos.z; float pz = pos.z;
vel += gravity * dt * gravityScale; vel += gravity * dt * gravityScale;
if (collisions) { if (collisions) {
colisionCalc(chunks, hitbox, vel, pos, half, colisionCalc(chunks, hitbox, vel, pos, half,
(prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f); (prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f);
} }
vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping); vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping);
vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping); vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping);
pos += vel * dt; pos += vel * dt;
if (shifting && hitbox->grounded){ if (shifting && hitbox->grounded){
float y = (pos.y-half.y-E); float y = (pos.y-half.y-E);
hitbox->grounded = false; hitbox->grounded = false;
for (float x = (px-half.x+E); x <= (px+half.x-E); x+=s){ for (float x = (px-half.x+E); x <= (px+half.x-E); x+=s){
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
if (chunks->isObstacleAt(x,y,z)){ if (chunks->isObstacleAt(x,y,z)){
hitbox->grounded = true; hitbox->grounded = true;
break; break;
} }
} }
} }
if (!hitbox->grounded) { if (!hitbox->grounded) {
pos.z = pz; pos.z = pz;
} }
hitbox->grounded = false; hitbox->grounded = false;
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
for (float z = (pz-half.z+E); z <= (pz+half.z-E); z+=s){ for (float z = (pz-half.z+E); z <= (pz+half.z-E); z+=s){
if (chunks->isObstacleAt(x,y,z)){ if (chunks->isObstacleAt(x,y,z)){
hitbox->grounded = true; hitbox->grounded = true;
break; break;
} }
} }
} }
if (!hitbox->grounded) { if (!hitbox->grounded) {
pos.x = px; pos.x = px;
} }
hitbox->grounded = true; hitbox->grounded = true;
} }
} }
} }
void PhysicsSolver::colisionCalc( void PhysicsSolver::colisionCalc(
Chunks* chunks, Chunks* chunks,
Hitbox* hitbox, Hitbox* hitbox,
vec3& vel, vec3& vel,
vec3& pos, vec3& pos,
const vec3 half, const vec3 half,
float stepHeight) float stepHeight)
{ {
// step size (smaller - more accurate, but slower) // step size (smaller - more accurate, but slower)
float s = 2.0f/BLOCK_AABB_GRID; float s = 2.0f/BLOCK_AABB_GRID;
if (stepHeight > 0.0f) { if (stepHeight > 0.0f) {
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
@@ -98,130 +98,130 @@ void PhysicsSolver::colisionCalc(
} }
} }
const AABB* aabb; const AABB* aabb;
if (vel.x < 0.0f){ if (vel.x < 0.0f){
for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
float x = (pos.x-half.x-E); float x = (pos.x-half.x-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){ if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.x *= 0.0f; vel.x *= 0.0f;
float newx = floor(x) + aabb->max().x + half.x + E; float newx = floor(x) + aabb->max().x + half.x + E;
if (glm::abs(newx-pos.x) <= MAX_FIX) { if (glm::abs(newx-pos.x) <= MAX_FIX) {
pos.x = newx; pos.x = newx;
} }
break; break;
} }
} }
} }
} }
if (vel.x > 0.0f){ if (vel.x > 0.0f){
for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
float x = (pos.x+half.x+E); float x = (pos.x+half.x+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){ if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.x *= 0.0f; vel.x *= 0.0f;
float newx = floor(x) - half.x + aabb->min().x - E; float newx = floor(x) - half.x + aabb->min().x - E;
if (glm::abs(newx-pos.x) <= MAX_FIX) { if (glm::abs(newx-pos.x) <= MAX_FIX) {
pos.x = newx; pos.x = newx;
} }
break; break;
} }
} }
} }
} }
if (vel.z < 0.0f){ if (vel.z < 0.0f){
for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
float z = (pos.z-half.z-E); float z = (pos.z-half.z-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){ if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.z *= 0.0f; vel.z *= 0.0f;
float newz = floor(z) + aabb->max().z + half.z + E; float newz = floor(z) + aabb->max().z + half.z + E;
if (glm::abs(newz-pos.z) <= MAX_FIX) { if (glm::abs(newz-pos.z) <= MAX_FIX) {
pos.z = newz; pos.z = newz;
} }
break; break;
} }
} }
} }
} }
if (vel.z > 0.0f){ if (vel.z > 0.0f){
for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
float z = (pos.z+half.z+E); float z = (pos.z+half.z+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){ if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.z *= 0.0f; vel.z *= 0.0f;
float newz = floor(z) - half.z + aabb->min().z - E; float newz = floor(z) - half.z + aabb->min().z - E;
if (glm::abs(newz-pos.z) <= MAX_FIX) { if (glm::abs(newz-pos.z) <= MAX_FIX) {
pos.z = newz; pos.z = newz;
} }
break; break;
} }
} }
} }
} }
if (vel.y < 0.0f){ if (vel.y < 0.0f){
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
float y = (pos.y-half.y-E); float y = (pos.y-half.y-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){ if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f; vel.y *= 0.0f;
float newy = floor(y) + aabb->max().y + half.y; float newy = floor(y) + aabb->max().y + half.y;
if (glm::abs(newy-pos.y) <= MAX_FIX) { if (glm::abs(newy-pos.y) <= MAX_FIX) {
pos.y = newy; pos.y = newy;
} }
hitbox->grounded = true; hitbox->grounded = true;
break; break;
} }
} }
} }
} }
if (stepHeight > 0.0 && vel.y <= 0.0f){ if (stepHeight > 0.0 && vel.y <= 0.0f){
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
float y = (pos.y-half.y+E); float y = (pos.y-half.y+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){ if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f; vel.y *= 0.0f;
float newy = floor(y) + aabb->max().y + half.y; float newy = floor(y) + aabb->max().y + half.y;
if (glm::abs(newy-pos.y) <= MAX_FIX+stepHeight) { if (glm::abs(newy-pos.y) <= MAX_FIX+stepHeight) {
pos.y = newy; pos.y = newy;
} }
break; break;
} }
} }
} }
} }
if (vel.y > 0.0f){ if (vel.y > 0.0f){
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
float y = (pos.y+half.y+E); float y = (pos.y+half.y+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){ if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f; vel.y *= 0.0f;
float newy = floor(y) - half.y + aabb->min().y - E; float newy = floor(y) - half.y + aabb->min().y - E;
if (glm::abs(newy-pos.y) <= MAX_FIX) { if (glm::abs(newy-pos.y) <= MAX_FIX) {
pos.y = newy; pos.y = newy;
} }
break; break;
} }
} }
} }
} }
} }
bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) { bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) {
vec3& pos = hitbox->position; vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize; vec3& half = hitbox->halfsize;
return x >= floor(pos.x-half.x) && x <= floor(pos.x+half.x) && return x >= floor(pos.x-half.x) && x <= floor(pos.x+half.x) &&
z >= floor(pos.z-half.z) && z <= floor(pos.z+half.z) && z >= floor(pos.z-half.z) && z <= floor(pos.z+half.z) &&
y >= floor(pos.y-half.y) && y <= floor(pos.y+half.y); y >= floor(pos.y-half.y) && y <= floor(pos.y+half.y);
} }
bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate_t states, Hitbox* hitbox) { bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate_t states, Hitbox* hitbox) {
vec3& pos = hitbox->position; vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize; vec3& half = hitbox->halfsize;
voxel v; voxel v;
v.states = states; v.states = states;
const auto& boxes = def->rotatable const auto& boxes = def->rotatable
@@ -236,5 +236,5 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate_t
min.y < pos.y+half.y-y-0.00001 && max.y > pos.y-half.y-y+0.00001) min.y < pos.y+half.y-y-0.00001 && max.y > pos.y-half.y-y+0.00001)
return true; return true;
} }
return false; return false;
} }
+28 -28
View File
@@ -84,47 +84,47 @@ uint util::encode_utf8(uint32_t c, ubyte* bytes) {
} }
struct utf_t { struct utf_t {
char mask; char mask;
char lead; char lead;
uint32_t beg; uint32_t beg;
uint32_t end; uint32_t end;
int bits_stored; int bits_stored;
}; };
const utf_t utf[] = { const utf_t utf[] = {
/* mask lead beg end bits */ /* mask lead beg end bits */
{(char)0b00111111, (char)0b10000000, 0, 0, 6}, {(char)0b00111111, (char)0b10000000, 0, 0, 6},
{(char)0b01111111, (char)0b00000000, 0000, 0177, 7}, {(char)0b01111111, (char)0b00000000, 0000, 0177, 7},
{(char)0b00011111, (char)0b11000000, 0200, 03777, 5}, {(char)0b00011111, (char)0b11000000, 0200, 03777, 5},
{(char)0b00001111, (char)0b11100000, 04000, 0177777, 4}, {(char)0b00001111, (char)0b11100000, 04000, 0177777, 4},
{(char)0b00000111, (char)0b11110000, 0200000, 04177777, 3}, {(char)0b00000111, (char)0b11110000, 0200000, 04177777, 3},
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
}; };
inline uint utf8_len(ubyte cp) { inline uint utf8_len(ubyte cp) {
uint len = 0; uint len = 0;
for (const utf_t* u = utf; u->mask; ++u) { for (const utf_t* u = utf; u->mask; ++u) {
if((cp >= u->beg) && (cp <= u->end)) { if((cp >= u->beg) && (cp <= u->end)) {
break; break;
} }
++len; ++len;
} }
if(len > 4) /* Out of bounds */ if(len > 4) /* Out of bounds */
throw std::runtime_error("utf-8 decode error"); throw std::runtime_error("utf-8 decode error");
return len; return len;
} }
extern uint32_t util::decode_utf8(uint& size, const char* chr) { extern uint32_t util::decode_utf8(uint& size, const char* chr) {
size = utf8_len(*chr); size = utf8_len(*chr);
int shift = utf[0].bits_stored * (size - 1); int shift = utf[0].bits_stored * (size - 1);
uint32_t code = (*chr++ & utf[size].mask) << shift; uint32_t code = (*chr++ & utf[size].mask) << shift;
for(uint i = 1; i < size; ++i, ++chr) { for(uint i = 1; i < size; ++i, ++chr) {
shift -= utf[0].bits_stored; shift -= utf[0].bits_stored;
code |= ((char)*chr & utf[0].mask) << shift; code |= ((char)*chr & utf[0].mask) << shift;
} }
return code; return code;
} }
-3
View File
@@ -1,11 +1,8 @@
#include "core_defs.hpp"
#include "engine.hpp" #include "engine.hpp"
#include "files/files.hpp"
#include "files/settings_io.hpp" #include "files/settings_io.hpp"
#include "files/engine_paths.hpp" #include "files/engine_paths.hpp"
#include "util/platform.hpp" #include "util/platform.hpp"
#include "util/command_line.hpp" #include "util/command_line.hpp"
#include "window/Events.hpp"
#include "debug/Logger.hpp" #include "debug/Logger.hpp"
#include <stdexcept> #include <stdexcept>
+18 -18
View File
@@ -1,18 +1,18 @@
#include "WorldGenerator.hpp" #include "WorldGenerator.hpp"
#include "voxel.hpp" #include "voxel.hpp"
#include "Chunk.hpp" #include "Chunk.hpp"
#include "Block.hpp" #include "Block.hpp"
#include "../content/Content.hpp" #include "../content/Content.hpp"
WorldGenerator::WorldGenerator(const Content* content) WorldGenerator::WorldGenerator(const Content* content)
: idStone(content->requireBlock("base:stone").rt.id), : idStone(content->requireBlock("base:stone").rt.id),
idDirt(content->requireBlock("base:dirt").rt.id), idDirt(content->requireBlock("base:dirt").rt.id),
idGrassBlock(content->requireBlock("base:grass_block").rt.id), idGrassBlock(content->requireBlock("base:grass_block").rt.id),
idSand(content->requireBlock("base:sand").rt.id), idSand(content->requireBlock("base:sand").rt.id),
idWater(content->requireBlock("base:water").rt.id), idWater(content->requireBlock("base:water").rt.id),
idWood(content->requireBlock("base:wood").rt.id), idWood(content->requireBlock("base:wood").rt.id),
idLeaves(content->requireBlock("base:leaves").rt.id), idLeaves(content->requireBlock("base:leaves").rt.id),
idGrass(content->requireBlock("base:grass").rt.id), idGrass(content->requireBlock("base:grass").rt.id),
idFlower(content->requireBlock("base:flower").rt.id), idFlower(content->requireBlock("base:flower").rt.id),
idBazalt(content->requireBlock("base:bazalt").rt.id) {} idBazalt(content->requireBlock("base:bazalt").rt.id) {}
+12 -12
View File
@@ -9,21 +9,21 @@ class Content;
class WorldGenerator { class WorldGenerator {
protected: protected:
blockid_t const idStone; blockid_t const idStone;
blockid_t const idDirt; blockid_t const idDirt;
blockid_t const idGrassBlock; blockid_t const idGrassBlock;
blockid_t const idSand; blockid_t const idSand;
blockid_t const idWater; blockid_t const idWater;
blockid_t const idWood; blockid_t const idWood;
blockid_t const idLeaves; blockid_t const idLeaves;
blockid_t const idGrass; blockid_t const idGrass;
blockid_t const idFlower; blockid_t const idFlower;
blockid_t const idBazalt; blockid_t const idBazalt;
public: public:
WorldGenerator(const Content* content); WorldGenerator(const Content* content);
virtual ~WorldGenerator() = default; virtual ~WorldGenerator() = default;
virtual void generate(voxel* voxels, int x, int z, int seed) = 0; virtual void generate(voxel* voxels, int x, int z, int seed) = 0;
}; };
#endif /* VOXELS_WORLDGENERATOR_HPP_ */ #endif /* VOXELS_WORLDGENERATOR_HPP_ */
-2
View File
@@ -1,2 +0,0 @@
#include "voxel.hpp"
+5 -5
View File
@@ -16,12 +16,12 @@ const int BLOCK_ROT_MASK = 0b0000'0111;
const int BLOCK_RESERVED_MASK = 0b1111'1000; const int BLOCK_RESERVED_MASK = 0b1111'1000;
struct voxel { struct voxel {
blockid_t id; blockid_t id;
blockstate_t states; blockstate_t states;
inline uint8_t rotation() const { inline uint8_t rotation() const {
return states & BLOCK_ROT_MASK; return states & BLOCK_ROT_MASK;
} }
inline void setRotation(uint8_t rotation) { inline void setRotation(uint8_t rotation) {
states = (states & (~BLOCK_ROT_MASK)) | (rotation & BLOCK_ROT_MASK); states = (states & (~BLOCK_ROT_MASK)) | (rotation & BLOCK_ROT_MASK);