Compare commits
22 Commits
7a388bcd62
...
920c2e20b3
| Author | SHA1 | Date | |
|---|---|---|---|
| 920c2e20b3 | |||
| 1e1880376d | |||
| de22c89975 | |||
| d1bb086daf | |||
| 7f5aee9e16 | |||
| 1bdf35a4e6 | |||
| 2bef8801e8 | |||
| 5492f52806 | |||
| 2cbe3f1219 | |||
| fe68b98ba1 | |||
| 860ec70829 | |||
| 438bc4a968 | |||
| 9aa546881a | |||
| 4db03f2b83 | |||
| 0119d36b5c | |||
| 249d7534a4 | |||
|
|
abe89d2089 | ||
| f070b28d8b | |||
|
|
a7f734d22e | ||
|
|
abbc4419fa | ||
| 86e47601d7 | |||
|
|
a3b6d2488f |
20
.vscode/c_cpp_properties.json
vendored
20
.vscode/c_cpp_properties.json
vendored
@@ -1,11 +1,13 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Blitz",
|
||||
"cppStandard": "c++17",
|
||||
"includePath": ["include"],
|
||||
"compileCommands": ".vscode/compile_commands.json"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Blitz",
|
||||
"cppStandard": "c++17",
|
||||
"includePath": [
|
||||
"include"
|
||||
],
|
||||
"compileCommands": ".vscode/compile_commands.json"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@@ -2,6 +2,13 @@
|
||||
// Xmake debug
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "xmake",
|
||||
"request": "launch",
|
||||
"name": "debug intersects test",
|
||||
"target": "test_intersects",
|
||||
"cwd": "",
|
||||
},
|
||||
{
|
||||
"type": "xmake",
|
||||
"request": "launch",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace game {
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Defines.h"
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace blitz {
|
||||
namespace game {
|
||||
|
||||
struct PlayerStats {
|
||||
std::uint16_t m_Deaths;
|
||||
std::uint16_t m_Kills;
|
||||
std::uint32_t m_ShootCount;
|
||||
std::uint32_t m_ShootSuccessCount;
|
||||
};
|
||||
|
||||
class Player {
|
||||
private:
|
||||
PlayerID m_ID;
|
||||
@@ -16,9 +23,12 @@ class Player {
|
||||
Vec3f m_Velocity;
|
||||
float m_Yaw;
|
||||
float m_Pitch;
|
||||
float m_HP;
|
||||
bool m_IsBot;
|
||||
PlayerStats m_Stats{};
|
||||
|
||||
public:
|
||||
Player(PlayerID id) : m_ID(id), m_Yaw(0), m_Pitch(0) {}
|
||||
Player(PlayerID id) : m_ID(id), m_Yaw(0), m_Pitch(0), m_IsBot(false) {}
|
||||
|
||||
PlayerID GetID() const {
|
||||
return m_ID;
|
||||
@@ -75,6 +85,26 @@ class Player {
|
||||
void AddPitch(float dPitch) {
|
||||
m_Pitch += dPitch;
|
||||
}
|
||||
|
||||
float GetHP() const {
|
||||
return m_HP;
|
||||
}
|
||||
|
||||
void SetHP(float hp) {
|
||||
m_HP = hp;
|
||||
}
|
||||
|
||||
bool IsBot() const {
|
||||
return m_IsBot;
|
||||
}
|
||||
|
||||
void SetBot() {
|
||||
m_IsBot = true;
|
||||
}
|
||||
|
||||
PlayerStats& GetStats() {
|
||||
return m_Stats;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace blitz {
|
||||
@@ -8,6 +8,22 @@ namespace maths {
|
||||
|
||||
static constexpr float PI = 3.141592653f;
|
||||
|
||||
template <typename T>
|
||||
/**
|
||||
* @brief returns the amount of overlap between the ranges [a1 ; b1] and [a2 ; b2]
|
||||
*/
|
||||
T RangesOverlap(T& a1, T& b1, T& a2, T& b2) {
|
||||
return std::min(std::max(a1, b1), std::max(a2, b2)) - std::max(std::min(a1, b1), std::min(a2, b2));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
/**
|
||||
* @brief returns whether the ranges [a1 ; b1] and [a2 ; b2] overlap
|
||||
*/
|
||||
bool RangesOverlapping(T& a1, T& b1, T& a2, T& b2) {
|
||||
return RangesOverlap(a1, a2, b1, b2) >= 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Vectors //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -55,6 +71,100 @@ T Distance(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||
return Length(vect - other);
|
||||
}
|
||||
|
||||
// it seems that `std::{min, max}`'s behavior conflicts with that of `cmath`'s `f{min, max}[f]`
|
||||
// Why? Like I fucking know dude
|
||||
|
||||
|
||||
template <typename T>
|
||||
T ReduceMin(const Vec3<T>& vect) {
|
||||
return std::min(std::min(vect.x, vect.y), vect.z);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ReduceMax(const Vec3<T>& vect) {
|
||||
return std::max(std::max(vect.x, vect.y), vect.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the (signed) minimal coordinate of the vector
|
||||
*
|
||||
* @param v
|
||||
* @return constexpr T
|
||||
*/
|
||||
template <>
|
||||
inline float ReduceMin<float>(const Vec3f& v) {
|
||||
return std::fminf(std::fminf(v.x, v.y), v.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the (signed) maximal coordinate of the vector
|
||||
*
|
||||
* @param v
|
||||
* @return constexpr T
|
||||
*/
|
||||
template <>
|
||||
inline float ReduceMax<float>(const Vec3f& v) {
|
||||
return std::fmaxf(std::fmaxf(v.x, v.y), v.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the (signed) minimal coordinate of the vector
|
||||
*
|
||||
* @param v
|
||||
* @return constexpr T
|
||||
*/
|
||||
template <>
|
||||
inline double ReduceMin<double>(const Vec3d& v) {
|
||||
return std::fmin(std::fmin(v.x, v.y), v.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the (signed) maximal coordinate of the vector
|
||||
*
|
||||
* @param v
|
||||
* @return constexpr T
|
||||
*/
|
||||
template <>
|
||||
inline double ReduceMax<double>(const Vec3d& v) {
|
||||
return std::fmax(std::fmax(v.x, v.y), v.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the coordinate-wise minimum of the given vectors,
|
||||
* where a coordinate in the returned vector is NAN iff any of the two compared ones are NAN
|
||||
*
|
||||
* @tparam T
|
||||
* @param self
|
||||
* @param other
|
||||
* @return constexpr Vec3f
|
||||
*/
|
||||
template <typename T>
|
||||
constexpr Vec3<T> Min(const Vec3<T>& self, const Vec3<T>& other) {
|
||||
return {
|
||||
std::min(self.x, other.x),
|
||||
std::min(self.y, other.y),
|
||||
std::min(self.z, other.z),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the coordinate-wise maximum of the given vectors,
|
||||
* where a coordinate in the returned vector is NAN iff any of the two compared ones are NAN
|
||||
*
|
||||
* @tparam T
|
||||
* @param self
|
||||
* @param other
|
||||
* @return constexpr Vec3f
|
||||
*/
|
||||
template <typename T>
|
||||
constexpr Vec3<T> Max(const Vec3<T>& self, const Vec3<T>& other) {
|
||||
return {
|
||||
std::max(self.x, other.x),
|
||||
std::max(self.y, other.y),
|
||||
std::max(self.z, other.z),
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Matricies //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
30
include/blitz/maths/Physics.h
Normal file
30
include/blitz/maths/Physics.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/maths/Vector.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace maths {
|
||||
|
||||
struct Ray {
|
||||
Vec3f origin;
|
||||
Vec3f direction;
|
||||
};
|
||||
|
||||
struct AABB {
|
||||
Vec3f from;
|
||||
Vec3f to;
|
||||
};
|
||||
|
||||
inline AABB operator+(const AABB& aabb, const Vec3f& offset) {
|
||||
AABB result = aabb;
|
||||
result.from += offset;
|
||||
result.to += offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
float Distance(const Ray& ray, const AABB& aabb);
|
||||
|
||||
bool Intersects(const Ray& ray, const AABB& aabb);
|
||||
|
||||
} // namespace maths
|
||||
} // namespace blitz
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
|
||||
namespace blitz {
|
||||
@@ -23,10 +25,6 @@ struct Vec2 {
|
||||
constexpr Vec2(T X = 0, T Y = 0) : x(X), y(Y) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct Vec3 {
|
||||
union {
|
||||
@@ -47,10 +45,6 @@ struct Vec3 {
|
||||
constexpr Vec3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct Vec4 {
|
||||
union {
|
||||
@@ -77,10 +71,6 @@ struct Vec4 {
|
||||
constexpr Vec4(T X = 0, T Y = 0, T Z = 0, T W = 0) : x(X), y(Y), z(Z), w(W) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using Vec2uc = Vec2<unsigned char>;
|
||||
using Vec2i = Vec2<int>;
|
||||
using Vec2u = Vec2<unsigned int>;
|
||||
@@ -178,7 +168,7 @@ Vec3<T>& operator+=(Vec3<T>& vect, const Vec3<T>& other) {
|
||||
|
||||
template <typename T>
|
||||
constexpr Vec3<T> operator-(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||
return vect + (-other);
|
||||
return {vect.x - other.x, vect.y - other.y, vect.z - other.z};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -197,9 +187,44 @@ constexpr Vec3<T> operator*(T mult, const Vec3<T>& vect) {
|
||||
return vect * mult;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Vec3<T> operator*=(const Vec3<T>& vect, T mult) {
|
||||
vect = vect * mult;
|
||||
return vect;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Vec3<T> operator*=(T mult, const Vec3<T>& vect) {
|
||||
vect = vect * mult;
|
||||
return vect;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Vec3<T> operator*(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||
return {vect.x * other.x, vect.y * other.y, vect.z * other.z};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vec3<T>& operator*=(Vec3<T>& vect, const Vec3<T>& other) {
|
||||
vect = vect * other;
|
||||
return vect;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Vec3<T> operator/(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||
return {vect.x / other.x, vect.y / other.y, vect.z / other.z};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vec3<T>& operator/=(Vec3<T>& vect, const Vec3<T>& other) {
|
||||
vect = vect / other;
|
||||
return vect;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool operator<(const Vec3<T>& vec3, const Vec3<T>& other) {
|
||||
return vec3.x < other.x && vec3.y < other.y && vec3.z < other.z;
|
||||
}
|
||||
|
||||
// Vec4
|
||||
|
||||
@@ -245,10 +270,6 @@ constexpr Vec4<T> operator*(T mult, const Vec4<T>& vect) {
|
||||
return vect * mult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Matrix //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -279,26 +300,18 @@ struct Mat4 {
|
||||
}
|
||||
|
||||
T at(std::size_t row, std::size_t column) const {
|
||||
return operator[](row* MATRIX_SIZE + column);
|
||||
return operator[](row * MATRIX_SIZE + column);
|
||||
}
|
||||
|
||||
T& at(std::size_t row, std::size_t column) {
|
||||
return operator[](row* MATRIX_SIZE + column);
|
||||
return operator[](row * MATRIX_SIZE + column);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef Mat4<float> Mat4f;
|
||||
typedef Mat4<int> Mat4i;
|
||||
typedef Mat4<double> Mat4d;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool operator==(const Mat4<T>& mat, const Mat4<T>& other) {
|
||||
return mat.x0 == other.x0 && mat.y0 == other.y0 && mat.z0 == other.z0 && mat.w0 == other.w0 && mat.x1 == other.x1 &&
|
||||
@@ -306,5 +319,4 @@ bool operator==(const Mat4<T>& mat, const Mat4<T>& other) {
|
||||
mat.z2 == other.z2 && mat.w2 == other.w2 && mat.x3 == other.x3 && mat.y3 == other.y3 && mat.z3 == other.z3 &&
|
||||
mat.w3 == other.w3;
|
||||
}
|
||||
|
||||
} // namespace blitz
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include <string>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
@@ -31,6 +31,7 @@ class PacketHandler {
|
||||
virtual void HandlePacket(const PlayerPositionAndRotationPacket* packet) {}
|
||||
virtual void HandlePacket(const PlayerShootPacket* packet) {}
|
||||
virtual void HandlePacket(const ServerTpsPacket* packet) {}
|
||||
virtual void HandlePacket(const UpdateHealthPacket* packet) {}
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
#include "packets/PlayerLoginPacket.h"
|
||||
#include "packets/PlayerPositionAndRotationPacket.h"
|
||||
#include "packets/PlayerShootPacket.h"
|
||||
#include "packets/ServerTpsPacket.h"
|
||||
#include "packets/ServerTpsPacket.h"
|
||||
#include "packets/UpdateHealthPacket.h"
|
||||
@@ -14,6 +14,7 @@ class PlayerLoginPacket;
|
||||
class PlayerPositionAndRotationPacket;
|
||||
class PlayerShootPacket;
|
||||
class ServerTpsPacket;
|
||||
class UpdateHealthPacket;
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
|
||||
@@ -20,6 +20,7 @@ enum class PacketType : std::uint8_t {
|
||||
// client --> server
|
||||
|
||||
PlayerLogin = 0, /**< Corresponds to PlayerLoginPacket */
|
||||
UpdateHealth, /**< Corresponds to UpdateHealthPacket */
|
||||
|
||||
// client <-- server
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include "blitz/protocol/Protocol.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Defines.h"
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include "blitz/protocol/Protocol.h"
|
||||
|
||||
namespace blitz {
|
||||
|
||||
31
include/blitz/protocol/packets/UpdateHealthPacket.h
Normal file
31
include/blitz/protocol/packets/UpdateHealthPacket.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/protocol/Protocol.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
class UpdateHealthPacket : public Packet {
|
||||
private:
|
||||
float m_NewHealth;
|
||||
|
||||
public:
|
||||
UpdateHealthPacket() {}
|
||||
UpdateHealthPacket(float newHealth) : m_NewHealth(newHealth) {}
|
||||
virtual ~UpdateHealthPacket() {}
|
||||
|
||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler) const;
|
||||
|
||||
std::uint8_t GetNewHealth() const {
|
||||
return m_NewHealth;
|
||||
}
|
||||
|
||||
virtual PacketType GetType() const {
|
||||
return PacketType::UpdateHealth;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
@@ -24,6 +24,7 @@ class ClientGame : public game::Game, public protocol::PacketHandler {
|
||||
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::PlayerShootPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::UpdateHealthPacket* packet) override;
|
||||
|
||||
private:
|
||||
void RegisterHandlers();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include "client/render/loader/ModelLoader.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/game/Player.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include "client/render/OpenGL.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ class ServerGame : public game::Game {
|
||||
ServerGame(Server* server);
|
||||
virtual ~ServerGame();
|
||||
|
||||
void CheckShoot(game::PlayerID player, Vec3f position, float yaw, float pitch);
|
||||
|
||||
void AddPlayer(game::PlayerID player, const std::string& name) override;
|
||||
void RemovePlayer(game::PlayerID player) override;
|
||||
|
||||
@@ -24,6 +26,8 @@ class ServerGame : public game::Game {
|
||||
|
||||
private:
|
||||
void SendPlayerPositions();
|
||||
void DamagePlayer(game::Player& player, game::Player& shooter);
|
||||
void UpdateHP(game::Player& player, float newHP);
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
|
||||
@@ -22,8 +22,11 @@ const Player* Game::GetPlayerById(PlayerID id) const {
|
||||
}
|
||||
|
||||
void Game::AddPlayer(PlayerID player, const std::string& name) {
|
||||
static float MAX_HP = 100;
|
||||
|
||||
game::Player newPlayer{player};
|
||||
newPlayer.SetName(name);
|
||||
newPlayer.SetHP(MAX_HP);
|
||||
|
||||
GetPlayers().insert({player, newPlayer});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "blitz/misc/Maths.h"
|
||||
#include "blitz/maths/Maths.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
68
src/blitz/maths/Physics.cpp
Executable file
68
src/blitz/maths/Physics.cpp
Executable file
@@ -0,0 +1,68 @@
|
||||
#include "blitz/maths/Physics.h"
|
||||
#include "blitz/maths/Maths.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace blitz {
|
||||
namespace maths {
|
||||
|
||||
/**
|
||||
* @brief Returns `true` if the half-line `ray` _strictly_ intersects with `aabb`,
|
||||
* and `false` if it _strictly_ doesn't intersect.
|
||||
* Note that if it only intersects with corners, edges, or sides of the box,
|
||||
* or if any coordinate in `ray` is `NAN` or `inf` or if any coordinate in
|
||||
* `aabb` is `NAN` the result is unspecified.
|
||||
* */
|
||||
float Distance(const Ray& ray, const AABB& aabb) {
|
||||
|
||||
// This function calculates smallest interval I = ] a, b [, for strictly positive a and b
|
||||
// such that for all t in I, for all l, r, o, d corresponding
|
||||
// coordinates in aabb.from, aabb.to, ray.origin, ray.direction, respectively
|
||||
//
|
||||
// min(l, r) < o + t * d < max(l, r)
|
||||
//
|
||||
// and returns true if it's non-empty i.e. a < b
|
||||
|
||||
// m = min(l, r), M = max(l, r)
|
||||
// m < o + t * d < M
|
||||
Vec3f l = Min(aabb.from, aabb.to);
|
||||
Vec3f r = Max(aabb.to, aabb.from);
|
||||
|
||||
// m - o < t * d < M - o
|
||||
l -= ray.origin;
|
||||
r -= ray.origin;
|
||||
|
||||
// (m - o) / d < t < (M - o) / d
|
||||
l /= ray.direction;
|
||||
r /= ray.direction;
|
||||
|
||||
// but if d is negative the inequality is flipped
|
||||
Vec3f u = Min(l, r);
|
||||
r = Max(l, r);
|
||||
l = u;
|
||||
|
||||
float tmin = ReduceMax(l);
|
||||
float tmax = ReduceMin(r);
|
||||
|
||||
// Since Min propagates NANs and ReduceMin doesn't, and since NAN !< <any float>
|
||||
// the inequality becomes ignored for coordinates where a NAN is involved
|
||||
// (as a result of 0.0 / 0.0). If all coordinates are NAN, this means
|
||||
// that the box is reduced to a point and the ray has direction 0,
|
||||
// in which case this returns -1
|
||||
if (tmax >= 0.0f && tmin <= tmax) {
|
||||
return std::fmaxf(tmin, 0.0f);
|
||||
}
|
||||
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
bool Intersects(const AABB& aabb1, const AABB& aabb2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Intersects(const Ray& ray, const AABB& aabb) {
|
||||
return Distance(ray, aabb) >= 0.0f;
|
||||
}
|
||||
|
||||
} // namespace maths
|
||||
} // namespace blitz
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "blitz/misc/Easing.h"
|
||||
|
||||
#include "blitz/misc/Maths.h"
|
||||
#include "blitz/maths/Maths.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace utils {
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef std::unique_ptr<Packet> PacketPtr;
|
||||
|
||||
static std::array<PacketPtr, static_cast<std::size_t>(PacketType::PACKET_COUNT)> Packets = {
|
||||
std::make_unique<PlayerLoginPacket>(),
|
||||
std::make_unique<UpdateHealthPacket>(),
|
||||
std::make_unique<ConnexionInfoPacket>(),
|
||||
std::make_unique<PlayerJoinPacket>(),
|
||||
std::make_unique<PlayerLeavePacket>(),
|
||||
|
||||
@@ -25,6 +25,7 @@ REGISTER_DISPATCH_CLASS(ServerTpsPacket)
|
||||
REGISTER_DISPATCH_CLASS(ChatPacket)
|
||||
REGISTER_DISPATCH_CLASS(PlayerPositionAndRotationPacket)
|
||||
REGISTER_DISPATCH_CLASS(PlayerShootPacket);
|
||||
REGISTER_DISPATCH_CLASS(UpdateHealthPacket);
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "blitz/protocol/packets/ChatPacket.h"
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
19
src/blitz/protocol/packets/UpdateHealthPacket.cpp
Normal file
19
src/blitz/protocol/packets/UpdateHealthPacket.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "blitz/protocol/packets/UpdateHealthPacket.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
DataBuffer UpdateHealthPacket::Serialize(bool packetID) const {
|
||||
DataBuffer data;
|
||||
|
||||
WritePacketID(data, packetID);
|
||||
data << m_NewHealth;
|
||||
return data;
|
||||
}
|
||||
|
||||
void UpdateHealthPacket::Deserialize(DataBuffer& data) {
|
||||
data >> m_NewHealth;
|
||||
}
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "client/display/PlayerController.h"
|
||||
|
||||
#include "blitz/game/Player.h"
|
||||
#include "blitz/maths/Maths.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
#include "blitz/misc/Maths.h"
|
||||
#include "client/Client.h"
|
||||
#include "client/display/InputManager.h"
|
||||
#include "imgui.h"
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include "client/game/ClientGame.h"
|
||||
|
||||
#include "blitz/misc/Log.h"
|
||||
#include "blitz/misc/Random.h"
|
||||
#include "blitz/protocol/PacketDispatcher.h"
|
||||
#include "blitz/protocol/packets/PlayerJoinPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerLeavePacket.h"
|
||||
#include "blitz/protocol/packets/PlayerListPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerShootPacket.h"
|
||||
#include "blitz/protocol/packets/UpdateHealthPacket.h"
|
||||
#include "client/Client.h"
|
||||
|
||||
namespace blitz {
|
||||
@@ -27,6 +29,7 @@ void ClientGame::RegisterHandlers() {
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerShoot, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateHealth, this);
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
|
||||
@@ -48,6 +51,17 @@ void ClientGame::HandlePacket(const protocol::PlayerListPacket* packet) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::UpdateHealthPacket* packet) {
|
||||
game::Player* player = m_Client->GetGame()->GetPlayerById(m_Client->GetPlayerID());
|
||||
player->SetHP(packet->GetNewHealth());
|
||||
|
||||
// we are dead
|
||||
if (player->GetHP() <= 0.0f) {
|
||||
player->SetPosition({utils::GetRandomReal(-10.0f, 10.0f), 0, utils::GetRandomReal(-10.0f, 10.0f)});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::PlayerShootPacket* packet) {
|
||||
m_Client->NotifyListeners(
|
||||
&GuiListener::OnPlayerShoot, packet->GetPlayer(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "client/gui/Hud.h"
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "client/game/ClientGame.h"
|
||||
#include "client/gui/GuiWidget.h"
|
||||
#include "client/render/loader/TextureLoader.h"
|
||||
#include <client/Client.h>
|
||||
#include <imgui.h>
|
||||
|
||||
namespace blitz {
|
||||
@@ -37,28 +38,16 @@ void Hud::Draw(const char* title, bool* p_open) {
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(m_JP), jpSize);
|
||||
|
||||
ImGui::SameLine(0.0f, paddingHeight);
|
||||
// ImGui::EndGroup();
|
||||
|
||||
// ImGui::SetCursorPosX(pvBarPos.x);
|
||||
// ImGui::SetCursorPosY(pvBarPos.y);
|
||||
ImGui::BeginGroup();
|
||||
{
|
||||
// Animate a simple progress bar
|
||||
static float progress = 0.0f, progress_dir = 1.0f;
|
||||
progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime;
|
||||
if (progress >= +1.0f) {
|
||||
progress = +1.0f;
|
||||
progress_dir *= -1.0f;
|
||||
}
|
||||
if (progress <= 0.0f) {
|
||||
progress = 0.0f;
|
||||
progress_dir *= -1.0f;
|
||||
}
|
||||
int pv = static_cast<int>(progress * 100);
|
||||
game::Player* player = m_Client->GetGame()->GetPlayerById(m_Client->GetPlayerID());
|
||||
|
||||
ImGui::Text("PV : %i", pv);
|
||||
// ImGui::Dummy();
|
||||
ImGui::ProgressBar(progress, progressSize, "");
|
||||
if (player) {
|
||||
ImGui::Text("PV : %.0f", player->GetHP());
|
||||
|
||||
ImGui::ProgressBar(static_cast<float>(player->GetHP() / 100.0f), progressSize, "");
|
||||
}
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
ImGui::EndGroup();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "client/render/BulletRenderer.h"
|
||||
|
||||
#include "blitz/maths/Maths.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
#include "blitz/misc/Maths.h"
|
||||
#include "blitz/misc/Test.h"
|
||||
#include "client/render/Camera.h"
|
||||
#include "client/render/OpenGL.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "client/render/Camera.h"
|
||||
|
||||
#include "blitz/game/Player.h"
|
||||
#include "blitz/misc/Maths.h"
|
||||
#include "blitz/maths/Maths.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace blitz {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "client/render/MainRenderer.h"
|
||||
|
||||
#include "blitz/maths/Maths.h"
|
||||
#include "blitz/misc/Easing.h"
|
||||
#include "blitz/misc/Format.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
#include "blitz/misc/Maths.h"
|
||||
#include "blitz/misc/Test.h"
|
||||
#include "blitz/misc/Time.h"
|
||||
#include "client/Client.h"
|
||||
|
||||
@@ -170,6 +170,7 @@ void Server::AddBot() {
|
||||
// set the bot at a random location to be able to see several of them
|
||||
game::Player* botPlayer = m_Game.GetPlayerById(botID);
|
||||
botPlayer->SetPosition({utils::GetRandomReal(-10.0f, 10.0f), 0.0f, utils::GetRandomReal(-10.0f, 10.0f)});
|
||||
botPlayer->SetBot();
|
||||
}
|
||||
|
||||
} // namespace server
|
||||
|
||||
@@ -134,6 +134,8 @@ void ServerConnexion::HandlePacket(const protocol::PlayerPositionAndRotationPack
|
||||
void ServerConnexion::HandlePacket(const protocol::PlayerShootPacket* packet) {
|
||||
protocol::PlayerShootPacket broadcastShoot(packet->GetPosition(), packet->GetYaw(), packet->GetPitch(), m_Player->GetID());
|
||||
m_Server->BroadcastPacket(&broadcastShoot);
|
||||
|
||||
m_Server->GetGame().CheckShoot(m_Player->GetID(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
|
||||
}
|
||||
|
||||
void ServerConnexion::Start() {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
#include "server/game/ServerGame.h"
|
||||
|
||||
#include "blitz/maths/Physics.h"
|
||||
#include "blitz/misc/Format.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
#include "blitz/misc/Random.h"
|
||||
#include "blitz/protocol/packets/ChatPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerJoinPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
|
||||
#include "blitz/protocol/packets/UpdateHealthPacket.h"
|
||||
#include "server/Server.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace blitz {
|
||||
namespace server {
|
||||
@@ -27,6 +31,33 @@ void ServerGame::SendPlayerPositions() {
|
||||
}
|
||||
}
|
||||
|
||||
void ServerGame::CheckShoot(game::PlayerID shooter, Vec3f position, float yaw, float pitch) {
|
||||
maths::Ray shootRay;
|
||||
shootRay.origin = position + Vec3f{0.0, 1.75, 0.0};
|
||||
shootRay.direction = {
|
||||
std::cos(yaw) * std::cos(pitch),
|
||||
std::sin(pitch),
|
||||
std::sin(yaw) * std::cos(pitch),
|
||||
};
|
||||
|
||||
static const maths::AABB playerStaticAABB = {Vec3f{-0.5f, 0.0f, -0.5f}, Vec3f{0.5f, 1.8f, 0.5f}};
|
||||
|
||||
bool shootLanded = false;
|
||||
|
||||
game::Player* shooterPlayer = GetPlayerById(shooter);
|
||||
|
||||
for (auto& [playerId, player] : GetPlayers()) {
|
||||
if (playerId != shooter && maths::Intersects(shootRay, playerStaticAABB + player.GetPosition())) {
|
||||
DamagePlayer(player, *shooterPlayer);
|
||||
shootLanded = true;
|
||||
}
|
||||
}
|
||||
|
||||
shooterPlayer->GetStats().m_ShootCount++;
|
||||
if (shootLanded)
|
||||
shooterPlayer->GetStats().m_ShootSuccessCount++;
|
||||
}
|
||||
|
||||
void ServerGame::AddPlayer(game::PlayerID player, const std::string& name) {
|
||||
Game::AddPlayer(player, name);
|
||||
|
||||
@@ -43,5 +74,30 @@ void ServerGame::RemovePlayer(game::PlayerID player) {
|
||||
Game::RemovePlayer(player);
|
||||
}
|
||||
|
||||
void ServerGame::DamagePlayer(game::Player& player, game::Player& shooter) {
|
||||
static float MAX_HP = 100;
|
||||
static float GUN_DAMAGE = 50;
|
||||
|
||||
UpdateHP(player, player.GetHP() - GUN_DAMAGE);
|
||||
|
||||
// player is dead
|
||||
if (player.GetHP() <= 0.0f) {
|
||||
UpdateHP(player, MAX_HP);
|
||||
player.GetStats().m_Deaths++;
|
||||
shooter.GetStats().m_Kills++;
|
||||
player.SetPosition({utils::GetRandomReal(-10.0f, 10.0f), 0.0f, utils::GetRandomReal(-10.0f, 10.0f)});
|
||||
}
|
||||
}
|
||||
|
||||
void ServerGame::UpdateHP(game::Player& player, float newHP) {
|
||||
player.SetHP(newHP);
|
||||
|
||||
if (player.IsBot())
|
||||
return;
|
||||
|
||||
protocol::UpdateHealthPacket packet(player.GetHP());
|
||||
m_Server->GetConnexions().at(player.GetID())->SendPacket(&packet);
|
||||
}
|
||||
|
||||
} // namespace server
|
||||
} // namespace blitz
|
||||
|
||||
105
test/test_intersects.cpp
Executable file
105
test/test_intersects.cpp
Executable file
@@ -0,0 +1,105 @@
|
||||
#include "blitz/misc/Test.h"
|
||||
|
||||
#include "blitz/maths/Physics.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
#include "blitz/misc/Format.h"
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
|
||||
using namespace blitz;
|
||||
using namespace maths;
|
||||
|
||||
#define let auto // sexy boiiii
|
||||
|
||||
static void test_left() {
|
||||
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {-2.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_right() {
|
||||
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {2.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_forward() {
|
||||
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.0f, 2.0f, 0.0f}, {0.0f, -1.0f, 0.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_backward() {
|
||||
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.0f, -2.0f, 0.0f}, {0.0f, 1.0f, 0.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_above() {
|
||||
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.0f, 0.0f, 2.0f}, {0.0f, 0.0f, -1.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_below() {
|
||||
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.0f, 0.0f, -2.0f}, {0.0f, 0.0f, 1.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_shifted() {
|
||||
let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {-3.0f, 0.0f, 100.0f}, {1.0f, 0.0f, 0.0f} };
|
||||
|
||||
blitz_test_assert(!Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_corner_inside() {
|
||||
let box = AABB { {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.0f, 0.0f, 0.0f}, {0.5f, 0.5f, 0.5f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_corner_inside_weird() {
|
||||
let box = AABB { {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_corner_inside_opposite_big() {
|
||||
let box = AABB { {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.0f, 0.0f, 0.0f}, {1.5f, 1.5f, 1.5f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
static void test_corner_inside_opposite_weird() {
|
||||
let box = AABB { {0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f} };
|
||||
let ray = Ray { {0.4f, 0.4f, 0.4f}, {-1.0f, -1.0f, -1.0f} };
|
||||
|
||||
blitz_test_assert(Intersects(ray, box));
|
||||
}
|
||||
|
||||
int main(int argc, const char* args[]) {
|
||||
test_left();
|
||||
test_right();
|
||||
test_forward();
|
||||
test_backward();
|
||||
test_below();
|
||||
test_above();
|
||||
test_shifted();
|
||||
test_corner_inside();
|
||||
test_corner_inside_weird();
|
||||
test_corner_inside_opposite_big();
|
||||
test_corner_inside_opposite_weird();
|
||||
return BLITZ_TEST_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "blitz/misc/Test.h"
|
||||
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
|
||||
using namespace blitz;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user