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

View File

@ -1,43 +1,43 @@
#include "core_defs.hpp"
#include "items/ItemDef.hpp"
#include "content/Content.hpp"
#include "window/Window.hpp"
#include "window/Events.hpp"
#include "window/input.hpp"
#include "voxels/Block.hpp"
// All in-game definitions (blocks, items, etc..)
void corecontent::setup(ContentBuilder* builder) {
Block& block = builder->createBlock("core:air");
block.replaceable = true;
block.drawGroup = 1;
block.lightPassing = true;
block.skyLightPassing = true;
block.obstacle = false;
block.selectable = false;
block.model = BlockModel::none;
block.pickingItem = "core:empty";
ItemDef& item = builder->createItem("core:empty");
item.iconType = item_icon_type::none;
}
void corecontent::setup_bindings() {
Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W);
Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S);
Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D);
Events::bind(BIND_MOVE_LEFT, inputtype::keyboard, keycode::A);
Events::bind(BIND_MOVE_JUMP, inputtype::keyboard, keycode::SPACE);
Events::bind(BIND_MOVE_SPRINT, inputtype::keyboard, keycode::LEFT_CONTROL);
Events::bind(BIND_MOVE_CROUCH, inputtype::keyboard, keycode::LEFT_SHIFT);
Events::bind(BIND_MOVE_CHEAT, inputtype::keyboard, keycode::R);
Events::bind(BIND_CAM_ZOOM, inputtype::keyboard, keycode::C);
Events::bind(BIND_CAM_MODE, inputtype::keyboard, keycode::F4);
Events::bind(BIND_PLAYER_NOCLIP, inputtype::keyboard, keycode::N);
Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F);
Events::bind(BIND_PLAYER_ATTACK, inputtype::mouse, mousecode::BUTTON_1);
Events::bind(BIND_PLAYER_BUILD, inputtype::mouse, mousecode::BUTTON_2);
Events::bind(BIND_PLAYER_PICK, inputtype::mouse, mousecode::BUTTON_3);
Events::bind(BIND_HUD_INVENTORY, inputtype::keyboard, keycode::TAB);
}
#include "core_defs.hpp"
#include "items/ItemDef.hpp"
#include "content/Content.hpp"
#include "window/Window.hpp"
#include "window/Events.hpp"
#include "window/input.hpp"
#include "voxels/Block.hpp"
// All in-game definitions (blocks, items, etc..)
void corecontent::setup(ContentBuilder* builder) {
Block& block = builder->createBlock("core:air");
block.replaceable = true;
block.drawGroup = 1;
block.lightPassing = true;
block.skyLightPassing = true;
block.obstacle = false;
block.selectable = false;
block.model = BlockModel::none;
block.pickingItem = "core:empty";
ItemDef& item = builder->createItem("core:empty");
item.iconType = item_icon_type::none;
}
void corecontent::setup_bindings() {
Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W);
Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S);
Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D);
Events::bind(BIND_MOVE_LEFT, inputtype::keyboard, keycode::A);
Events::bind(BIND_MOVE_JUMP, inputtype::keyboard, keycode::SPACE);
Events::bind(BIND_MOVE_SPRINT, inputtype::keyboard, keycode::LEFT_CONTROL);
Events::bind(BIND_MOVE_CROUCH, inputtype::keyboard, keycode::LEFT_SHIFT);
Events::bind(BIND_MOVE_CHEAT, inputtype::keyboard, keycode::R);
Events::bind(BIND_CAM_ZOOM, inputtype::keyboard, keycode::C);
Events::bind(BIND_CAM_MODE, inputtype::keyboard, keycode::F4);
Events::bind(BIND_PLAYER_NOCLIP, inputtype::keyboard, keycode::N);
Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F);
Events::bind(BIND_PLAYER_ATTACK, inputtype::mouse, mousecode::BUTTON_1);
Events::bind(BIND_PLAYER_BUILD, inputtype::mouse, mousecode::BUTTON_2);
Events::bind(BIND_PLAYER_PICK, inputtype::mouse, mousecode::BUTTON_3);
Events::bind(BIND_HUD_INVENTORY, inputtype::keyboard, keycode::TAB);
}

View File

@ -25,7 +25,7 @@ Lighting::~Lighting(){
}
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];
if (chunk == nullptr)
continue;

View File

@ -6,113 +6,113 @@
class Frustum
{
public:
Frustum() {};
Frustum() {};
void update(glm::mat4 projview);
bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
void update(glm::mat4 projview);
bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
private:
enum Planes
{
Left = 0,
Right,
Bottom,
Top,
Near,
Far,
Count,
Combinations = Count * (Count - 1) / 2
};
enum Planes
{
Left = 0,
Right,
Bottom,
Top,
Near,
Far,
Count,
Combinations = Count * (Count - 1) / 2
};
template<Planes i, Planes j>
struct ij2k
{
enum { k = i * (9 - i) / 2 + j - 1 };
};
template<Planes i, Planes j>
struct ij2k
{
enum { k = i * (9 - i) / 2 + j - 1 };
};
template<Planes a, Planes b, Planes c>
glm::vec3 intersection(const glm::vec3* crosses) const;
template<Planes a, Planes b, Planes c>
glm::vec3 intersection(const glm::vec3* crosses) const;
glm::vec4 m_planes[Count];
glm::vec3 m_points[8];
glm::vec4 m_planes[Count];
glm::vec3 m_points[8];
};
inline void Frustum::update(glm::mat4 m)
{
m = glm::transpose(m);
m_planes[Left] = m[3] + m[0];
m_planes[Right] = m[3] - m[0];
m_planes[Bottom] = m[3] + m[1];
m_planes[Top] = m[3] - m[1];
m_planes[Near] = m[3] + m[2];
m_planes[Far] = m[3] - m[2];
m = glm::transpose(m);
m_planes[Left] = m[3] + m[0];
m_planes[Right] = m[3] - m[0];
m_planes[Bottom] = m[3] + m[1];
m_planes[Top] = m[3] - m[1];
m_planes[Near] = m[3] + m[2];
m_planes[Far] = m[3] - m[2];
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[Bottom])),
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[Far])),
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[Near])),
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[Near])),
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[Far])),
glm::cross(glm::vec3(m_planes[Near]), glm::vec3(m_planes[Far]))
};
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[Bottom])),
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[Far])),
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[Near])),
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[Near])),
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[Far])),
glm::cross(glm::vec3(m_planes[Near]), glm::vec3(m_planes[Far]))
};
m_points[0] = intersection<Left, Bottom, Near>(crosses);
m_points[1] = intersection<Left, Top, Near>(crosses);
m_points[2] = intersection<Right, Bottom, Near>(crosses);
m_points[3] = intersection<Right, Top, Near>(crosses);
m_points[4] = intersection<Left, Bottom, Far>(crosses);
m_points[5] = intersection<Left, Top, Far>(crosses);
m_points[6] = intersection<Right, Bottom, Far>(crosses);
m_points[7] = intersection<Right, Top, Far>(crosses);
m_points[0] = intersection<Left, Bottom, Near>(crosses);
m_points[1] = intersection<Left, Top, Near>(crosses);
m_points[2] = intersection<Right, Bottom, Near>(crosses);
m_points[3] = intersection<Right, Top, Near>(crosses);
m_points[4] = intersection<Left, Bottom, Far>(crosses);
m_points[5] = intersection<Left, Top, Far>(crosses);
m_points[6] = intersection<Right, Bottom, Far>(crosses);
m_points[7] = intersection<Right, Top, Far>(crosses);
}
inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const
{
// check box outside/inside of frustum
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) &&
(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(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(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(maxp.x, maxp.y, maxp.z, 1.0f)) < 0.0))
{
return false;
}
}
// check box outside/inside of frustum
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) &&
(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(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(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(maxp.x, maxp.y, maxp.z, 1.0f)) < 0.0))
{
return false;
}
}
// check frustum outside/inside box
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 < 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 < 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 < minp.z) ? 1 : 0); if (out == 8) return false;
// check frustum outside/inside box
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 < 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 < 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 < minp.z) ? 1 : 0); if (out == 8) return false;
return true;
return true;
}
template<Frustum::Planes a, Frustum::Planes b, Frustum::Planes c>
inline glm::vec3 Frustum::intersection(const glm::vec3* crosses) const
{
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(m_planes[a].w, m_planes[b].w, m_planes[c].w);
return res * (-1.0f / D);
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(m_planes[a].w, m_planes[b].w, m_planes[c].w);
return res * (-1.0f / D);
}
#endif // MATHS_FRUSTUM_CULLING_HPP_

View File

@ -2,15 +2,15 @@
#define MATHS_UVREGION_HPP_
struct UVRegion {
float u1;
float v1;
float u2;
float v2;
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){}
UVRegion(float u1, float v1, float u2, float 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_

View File

@ -5,7 +5,7 @@
// Axis Aligned Bounding Box
struct AABB {
glm::vec3 a {0.0f};
glm::vec3 a {0.0f};
glm::vec3 b {1.0f};
/* Get AABB point with minimal x,y,z */

View File

@ -10,249 +10,249 @@ Ray::Ray(const rayvec3& origin, const rayvec3& dir) : origin(origin), dir(dir) {
//make faces from AABB
AABBFaces::AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox){
rayvec3 pbMin = parentBox.min(), // every face is min-point and opposite corner point
pbMax = parentBox.max(),
pbRealPos = parentBoxPos + pbMin;
rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ),
xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ),
xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y );
faces[0] = { parentBoxPos + rayvec3(pbMax.x, pbMin.y, pbMin.z), yzMax };
rayvec3 pbMin = parentBox.min(), // every face is min-point and opposite corner point
pbMax = parentBox.max(),
pbRealPos = parentBoxPos + pbMin;
rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ),
xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ),
xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y );
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(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //y and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret //sinonym of rayCoef
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //y and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret //sinonym of rayCoef
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = {faceMin.x,
rayCoef*dir.y + origin.y,
rayCoef*dir.z + origin.z};
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = {faceMin.x,
rayCoef*dir.y + origin.y,
rayCoef*dir.z + origin.z};
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]){
distance_ret = rayCoef; // believe that dir normalized
if (dir.x > 0) normal_ret = -X_AXIS;
else normal_ret = X_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]){
distance_ret = rayCoef; // believe that dir normalized
if (dir.x > 0) normal_ret = -X_AXIS;
else normal_ret = X_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::intersectXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and z global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
faceMin.y,
rayCoef*dir.z + origin.z};
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);// equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
faceMin.y,
rayCoef*dir.z + origin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.y > 0) normal_ret = -Y_AXIS;
else normal_ret = Y_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.y > 0) normal_ret = -Y_AXIS;
else normal_ret = Y_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::intersectXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and y global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z); // equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
rayCoef*dir.y + origin.y,
faceMin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.z > 0) normal_ret = -Z_AXIS;
else normal_ret = Z_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner, //x and y global coords of opposite corner
glm::ivec3& normal_ret,
scalar_t& distance_ret
){
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8){ //precision
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z); // equivalent to distance if dir normalized
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef *dir.x + origin.x,
rayCoef*dir.y + origin.y,
faceMin.z};
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1] ){
distance_ret = rayCoef; // believe that dir normalized
if (dir.z > 0) normal_ret = -Z_AXIS;
else normal_ret = Z_AXIS;
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::isIntersectsYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
){
if (fabs(glm::dot(dir, X_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { faceMin.x,
rayCoef * dir.y + origin.y,
rayCoef * dir.z + origin.z };
scalar_t rayCoef = (faceMin.x - origin.x) / (dir.x);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { faceMin.x,
rayCoef * dir.y + origin.y,
rayCoef * dir.z + origin.z };
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::isIntersectsXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Y_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
faceMin.y,
rayCoef * dir.z + origin.z };
scalar_t rayCoef = (faceMin.y - origin.y) / (dir.y);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
faceMin.y,
rayCoef * dir.z + origin.z };
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.z >= faceMin.z
&& intersectPoint.z <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::isIntersectsXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner
) {
if (fabs(glm::dot(dir, Z_AXIS)) < 1.0E-8) { //precision of "parallelity"
return RayRelation::Parallel;
}
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
rayCoef * dir.y + origin.y,
faceMin.z };
scalar_t rayCoef = (faceMin.z - origin.z) / (dir.z);
if (rayCoef < 0) return RayRelation::None;
rayvec3 intersectPoint = { rayCoef * dir.x + origin.x,
rayCoef * dir.y + origin.y,
faceMin.z };
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
if (intersectPoint.x >= faceMin.x //Face-hit check
&& intersectPoint.x <= faceOppositeCorner[0]
&& intersectPoint.y >= faceMin.y
&& intersectPoint.y <= faceOppositeCorner[1]) {
return RayRelation::Intersect;
}
return RayRelation::None;
}
RayRelation Ray::intersectAABB(
const rayvec3& boxPos,
const AABB& box,
float maxDist,
const AABB& box,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret){
const AABBFaces& boxFaces = AABBFaces(boxPos, box);
return intersectAABBFaces(boxFaces, maxDist, normal_ret, distance_ret);
scalar_t& distance_ret){
const AABBFaces& boxFaces = AABBFaces(boxPos, box);
return intersectAABBFaces(boxFaces, maxDist, normal_ret, distance_ret);
}
RayRelation Ray::intersectAABBFaces(
const AABBFaces& boxFaces,
float maxDist,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret){
scalar_t& distance_ret){
scalar_t faceDist;
distance_ret = maxDist;
glm::ivec3 bufNormal;
//unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT!
bool isIntersect = false;
scalar_t faceDist;
distance_ret = maxDist;
glm::ivec3 bufNormal;
//unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT!
bool isIntersect = false;
if (intersectYZFace(
boxFaces.faces[0].first, boxFaces.faces[0].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret){
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectYZFace(
boxFaces.faces[0].first, boxFaces.faces[0].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret){
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectYZFace(
boxFaces.faces[1].first, boxFaces.faces[1].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectYZFace(
boxFaces.faces[1].first, boxFaces.faces[1].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[2].first, boxFaces.faces[2].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[2].first, boxFaces.faces[2].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[3].first, boxFaces.faces[3].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXZFace(
boxFaces.faces[3].first, boxFaces.faces[3].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXYFace(
boxFaces.faces[4].first, boxFaces.faces[4].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXYFace(
boxFaces.faces[4].first, boxFaces.faces[4].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (intersectXYFace(
boxFaces.faces[5].first, boxFaces.faces[5].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (isIntersect) return RayRelation::Intersect;
return RayRelation::None;
if (intersectXYFace(
boxFaces.faces[5].first, boxFaces.faces[5].second, bufNormal, faceDist
) > RayRelation::None && faceDist < distance_ret) {
isIntersect = true;
normal_ret = bufNormal;
distance_ret = faceDist;
}
if (isIntersect) return RayRelation::Intersect;
return RayRelation::None;
}

View File

@ -17,61 +17,61 @@ enum class RayRelation {
};
class AABBFaces {
static const unsigned char AABBFACES_COUNT = 6;
static const unsigned char AABBFACES_COUNT = 6;
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(const rayvec3& parentBoxPos, const AABB& parentBox);
AABBFaces(){};
AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox);
};
class Ray {
public:
rayvec3 origin;
rayvec3 dir;
rayvec3 origin;
rayvec3 dir;
Ray(const rayvec3& rayOrigin,
const rayvec3& rayDir);
Ray(const rayvec3& rayOrigin,
const rayvec3& rayDir);
RayRelation isIntersectsYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
RayRelation isIntersectsXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner);
///returns normal and distance
RayRelation intersectYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectYZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXZFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectXYFace(
const rayvec3& faceMin,
const rayvec2& faceOppositeCorner,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABB(
const rayvec3& boxPos,
const AABB& box,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABB(
const rayvec3& boxPos,
const AABB& box,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABBFaces( // calculates only normal and distance
const AABBFaces& boxFaces,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
RayRelation intersectAABBFaces( // calculates only normal and distance
const AABBFaces& boxFaces,
float maxDist,
glm::ivec3& normal_ret,
scalar_t& distance_ret);
};
#endif // SRC_VOXNATHS_HPP_

View File

@ -4,48 +4,48 @@
#include "../typedefs.hpp"
inline int floordiv(int a, int b) {
if (a < 0 && a % b) {
return (a / b) - 1;
}
return a / b;
if (a < 0 && a % b) {
return (a / b) - 1;
}
return a / b;
}
inline int ceildiv(int a, int b) {
if (a > 0 && a % b) {
return a / b + 1;
}
return a / b;
if (a > 0 && a % b) {
return a / b + 1;
}
return a / 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) {
return (a < b) ? a : b;
return (a < b) ? a : 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) {
return (a < b) ? a : b;
return (a < b) ? a : b;
}
static unsigned int g_seed;
inline void fast_srand(int seed) {
g_seed = seed;
g_seed = seed;
}
inline int fast_rand(void) {
g_seed = (214013 * g_seed + 2531011);
return (g_seed >> 16) & 0x7FFF;
g_seed = (214013 * g_seed + 2531011);
return (g_seed >> 16) & 0x7FFF;
}
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_

View File

@ -5,13 +5,13 @@
class Hitbox {
public:
glm::vec3 position;
glm::vec3 halfsize;
glm::vec3 velocity;
float linear_damping;
bool grounded = false;
glm::vec3 position;
glm::vec3 halfsize;
glm::vec3 velocity;
float linear_damping;
bool grounded = false;
Hitbox(glm::vec3 position, glm::vec3 halfsize);
Hitbox(glm::vec3 position, glm::vec3 halfsize);
};
#endif /* PHYSICS_HITBOX_HPP_ */

View File

@ -15,77 +15,77 @@ PhysicsSolver::PhysicsSolver(vec3 gravity) : gravity(gravity) {
}
void PhysicsSolver::step(
Chunks* chunks,
Hitbox* hitbox,
float delta,
uint substeps,
bool shifting,
float gravityScale,
bool collisions)
Chunks* chunks,
Hitbox* hitbox,
float delta,
uint substeps,
bool shifting,
float gravityScale,
bool collisions)
{
float dt = delta / float(substeps);
float linear_damping = hitbox->linear_damping;
float s = 2.0f/BLOCK_AABB_GRID;
float dt = delta / float(substeps);
float linear_damping = hitbox->linear_damping;
float s = 2.0f/BLOCK_AABB_GRID;
bool prevGrounded = hitbox->grounded;
hitbox->grounded = false;
for (uint i = 0; i < substeps; i++) {
vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize;
vec3& vel = hitbox->velocity;
float px = pos.x;
float pz = pos.z;
vel += gravity * dt * gravityScale;
if (collisions) {
colisionCalc(chunks, hitbox, vel, pos, half,
hitbox->grounded = false;
for (uint i = 0; i < substeps; i++) {
vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize;
vec3& vel = hitbox->velocity;
float px = pos.x;
float pz = pos.z;
vel += gravity * dt * gravityScale;
if (collisions) {
colisionCalc(chunks, hitbox, vel, pos, half,
(prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f);
}
vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping);
vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping);
pos += vel * dt;
}
vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping);
vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping);
pos += vel * dt;
if (shifting && hitbox->grounded){
float y = (pos.y-half.y-E);
hitbox->grounded = false;
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){
if (chunks->isObstacleAt(x,y,z)){
hitbox->grounded = true;
break;
}
}
}
if (!hitbox->grounded) {
pos.z = pz;
}
hitbox->grounded = false;
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){
if (chunks->isObstacleAt(x,y,z)){
hitbox->grounded = true;
break;
}
}
}
if (!hitbox->grounded) {
pos.x = px;
}
hitbox->grounded = true;
}
}
if (shifting && hitbox->grounded){
float y = (pos.y-half.y-E);
hitbox->grounded = false;
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){
if (chunks->isObstacleAt(x,y,z)){
hitbox->grounded = true;
break;
}
}
}
if (!hitbox->grounded) {
pos.z = pz;
}
hitbox->grounded = false;
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){
if (chunks->isObstacleAt(x,y,z)){
hitbox->grounded = true;
break;
}
}
}
if (!hitbox->grounded) {
pos.x = px;
}
hitbox->grounded = true;
}
}
}
void PhysicsSolver::colisionCalc(
Chunks* chunks,
Hitbox* hitbox,
vec3& vel,
vec3& pos,
const vec3 half,
Chunks* chunks,
Hitbox* hitbox,
vec3& vel,
vec3& pos,
const vec3 half,
float stepHeight)
{
// step size (smaller - more accurate, but slower)
float s = 2.0f/BLOCK_AABB_GRID;
// step size (smaller - more accurate, but slower)
float s = 2.0f/BLOCK_AABB_GRID;
if (stepHeight > 0.0f) {
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;
if (vel.x < 0.0f){
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){
float x = (pos.x-half.x-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.x *= 0.0f;
float newx = floor(x) + aabb->max().x + half.x + E;
if (glm::abs(newx-pos.x) <= MAX_FIX) {
pos.x = newx;
}
break;
}
}
}
}
if (vel.x > 0.0f){
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){
float x = (pos.x+half.x+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.x *= 0.0f;
float newx = floor(x) - half.x + aabb->min().x - E;
if (glm::abs(newx-pos.x) <= MAX_FIX) {
pos.x = newx;
}
break;
}
}
}
}
const AABB* aabb;
if (vel.x < 0.0f){
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){
float x = (pos.x-half.x-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.x *= 0.0f;
float newx = floor(x) + aabb->max().x + half.x + E;
if (glm::abs(newx-pos.x) <= MAX_FIX) {
pos.x = newx;
}
break;
}
}
}
}
if (vel.x > 0.0f){
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){
float x = (pos.x+half.x+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.x *= 0.0f;
float newx = floor(x) - half.x + aabb->min().x - E;
if (glm::abs(newx-pos.x) <= MAX_FIX) {
pos.x = newx;
}
break;
}
}
}
}
if (vel.z < 0.0f){
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){
float z = (pos.z-half.z-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.z *= 0.0f;
float newz = floor(z) + aabb->max().z + half.z + E;
if (glm::abs(newz-pos.z) <= MAX_FIX) {
pos.z = newz;
}
break;
}
}
}
}
if (vel.z < 0.0f){
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){
float z = (pos.z-half.z-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.z *= 0.0f;
float newz = floor(z) + aabb->max().z + half.z + E;
if (glm::abs(newz-pos.z) <= MAX_FIX) {
pos.z = newz;
}
break;
}
}
}
}
if (vel.z > 0.0f){
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){
float z = (pos.z+half.z+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.z *= 0.0f;
float newz = floor(z) - half.z + aabb->min().z - E;
if (glm::abs(newz-pos.z) <= MAX_FIX) {
pos.z = newz;
}
break;
}
}
}
}
if (vel.z > 0.0f){
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){
float z = (pos.z+half.z+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.z *= 0.0f;
float newz = floor(z) - half.z + aabb->min().z - E;
if (glm::abs(newz-pos.z) <= MAX_FIX) {
pos.z = newz;
}
break;
}
}
}
}
if (vel.y < 0.0f){
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){
float y = (pos.y-half.y-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f;
float newy = floor(y) + aabb->max().y + half.y;
if (glm::abs(newy-pos.y) <= MAX_FIX) {
pos.y = newy;
}
hitbox->grounded = true;
break;
}
}
}
}
if (vel.y < 0.0f){
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){
float y = (pos.y-half.y-E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f;
float newy = floor(y) + aabb->max().y + half.y;
if (glm::abs(newy-pos.y) <= MAX_FIX) {
pos.y = newy;
}
hitbox->grounded = true;
break;
}
}
}
}
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 z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
float y = (pos.y-half.y+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f;
float newy = floor(y) + aabb->max().y + half.y;
if (glm::abs(newy-pos.y) <= MAX_FIX+stepHeight) {
pos.y = newy;
}
break;
}
}
}
}
if (vel.y > 0.0f){
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){
float y = (pos.y+half.y+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f;
float newy = floor(y) - half.y + aabb->min().y - E;
if (glm::abs(newy-pos.y) <= MAX_FIX) {
pos.y = newy;
}
break;
}
}
}
}
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){
float y = (pos.y-half.y+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f;
float newy = floor(y) + aabb->max().y + half.y;
if (glm::abs(newy-pos.y) <= MAX_FIX+stepHeight) {
pos.y = newy;
}
break;
}
}
}
}
if (vel.y > 0.0f){
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){
float y = (pos.y+half.y+E);
if ((aabb = chunks->isObstacleAt(x,y,z))){
vel.y *= 0.0f;
float newy = floor(y) - half.y + aabb->min().y - E;
if (glm::abs(newy-pos.y) <= MAX_FIX) {
pos.y = newy;
}
break;
}
}
}
}
}
bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) {
vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize;
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) &&
y >= floor(pos.y-half.y) && y <= floor(pos.y+half.y);
vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize;
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) &&
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) {
vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize;
vec3& pos = hitbox->position;
vec3& half = hitbox->halfsize;
voxel v;
v.states = states;
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)
return true;
}
return false;
return false;
}

View File

@ -84,47 +84,47 @@ uint util::encode_utf8(uint32_t c, ubyte* bytes) {
}
struct utf_t {
char mask;
char lead;
uint32_t beg;
uint32_t end;
int bits_stored;
char mask;
char lead;
uint32_t beg;
uint32_t end;
int bits_stored;
};
const utf_t utf[] = {
/* mask lead beg end bits */
{(char)0b00111111, (char)0b10000000, 0, 0, 6},
{(char)0b01111111, (char)0b00000000, 0000, 0177, 7},
{(char)0b00011111, (char)0b11000000, 0200, 03777, 5},
{(char)0b00001111, (char)0b11100000, 04000, 0177777, 4},
{(char)0b00000111, (char)0b11110000, 0200000, 04177777, 3},
{0, 0, 0, 0, 0},
/* mask lead beg end bits */
{(char)0b00111111, (char)0b10000000, 0, 0, 6},
{(char)0b01111111, (char)0b00000000, 0000, 0177, 7},
{(char)0b00011111, (char)0b11000000, 0200, 03777, 5},
{(char)0b00001111, (char)0b11100000, 04000, 0177777, 4},
{(char)0b00000111, (char)0b11110000, 0200000, 04177777, 3},
{0, 0, 0, 0, 0},
};
inline uint utf8_len(ubyte cp) {
uint len = 0;
for (const utf_t* u = utf; u->mask; ++u) {
if((cp >= u->beg) && (cp <= u->end)) {
break;
}
++len;
}
if(len > 4) /* Out of bounds */
throw std::runtime_error("utf-8 decode error");
for (const utf_t* u = utf; u->mask; ++u) {
if((cp >= u->beg) && (cp <= u->end)) {
break;
}
++len;
}
if(len > 4) /* Out of bounds */
throw std::runtime_error("utf-8 decode error");
return len;
return len;
}
extern uint32_t util::decode_utf8(uint& size, const char* chr) {
size = utf8_len(*chr);
int shift = utf[0].bits_stored * (size - 1);
uint32_t code = (*chr++ & utf[size].mask) << shift;
size = utf8_len(*chr);
int shift = utf[0].bits_stored * (size - 1);
uint32_t code = (*chr++ & utf[size].mask) << shift;
for(uint i = 1; i < size; ++i, ++chr) {
shift -= utf[0].bits_stored;
code |= ((char)*chr & utf[0].mask) << shift;
}
for(uint i = 1; i < size; ++i, ++chr) {
shift -= utf[0].bits_stored;
code |= ((char)*chr & utf[0].mask) << shift;
}
return code;
}

View File

@ -1,11 +1,8 @@
#include "core_defs.hpp"
#include "engine.hpp"
#include "files/files.hpp"
#include "files/settings_io.hpp"
#include "files/engine_paths.hpp"
#include "util/platform.hpp"
#include "util/command_line.hpp"
#include "window/Events.hpp"
#include "debug/Logger.hpp"
#include <stdexcept>

View File

@ -1,18 +1,18 @@
#include "WorldGenerator.hpp"
#include "voxel.hpp"
#include "Chunk.hpp"
#include "Block.hpp"
#include "../content/Content.hpp"
WorldGenerator::WorldGenerator(const Content* content)
: idStone(content->requireBlock("base:stone").rt.id),
idDirt(content->requireBlock("base:dirt").rt.id),
idGrassBlock(content->requireBlock("base:grass_block").rt.id),
idSand(content->requireBlock("base:sand").rt.id),
idWater(content->requireBlock("base:water").rt.id),
idWood(content->requireBlock("base:wood").rt.id),
idLeaves(content->requireBlock("base:leaves").rt.id),
idGrass(content->requireBlock("base:grass").rt.id),
idFlower(content->requireBlock("base:flower").rt.id),
idBazalt(content->requireBlock("base:bazalt").rt.id) {}
#include "WorldGenerator.hpp"
#include "voxel.hpp"
#include "Chunk.hpp"
#include "Block.hpp"
#include "../content/Content.hpp"
WorldGenerator::WorldGenerator(const Content* content)
: idStone(content->requireBlock("base:stone").rt.id),
idDirt(content->requireBlock("base:dirt").rt.id),
idGrassBlock(content->requireBlock("base:grass_block").rt.id),
idSand(content->requireBlock("base:sand").rt.id),
idWater(content->requireBlock("base:water").rt.id),
idWood(content->requireBlock("base:wood").rt.id),
idLeaves(content->requireBlock("base:leaves").rt.id),
idGrass(content->requireBlock("base:grass").rt.id),
idFlower(content->requireBlock("base:flower").rt.id),
idBazalt(content->requireBlock("base:bazalt").rt.id) {}

View File

@ -9,21 +9,21 @@ class Content;
class WorldGenerator {
protected:
blockid_t const idStone;
blockid_t const idDirt;
blockid_t const idGrassBlock;
blockid_t const idSand;
blockid_t const idWater;
blockid_t const idWood;
blockid_t const idLeaves;
blockid_t const idGrass;
blockid_t const idFlower;
blockid_t const idBazalt;
blockid_t const idStone;
blockid_t const idDirt;
blockid_t const idGrassBlock;
blockid_t const idSand;
blockid_t const idWater;
blockid_t const idWood;
blockid_t const idLeaves;
blockid_t const idGrass;
blockid_t const idFlower;
blockid_t const idBazalt;
public:
WorldGenerator(const Content* content);
WorldGenerator(const Content* content);
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_ */

View File

@ -1,2 +0,0 @@
#include "voxel.hpp"

View File

@ -16,12 +16,12 @@ const int BLOCK_ROT_MASK = 0b0000'0111;
const int BLOCK_RESERVED_MASK = 0b1111'1000;
struct voxel {
blockid_t id;
blockstate_t states;
blockid_t id;
blockstate_t states;
inline uint8_t rotation() const {
return states & BLOCK_ROT_MASK;
}
inline uint8_t rotation() const {
return states & BLOCK_ROT_MASK;
}
inline void setRotation(uint8_t rotation) {
states = (states & (~BLOCK_ROT_MASK)) | (rotation & BLOCK_ROT_MASK);