7 Commits
sync ... 3D

Author SHA1 Message Date
4b732c2fe9 add ressources 2023-06-28 22:54:22 +02:00
66b39e1855 multiple mobs render 2023-06-28 22:51:36 +02:00
b985cc7ade make use of TexturedModel 2023-06-28 22:19:18 +02:00
385dcf11d0 load basic 3d model 2023-06-28 21:23:42 +02:00
385626d42b debug spawning 2023-06-28 21:18:02 +02:00
6b9528c2ae add face culling 2023-06-26 09:59:08 +02:00
c9ee8216be add depth 2023-06-26 09:37:23 +02:00
111 changed files with 6521 additions and 1958 deletions

View File

@@ -36,8 +36,6 @@ protected:
TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
GameState m_GameState = GameState::Lobby;
PlayerList m_Players;
std::uint64_t m_GameStartTime = 0;
public:
Game(World* world);
virtual ~Game();
@@ -67,8 +65,6 @@ public:
const TeamList& GetTeams() const { return m_Teams; }
std::uint64_t GetGameStartTime() const { return m_GameStartTime; }
};
} // namespace game

View File

@@ -7,7 +7,6 @@
#include "game/Player.h"
#include "protocol/Protocol.h"
#include "protocol/packets/SendMobsPacket.h"
#include "render/Renderer.h"

View File

@@ -18,7 +18,7 @@ class ClientGame : public protocol::PacketHandler, public game::Game {
private:
Client* m_Client;
std::uint8_t m_ConnexionID;
std::uint64_t m_LobbyStartTime = 0;
std::uint32_t m_LobbyTime = 0;
game::Player* m_Player = nullptr;
render::Renderer* m_Renderer;
client::WorldClient m_WorldClient;
@@ -31,7 +31,7 @@ public:
void RenderWorld();
std::uint64_t GetLobbyStartTime() const { return m_LobbyStartTime; }
std::uint32_t GetLobbyTime() const { return m_LobbyTime; }
const game::Player* GetPlayer() const { return m_Player; }
const WorldClient& GetWorld() const { return m_WorldClient; }
Client* GetClient() const { return m_Client; }

View File

@@ -13,7 +13,7 @@ class Lobby {
private:
Server* m_Server;
bool m_GameStarted = false;
std::uint64_t m_StartTime = 0;
std::uint64_t m_StartTimerTime = 0;
std::vector<std::uint8_t> m_Players;
utils::AutoTimer m_Timer;
public:

View File

@@ -1,7 +1,6 @@
#pragma once
#include "protocol/Protocol.h"
#include "protocol/PacketsForward.h"
namespace td {
namespace protocol {

View File

@@ -1,27 +0,0 @@
#include "packets/ConnectionInfoPacket.h"
#include "packets/DisconnectPacket.h"
#include "packets/KeepAlivePacket.h"
#include "packets/PlaceTowerPacket.h"
#include "packets/PlayerBuyItemPacket.h"
#include "packets/PlayerBuyMobUpgradePacket.h"
#include "packets/PlayerJoinPacket.h"
#include "packets/PlayerLeavePacket.h"
#include "packets/PlayerListPacket.h"
#include "packets/PlayerLoginPacket.h"
#include "packets/RemoveTowerPacket.h"
#include "packets/SelectTeamPacket.h"
#include "packets/SendMobsPacket.h"
#include "packets/ServerTpsPacket.h"
#include "packets/SpawnMobPacket.h"
#include "packets/UpdateCastleLifePacket.h"
#include "packets/UpdateExpPacket.h"
#include "packets/UpdateGameStatePacket.h"
#include "packets/UpdateLobbyTimePacket.h"
#include "packets/UpdateMobStatesPacket.h"
#include "packets/UpdateMoneyPacket.h"
#include "packets/UpdatePlayerTeamPacket.h"
#include "packets/UpgradeTowerPacket.h"
#include "packets/WorldAddTowerPacket.h"
#include "packets/WorldAddTowerPacket.h"
#include "packets/WorldBeginDataPacket.h"
#include "packets/WorldDataPacket.h"

View File

@@ -1,34 +0,0 @@
#pragma once
namespace td {
namespace protocol {
class PlayerLoginPacket;
class WorldBeginDataPacket;
class WorldDataPacket;
class KeepAlivePacket;
class UpdateExpPacket;
class UpdateMoneyPacket;
class UpdateLobbyTimePacket;
class UpdateGameStatePacket;
class PlayerListPacket;
class PlayerJoinPacket;
class PlayerLeavePacket;
class ConnexionInfoPacket;
class SelectTeamPacket;
class UpdatePlayerTeamPacket;
class DisconnectPacket;
class ServerTpsPacket;
class SpawnMobPacket;
class PlaceTowerPacket;
class WorldAddTowerPacket;
class RemoveTowerPacket;
class SendMobsPacket;
class UpgradeTowerPacket;
class UpdateCastleLifePacket;
class UpdateMobStatesPacket;
class PlayerBuyItemPacket;
class PlayerBuyMobUpgradePacket;
} // namespace protocol
} // namespace td

View File

@@ -1,6 +1,8 @@
#pragma once
#include "misc/DataBuffer.h"
#include "game/World.h"
#include "game/BaseGame.h"
#include <memory>
@@ -45,6 +47,26 @@ enum class PacketType : std::uint8_t {
PACKET_COUNT
};
struct WorldHeader {
game::TowerTileColorPalette m_TowerPlacePalette;
Color m_WalkablePalette;
std::vector<Color> m_DecorationPalette;
Color m_Background;
game::SpawnColorPalette m_SpawnColorPalette;
game::TilePalette m_TilePalette;
game::Spawn m_RedSpawn, m_BlueSpawn;
game::TeamCastle m_RedCastle, m_BlueCastle;
const game::World* m_World;
};
struct WorldData {
std::unordered_map<game::ChunkCoord, game::ChunkPtr> m_Chunks;
};
class Packet {
public:
Packet() {}
@@ -54,37 +76,564 @@ public:
virtual void Deserialize(DataBuffer& data) = 0;
virtual void Dispatch(PacketHandler* handler) const = 0;
virtual void WritePacketID(DataBuffer& data, bool packetID) const;
void WritePacketID(DataBuffer& data, bool packetID) const;
virtual PacketType GetType() const = 0;
std::uint8_t GetID() const { return static_cast<std::uint8_t>(GetType()); }
virtual bool IsTimed() const { return false; }
};
class DelayedPacket : public Packet {
protected:
std::uint64_t m_PacketTime = 69;
public:
DelayedPacket() {}
virtual ~DelayedPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const = 0;
virtual void Deserialize(DataBuffer& data) = 0;
virtual void Dispatch(PacketHandler* handler) const = 0;
virtual void WritePacketID(DataBuffer& data, bool packetID) const override;
virtual PacketType GetType() const = 0;
virtual bool IsTimed() const override { return true; }
void SetPacketTime(std::uint64_t packetTime) { m_PacketTime = packetTime; }
};
typedef std::unique_ptr<Packet> PacketPtr;
typedef std::unique_ptr<DelayedPacket> DelayedPacketPtr;
class KeepAlivePacket : public Packet {
private:
std::uint64_t m_AliveID;
public:
KeepAlivePacket() {}
KeepAlivePacket(std::uint64_t aliveID) : m_AliveID(aliveID) {}
virtual ~KeepAlivePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint64_t GetAliveID() const { return m_AliveID; }
virtual PacketType GetType() const { return PacketType::KeepAlive; }
};
class PlayerLoginPacket : public Packet {
private:
std::string m_PlayerName;
public:
PlayerLoginPacket() {}
PlayerLoginPacket(std::string playerName) : m_PlayerName(playerName) {}
virtual ~PlayerLoginPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::PlayerLogin; }
const std::string& GetPlayerName() const { return m_PlayerName; }
};
class WorldBeginDataPacket : public Packet {
private:
WorldHeader m_Header;
public:
WorldBeginDataPacket() {}
WorldBeginDataPacket(const game::World* world) {
m_Header.m_World = world;
}
virtual ~WorldBeginDataPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::WorldBeginData; }
const game::TowerTileColorPalette& GetTowerTilePalette() const { return m_Header.m_TowerPlacePalette; }
const Color& GetWalkableTileColor() const { return m_Header.m_WalkablePalette; }
const std::vector<Color>& GetDecorationPalette() const { return m_Header.m_DecorationPalette; }
const Color& GetBackgroundColor() const { return m_Header.m_Background; }
const game::Spawn& GetRedSpawn() const { return m_Header.m_RedSpawn; }
const game::Spawn& GetBlueSpawn() const { return m_Header.m_BlueSpawn; }
const game::SpawnColorPalette& GetSpawnPalette() const { return m_Header.m_SpawnColorPalette; }
const game::TeamCastle& GetRedCastle() const { return m_Header.m_RedCastle; }
const game::TeamCastle& GetBlueCastle() const { return m_Header.m_BlueCastle; }
const game::TilePalette GetTilePalette() const { return m_Header.m_TilePalette; }
void setWorldHeader(const WorldHeader& header) { m_Header = header; }
};
class WorldDataPacket : public Packet {
private:
WorldData m_WorldData;
const game::World* m_World;
public:
WorldDataPacket() {}
WorldDataPacket(const game::World* world) : m_World(world) {}
virtual ~WorldDataPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::WorldData; }
const std::unordered_map<game::ChunkCoord, game::ChunkPtr>& GetChunks() const { return m_WorldData.m_Chunks; }
DataBuffer SerializeCustom() const; // allow serialisation with invalid World member
void SetWorldData(const WorldData& worldData) { m_WorldData = worldData; }
};
class UpdateMoneyPacket : public Packet {
private:
std::uint32_t m_NewAmount;
public:
UpdateMoneyPacket() {}
UpdateMoneyPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
virtual ~UpdateMoneyPacket() {}
std::uint32_t GetGold() const { return m_NewAmount; }
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::UpdateMoney; }
};
class UpdateExpPacket : public Packet {
private:
std::uint32_t m_NewAmount;
public:
UpdateExpPacket() {}
UpdateExpPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
virtual ~UpdateExpPacket() {}
std::uint32_t GetExp() const { return m_NewAmount; }
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::UpdateEXP; }
};
class UpdateLobbyTimePacket : public Packet {
private:
std::uint32_t m_RemainingTime;
public:
UpdateLobbyTimePacket() {}
UpdateLobbyTimePacket(std::uint32_t remainingTime) : m_RemainingTime(remainingTime) {}
virtual ~UpdateLobbyTimePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint32_t GetRemainingTime() const { return m_RemainingTime; }
virtual PacketType GetType() const { return PacketType::UpdateLobbyTime; }
};
class UpdateGameStatePacket : public Packet {
private:
game::GameState m_GameState;
public:
UpdateGameStatePacket() {}
UpdateGameStatePacket(game::GameState gameState) : m_GameState(gameState) {}
virtual ~UpdateGameStatePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::GameState GetGameState() const { return m_GameState; }
virtual PacketType GetType() const { return PacketType::UpdateGameState; }
};
struct PlayerInfo {
std::string name;
game::TeamColor team;
};
class PlayerListPacket : public Packet {
private:
std::map<std::uint8_t, PlayerInfo> m_Players;
public:
PlayerListPacket() {}
PlayerListPacket(std::map<std::uint8_t, PlayerInfo> players) : m_Players(players) {}
virtual ~PlayerListPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::map<std::uint8_t, PlayerInfo>& GetPlayers() const { return m_Players; }
virtual PacketType GetType() const { return PacketType::PlayerList; }
};
class PlayerJoinPacket : public Packet {
private:
std::uint8_t m_PlayerID;
std::string m_PlayerName;
public:
PlayerJoinPacket() {}
PlayerJoinPacket(std::uint8_t playerID, const std::string& playerName) : m_PlayerID(playerID), m_PlayerName(playerName) {}
virtual ~PlayerJoinPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t GetPlayerID() const { return m_PlayerID; }
const std::string& GetPlayerName() const { return m_PlayerName; }
virtual PacketType GetType() const { return PacketType::PlayerJoin; }
};
class PlayerLeavePacket : public Packet {
private:
std::uint8_t m_PlayerID;
public:
PlayerLeavePacket() {}
PlayerLeavePacket(std::uint8_t playerID) : m_PlayerID(playerID) {}
virtual ~PlayerLeavePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t GetPlayerID() const { return m_PlayerID; }
virtual PacketType GetType() const { return PacketType::PlayerLeave; }
};
class ConnexionInfoPacket : public Packet {
private:
std::uint8_t m_ConnectionID;
public:
ConnexionInfoPacket() {}
ConnexionInfoPacket(std::uint8_t connectionID) : m_ConnectionID(connectionID) {}
virtual ~ConnexionInfoPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t GetConnectionID() const { return m_ConnectionID; }
virtual PacketType GetType() const { return PacketType::ConnectionInfo; }
};
class SelectTeamPacket : public Packet {
private:
game::TeamColor m_SelectedTeam;
public:
SelectTeamPacket() {}
SelectTeamPacket(game::TeamColor selectedTeam) : m_SelectedTeam(selectedTeam) {}
virtual ~SelectTeamPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
virtual PacketType GetType() const { return PacketType::SelectTeam; }
};
class UpdatePlayerTeamPacket : public Packet {
private:
std::uint8_t m_PlayerID;
game::TeamColor m_SelectedTeam;
public:
UpdatePlayerTeamPacket() {}
UpdatePlayerTeamPacket(std::uint8_t playerID, game::TeamColor selectedTeam) : m_PlayerID(playerID), m_SelectedTeam(selectedTeam) {}
virtual ~UpdatePlayerTeamPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
std::uint8_t GetPlayerID() const { return m_PlayerID; }
virtual PacketType GetType() const { return PacketType::UpdatePlayerTeam; }
};
class DisconnectPacket : public Packet {
private:
std::string m_Reason; // only when sent from server
public:
DisconnectPacket() {}
DisconnectPacket(std::string reason) : m_Reason(reason) {}
virtual ~DisconnectPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::string& GetReason() const { return m_Reason; }
virtual PacketType GetType() const { return PacketType::Disconnect; }
};
class ServerTpsPacket : public Packet {
private:
float m_TPS;
float m_MSPT;
std::uint64_t m_PacketSendTime; // used to calculate ping
public:
ServerTpsPacket() {}
ServerTpsPacket(float tps, float mspt, std::uint64_t sendTime) : m_TPS(tps), m_MSPT(mspt), m_PacketSendTime(sendTime) {}
virtual ~ServerTpsPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
float GetTPS() const { return m_TPS; }
float GetMSPT() const { return m_MSPT; }
std::uint64_t GetPacketSendTime() const { return m_PacketSendTime; }
virtual PacketType GetType() const { return PacketType::ServerTps; }
};
struct MobSend { // represents a mob send
game::MobType mobType : 4;
game::MobLevel mobLevel : 4;
std::uint8_t mobCount; // the max is 12
};
class SendMobsPacket : public Packet {
private:
std::vector<MobSend> m_MobSends;
public:
SendMobsPacket() {}
SendMobsPacket(const std::vector<MobSend>& mobSends) : m_MobSends(mobSends) {}
virtual ~SendMobsPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::vector<MobSend>& GetMobSends() const { return m_MobSends; }
virtual PacketType GetType() const { return PacketType::SendMobs; }
};
class SpawnMobPacket : public Packet {
private:
game::MobID m_MobID;
game::MobType m_MobType;
game::MobLevel m_MobLevel;
game::Direction m_MobDirection;
game::PlayerID m_Sender;
float m_MobX, m_MobY;
public:
SpawnMobPacket() {}
SpawnMobPacket(game::MobID id, game::MobType type, std::uint8_t level, game::PlayerID sender,
float x, float y, game::Direction dir) : m_MobID(id), m_MobType(type), m_MobLevel(level),
m_MobDirection(dir), m_Sender(sender), m_MobX(x), m_MobY(y) {
}
virtual ~SpawnMobPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::MobID GetMobID() const { return m_MobID; }
game::MobType GetMobType() const { return m_MobType; }
game::MobLevel GetMobLevel() const { return m_MobLevel; }
game::Direction GetMobDirection() const { return m_MobDirection; }
game::PlayerID GetSender() const { return m_Sender; }
float GetMobX() const { return m_MobX; }
float GetMobY() const { return m_MobY; }
virtual PacketType GetType() const { return PacketType::SpawnMob; }
};
class PlaceTowerPacket : public Packet {
private:
std::int32_t m_TowerX, m_TowerY;
game::TowerType m_TowerType;
public:
PlaceTowerPacket() {}
PlaceTowerPacket(std::int32_t x, std::int32_t y, game::TowerType type) :
m_TowerX(x), m_TowerY(y), m_TowerType(type) {
}
virtual ~PlaceTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::int32_t GetTowerX() const { return m_TowerX; }
std::int32_t GetTowerY() const { return m_TowerY; }
game::TowerType GetTowerType() const { return m_TowerType; }
virtual PacketType GetType() const { return PacketType::PlaceTower; }
};
class WorldAddTowerPacket : public Packet {
private:
game::TowerID m_TowerID;
std::int32_t m_TowerX, m_TowerY;
game::TowerType m_TowerType;
game::PlayerID m_Builder;
public:
WorldAddTowerPacket() {}
WorldAddTowerPacket(game::TowerID id, std::int32_t x, std::int32_t y, game::TowerType type, game::PlayerID player) :
m_TowerID(id), m_TowerX(x), m_TowerY(y), m_TowerType(type), m_Builder(player) {
}
virtual ~WorldAddTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID GetTowerID() const { return m_TowerID; }
std::int32_t GetTowerX() const { return m_TowerX; }
std::int32_t GetTowerY() const { return m_TowerY; }
game::TowerType GetTowerType() const { return m_TowerType; }
game::PlayerID GetBuilder() const { return m_Builder; }
virtual PacketType GetType() const { return PacketType::WorldAddTower; }
};
class RemoveTowerPacket : public Packet {
private:
game::TowerID m_TowerID;
public:
RemoveTowerPacket() {}
RemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
virtual ~RemoveTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID GetTowerID() const { return m_TowerID; }
virtual PacketType GetType() const { return PacketType::RemoveTower; }
};
class UpgradeTowerPacket : public Packet {
private:
game::TowerID m_TowerID;
game::TowerLevel m_TowerLevel;
public:
UpgradeTowerPacket() {}
UpgradeTowerPacket(game::TowerID tower, game::TowerLevel level) : m_TowerID(tower), m_TowerLevel(level) {}
virtual ~UpgradeTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID GetTowerID() const { return m_TowerID; }
game::TowerLevel GetTowerLevel() const { return m_TowerLevel; }
virtual PacketType GetType() const { return PacketType::UpgradeTower; }
};
class MobState {
using Point = utils::shape::Point;
private:
game::MobID m_MobID;
Point m_MobPosition;
float m_MobLife;
game::Direction m_MobDirection;
public:
MobState() {}
MobState(game::MobID id, const Point& position, float life, game::Direction direction) :
m_MobID(id), m_MobPosition(position), m_MobLife(life), m_MobDirection(direction) {
}
game::MobID GetMobId() const { return m_MobID; }
Point GetMobPosition() const { return m_MobPosition; }
float GetMobLife() const { return m_MobLife; }
game::Direction GetMobDirection() const { return m_MobDirection; }
};
class UpdateMobStatesPacket : public Packet {
private:
std::vector<MobState> m_MobStates;
public:
UpdateMobStatesPacket() {}
virtual ~UpdateMobStatesPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
void addMobState(MobState mobState) { m_MobStates.push_back(mobState); }
const std::vector<MobState>& GetMobStates() const { return m_MobStates; }
virtual PacketType GetType() const { return PacketType::UpdateMobStates; }
};
class UpdateCastleLifePacket : public Packet {
private:
std::uint16_t m_CastleLife;
game::TeamColor m_Team;
public:
UpdateCastleLifePacket() {}
UpdateCastleLifePacket(std::uint16_t life, game::TeamColor team) : m_CastleLife(life), m_Team(team) {}
virtual ~UpdateCastleLifePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint16_t GetCastleLife() const { return m_CastleLife; }
game::TeamColor GetTeamColor() const { return m_Team; }
virtual PacketType GetType() const { return PacketType::UpdateCastleLife; }
};
enum class ItemType : std::uint8_t {
// Upgrades
ClickerUpgrade,
GoldPerSecUpgrade,
// Items
};
/** Packet used by the client to buy items or upgrades
Packet used by the server to confirm transaction */
class PlayerBuyItemPacket : public Packet {
private:
ItemType m_ItemType;
std::uint8_t m_Count;
public:
PlayerBuyItemPacket() {}
PlayerBuyItemPacket(ItemType itemType, std::uint8_t count) : m_ItemType(itemType), m_Count(count) {}
virtual ~PlayerBuyItemPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
ItemType GetItemType() const { return m_ItemType; }
std::uint8_t GetCount() const { return m_Count; }
virtual PacketType GetType() const { return PacketType::PlayerBuyItem; }
};
/** Packet used by the client to buy mob upgrades
Packet used by the server to confirm transaction */
class PlayerBuyMobUpgradePacket : public Packet {
private:
game::MobType m_MobType;
std::uint8_t m_MobLevel;
public:
PlayerBuyMobUpgradePacket() {}
PlayerBuyMobUpgradePacket(game::MobType mobType, std::uint8_t level) : m_MobType(mobType), m_MobLevel(level) {}
virtual ~PlayerBuyMobUpgradePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::MobType GetMobType() const { return m_MobType; }
std::uint8_t GetLevel() const { return m_MobLevel; }
virtual PacketType GetType() const { return PacketType::PlayerBuyMobUpgrade; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class ConnexionInfoPacket : public Packet {
private:
std::uint8_t m_ConnectionID;
public:
ConnexionInfoPacket() {}
ConnexionInfoPacket(std::uint8_t connectionID) : m_ConnectionID(connectionID) {}
virtual ~ConnexionInfoPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t GetConnectionID() const { return m_ConnectionID; }
virtual PacketType GetType() const { return PacketType::ConnectionInfo; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class DisconnectPacket : public Packet {
private:
std::string m_Reason; // only when sent from server
public:
DisconnectPacket() {}
DisconnectPacket(std::string reason) : m_Reason(reason) {}
virtual ~DisconnectPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::string& GetReason() const { return m_Reason; }
virtual PacketType GetType() const { return PacketType::Disconnect; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class KeepAlivePacket : public Packet{
private:
std::uint64_t m_AliveID;
public:
KeepAlivePacket() {}
KeepAlivePacket(std::uint64_t aliveID) : m_AliveID(aliveID) {}
virtual ~KeepAlivePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint64_t GetAliveID() const { return m_AliveID; }
virtual PacketType GetType() const { return PacketType::KeepAlive; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,32 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class PlaceTowerPacket : public Packet {
private:
std::int32_t m_TowerX, m_TowerY;
game::TowerType m_TowerType;
public:
PlaceTowerPacket() {}
PlaceTowerPacket(std::int32_t x, std::int32_t y, game::TowerType type) :
m_TowerX(x), m_TowerY(y), m_TowerType(type) {
}
virtual ~PlaceTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::int32_t GetTowerX() const { return m_TowerX; }
std::int32_t GetTowerY() const { return m_TowerY; }
game::TowerType GetTowerType() const { return m_TowerType; }
virtual PacketType GetType() const { return PacketType::PlaceTower; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,38 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
enum class ItemType : std::uint8_t {
// Upgrades
ClickerUpgrade,
GoldPerSecUpgrade,
// Items
};
/** Packet used by the client to buy items or upgrades
Packet used by the server to confirm transaction */
class PlayerBuyItemPacket : public Packet {
private:
ItemType m_ItemType;
std::uint8_t m_Count;
public:
PlayerBuyItemPacket() {}
PlayerBuyItemPacket(ItemType itemType, std::uint8_t count) : m_ItemType(itemType), m_Count(count) {}
virtual ~PlayerBuyItemPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
ItemType GetItemType() const { return m_ItemType; }
std::uint8_t GetCount() const { return m_Count; }
virtual PacketType GetType() const { return PacketType::PlayerBuyItem; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,31 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
/** Packet used by the client to buy mob upgrades
Packet used by the server to confirm transaction */
class PlayerBuyMobUpgradePacket : public Packet {
private:
game::MobType m_MobType;
std::uint8_t m_MobLevel;
public:
PlayerBuyMobUpgradePacket() {}
PlayerBuyMobUpgradePacket(game::MobType mobType, std::uint8_t level) : m_MobType(mobType), m_MobLevel(level) {}
virtual ~PlayerBuyMobUpgradePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::MobType GetMobType() const { return m_MobType; }
std::uint8_t GetLevel() const { return m_MobLevel; }
virtual PacketType GetType() const { return PacketType::PlayerBuyMobUpgrade; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,28 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class PlayerJoinPacket : public Packet {
private:
std::uint8_t m_PlayerID;
std::string m_PlayerName;
public:
PlayerJoinPacket() {}
PlayerJoinPacket(std::uint8_t playerID, const std::string& playerName) : m_PlayerID(playerID), m_PlayerName(playerName) {}
virtual ~PlayerJoinPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t GetPlayerID() const { return m_PlayerID; }
const std::string& GetPlayerName() const { return m_PlayerName; }
virtual PacketType GetType() const { return PacketType::PlayerJoin; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class PlayerLeavePacket : public Packet {
private:
std::uint8_t m_PlayerID;
public:
PlayerLeavePacket() {}
PlayerLeavePacket(std::uint8_t playerID) : m_PlayerID(playerID) {}
virtual ~PlayerLeavePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t GetPlayerID() const { return m_PlayerID; }
virtual PacketType GetType() const { return PacketType::PlayerLeave; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,32 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
struct PlayerInfo {
std::string name;
game::TeamColor team;
};
class PlayerListPacket : public Packet {
private:
std::map<std::uint8_t, PlayerInfo> m_Players;
public:
PlayerListPacket() {}
PlayerListPacket(std::map<std::uint8_t, PlayerInfo> players) : m_Players(players) {}
virtual ~PlayerListPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::map<std::uint8_t, PlayerInfo>& GetPlayers() const { return m_Players; }
virtual PacketType GetType() const { return PacketType::PlayerList; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class PlayerLoginPacket : public Packet {
private:
std::string m_PlayerName;
public:
PlayerLoginPacket() {}
PlayerLoginPacket(std::string playerName) : m_PlayerName(playerName) {}
virtual ~PlayerLoginPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::PlayerLogin; }
const std::string& GetPlayerName() const { return m_PlayerName; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,27 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class RemoveTowerPacket : public DelayedPacket {
private:
game::TowerID m_TowerID;
public:
RemoveTowerPacket() {}
RemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
virtual ~RemoveTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID GetTowerID() const { return m_TowerID; }
virtual PacketType GetType() const { return PacketType::RemoveTower; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,27 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class SelectTeamPacket : public Packet {
private:
game::TeamColor m_SelectedTeam;
public:
SelectTeamPacket() {}
SelectTeamPacket(game::TeamColor selectedTeam) : m_SelectedTeam(selectedTeam) {}
virtual ~SelectTeamPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
virtual PacketType GetType() const { return PacketType::SelectTeam; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,33 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
struct MobSend { // represents a mob send
game::MobType mobType : 4;
game::MobLevel mobLevel : 4;
std::uint8_t mobCount; // the max is 12
};
class SendMobsPacket : public Packet {
private:
std::vector<MobSend> m_MobSends;
public:
SendMobsPacket() {}
SendMobsPacket(const std::vector<MobSend>& mobSends) : m_MobSends(mobSends) {}
virtual ~SendMobsPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::vector<MobSend>& GetMobSends() const { return m_MobSends; }
virtual PacketType GetType() const { return PacketType::SendMobs; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,30 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class ServerTpsPacket : public Packet {
private:
float m_TPS;
float m_MSPT;
std::uint64_t m_PacketSendTime; // used to calculate ping
public:
ServerTpsPacket() {}
ServerTpsPacket(float tps, float mspt, std::uint64_t sendTime) : m_TPS(tps), m_MSPT(mspt), m_PacketSendTime(sendTime) {}
virtual ~ServerTpsPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
float GetTPS() const { return m_TPS; }
float GetMSPT() const { return m_MSPT; }
std::uint64_t GetPacketSendTime() const { return m_PacketSendTime; }
virtual PacketType GetType() const { return PacketType::ServerTps; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,41 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class SpawnMobPacket : public Packet {
private:
game::MobID m_MobID;
game::MobType m_MobType;
game::MobLevel m_MobLevel;
game::Direction m_MobDirection;
game::PlayerID m_Sender;
float m_MobX, m_MobY;
public:
SpawnMobPacket() {}
SpawnMobPacket(game::MobID id, game::MobType type, std::uint8_t level, game::PlayerID sender,
float x, float y, game::Direction dir) : m_MobID(id), m_MobType(type), m_MobLevel(level),
m_MobDirection(dir), m_Sender(sender), m_MobX(x), m_MobY(y) {
}
virtual ~SpawnMobPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::MobID GetMobID() const { return m_MobID; }
game::MobType GetMobType() const { return m_MobType; }
game::MobLevel GetMobLevel() const { return m_MobLevel; }
game::Direction GetMobDirection() const { return m_MobDirection; }
game::PlayerID GetSender() const { return m_Sender; }
float GetMobX() const { return m_MobX; }
float GetMobY() const { return m_MobY; }
virtual PacketType GetType() const { return PacketType::SpawnMob; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,29 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class UpdateCastleLifePacket : public Packet {
private:
std::uint16_t m_CastleLife;
game::TeamColor m_Team;
public:
UpdateCastleLifePacket() {}
UpdateCastleLifePacket(std::uint16_t life, game::TeamColor team) : m_CastleLife(life), m_Team(team) {}
virtual ~UpdateCastleLifePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint16_t GetCastleLife() const { return m_CastleLife; }
game::TeamColor GetTeamColor() const { return m_Team; }
virtual PacketType GetType() const { return PacketType::UpdateCastleLife; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class UpdateExpPacket : public Packet {
private:
std::uint32_t m_NewAmount;
public:
UpdateExpPacket() {}
UpdateExpPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
virtual ~UpdateExpPacket() {}
std::uint32_t GetExp() const { return m_NewAmount; }
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::UpdateEXP; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,27 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class UpdateGameStatePacket : public Packet {
private:
game::GameState m_GameState;
public:
UpdateGameStatePacket() {}
UpdateGameStatePacket(game::GameState gameState) : m_GameState(gameState) {}
virtual ~UpdateGameStatePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::GameState GetGameState() const { return m_GameState; }
virtual PacketType GetType() const { return PacketType::UpdateGameState; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class UpdateLobbyTimePacket : public Packet {
private:
std::uint64_t m_StartTime; // unix millis
public:
UpdateLobbyTimePacket() {}
UpdateLobbyTimePacket(std::uint64_t startTime) : m_StartTime(startTime) {}
virtual ~UpdateLobbyTimePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint64_t GetStartTime() const { return m_StartTime; }
virtual PacketType GetType() const { return PacketType::UpdateLobbyTime; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,47 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class MobState {
using Point = utils::shape::Point;
private:
game::MobID m_MobID;
Point m_MobPosition;
float m_MobLife;
game::Direction m_MobDirection;
public:
MobState() {}
MobState(game::MobID id, const Point& position, float life, game::Direction direction) :
m_MobID(id), m_MobPosition(position), m_MobLife(life), m_MobDirection(direction) {
}
game::MobID GetMobId() const { return m_MobID; }
Point GetMobPosition() const { return m_MobPosition; }
float GetMobLife() const { return m_MobLife; }
game::Direction GetMobDirection() const { return m_MobDirection; }
};
class UpdateMobStatesPacket : public DelayedPacket {
private:
std::vector<MobState> m_MobStates;
public:
UpdateMobStatesPacket() {}
virtual ~UpdateMobStatesPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
void addMobState(MobState mobState) { m_MobStates.push_back(mobState); }
const std::vector<MobState>& GetMobStates() const { return m_MobStates; }
virtual PacketType GetType() const { return PacketType::UpdateMobStates; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class UpdateMoneyPacket : public Packet {
private:
std::uint32_t m_NewAmount;
public:
UpdateMoneyPacket() {}
UpdateMoneyPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
virtual ~UpdateMoneyPacket() {}
std::uint32_t GetGold() const { return m_NewAmount; }
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::UpdateMoney; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,29 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class UpdatePlayerTeamPacket : public Packet {
private:
std::uint8_t m_PlayerID;
game::TeamColor m_SelectedTeam;
public:
UpdatePlayerTeamPacket() {}
UpdatePlayerTeamPacket(std::uint8_t playerID, game::TeamColor selectedTeam) : m_PlayerID(playerID), m_SelectedTeam(selectedTeam) {}
virtual ~UpdatePlayerTeamPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
std::uint8_t GetPlayerID() const { return m_PlayerID; }
virtual PacketType GetType() const { return PacketType::UpdatePlayerTeam; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,29 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class UpgradeTowerPacket : public DelayedPacket {
private:
game::TowerID m_TowerID;
game::TowerLevel m_TowerLevel;
public:
UpgradeTowerPacket() {}
UpgradeTowerPacket(game::TowerID tower, game::TowerLevel level) : m_TowerID(tower), m_TowerLevel(level) {}
virtual ~UpgradeTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID GetTowerID() const { return m_TowerID; }
game::TowerLevel GetTowerLevel() const { return m_TowerLevel; }
virtual PacketType GetType() const { return PacketType::UpgradeTower; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,36 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
class WorldAddTowerPacket : public DelayedPacket {
private:
game::TowerID m_TowerID;
std::int32_t m_TowerX, m_TowerY;
game::TowerType m_TowerType;
game::PlayerID m_Builder;
public:
WorldAddTowerPacket() {}
WorldAddTowerPacket(game::TowerID id, std::int32_t x, std::int32_t y, game::TowerType type, game::PlayerID player) :
m_TowerID(id), m_TowerX(x), m_TowerY(y), m_TowerType(type), m_Builder(player) {
}
virtual ~WorldAddTowerPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID GetTowerID() const { return m_TowerID; }
std::int32_t GetTowerX() const { return m_TowerX; }
std::int32_t GetTowerY() const { return m_TowerY; }
game::TowerType GetTowerType() const { return m_TowerType; }
game::PlayerID GetBuilder() const { return m_Builder; }
virtual PacketType GetType() const { return PacketType::WorldAddTower; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,60 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
struct WorldHeader {
game::TowerTileColorPalette m_TowerPlacePalette;
Color m_WalkablePalette;
std::vector<Color> m_DecorationPalette;
Color m_Background;
game::SpawnColorPalette m_SpawnColorPalette;
game::TilePalette m_TilePalette;
game::Spawn m_RedSpawn, m_BlueSpawn;
game::TeamCastle m_RedCastle, m_BlueCastle;
const game::World* m_World;
};
class WorldBeginDataPacket : public Packet {
private:
WorldHeader m_Header;
public:
WorldBeginDataPacket() {}
WorldBeginDataPacket(const game::World* world) {
m_Header.m_World = world;
}
virtual ~WorldBeginDataPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::WorldBeginData; }
const game::TowerTileColorPalette& GetTowerTilePalette() const { return m_Header.m_TowerPlacePalette; }
const Color& GetWalkableTileColor() const { return m_Header.m_WalkablePalette; }
const std::vector<Color>& GetDecorationPalette() const { return m_Header.m_DecorationPalette; }
const Color& GetBackgroundColor() const { return m_Header.m_Background; }
const game::Spawn& GetRedSpawn() const { return m_Header.m_RedSpawn; }
const game::Spawn& GetBlueSpawn() const { return m_Header.m_BlueSpawn; }
const game::SpawnColorPalette& GetSpawnPalette() const { return m_Header.m_SpawnColorPalette; }
const game::TeamCastle& GetRedCastle() const { return m_Header.m_RedCastle; }
const game::TeamCastle& GetBlueCastle() const { return m_Header.m_BlueCastle; }
const game::TilePalette GetTilePalette() const { return m_Header.m_TilePalette; }
void setWorldHeader(const WorldHeader& header) { m_Header = header; }
};
} // namespace protocol
} // namespace td

View File

@@ -1,36 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include "game/BaseGame.h"
namespace td {
namespace protocol {
struct WorldData {
std::unordered_map<game::ChunkCoord, game::ChunkPtr> m_Chunks;
};
class WorldDataPacket : public Packet {
private:
WorldData m_WorldData;
const game::World* m_World;
public:
WorldDataPacket() {}
WorldDataPacket(const game::World* world) : m_World(world) {}
virtual ~WorldDataPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const { return PacketType::WorldData; }
const std::unordered_map<game::ChunkCoord, game::ChunkPtr>& GetChunks() const { return m_WorldData.m_Chunks; }
DataBuffer SerializeCustom() const; // allow serialisation with invalid World member
void SetWorldData(const WorldData& worldData) { m_WorldData = worldData; }
};
} // namespace protocol
} // namespace td

View File

@@ -16,23 +16,48 @@ struct Camera {
Mat4f InvProjectionMatrix;
float CamDistance = 25.0f;
Vec3f CamPos {0, CamDistance, 0};
Vec2f CamLook {};
Vec3f CamPos{ 0, CamDistance, 0 };
Vec2f CamLook{};
float m_Yaw = -PI / 2.0f;
float m_Pitch = -PI / 2.0f + 0.0000001f;
};
struct Model {
std::unique_ptr<GL::VertexArray> vao;
Vec3f positon;
Vec3f color = { 1, 1, 1 };
};
class TexturedModel {
private:
std::unique_ptr<GL::VertexArray> m_Vao;
std::unique_ptr<GL::Texture> m_Texture;
Vec3f m_Positon;
Vec3f m_Color = { 1, 1, 1 };
public:
REMOVE_COPY(TexturedModel);
TexturedModel(GL::VertexArray&& vao, GL::Texture&& texture);
TexturedModel(TexturedModel&& other);
~TexturedModel() {}
const GL::VertexArray& GetVao() const { return *m_Vao; }
const GL::Texture& GetTexture() const { return *m_Texture; }
Vec3f GetPosition() const { return m_Positon; }
Vec3f GetColor() const { return m_Color; }
void SetPosition(Vec3f newPos) { m_Positon = newPos; }
void SetColor(Vec3f newColor) { m_Color = newColor; }
};
class Renderer {
public:
static constexpr float m_AnimationSpeed = 2.0f;
static constexpr float m_MouseSensitivity = 200.0f;
struct Model {
GL::VertexArray* vao;
Vec3f positon;
Vec3f color = { 1, 1, 1 };
};
private:
std::unique_ptr<shader::WorldShader> m_WorldShader;
std::unique_ptr<shader::EntityShader> m_EntityShader;
@@ -41,7 +66,7 @@ private:
Vec3f m_BackgroundColor;
Camera m_Camera {};
Camera m_Camera{};
public:
Renderer();
~Renderer();
@@ -53,6 +78,7 @@ public:
void RenderVAO(const GL::VertexArray& vao);
void RenderModel(const Model& model);
void RenderModel(const TexturedModel& model);
void AddZoom(float zoom);
void SetCamAngularMovement(const Vec2f& mov);

View File

@@ -10,6 +10,8 @@
#include "render/gui/MobTooltip.h"
#include "render/gui/CastleTooltip.h"
#include "render/gui/imgui/imgui.h"
namespace td {
namespace client {
@@ -18,6 +20,7 @@ class ClientGame;
} // namespace client
namespace render {
class WorldRenderer : public game::WorldListener {
@@ -25,7 +28,9 @@ private:
client::ClientGame* m_Client;
Renderer* m_Renderer;
game::World* m_World;
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
std::unique_ptr<GL::VertexArray> m_WorldVao;
std::unique_ptr<Model> m_SelectTileModel;
std::vector<TexturedModel> m_MobModels;
Vec2f m_CamPos;
Vec2f m_CursorPos;
Vec2f m_HoldCursorPos;
@@ -45,6 +50,8 @@ public:
void LoadModels();
static ImVec4 GetImGuiTeamColor(game::TeamColor color);
void Update();
void Render();
@@ -61,7 +68,7 @@ private:
void Click();
void RenderWorld() const;
void RenderTowers() const;
void RenderMobs() const;
void RenderMobs();
void RenderTileSelect() const;
void RenderPopups();
void RenderMobTooltip() const;

View File

@@ -1,13 +0,0 @@
#pragma once
#include "render/gui/imgui/imgui.h"
#include "game/Team.h"
namespace td {
namespace render {
ImVec4 GetImGuiTeamColor(game::TeamColor color);
} // namespace render
} // namespace td

View File

@@ -70,5 +70,24 @@ public:
void Unbind() const;
};
class Texture {
private:
unsigned int m_ID;
public:
REMOVE_COPY(Texture);
Texture(Texture&& other) {
m_ID = other.m_ID;
other.m_ID = 0;
}
Texture(const char* textureData, int width, int height, int comp);
~Texture();
unsigned int GetTextureID() const { return m_ID; }
void Bind() const;
static void Unbind();
};
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "GLLoader.h"
#include "render/Renderer.h"
#include "game/Mobs.h"
namespace td {
namespace render {
namespace MobLoader {
TexturedModel LoadMobModel(game::MobType mobType);
} // namespace MobLoader
} // namespace render
} // namespace td

View File

@@ -8,9 +8,12 @@
#ifndef RENDER_LOADER_TEXTURELOADER_H_
#define RENDER_LOADER_TEXTURELOADER_H_
#include "render/loader/GLLoader.h"
#include <string>
namespace TextureLoader {
unsigned int LoadGLTexture(const char* fileName);
GL::Texture LoadTexture(const std::string& fileName);
}

View File

@@ -1,8 +1,6 @@
#include "game/World.h"
#include "protocol/PacketDispatcher.h"
#include "protocol/Protocol.h"
#include "protocol/packets/WorldBeginDataPacket.h"
#include "protocol/packets/WorldDataPacket.h"
#include "game/BaseGame.h"
#include "misc/Random.h"
#include "misc/Compression.h"

View File

@@ -1,12 +1,6 @@
#include "game/client/Client.h"
#include "misc/Format.h"
#include "protocol/packets/DisconnectPacket.h"
#include "protocol/packets/PlaceTowerPacket.h"
#include "protocol/packets/RemoveTowerPacket.h"
#include "protocol/packets/SelectTeamPacket.h"
#include "protocol/packets/UpgradeTowerPacket.h"
namespace td {
namespace client {

View File

@@ -1,12 +1,6 @@
#include "game/client/ClientConnexion.h"
#include "render/WorldRenderer.h"
#include "protocol/packets/ConnectionInfoPacket.h"
#include "protocol/packets/DisconnectPacket.h"
#include "protocol/packets/KeepAlivePacket.h"
#include "protocol/packets/PlayerLoginPacket.h"
#include "protocol/packets/ServerTpsPacket.h"
namespace td {
namespace client {
@@ -38,7 +32,7 @@ void ClientConnexion::HandlePacket(const protocol::ServerTpsPacket* packet) {
}
void ClientConnexion::Login() {
td::protocol::PlayerLoginPacket loginPacket("Persson" + std::to_string(static_cast<unsigned int>(m_ConnectionID)));
td::protocol::PlayerLoginPacket loginPacket("Persson" + std::to_string(m_ConnectionID));
SendPacket(&loginPacket);
}

View File

@@ -2,18 +2,6 @@
#include "protocol/PacketDispatcher.h"
#include "game/client/Client.h"
#include "protocol/packets/ConnectionInfoPacket.h"
#include "protocol/packets/PlayerJoinPacket.h"
#include "protocol/packets/PlayerListPacket.h"
#include "protocol/packets/PlayerLeavePacket.h"
#include "protocol/packets/UpdatePlayerTeamPacket.h"
#include "protocol/packets/UpdateLobbyTimePacket.h"
#include "protocol/packets/UpdateGameStatePacket.h"
#include "protocol/packets/UpdateMoneyPacket.h"
#include "protocol/packets/UpdateExpPacket.h"
#include "protocol/packets/DisconnectPacket.h"
#include "protocol/packets/WorldDataPacket.h"
namespace td {
namespace client {
@@ -40,6 +28,9 @@ ClientGame::~ClientGame() {
void ClientGame::Tick(std::uint64_t delta) {
game::Game::Tick(delta);
m_WorldRenderer.Update();
if (m_GameState == game::GameState::Lobby && m_LobbyTime > 0) {
m_LobbyTime -= delta;
}
}
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
@@ -52,7 +43,7 @@ void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
void ClientGame::HandlePacket(const protocol::PlayerLeavePacket* packet) {
game::Player* player = &m_Players[packet->GetPlayerID()];
if (player->GetTeamColor() != game::TeamColor::None) {
m_Teams[static_cast<std::size_t>(player->GetTeamColor())].RemovePlayer(player);
m_Teams[(std::size_t)player->GetTeamColor()].RemovePlayer(player);
}
m_Players.erase(player->GetID());
}
@@ -66,7 +57,7 @@ void ClientGame::HandlePacket(const protocol::PlayerListPacket* packet) {
player.SetTeamColor(playerInfo.team);
m_Players.insert({ playerID, player });
if (player.GetTeamColor() != game::TeamColor::None) {
m_Teams[static_cast<std::size_t>(player.GetTeamColor())].AddPlayer(&m_Players[playerID]);
m_Teams[(std::size_t)player.GetTeamColor()].AddPlayer(&m_Players[playerID]);
}
}
m_Player = &m_Players[m_ConnexionID];
@@ -94,8 +85,7 @@ void ClientGame::HandlePacket(const protocol::ConnexionInfoPacket* packet) {
}
void ClientGame::HandlePacket(const protocol::UpdateLobbyTimePacket* packet) {
m_GameStartTime = packet->GetStartTime();
m_LobbyStartTime = utils::GetTime();
m_LobbyTime = packet->GetRemainingTime();
}
void ClientGame::HandlePacket(const protocol::UpdateMoneyPacket* packet) {

View File

@@ -3,15 +3,6 @@
#include "game/client/ClientGame.h"
#include "render/WorldRenderer.h"
#include "protocol/packets/WorldAddTowerPacket.h"
#include "protocol/packets/WorldBeginDataPacket.h"
#include "protocol/packets/WorldDataPacket.h"
#include "protocol/packets/SpawnMobPacket.h"
#include "protocol/packets/UpgradeTowerPacket.h"
#include "protocol/packets/RemoveTowerPacket.h"
#include "protocol/packets/UpdateCastleLifePacket.h"
#include "protocol/packets/UpdateMobStatesPacket.h"
namespace td {
namespace client {

View File

@@ -1,8 +1,6 @@
#include "game/server/Lobby.h"
#include "game/server/Server.h"
#include "protocol/packets/UpdateLobbyTimePacket.h"
#include "misc/Time.h"
#ifdef NDEBUG
@@ -33,39 +31,33 @@ Lobby::Lobby(Server* server) : m_Server(server), m_Timer(1000, std::bind(&Lobby:
}
void Lobby::Tick() {
if (m_GameStarted || m_StartTime == 0)
if (m_GameStarted || m_StartTimerTime == 0)
return;
if (utils::GetTime() >= m_StartTime) {
if (utils::GetTime() - m_StartTimerTime >= LobbyWaitingTime) {
m_Server->GetGame().NotifyListeners(&game::GameListener::OnGameBegin);
m_GameStarted = true;
return;
}
//m_Timer.Update();
m_Timer.Update();
}
void Lobby::SendTimeRemaining() {
protocol::UpdateLobbyTimePacket packet(m_StartTime);
protocol::UpdateLobbyTimePacket packet(LobbyWaitingTime - (utils::GetTime() - m_StartTimerTime)); // converting second to millis
m_Server->BroadcastPacket(&packet);
}
void Lobby::OnPlayerJoin(std::uint8_t playerID) {
if (m_GameStarted)
return;
utils::LOG("(Server) Player Joined Lobby !");
m_Players.push_back(playerID);
if (m_Players.size() == MIN_PLAYER_WAITING) { // start timer if a second player join the match
m_StartTime = utils::GetTime() + static_cast<std::uint64_t>(LobbyWaitingTime);
m_StartTimerTime = utils::GetTime();
m_Timer.Reset();
SendTimeRemaining();
}
// notify player that just arrived
protocol::UpdateLobbyTimePacket packet(m_StartTime);
m_Server->GetConnexions().at(playerID).SendPacket(&packet);
}
void Lobby::OnPlayerLeave(std::uint8_t playerID) {
@@ -79,8 +71,9 @@ void Lobby::OnPlayerLeave(std::uint8_t playerID) {
m_Players.erase(it);
if (m_Players.size() == 1) {
m_StartTime = 0; // reset timer if there is only one player left
SendTimeRemaining();
protocol::UpdateLobbyTimePacket packet(0);
m_Server->BroadcastPacket(&packet);
m_StartTimerTime = 0; // reset timer if there is only one player left
}
}

View File

@@ -1,10 +1,6 @@
#include "game/server/Server.h"
#include "protocol/PacketFactory.h"
#include "protocol/packets/DisconnectPacket.h"
#include "protocol/packets/ServerTpsPacket.h"
#include "protocol/packets/PlayerLeavePacket.h"
#include "misc/Format.h"
namespace td {
@@ -145,10 +141,6 @@ void Server::OnPlayerJoin(std::uint8_t id) {
void Server::OnPlayerLeave(std::uint8_t id) {
protocol::PlayerLeavePacket packet(id);
BroadcastPacket(&packet);
if (GetPlayers().empty()) {
Close();
}
}
} // namespace server

View File

@@ -3,23 +3,6 @@
#include "protocol/PacketFactory.h"
#include "game/server/Server.h"
#include "protocol/packets/ConnectionInfoPacket.h"
#include "protocol/packets/DisconnectPacket.h"
#include "protocol/packets/KeepAlivePacket.h"
#include "protocol/packets/PlaceTowerPacket.h"
#include "protocol/packets/PlayerLoginPacket.h"
#include "protocol/packets/PlayerJoinPacket.h"
#include "protocol/packets/PlayerListPacket.h"
#include "protocol/packets/RemoveTowerPacket.h"
#include "protocol/packets/SelectTeamPacket.h"
#include "protocol/packets/SendMobsPacket.h"
#include "protocol/packets/UpdatePlayerTeamPacket.h"
#include "protocol/packets/UpdateGameStatePacket.h"
#include "protocol/packets/UpgradeTowerPacket.h"
#include "protocol/packets/WorldBeginDataPacket.h"
#include "protocol/packets/WorldDataPacket.h"
#include "protocol/packets/WorldAddTowerPacket.h"
#include "misc/Time.h"
#include "misc/Random.h"

View File

@@ -1,15 +1,6 @@
#include "game/server/ServerGame.h"
#include "game/server/Server.h"
#include "protocol/packets/DisconnectPacket.h"
#include "protocol/packets/UpdatePlayerTeamPacket.h"
#include "protocol/packets/UpdateGameStatePacket.h"
#include "protocol/packets/UpdateMoneyPacket.h"
#include "protocol/packets/UpdateExpPacket.h"
#include "protocol/packets/UpdateMobStatesPacket.h"
#include "protocol/packets/WorldDataPacket.h"
#include "protocol/packets/WorldBeginDataPacket.h"
namespace td {
namespace server {

View File

@@ -2,9 +2,6 @@
#include "game/server/Server.h"
#include "misc/Random.h"
#include "protocol/packets/SpawnMobPacket.h"
#include "protocol/packets/UpdateCastleLifePacket.h"
#define MOB_SPAWN_PRECISION 100.0f
namespace td {

View File

@@ -1,5 +1,4 @@
#include "protocol/PacketFactory.h"
#include "protocol/Packets.h"
#include <map>
#include <functional>
@@ -39,27 +38,7 @@ static std::map<PacketType, PacketCreator> packets = {
};
PacketPtr CreatePacket(PacketType type, DataBuffer& buffer) {
std::uint8_t packetTypeInt = static_cast<std::uint8_t>(type);
PacketPtr packet;
// we have a timed packet
if (packetTypeInt >> 7) {
std::uint64_t packetTime = 0;
buffer >> packetTime;
packetTypeInt &= 0x7F;
type = protocol::PacketType(packetTypeInt);
packet = packets[type]();
DelayedPacket* delayedPacket = reinterpret_cast<DelayedPacket*>(packet.get());
delayedPacket->SetPacketTime(packetTime);
} else {
packet = packets[type]();
}
PacketPtr packet = packets[type]();
packet->Deserialize(buffer);
return packet;
}

View File

@@ -1,49 +1,599 @@
#include "protocol/PacketHandler.h"
#include "protocol/Packets.h"
#define REGISTER_DISPATCH(className) void className::Dispatch(PacketHandler* handler) const { \
#include <cmath>
#define REGISTER_DISPATCH_CLASS(className) void className::Dispatch(PacketHandler* handler) const { \
handler->HandlePacket(this);\
}
namespace td {
namespace protocol {
const int BITS_IN_BYTE = 8;
const int BITS_IN_LONG = BITS_IN_BYTE * sizeof(std::uint64_t);
static unsigned int countBits(unsigned int number) {
// log function in base 2
// take only integer part
return static_cast<unsigned int>(std::log2(number) + 1);
}
void Packet::WritePacketID(DataBuffer& data, bool packetID) const {
if (packetID)
data << GetID();
}
void DelayedPacket::WritePacketID(DataBuffer& data, bool packetID) const {
if (packetID)
data << static_cast<std::uint8_t>(GetID() | static_cast<std::uint8_t>(0x80)) << m_PacketTime;
static DataBuffer& operator<<(DataBuffer& buffer, game::TilePtr tile) {
buffer << tile->GetType();
switch (tile->GetType()) {
case game::TileType::Tower: {
const game::TowerTile* towerTile = dynamic_cast<const game::TowerTile*>(tile.get());
buffer << towerTile->color_palette_ref << towerTile->team_owner;
break;
}
case game::TileType::Walk: {
const game::WalkableTile* walkTile = dynamic_cast<const game::WalkableTile*>(tile.get());
buffer << walkTile->direction;
break;
}
case game::TileType::Decoration: {
const game::DecorationTile* decoTile = dynamic_cast<const game::DecorationTile*>(tile.get());
buffer << decoTile->color_palette_ref;
break;
}
default:
break;
}
return buffer;
}
REGISTER_DISPATCH(PlayerLoginPacket)
REGISTER_DISPATCH(WorldBeginDataPacket)
REGISTER_DISPATCH(WorldDataPacket)
REGISTER_DISPATCH(KeepAlivePacket)
REGISTER_DISPATCH(UpdateExpPacket)
REGISTER_DISPATCH(UpdateMoneyPacket)
REGISTER_DISPATCH(UpdateLobbyTimePacket)
REGISTER_DISPATCH(UpdateGameStatePacket)
REGISTER_DISPATCH(PlayerListPacket)
REGISTER_DISPATCH(PlayerJoinPacket)
REGISTER_DISPATCH(PlayerLeavePacket)
REGISTER_DISPATCH(ConnexionInfoPacket)
REGISTER_DISPATCH(SelectTeamPacket)
REGISTER_DISPATCH(UpdatePlayerTeamPacket)
REGISTER_DISPATCH(DisconnectPacket)
REGISTER_DISPATCH(ServerTpsPacket)
REGISTER_DISPATCH(SpawnMobPacket)
REGISTER_DISPATCH(PlaceTowerPacket)
REGISTER_DISPATCH(WorldAddTowerPacket)
REGISTER_DISPATCH(RemoveTowerPacket)
REGISTER_DISPATCH(SendMobsPacket)
REGISTER_DISPATCH(UpgradeTowerPacket)
REGISTER_DISPATCH(UpdateCastleLifePacket)
REGISTER_DISPATCH(UpdateMobStatesPacket)
REGISTER_DISPATCH(PlayerBuyItemPacket)
REGISTER_DISPATCH(PlayerBuyMobUpgradePacket)
static DataBuffer& operator>>(DataBuffer& buffer, game::TilePtr& tile) {
game::TileType tileType;
buffer >> tileType;
switch (tileType) {
case game::TileType::Tower: {
auto tilePtr = std::make_shared<game::TowerTile>();
buffer >> tilePtr->color_palette_ref >> tilePtr->team_owner;
tile = tilePtr;
break;
}
case game::TileType::Walk: {
auto tilePtr = std::make_shared<game::WalkableTile>();
buffer >> tilePtr->direction;
tile = tilePtr;
break;
}
case game::TileType::Decoration: {
auto tilePtr = std::make_shared<game::DecorationTile>();
buffer >> tilePtr->color_palette_ref;
tile = tilePtr;
break;
}
default:
break;
}
return buffer;
}
DataBuffer PlayerLoginPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerName;
return data;
}
void PlayerLoginPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerName;
}
DataBuffer WorldBeginDataPacket::Serialize(bool packetID) const {
DataBuffer data;
const game::TowerTileColorPalette& towerTilePalette = m_Header.m_World->GetTowerTileColorPalette();
const std::vector<Color>& decoTilePalette = m_Header.m_World->GetDecorationPalette();
WritePacketID(data, packetID);
data << towerTilePalette << m_Header.m_World->GetWalkableTileColor()
<< static_cast<std::uint16_t>(decoTilePalette.size());
// deco color palette
std::size_t bufferSize = data.GetSize();
data.Resize(bufferSize + decoTilePalette.size() * sizeof(Color));
memcpy(reinterpret_cast<std::uint8_t*>(data.data()) + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(Color));
data << m_Header.m_World->GetBackgroundColor();
const game::Spawn& redSpawn = m_Header.m_World->GetRedTeam().GetSpawn(), blueSpawn = m_Header.m_World->GetBlueTeam().GetSpawn();
const game::TeamCastle& redCastle = m_Header.m_World->GetRedTeam().GetCastle(), blueCastle = m_Header.m_World->GetBlueTeam().GetCastle();
data << redSpawn << static_cast<utils::shape::Rectangle>(redCastle);
data << blueSpawn << static_cast<utils::shape::Rectangle>(blueCastle);
// tile palette
data << static_cast<std::uint64_t>(m_Header.m_World->GetTilePalette().size());
for (game::TilePtr tile : m_Header.m_World->GetTilePalette()) {
data << tile;
}
data << m_Header.m_World->GetSpawnColors();
return data;
}
void WorldBeginDataPacket::Deserialize(DataBuffer& data) {
data >> m_Header.m_TowerPlacePalette >> m_Header.m_WalkablePalette;
std::uint16_t decoPaletteSize;
data >> decoPaletteSize;
std::size_t decoPalletteSizeByte = decoPaletteSize * sizeof(Color);
m_Header.m_DecorationPalette.resize(decoPaletteSize);
memcpy(reinterpret_cast<std::uint8_t*>(m_Header.m_DecorationPalette.data()), data.data() + data.GetReadOffset(), decoPalletteSizeByte);
data.SetReadOffset(data.GetReadOffset() + decoPalletteSizeByte);
data >> m_Header.m_Background;
utils::shape::Rectangle redCastle, blueCastle;
data >> m_Header.m_RedSpawn >> redCastle;
data >> m_Header.m_BlueSpawn >> blueCastle;
m_Header.m_RedCastle.SetShape(redCastle);
m_Header.m_BlueCastle.SetShape(blueCastle);
std::uint64_t tilePaletteSize;
data >> tilePaletteSize;
m_Header.m_TilePalette.reserve(tilePaletteSize);
for (std::uint64_t tileNumber = 0; tileNumber < tilePaletteSize; tileNumber++) {
game::TilePtr tile;
data >> tile;
m_Header.m_TilePalette.push_back(tile);
}
data >> m_Header.m_SpawnColorPalette;
}
typedef std::vector<uint64_t> ChunkPackedData;
DataBuffer WorldDataPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_World->GetChunks().size();
for (const auto& pair : m_World->GetChunks()) {
game::ChunkCoord coords = pair.first;
game::ChunkPtr chunk = pair.second;
data << coords.x << coords.y << static_cast<std::uint64_t>(chunk->palette.size());
std::size_t bufferSize = data.GetSize();
data.Resize(data.GetSize() + chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
memcpy(reinterpret_cast<std::uint8_t*>(data.data()) + bufferSize, chunk->palette.data(), chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
std::uint8_t bitsPerTile = countBits(chunk->palette.size());
game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
ChunkPackedData chunkData(game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
for (unsigned int tileNumber = 0; tileNumber < game::Chunk::ChunkSize; tileNumber++) {
std::size_t startLong = static_cast<std::size_t>((tileNumber * bitsPerTile) / BITS_IN_LONG);
std::size_t startOffset = static_cast<std::size_t>((tileNumber * bitsPerTile) % BITS_IN_LONG);
std::size_t endLong = static_cast<std::size_t>(((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG);
std::uint64_t value = static_cast<std::uint64_t>(chunk->tiles[tileNumber]);
value &= individualValueMask;
chunkData[startLong] |= (value << startOffset);
if (startLong != endLong) {
chunkData[endLong] = (value >> (BITS_IN_LONG - startOffset));
}
}
bufferSize = data.GetSize();
data.Resize(data.GetSize() + chunkData.size() * sizeof(ChunkPackedData::value_type));
memcpy(reinterpret_cast<std::uint8_t*>(data.data()) + bufferSize, chunkData.data(), chunkData.size() * sizeof(ChunkPackedData::value_type));
}
return data;
}
void WorldDataPacket::Deserialize(DataBuffer& data) {
std::uint64_t chunkCount;
data >> chunkCount;
for (std::uint64_t chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {
game::ChunkPtr chunk = std::make_shared<game::Chunk>();
decltype(game::ChunkCoord::x) chunkX, chunkY;
data >> chunkX >> chunkY;
std::uint64_t chunkPaletteSize;
data >> chunkPaletteSize;
game::ChunkPalette chunkPalette(chunkPaletteSize);
memcpy(reinterpret_cast<void*>(chunkPalette.data()), data.data() + data.GetReadOffset(), chunkPaletteSize * sizeof(game::ChunkPalette::value_type));
data.SetReadOffset(data.GetReadOffset() + chunkPaletteSize * sizeof(game::ChunkPalette::value_type));
chunk->palette = chunkPalette;
std::uint8_t bitsPerTile = countBits(chunkPaletteSize);
// A bitmask that contains bitsPerTile set bits
game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
ChunkPackedData chunkData(game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
memcpy(reinterpret_cast<void*>(chunkData.data()), data.data() + data.GetReadOffset(), chunkData.size() * sizeof(ChunkPackedData::value_type));
data.SetReadOffset(data.GetReadOffset() + chunkData.size() * sizeof(ChunkPackedData::value_type));
for (unsigned int tileNumber = 0; tileNumber < game::Chunk::ChunkSize; tileNumber++) {
std::size_t startLong = (tileNumber * bitsPerTile) / BITS_IN_LONG;
std::size_t startOffset = (tileNumber * bitsPerTile) % BITS_IN_LONG;
std::size_t endLong = ((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG;
game::Chunk::ChunkData::value_type value;
if (startLong == endLong) {
value = (chunkData[startLong] >> startOffset);
} else {
int endOffset = BITS_IN_LONG - startOffset;
value = (chunkData[startLong] >> startOffset | chunkData[endLong] << endOffset);
}
value &= individualValueMask;
chunk->tiles[tileNumber] = value;
}
m_WorldData.m_Chunks.insert({ {chunkX, chunkY}, chunk });
}
}
DataBuffer KeepAlivePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_AliveID;
return data;
}
void KeepAlivePacket::Deserialize(DataBuffer& data) {
data >> m_AliveID;
}
DataBuffer UpdateMoneyPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_NewAmount;
return data;
}
void UpdateMoneyPacket::Deserialize(DataBuffer& data) {
data >> m_NewAmount;
}
DataBuffer UpdateExpPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_NewAmount;
return data;
}
void UpdateExpPacket::Deserialize(DataBuffer& data) {
data >> m_NewAmount;
}
DataBuffer UpdateLobbyTimePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_RemainingTime;
return data;
}
void UpdateLobbyTimePacket::Deserialize(DataBuffer& data) {
data >> m_RemainingTime;
}
DataBuffer UpdateGameStatePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_GameState;
return data;
}
void UpdateGameStatePacket::Deserialize(DataBuffer& data) {
data >> m_GameState;
}
DataBuffer PlayerListPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << static_cast<std::uint8_t>(m_Players.size());
for (auto [playerID, playerInfo] : m_Players) {
data << playerID << playerInfo.name << playerInfo.team;
}
return data;
}
void PlayerListPacket::Deserialize(DataBuffer& data) {
std::uint8_t playerCount;
data >> playerCount;
for (int i = 0; i < playerCount; i++) {
std::uint8_t playerID;
PlayerInfo playerInfo;
data >> playerID >> playerInfo.name >> playerInfo.team;
m_Players.insert({ playerID, playerInfo });
}
}
DataBuffer PlayerJoinPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID << m_PlayerName;
return data;
}
void PlayerJoinPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID >> m_PlayerName;
}
DataBuffer PlayerLeavePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID;
return data;
}
void PlayerLeavePacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID;
}
DataBuffer ConnexionInfoPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_ConnectionID;
return data;
}
void ConnexionInfoPacket::Deserialize(DataBuffer& data) {
data >> m_ConnectionID;
}
DataBuffer SelectTeamPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_SelectedTeam;
return data;
}
void SelectTeamPacket::Deserialize(DataBuffer& data) {
data >> m_SelectedTeam;
}
DataBuffer UpdatePlayerTeamPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID << m_SelectedTeam;
return data;
}
void UpdatePlayerTeamPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID >> m_SelectedTeam;
}
DataBuffer DisconnectPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_Reason;
return data;
}
void DisconnectPacket::Deserialize(DataBuffer& data) {
data >> m_Reason;
}
DataBuffer ServerTpsPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TPS << m_MSPT << m_PacketSendTime;
return data;
}
void ServerTpsPacket::Deserialize(DataBuffer& data) {
data >> m_TPS >> m_MSPT >> m_PacketSendTime;
}
DataBuffer SpawnMobPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_MobID << m_MobType << m_MobLevel << m_MobDirection
<< m_Sender << m_MobX << m_MobY;
return data;
}
void SpawnMobPacket::Deserialize(DataBuffer& data) {
data >> m_MobID >> m_MobType >> m_MobLevel >> m_MobDirection
>> m_Sender >> m_MobX >> m_MobY;
}
DataBuffer PlaceTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerX << m_TowerY << m_TowerType;
return data;
}
void PlaceTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerX >> m_TowerY >> m_TowerType;
}
DataBuffer WorldAddTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerID << m_TowerX << m_TowerY << m_TowerType << m_Builder;
return data;
}
void WorldAddTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerID >> m_TowerX >> m_TowerY >> m_TowerType >> m_Builder;
}
DataBuffer RemoveTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerID;
return data;
}
void RemoveTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerID;
}
DataBuffer SendMobsPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << static_cast<std::uint8_t>(m_MobSends.size());
data.WriteSome(reinterpret_cast<const std::uint8_t*>(m_MobSends.data()), m_MobSends.size() * sizeof(m_MobSends));
return data;
}
void SendMobsPacket::Deserialize(DataBuffer& data) {
std::uint8_t mobSendCount;
data >> mobSendCount;
m_MobSends.resize(mobSendCount);
data.ReadSome(reinterpret_cast<std::uint8_t*>(m_MobSends.data()), mobSendCount * sizeof(MobSend));
}
DataBuffer UpgradeTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerID << m_TowerLevel;
return data;
}
void UpgradeTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerID >> m_TowerLevel;
}
DataBuffer UpdateCastleLifePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_CastleLife << m_Team;
return data;
}
void UpdateCastleLifePacket::Deserialize(DataBuffer& data) {
data >> m_CastleLife >> m_Team;
}
DataBuffer UpdateMobStatesPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << static_cast<std::uint64_t>(m_MobStates.size());
data.WriteSome(reinterpret_cast<const std::uint8_t*>(m_MobStates.data()), m_MobStates.size() * sizeof(MobState));
return data;
}
void UpdateMobStatesPacket::Deserialize(DataBuffer& data) {
std::uint64_t mobCount;
data >> mobCount;
m_MobStates.resize(mobCount);
data.ReadSome(reinterpret_cast<std::uint8_t*>(m_MobStates.data()), mobCount * sizeof(MobState));
}
DataBuffer PlayerBuyItemPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_ItemType << m_Count;
return data;
}
void PlayerBuyItemPacket::Deserialize(DataBuffer& data) {
data >> m_ItemType >> m_Count;
}
DataBuffer PlayerBuyMobUpgradePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_MobType << m_MobLevel;
return data;
}
void PlayerBuyMobUpgradePacket::Deserialize(DataBuffer& data) {
data >> m_MobType >> m_MobLevel;
}
REGISTER_DISPATCH_CLASS(PlayerLoginPacket)
REGISTER_DISPATCH_CLASS(WorldBeginDataPacket)
REGISTER_DISPATCH_CLASS(WorldDataPacket)
REGISTER_DISPATCH_CLASS(KeepAlivePacket)
REGISTER_DISPATCH_CLASS(UpdateExpPacket)
REGISTER_DISPATCH_CLASS(UpdateMoneyPacket)
REGISTER_DISPATCH_CLASS(UpdateLobbyTimePacket)
REGISTER_DISPATCH_CLASS(UpdateGameStatePacket)
REGISTER_DISPATCH_CLASS(PlayerListPacket)
REGISTER_DISPATCH_CLASS(PlayerJoinPacket)
REGISTER_DISPATCH_CLASS(PlayerLeavePacket)
REGISTER_DISPATCH_CLASS(ConnexionInfoPacket)
REGISTER_DISPATCH_CLASS(SelectTeamPacket)
REGISTER_DISPATCH_CLASS(UpdatePlayerTeamPacket)
REGISTER_DISPATCH_CLASS(DisconnectPacket)
REGISTER_DISPATCH_CLASS(ServerTpsPacket)
REGISTER_DISPATCH_CLASS(SpawnMobPacket)
REGISTER_DISPATCH_CLASS(PlaceTowerPacket)
REGISTER_DISPATCH_CLASS(WorldAddTowerPacket)
REGISTER_DISPATCH_CLASS(RemoveTowerPacket)
REGISTER_DISPATCH_CLASS(SendMobsPacket)
REGISTER_DISPATCH_CLASS(UpgradeTowerPacket)
REGISTER_DISPATCH_CLASS(UpdateCastleLifePacket)
REGISTER_DISPATCH_CLASS(UpdateMobStatesPacket)
REGISTER_DISPATCH_CLASS(PlayerBuyItemPacket)
REGISTER_DISPATCH_CLASS(PlayerBuyMobUpgradePacket)
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/ConnectionInfoPacket.h"
namespace td {
namespace protocol {
DataBuffer ConnexionInfoPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_ConnectionID;
return data;
}
void ConnexionInfoPacket::Deserialize(DataBuffer& data) {
data >> m_ConnectionID;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/DisconnectPacket.h"
namespace td {
namespace protocol {
DataBuffer DisconnectPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_Reason;
return data;
}
void DisconnectPacket::Deserialize(DataBuffer& data) {
data >> m_Reason;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/KeepAlivePacket.h"
namespace td {
namespace protocol {
DataBuffer KeepAlivePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_AliveID;
return data;
}
void KeepAlivePacket::Deserialize(DataBuffer& data) {
data >> m_AliveID;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/PlaceTowerPacket.h"
namespace td {
namespace protocol {
DataBuffer PlaceTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerX << m_TowerY << m_TowerType;
return data;
}
void PlaceTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerX >> m_TowerY >> m_TowerType;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/PlayerBuyItemPacket.h"
namespace td {
namespace protocol {
DataBuffer PlayerBuyItemPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_ItemType << m_Count;
return data;
}
void PlayerBuyItemPacket::Deserialize(DataBuffer& data) {
data >> m_ItemType >> m_Count;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/PlayerBuyMobUpgradePacket.h"
namespace td {
namespace protocol {
DataBuffer PlayerBuyMobUpgradePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_MobType << m_MobLevel;
return data;
}
void PlayerBuyMobUpgradePacket::Deserialize(DataBuffer& data) {
data >> m_MobType >> m_MobLevel;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/PlayerJoinPacket.h"
namespace td {
namespace protocol {
DataBuffer PlayerJoinPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID << m_PlayerName;
return data;
}
void PlayerJoinPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID >> m_PlayerName;
}
} // namespace protocol
} // namespace td

View File

@@ -1,20 +0,0 @@
#include "protocol/packets/PlayerLeavePacket.h"
namespace td {
namespace protocol {
DataBuffer PlayerLeavePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID;
return data;
}
void PlayerLeavePacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID;
}
} // namespace protocol
} // namespace td

View File

@@ -1,30 +0,0 @@
#include "protocol/packets/PlayerListPacket.h"
namespace td {
namespace protocol {
DataBuffer PlayerListPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << static_cast<std::uint8_t>(m_Players.size());
for (auto [playerID, playerInfo] : m_Players) {
data << playerID << playerInfo.name << playerInfo.team;
}
return data;
}
void PlayerListPacket::Deserialize(DataBuffer& data) {
std::uint8_t playerCount;
data >> playerCount;
for (int i = 0; i < playerCount; i++) {
std::uint8_t playerID;
PlayerInfo playerInfo;
data >> playerID >> playerInfo.name >> playerInfo.team;
m_Players.insert({ playerID, playerInfo });
}
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/PlayerLoginPacket.h"
namespace td {
namespace protocol {
DataBuffer PlayerLoginPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerName;
return data;
}
void PlayerLoginPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerName;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/RemoveTowerPacket.h"
namespace td {
namespace protocol {
DataBuffer RemoveTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerID;
return data;
}
void RemoveTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerID;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/SelectTeamPacket.h"
namespace td {
namespace protocol {
DataBuffer SelectTeamPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_SelectedTeam;
return data;
}
void SelectTeamPacket::Deserialize(DataBuffer& data) {
data >> m_SelectedTeam;
}
} // namespace protocol
} // namespace td

View File

@@ -1,26 +0,0 @@
#include "protocol/packets/SendMobsPacket.h"
namespace td {
namespace protocol {
DataBuffer SendMobsPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << static_cast<std::uint8_t>(m_MobSends.size());
data.WriteSome(reinterpret_cast<const std::uint8_t*>(m_MobSends.data()), m_MobSends.size() * sizeof(m_MobSends));
return data;
}
void SendMobsPacket::Deserialize(DataBuffer& data) {
std::uint8_t mobSendCount;
data >> mobSendCount;
m_MobSends.resize(mobSendCount);
data.ReadSome(reinterpret_cast<std::uint8_t*>(m_MobSends.data()), mobSendCount * sizeof(MobSend));
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/ServerTpsPacket.h"
namespace td {
namespace protocol {
DataBuffer ServerTpsPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TPS << m_MSPT << m_PacketSendTime;
return data;
}
void ServerTpsPacket::Deserialize(DataBuffer& data) {
data >> m_TPS >> m_MSPT >> m_PacketSendTime;
}
} // namespace protocol
} // namespace td

View File

@@ -1,21 +0,0 @@
#include "protocol/packets/SpawnMobPacket.h"
namespace td {
namespace protocol {
DataBuffer SpawnMobPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_MobID << m_MobType << m_MobLevel << m_MobDirection
<< m_Sender << m_MobX << m_MobY;
return data;
}
void SpawnMobPacket::Deserialize(DataBuffer& data) {
data >> m_MobID >> m_MobType >> m_MobLevel >> m_MobDirection
>> m_Sender >> m_MobX >> m_MobY;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/UpdateCastleLifePacket.h"
namespace td {
namespace protocol {
DataBuffer UpdateCastleLifePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_CastleLife << m_Team;
return data;
}
void UpdateCastleLifePacket::Deserialize(DataBuffer& data) {
data >> m_CastleLife >> m_Team;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/UpdateExpPacket.h"
namespace td {
namespace protocol {
DataBuffer UpdateExpPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_NewAmount;
return data;
}
void UpdateExpPacket::Deserialize(DataBuffer& data) {
data >> m_NewAmount;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/UpdateGameStatePacket.h"
namespace td {
namespace protocol {
DataBuffer UpdateGameStatePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_GameState;
return data;
}
void UpdateGameStatePacket::Deserialize(DataBuffer& data) {
data >> m_GameState;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/UpdateLobbyTimePacket.h"
namespace td {
namespace protocol {
DataBuffer UpdateLobbyTimePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_StartTime;
return data;
}
void UpdateLobbyTimePacket::Deserialize(DataBuffer& data) {
data >> m_StartTime;
}
} // namespace protocol
} // namespace td

View File

@@ -1,25 +0,0 @@
#include "protocol/packets/UpdateMobStatesPacket.h"
namespace td {
namespace protocol {
DataBuffer UpdateMobStatesPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << static_cast<std::uint64_t>(m_MobStates.size());
data.WriteSome(reinterpret_cast<const std::uint8_t*>(m_MobStates.data()), m_MobStates.size() * sizeof(MobState));
return data;
}
void UpdateMobStatesPacket::Deserialize(DataBuffer& data) {
std::uint64_t mobCount;
data >> mobCount;
m_MobStates.resize(mobCount);
data.ReadSome(reinterpret_cast<std::uint8_t*>(m_MobStates.data()), mobCount * sizeof(MobState));
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/UpdateMoneyPacket.h"
namespace td {
namespace protocol {
DataBuffer UpdateMoneyPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_NewAmount;
return data;
}
void UpdateMoneyPacket::Deserialize(DataBuffer& data) {
data >> m_NewAmount;
}
} // namespace protocol
} // namespace td

View File

@@ -1,20 +0,0 @@
#include "protocol/packets/UpdatePlayerTeamPacket.h"
namespace td {
namespace protocol {
DataBuffer UpdatePlayerTeamPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID << m_SelectedTeam;
return data;
}
void UpdatePlayerTeamPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID >> m_SelectedTeam;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/UpgradeTowerPacket.h"
namespace td {
namespace protocol {
DataBuffer UpgradeTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerID << m_TowerLevel;
return data;
}
void UpgradeTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerID >> m_TowerLevel;
}
} // namespace protocol
} // namespace td

View File

@@ -1,19 +0,0 @@
#include "protocol/packets/WorldAddTowerPacket.h"
namespace td {
namespace protocol {
DataBuffer WorldAddTowerPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TowerID << m_TowerX << m_TowerY << m_TowerType << m_Builder;
return data;
}
void WorldAddTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerID >> m_TowerX >> m_TowerY >> m_TowerType >> m_Builder;
}
} // namespace protocol
} // namespace td

View File

@@ -1,139 +0,0 @@
#include "protocol/packets/WorldBeginDataPacket.h"
namespace td {
namespace protocol {
static DataBuffer& operator<<(DataBuffer& buffer, game::TilePtr tile) {
buffer << tile->GetType();
switch (tile->GetType()) {
case game::TileType::Tower: {
const game::TowerTile* towerTile = dynamic_cast<const game::TowerTile*>(tile.get());
buffer << towerTile->color_palette_ref << towerTile->team_owner;
break;
}
case game::TileType::Walk: {
const game::WalkableTile* walkTile = dynamic_cast<const game::WalkableTile*>(tile.get());
buffer << walkTile->direction;
break;
}
case game::TileType::Decoration: {
const game::DecorationTile* decoTile = dynamic_cast<const game::DecorationTile*>(tile.get());
buffer << decoTile->color_palette_ref;
break;
}
default:
break;
}
return buffer;
}
static DataBuffer& operator>>(DataBuffer& buffer, game::TilePtr& tile) {
game::TileType tileType;
buffer >> tileType;
switch (tileType) {
case game::TileType::Tower: {
auto tilePtr = std::make_shared<game::TowerTile>();
buffer >> tilePtr->color_palette_ref >> tilePtr->team_owner;
tile = tilePtr;
break;
}
case game::TileType::Walk: {
auto tilePtr = std::make_shared<game::WalkableTile>();
buffer >> tilePtr->direction;
tile = tilePtr;
break;
}
case game::TileType::Decoration: {
auto tilePtr = std::make_shared<game::DecorationTile>();
buffer >> tilePtr->color_palette_ref;
tile = tilePtr;
break;
}
default:
break;
}
return buffer;
}
DataBuffer WorldBeginDataPacket::Serialize(bool packetID) const {
DataBuffer data;
const game::TowerTileColorPalette& towerTilePalette = m_Header.m_World->GetTowerTileColorPalette();
const std::vector<Color>& decoTilePalette = m_Header.m_World->GetDecorationPalette();
WritePacketID(data, packetID);
data << towerTilePalette << m_Header.m_World->GetWalkableTileColor()
<< static_cast<std::uint16_t>(decoTilePalette.size());
// deco color palette
std::size_t bufferSize = data.GetSize();
data.Resize(bufferSize + decoTilePalette.size() * sizeof(Color));
memcpy(reinterpret_cast<std::uint8_t*>(data.data()) + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(Color));
data << m_Header.m_World->GetBackgroundColor();
const game::Spawn& redSpawn = m_Header.m_World->GetRedTeam().GetSpawn(), blueSpawn = m_Header.m_World->GetBlueTeam().GetSpawn();
const game::TeamCastle& redCastle = m_Header.m_World->GetRedTeam().GetCastle(), blueCastle = m_Header.m_World->GetBlueTeam().GetCastle();
data << redSpawn << static_cast<utils::shape::Rectangle>(redCastle);
data << blueSpawn << static_cast<utils::shape::Rectangle>(blueCastle);
// tile palette
data << static_cast<std::uint64_t>(m_Header.m_World->GetTilePalette().size());
for (game::TilePtr tile : m_Header.m_World->GetTilePalette()) {
data << tile;
}
data << m_Header.m_World->GetSpawnColors();
return data;
}
void WorldBeginDataPacket::Deserialize(DataBuffer& data) {
data >> m_Header.m_TowerPlacePalette >> m_Header.m_WalkablePalette;
std::uint16_t decoPaletteSize;
data >> decoPaletteSize;
std::size_t decoPalletteSizeByte = decoPaletteSize * sizeof(Color);
m_Header.m_DecorationPalette.resize(decoPaletteSize);
memcpy(reinterpret_cast<std::uint8_t*>(m_Header.m_DecorationPalette.data()), data.data() + data.GetReadOffset(), decoPalletteSizeByte);
data.SetReadOffset(data.GetReadOffset() + decoPalletteSizeByte);
data >> m_Header.m_Background;
utils::shape::Rectangle redCastle, blueCastle;
data >> m_Header.m_RedSpawn >> redCastle;
data >> m_Header.m_BlueSpawn >> blueCastle;
m_Header.m_RedCastle.SetShape(redCastle);
m_Header.m_BlueCastle.SetShape(blueCastle);
std::uint64_t tilePaletteSize;
data >> tilePaletteSize;
m_Header.m_TilePalette.reserve(tilePaletteSize);
for (std::uint64_t tileNumber = 0; tileNumber < tilePaletteSize; tileNumber++) {
game::TilePtr tile;
data >> tile;
m_Header.m_TilePalette.push_back(tile);
}
data >> m_Header.m_SpawnColorPalette;
}
} // namespace protocol
} // namespace td

View File

@@ -1,115 +0,0 @@
#include "protocol/packets/WorldDataPacket.h"
namespace td {
namespace protocol {
const int BITS_IN_BYTE = 8;
const int BITS_IN_LONG = BITS_IN_BYTE * sizeof(std::uint64_t);
static unsigned int countBits(unsigned int number) {
// log function in base 2
// take only integer part
return static_cast<unsigned int>(std::log2(number) + 1);
}
typedef std::vector<uint64_t> ChunkPackedData;
DataBuffer WorldDataPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_World->GetChunks().size();
for (const auto& pair : m_World->GetChunks()) {
game::ChunkCoord coords = pair.first;
game::ChunkPtr chunk = pair.second;
data << coords.x << coords.y << static_cast<std::uint64_t>(chunk->palette.size());
std::size_t bufferSize = data.GetSize();
data.Resize(data.GetSize() + chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
memcpy(reinterpret_cast<std::uint8_t*>(data.data()) + bufferSize, chunk->palette.data(), chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
std::uint8_t bitsPerTile = countBits(chunk->palette.size());
game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
ChunkPackedData chunkData(game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
for (unsigned int tileNumber = 0; tileNumber < game::Chunk::ChunkSize; tileNumber++) {
std::size_t startLong = static_cast<std::size_t>((tileNumber * bitsPerTile) / BITS_IN_LONG);
std::size_t startOffset = static_cast<std::size_t>((tileNumber * bitsPerTile) % BITS_IN_LONG);
std::size_t endLong = static_cast<std::size_t>(((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG);
std::uint64_t value = static_cast<std::uint64_t>(chunk->tiles[tileNumber]);
value &= individualValueMask;
chunkData[startLong] |= (value << startOffset);
if (startLong != endLong) {
chunkData[endLong] = (value >> (BITS_IN_LONG - startOffset));
}
}
bufferSize = data.GetSize();
data.Resize(data.GetSize() + chunkData.size() * sizeof(ChunkPackedData::value_type));
memcpy(reinterpret_cast<std::uint8_t*>(data.data()) + bufferSize, chunkData.data(), chunkData.size() * sizeof(ChunkPackedData::value_type));
}
return data;
}
void WorldDataPacket::Deserialize(DataBuffer& data) {
std::uint64_t chunkCount;
data >> chunkCount;
for (std::uint64_t chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {
game::ChunkPtr chunk = std::make_shared<game::Chunk>();
decltype(game::ChunkCoord::x) chunkX, chunkY;
data >> chunkX >> chunkY;
std::uint64_t chunkPaletteSize;
data >> chunkPaletteSize;
game::ChunkPalette chunkPalette(chunkPaletteSize);
memcpy(reinterpret_cast<void*>(chunkPalette.data()), data.data() + data.GetReadOffset(), chunkPaletteSize * sizeof(game::ChunkPalette::value_type));
data.SetReadOffset(data.GetReadOffset() + chunkPaletteSize * sizeof(game::ChunkPalette::value_type));
chunk->palette = chunkPalette;
std::uint8_t bitsPerTile = countBits(chunkPaletteSize);
// A bitmask that contains bitsPerTile set bits
game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
ChunkPackedData chunkData(game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
memcpy(reinterpret_cast<void*>(chunkData.data()), data.data() + data.GetReadOffset(), chunkData.size() * sizeof(ChunkPackedData::value_type));
data.SetReadOffset(data.GetReadOffset() + chunkData.size() * sizeof(ChunkPackedData::value_type));
for (unsigned int tileNumber = 0; tileNumber < game::Chunk::ChunkSize; tileNumber++) {
std::size_t startLong = (tileNumber * bitsPerTile) / BITS_IN_LONG;
std::size_t startOffset = (tileNumber * bitsPerTile) % BITS_IN_LONG;
std::size_t endLong = ((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG;
game::Chunk::ChunkData::value_type value;
if (startLong == endLong) {
value = (chunkData[startLong] >> startOffset);
} else {
int endOffset = BITS_IN_LONG - startOffset;
value = (chunkData[startLong] >> startOffset | chunkData[endLong] << endOffset);
}
value &= individualValueMask;
chunk->tiles[tileNumber] = value;
}
m_WorldData.m_Chunks.insert({ {chunkX, chunkY}, chunk });
}
}
} // namespace protocol
} // namespace td

View File

@@ -49,7 +49,11 @@ bool Renderer::Init() {
#endif
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_LESS);
glFrontFace(GL_CCW);
InitShaders();
return true;
}
@@ -70,8 +74,19 @@ void Renderer::RenderModel(const Model& model) {
model.vao->Unbind();
}
void Renderer::RenderModel(const TexturedModel& model) {
m_EntityShader->Start();
m_EntityShader->SetModelPos(model.GetPosition());
m_EntityShader->SetColorEffect(model.GetColor());
model.GetTexture().Bind();
model.GetVao().Bind();
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(model.GetVao().GetVertexCount()));
model.GetVao().Unbind();
GL::Texture::Unbind();
}
void Renderer::Prepare() {
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(m_BackgroundColor.r, m_BackgroundColor.g, m_BackgroundColor.b, 0);
}

View File

@@ -1,5 +1,7 @@
#include "render/WorldRenderer.h"
#include "render/loader/WorldLoader.h"
#include "render/loader/TextureLoader.h"
#include "render/loader/MobLoader.h"
#include "render/Renderer.h"
#include "render/gui/imgui/imgui.h"
#include "gui/imgui/imgui_internal.h"
@@ -11,11 +13,29 @@
namespace td {
namespace render {
ImVec4 WorldRenderer::GetImGuiTeamColor(game::TeamColor color) {
switch (color) {
case td::game::TeamColor::None:
break;
case td::game::TeamColor::Red:
return ImVec4(1, 0, 0, 1);
case td::game::TeamColor::Blue:
return ImVec4(0, 0, 1, 1);
}
return ImVec4(1, 1, 1, 1);
}
void WorldRenderer::LoadModels() {
utils::LOGD("World Created !");
m_WorldVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::LoadWorldModel(m_World)));
m_MobVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::LoadMobModel()));
m_SelectTileVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::LoadTileSelectModel()));
m_WorldVao = std::make_unique<GL::VertexArray>(WorldLoader::LoadWorldModel(m_World));
m_SelectTileModel = std::make_unique<Model>();
m_SelectTileModel->vao = std::make_unique<GL::VertexArray>(WorldLoader::LoadTileSelectModel());
for (std::size_t i = 0; i < static_cast<std::size_t>(game::MobType::MOB_COUNT); i++) {
m_MobModels.push_back(MobLoader::LoadMobModel(game::MobType(i)));
}
utils::LOGD(utils::format("Vertex Count : %u", m_WorldVao->GetVertexCount()));
}
@@ -77,13 +97,13 @@ void WorldRenderer::RenderWorld() const {
m_Renderer->RenderVAO(*m_WorldVao);
}
void WorldRenderer::RenderMobs() const {
void WorldRenderer::RenderMobs() {
for (game::MobPtr mob : m_World->GetMobList()) {
Renderer::Model model;
model.vao = m_MobVao.get();
model.positon = { mob->GetCenterX(), 0, mob->GetCenterY() };
model.color = mob->HasTakenDamage() ? Vec3f{ 1, 0.5, 0.5 } : Vec3f{ 1, 1, 1 };
m_Renderer->RenderModel(model);
TexturedModel& mobModel = m_MobModels.at(static_cast<std::size_t>(mob->GetType()));
mobModel.SetPosition({ mob->GetCenterX(), 0, mob->GetCenterY() });
mobModel.SetColor(mob->HasTakenDamage() ? Vec3f{ 1, 0.5, 0.5 } : Vec3f{ 1, 1, 1 });
m_Renderer->RenderModel(mobModel);
}
}
@@ -97,11 +117,9 @@ void WorldRenderer::RenderTileSelect() const {
if (m_MobTooltip->IsShown() || m_CastleTooltip->IsShown()) return;
Renderer::Model tileSelectModel;
tileSelectModel.vao = m_SelectTileVao.get();
tileSelectModel.positon = { std::floor(m_CursorPos.x), 0, std::floor(m_CursorPos.y) };
m_SelectTileModel->positon = { std::floor(m_CursorPos.x), 0, std::floor(m_CursorPos.y) };
m_Renderer->RenderModel(tileSelectModel);
m_Renderer->RenderModel(*m_SelectTileModel);
}
void WorldRenderer::RenderPopups() {

View File

@@ -1,7 +1,6 @@
#include "render/gui/CastleTooltip.h"
#include "render/gui/imgui/imgui.h"
#include "render/gui/LifeProgress.h"
#include "render/gui/ImGuiTeamColor.h"
#include "render/WorldRenderer.h"
@@ -19,7 +18,7 @@ void CastleTooltip::Render() {
if (ImGui::GetIO().KeyShift) {
ImGui::BeginTooltip();
ImGui::PushStyleColor(ImGuiCol_Text, render::GetImGuiTeamColor(m_Castle->GetTeam()->GetColor()));
ImGui::PushStyleColor(ImGuiCol_Text, render::WorldRenderer::GetImGuiTeamColor(m_Castle->GetTeam()->GetColor()));
ImGui::Text("Castle : ");
ImGui::PopStyleColor();
ImGui::Text("\tCastle HP : %i/%i", static_cast<int>(m_Castle->GetLife()), game::TeamCastle::CastleMaxLife);

View File

@@ -1,6 +1,5 @@
#include "render/gui/GameMenu.h"
#include "render/gui/imgui/imgui.h"
#include "render/gui/ImGuiTeamColor.h"
#include "render/WorldRenderer.h"
@@ -44,7 +43,7 @@ void GameMenu::ShowPlayers() {
if (ImGui::TreeNode(std::string("Players (" + std::to_string(GetClient()->GetGame().GetPlayers().size()) + ")##player_list").c_str())) {
for (auto pair : GetClient()->GetGame().GetPlayers()) {
const td::game::Player& player = pair.second;
ImGui::PushStyleColor(ImGuiCol_Text, render::GetImGuiTeamColor(player.GetTeamColor()));
ImGui::PushStyleColor(ImGuiCol_Text, render::WorldRenderer::GetImGuiTeamColor(player.GetTeamColor()));
ImGui::Text("%s", player.GetName().c_str());
ImGui::PopStyleColor();
}
@@ -73,12 +72,10 @@ void GameMenu::ShowTeamSelection() {
}
void GameMenu::ShowLobbyProgress() {
const std::uint64_t waitTime = GetClient()->GetGame().GetGameStartTime() - GetClient()->GetGame().GetLobbyStartTime();
const std::uint64_t timeRemaining = GetClient()->GetGame().GetGameStartTime() - utils::GetTime();
const float progress = static_cast<float>(timeRemaining) / static_cast<float>(waitTime);
const int timePassed = server::Lobby::LobbyWaitingTime - GetClient()->GetGame().GetLobbyTime();
const float progress = (float)timePassed / (float)(server::Lobby::LobbyWaitingTime);
if (progress > 0 && progress < 1) {
ImGui::ProgressBar(1.0f - progress, ImVec2(0.0f, 0.0f), std::string(std::to_string(timeRemaining / 1000) + "s").c_str());
ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f), std::string(std::to_string(GetClient()->GetGame().GetLobbyTime() / 1000) + "s").c_str());
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
ImGui::Text("Time Remaining");
} else {
@@ -88,7 +85,7 @@ void GameMenu::ShowLobbyProgress() {
void GameMenu::ShowTPS() {
ImGui::Text("Server TPS : %.1f", GetClient()->GetConnexion().GetServerTPS());
ImGui::Text("Server MSPT : %i", static_cast<int>(GetClient()->GetConnexion().GetServerMSPT()));
ImGui::Text("Server MSPT : %i", (int)GetClient()->GetConnexion().GetServerMSPT());
ImGui::Text("Server Ping : %i", GetClient()->GetConnexion().GetServerPing());
}

View File

@@ -1,19 +0,0 @@
#include "render/gui/ImGuiTeamColor.h"
namespace td {
namespace render {
ImVec4 GetImGuiTeamColor(game::TeamColor color) {
switch (color) {
case td::game::TeamColor::None:
break;
case td::game::TeamColor::Red:
return ImVec4(1, 0, 0, 1);
case td::game::TeamColor::Blue:
return ImVec4(0, 0, 1, 1);
}
return ImVec4(1, 1, 1, 1);
}
} // namespace render
} // namespace td

View File

@@ -1,7 +1,6 @@
#include "render/gui/MobTooltip.h"
#include "render/gui/imgui/imgui.h"
#include "render/gui/LifeProgress.h"
#include "render/gui/ImGuiTeamColor.h"
#include "render/WorldRenderer.h"
@@ -26,7 +25,7 @@ void MobTooltip::Render() {
ImGui::BeginTooltip();
ImGui::Text("Sender :");
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Text, render::GetImGuiTeamColor(sender->GetTeamColor()));
ImGui::PushStyleColor(ImGuiCol_Text, render::WorldRenderer::GetImGuiTeamColor(sender->GetTeamColor()));
ImGui::Text("%s", sender->GetName().c_str());
ImGui::PopStyleColor();
ImGui::Text("Mob HP : %.1f/%i", m_Mob->GetHealth(), m_Mob->GetStats()->GetMaxLife());

View File

@@ -8,6 +8,7 @@
#include "render/loader/GLLoader.h"
#include "render/GL.h"
#include <cassert>
namespace GL {
@@ -69,4 +70,37 @@ void VertexBuffer::BindVertexAttribs() const {
glVertexAttribPointer(pointer.m_Index, static_cast<GLint>(pointer.m_Size), GL_FLOAT, false, m_DataStride * sizeof(float), reinterpret_cast<void*>(pointer.m_Offset));
}
}
Texture::Texture(const char* textureData, int width, int height, int comp) {
glGenTextures(1, &m_ID);
Bind();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
assert(comp == 3 || comp == 4);
if (comp == 3)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
GL_UNSIGNED_BYTE, textureData);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, textureData);
Unbind();
}
Texture::~Texture() {
glDeleteTextures(1, &m_ID);
}
void Texture::Bind() const {
glBindTexture(GL_TEXTURE_2D, m_ID);
}
void Texture::Unbind() {
glBindTexture(GL_TEXTURE_2D, 0);
}
}

View File

@@ -0,0 +1,216 @@
#include "Defines.h"
#include "render/loader/MobLoader.h"
#include "render/loader/TextureLoader.h"
#include <fstream>
#include <map>
#include <sstream>
#include <algorithm>
namespace td {
namespace render {
TexturedModel::TexturedModel(GL::VertexArray&& vao, GL::Texture&& texture) {
m_Vao = std::make_unique<GL::VertexArray>(std::move(vao));
m_Texture = std::make_unique<GL::Texture>(std::move(texture));
}
TexturedModel::TexturedModel(TexturedModel&& other) {
m_Vao = std::move(other.m_Vao);
m_Texture = std::move(other.m_Texture);
m_Positon = other.m_Positon;
m_Color = other.m_Color;
}
namespace MobLoader {
const static int POSITION_VERTEX_SIZE = 3;
const static int TEXTURE_VERTEX_SIZE = 2;
typedef Vec3f Vertex;
typedef Vec2f TextureUV;
typedef Vec3f Normal;
struct Index {
std::size_t vertexIndex;
std::size_t textureIndex;
std::size_t normalIndex;
};
enum DataType : std::uint8_t {
dt_Vertex,
dt_Texture,
dt_Normal,
dt_Index,
dt_None
};
static DataType GetDataType(const std::string& type) {
static const std::map<std::string, DataType> Types = {
{"v", dt_Vertex},
{"vt", dt_Texture},
{"vn", dt_Normal},
{"f", dt_Index}
};
auto it = Types.find(type);
return it != Types.end() ? it->second : dt_None;
}
static GL::VertexArray LoadMobVao(const std::string& objFile) {
std::ifstream fileStream{ objFile };
std::string line;
std::vector<Vertex> tempVertecies;
std::vector<TextureUV> tempTextureUvs;
std::vector<Normal> tempNormals;
std::vector<float> vertecies;
std::vector<float> textureUvs;
std::vector<float> normals;
while (getline(fileStream, line)) {
std::replace(line.begin(), line.end(), '/', ' ');
std::stringstream ss;
ss << line;
std::string typeStr;
ss >> typeStr;
DataType dataType = GetDataType(typeStr);
switch (dataType) {
case dt_Vertex: {
Vertex vertex;
ss >> vertex.x;
ss >> vertex.y;
ss >> vertex.z;
tempVertecies.push_back(vertex);
break;
}
case dt_Texture: {
TextureUV texture;
ss >> texture.x;
ss >> texture.y;
tempTextureUvs.push_back(texture);
break;
}
case dt_Normal: {
Normal normal;
ss >> normal.x;
ss >> normal.y;
ss >> normal.z;
tempNormals.push_back(normal);
break;
}
case dt_Index: {
Index tempIndicies[4];
for (std::size_t i = 0; i < 4; i++){
ss >> tempIndicies[i].vertexIndex;
ss >> tempIndicies[i].textureIndex;
ss >> tempIndicies[i].normalIndex;
}
static const std::vector<std::size_t> vertexOrder = {0, 1, 2, 0, 2, 3};
for(std::size_t i = 0; i < vertexOrder.size(); i++) {
Index& index = tempIndicies[vertexOrder[i]];
std::size_t vertexIndex = index.vertexIndex - 1;
std::size_t textureIndex = index.textureIndex - 1;
std::size_t normalIndex = index.normalIndex - 1;
Vertex vertex = tempVertecies[vertexIndex];
TextureUV texture = tempTextureUvs[textureIndex];
Normal normal = tempNormals[normalIndex];
vertecies.push_back(vertex.x);
vertecies.push_back(vertex.y);
vertecies.push_back(vertex.z);
textureUvs.push_back(texture.x);
textureUvs.push_back(1.0f - texture.y);
normals.push_back(normal.x);
normals.push_back(normal.y);
normals.push_back(normal.z);
}
break;
}
default:
break;
}
}
GL::VertexBuffer positionVBO(vertecies, POSITION_VERTEX_SIZE);
positionVBO.AddVertexAttribPointer(0, POSITION_VERTEX_SIZE, 0);
GL::VertexBuffer textureVBO(textureUvs, TEXTURE_VERTEX_SIZE);
textureVBO.AddVertexAttribPointer(1, TEXTURE_VERTEX_SIZE, 0);
GL::VertexArray mobVao(vertecies.size() / POSITION_VERTEX_SIZE); // each pos = 1 color
mobVao.Bind();
mobVao.BindVertexBuffer(positionVBO);
mobVao.BindVertexBuffer(textureVBO);
mobVao.Unbind();
return mobVao;
}
TexturedModel LoadMobModel(game::MobType mobType) {
switch (mobType){
case game::MobType::Blaze:
return {LoadMobVao("Assets/blaze.obj"), TextureLoader::LoadTexture("Assets/blaze.png")};
case game::MobType::Creeper:
return {LoadMobVao("Assets/creeper.obj"), TextureLoader::LoadTexture("Assets/creeper.png")};
case game::MobType::Giant:
return {LoadMobVao("Assets/giant.obj"), TextureLoader::LoadTexture("Assets/giant.png")};
case game::MobType::Pigman:
return {LoadMobVao("Assets/zombified_piglin.obj"), TextureLoader::LoadTexture("Assets/zombified_piglin.png")};
case game::MobType::Silverfish:
return {LoadMobVao("Assets/silverfish.obj"), TextureLoader::LoadTexture("Assets/silverfish.png")};
case game::MobType::Skeleton:
return {LoadMobVao("Assets/skeleton.obj"), TextureLoader::LoadTexture("Assets/skeleton.png")};
case game::MobType::Slime:
return {LoadMobVao("Assets/slime.obj"), TextureLoader::LoadTexture("Assets/slime.png")};
case game::MobType::Spider :
return {LoadMobVao("Assets/spider.obj"), TextureLoader::LoadTexture("Assets/spider.png")};
case game::MobType::Witch :
return {LoadMobVao("Assets/witch.obj"), TextureLoader::LoadTexture("Assets/witch.png")};
case game::MobType::Zombie :
return {LoadMobVao("Assets/zombie.obj"), TextureLoader::LoadTexture("Assets/zombie.png")};
default:
return {LoadMobVao("Assets/armor_stand.obj"), TextureLoader::LoadTexture("Assets/armor_stand.png")};
}
}
} // namespace MobLoader
} // namespace render
} // namespace td

View File

@@ -10,37 +10,29 @@
#include "render/loader/stb_image.h"
#include <iostream>
#include "render/GL.h"
#include "misc/Log.h"
#include "misc/Format.h"
namespace TextureLoader {
unsigned int LoadGLTexture(const char* fileName) {
GL::Texture LoadTexture(const std::string& fileName) {
int width, height, comp;
const unsigned char* image = stbi_load(fileName, &width, &height, &comp, STBI_rgb_alpha);
const unsigned char* image = stbi_load(fileName.c_str(), &width, &height, &comp, STBI_rgb_alpha);
if (image == nullptr) {
std::cerr << "Erreur lors du chargement de la texture !" << std::endl;
td::utils::LOGE("Erreur lors du chargement de la texture !");
throw(std::runtime_error("Failed to load texture"));
}
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
GL::Texture texture {reinterpret_cast<const char*>(image), width, height, comp};
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
delete image;
if (comp == 3)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
GL_UNSIGNED_BYTE, image);
else if (comp == 4)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image);
td::utils::LOGD(td::utils::format("Texture %s chargée !", fileName.c_str()));
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free((void*)image);
return textureID;
return texture;
}
}

View File

@@ -5,50 +5,15 @@
#include "game/BaseGame.h"
#include "misc/Random.h"
namespace td {
namespace render {
namespace WorldLoader {
const static int VERTEX_SIZE = 3;
GL::VertexArray LoadMobModel() {
std::vector<float> positions = {
-0.5, 0, -0.5,
0.5, 0, -0.5,
-0.5, 0, 0.5,
0.5, 0, -0.5,
-0.5, 0, 0.5,
0.5, 0, 0.5
};
float yellowFloat;
int yellow = 255 << 24 | 255 << 16 | 255;
memcpy(&yellowFloat, &yellow, sizeof(int));
std::vector<float> colors = {
yellowFloat,
yellowFloat,
yellowFloat,
yellowFloat,
yellowFloat,
yellowFloat
};
GL::VertexBuffer positionVBO(positions, VERTEX_SIZE);
positionVBO.AddVertexAttribPointer(0, VERTEX_SIZE, 0);
GL::VertexBuffer colorVBO(colors, 1);
colorVBO.AddVertexAttribPointer(1, 1, 0);
GL::VertexArray mobVao(colors.size()); // each pos = 1 color
mobVao.Bind();
mobVao.BindVertexBuffer(positionVBO);
mobVao.BindVertexBuffer(colorVBO);
mobVao.Unbind();
return mobVao;
}
const static int POSITION_VERTEX_SIZE = 3;
const static int TEXTURE_VERTEX_SIZE = 2;
GL::VertexArray LoadWorldModel(const td::game::World* world) {
std::vector<float> positions;
@@ -71,12 +36,12 @@ GL::VertexArray LoadWorldModel(const td::game::World* world) {
continue;
positions.insert(positions.end(), {
static_cast<float>(chunkX + tileX), 0, static_cast<float>(chunkY + tileY),
static_cast<float>(chunkX + tileX + 1), 0, static_cast<float>(chunkY + tileY),
static_cast<float>(chunkX + tileX), 0, static_cast<float>(chunkY + tileY + 1),
static_cast<float>(chunkX + tileX + 1), 0, static_cast<float>(chunkY + tileY),
static_cast<float>(chunkX + tileX), 0, static_cast<float>(chunkY + tileY),
static_cast<float>(chunkX + tileX), 0, static_cast<float>(chunkY + tileY + 1),
static_cast<float>(chunkX + tileX + 1), 0, static_cast<float>(chunkY + tileY),
static_cast<float>(chunkX + tileX), 0, static_cast<float>(chunkY + tileY + 1),
static_cast<float>(chunkX + tileX + 1), 0, static_cast<float>(chunkY + tileY),
static_cast<float>(chunkX + tileX), 0, static_cast<float>(chunkY + tileY + 1),
static_cast<float>(chunkX + tileX + 1), 0, static_cast<float>(chunkY + tileY + 1)
});
@@ -107,8 +72,8 @@ GL::VertexArray LoadWorldModel(const td::game::World* world) {
fromX, 0, toY,
toX, 0, fromY,
toX, 0, toY,
fromX, 0, toY,
toX, 0, toY,
toX, 0, fromY,
});
@@ -135,8 +100,8 @@ GL::VertexArray LoadWorldModel(const td::game::World* world) {
fromX, 0, toY,
toX, 0, fromY,
toX, 0, toY,
fromX, 0, toY,
toX, 0, toY,
toX, 0, fromY,
});
@@ -153,12 +118,12 @@ GL::VertexArray LoadWorldModel(const td::game::World* world) {
}
}
GL::VertexBuffer positionVBO(positions, VERTEX_SIZE);
positionVBO.AddVertexAttribPointer(0, VERTEX_SIZE, 0);
GL::VertexBuffer positionVBO(positions, POSITION_VERTEX_SIZE);
positionVBO.AddVertexAttribPointer(0, POSITION_VERTEX_SIZE, 0);
GL::VertexBuffer colorVBO(colors, 1);
colorVBO.AddVertexAttribPointer(1, 1, 0);
GL::VertexArray worldVao(positions.size() / VERTEX_SIZE); // each pos = 3 vertecies
GL::VertexArray worldVao(positions.size() / POSITION_VERTEX_SIZE); // each pos = 3 vertecies
worldVao.Bind();
worldVao.BindVertexBuffer(positionVBO);
worldVao.BindVertexBuffer(colorVBO);
@@ -168,13 +133,13 @@ GL::VertexArray LoadWorldModel(const td::game::World* world) {
GL::VertexArray LoadTileSelectModel() {
std::vector<float> positions = {
0, 0, 0,
1, 0, 0,
0, 0, 1,
1, .01, 0,
0, .01, 0,
0, .01, 1,
1, 0, 0,
0, 0, 1,
1, 0, 1
1, .01, 0,
0, .01, 1,
1, .01, 1
};
int color = 255 << 24 | 255 << 16 | 255 << 8 | 150;
@@ -184,12 +149,12 @@ GL::VertexArray LoadTileSelectModel() {
std::vector<float> colors(6, colorFloat);
GL::VertexBuffer positionVBO(positions, VERTEX_SIZE);
positionVBO.AddVertexAttribPointer(0, VERTEX_SIZE, 0);
GL::VertexBuffer positionVBO(positions, POSITION_VERTEX_SIZE);
positionVBO.AddVertexAttribPointer(0, POSITION_VERTEX_SIZE, 0);
GL::VertexBuffer colorVBO(colors, 1);
colorVBO.AddVertexAttribPointer(1, 1, 0);
GL::VertexArray tileSelectVao(positions.size() / 2); // each pos = 2 vertecies
GL::VertexArray tileSelectVao(positions.size() / POSITION_VERTEX_SIZE);
tileSelectVao.Bind();
tileSelectVao.BindVertexBuffer(positionVBO);
tileSelectVao.BindVertexBuffer(colorVBO);
@@ -218,13 +183,13 @@ RenderData LoadTowerModel(game::TowerPtr tower) {
towerDY = tower->GetCenterY() + 2.5f;
}
std::vector<float> positions = {
towerX, 0, towerY,
towerDX, 0, towerY,
towerX, 0, towerDY,
towerDX, 0.001, towerY,
towerX, 0.001, towerY,
towerX, 0.001, towerDY,
towerDX, 0, towerY,
towerX, 0, towerDY,
towerDX, 0, towerDY
towerDX, 0.001, towerY,
towerX, 0.001, towerDY,
towerDX, 0.001, towerDY
};
renderData.positions = positions;

View File

@@ -3,6 +3,8 @@
namespace td {
namespace shader {
// TODO: update ES shaders
#ifdef __ANDROID__
static const char vertexSource[] =
R"(#version 300 es
@@ -51,16 +53,16 @@ static const char vertexSource[] = R"(
#version 330
layout(location = 0) in vec3 position;
layout(location = 1) in int color;
layout(location = 1) in vec2 textureCoords;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform vec3 modelPosition;
flat out int pass_color;
out vec2 pass_textureCoords;
void main(void){
pass_color = color;
pass_textureCoords = textureCoords;
gl_Position = projectionMatrix * viewMatrix * vec4(position + modelPosition, 1.0);
}
)";
@@ -68,20 +70,21 @@ void main(void){
static const char fragmentSource[] = R"(
#version 330
flat in int pass_color;
in vec2 pass_textureCoords;
out vec4 out_color;
uniform vec3 ColorEffect;
uniform sampler2D textureSampler;
void main(void){
float r = float(pass_color >> 24 & 0xFF) / 255.0;
float g = float(pass_color >> 16 & 0xFF) / 255.0;
float b = float(pass_color >> 8 & 0xFF) / 255.0;
float a = float(pass_color & 0xFF) / 255.0;
vec3 intermediate_color = vec3(r, g, b) * ColorEffect;
out_color = vec4(intermediate_color, a);
vec4 color = vec4(ColorEffect, 1.0) * texture(textureSampler, pass_textureCoords);
if (color.a <= 0.1)
discard;
out_color = color;
}
)";

463
test/Assets/armor_stand.obj Normal file
View File

@@ -0,0 +1,463 @@
# Made in Blockbench 4.7.4
mtllib armor_stand.mtl
o head
v 0.0625 1.875 0.0625
v 0.0625 1.875 -0.0625
v 0.0625 1.4375 0.0625
v 0.0625 1.4375 -0.0625
v -0.0625 1.875 -0.0625
v -0.0625 1.875 0.0625
v -0.0625 1.4375 -0.0625
v -0.0625 1.4375 0.0625
vt 0.03125 0.96875
vt 0.0625 0.96875
vt 0.0625 0.859375
vt 0.03125 0.859375
vt 0 0.96875
vt 0.03125 0.96875
vt 0.03125 0.859375
vt 0 0.859375
vt 0.09375 0.96875
vt 0.125 0.96875
vt 0.125 0.859375
vt 0.09375 0.859375
vt 0.0625 0.96875
vt 0.09375 0.96875
vt 0.09375 0.859375
vt 0.0625 0.859375
vt 0.0625 0.96875
vt 0.03125 0.96875
vt 0.03125 1
vt 0.0625 1
vt 0.09375 1
vt 0.0625 1
vt 0.0625 0.96875
vt 0.09375 0.96875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 4/4/1 7/3/1 5/2/1 2/1/1
f 3/8/2 4/7/2 2/6/2 1/5/2
f 8/12/3 3/11/3 1/10/3 6/9/3
f 7/16/4 8/15/4 6/14/4 5/13/4
f 6/20/5 1/19/5 2/18/5 5/17/5
f 7/24/6 4/23/6 3/22/6 8/21/6
o body
v 0.375 1.5 0.09375
v 0.375 1.5 -0.09375
v 0.375 1.3125 0.09375
v 0.375 1.3125 -0.09375
v -0.375 1.5 -0.09375
v -0.375 1.5 0.09375
v -0.375 1.3125 -0.09375
v -0.375 1.3125 0.09375
vt 0.046875 0.546875
vt 0.234375 0.546875
vt 0.234375 0.5
vt 0.046875 0.5
vt 0 0.546875
vt 0.046875 0.546875
vt 0.046875 0.5
vt 0 0.5
vt 0.28125 0.546875
vt 0.46875 0.546875
vt 0.46875 0.5
vt 0.28125 0.5
vt 0.234375 0.546875
vt 0.28125 0.546875
vt 0.28125 0.5
vt 0.234375 0.5
vt 0.234375 0.546875
vt 0.046875 0.546875
vt 0.046875 0.59375
vt 0.234375 0.59375
vt 0.421875 0.59375
vt 0.234375 0.59375
vt 0.234375 0.546875
vt 0.421875 0.546875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 12/28/7 15/27/7 13/26/7 10/25/7
f 11/32/8 12/31/8 10/30/8 9/29/8
f 16/36/9 11/35/9 9/34/9 14/33/9
f 15/40/10 16/39/10 14/38/10 13/37/10
f 14/44/11 9/43/11 10/42/11 13/41/11
f 15/48/12 12/47/12 11/46/12 16/45/12
o left_arm
v -0.3125 1.5 0.0625
v -0.3125 1.5 -0.0625
v -0.3125 0.75 0.0625
v -0.3125 0.75 -0.0625
v -0.4375 1.5 -0.0625
v -0.4375 1.5 0.0625
v -0.4375 0.75 -0.0625
v -0.4375 0.75 0.0625
vt 0.5625 0.71875
vt 0.53125 0.71875
vt 0.53125 0.53125
vt 0.5625 0.53125
vt 0.59375 0.71875
vt 0.5625 0.71875
vt 0.5625 0.53125
vt 0.59375 0.53125
vt 0.625 0.71875
vt 0.59375 0.71875
vt 0.59375 0.53125
vt 0.625 0.53125
vt 0.53125 0.71875
vt 0.5 0.71875
vt 0.5 0.53125
vt 0.53125 0.53125
vt 0.53125 0.71875
vt 0.5625 0.71875
vt 0.5625 0.75
vt 0.53125 0.75
vt 0.5625 0.75
vt 0.59375 0.75
vt 0.59375 0.71875
vt 0.5625 0.71875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 20/52/13 23/51/13 21/50/13 18/49/13
f 19/56/14 20/55/14 18/54/14 17/53/14
f 24/60/15 19/59/15 17/58/15 22/57/15
f 23/64/16 24/63/16 22/62/16 21/61/16
f 22/68/17 17/67/17 18/66/17 21/65/17
f 23/72/18 20/71/18 19/70/18 24/69/18
o right_arm
v 0.4375 1.5 0.0625
v 0.4375 1.5 -0.0625
v 0.4375 0.75 0.0625
v 0.4375 0.75 -0.0625
v 0.3125 1.5 -0.0625
v 0.3125 1.5 0.0625
v 0.3125 0.75 -0.0625
v 0.3125 0.75 0.0625
vt 0.40625 0.96875
vt 0.4375 0.96875
vt 0.4375 0.78125
vt 0.40625 0.78125
vt 0.375 0.96875
vt 0.40625 0.96875
vt 0.40625 0.78125
vt 0.375 0.78125
vt 0.46875 0.96875
vt 0.5 0.96875
vt 0.5 0.78125
vt 0.46875 0.78125
vt 0.4375 0.96875
vt 0.46875 0.96875
vt 0.46875 0.78125
vt 0.4375 0.78125
vt 0.4375 0.96875
vt 0.40625 0.96875
vt 0.40625 1
vt 0.4375 1
vt 0.46875 1
vt 0.4375 1
vt 0.4375 0.96875
vt 0.46875 0.96875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 28/76/19 31/75/19 29/74/19 26/73/19
f 27/80/20 28/79/20 26/78/20 25/77/20
f 32/84/21 27/83/21 25/82/21 30/81/21
f 31/88/22 32/87/22 30/86/22 29/85/22
f 30/92/23 25/91/23 26/90/23 29/89/23
f 31/96/24 28/95/24 27/94/24 32/93/24
o left_leg
v -0.05625000000000002 0.75 0.0625
v -0.05625000000000002 0.75 -0.0625
v -0.05625000000000002 0.0625 0.0625
v -0.05625000000000002 0.0625 -0.0625
v -0.18125000000000002 0.75 -0.0625
v -0.18125000000000002 0.75 0.0625
v -0.18125000000000002 0.0625 -0.0625
v -0.18125000000000002 0.0625 0.0625
vt 0.6875 0.71875
vt 0.65625 0.71875
vt 0.65625 0.546875
vt 0.6875 0.546875
vt 0.71875 0.71875
vt 0.6875 0.71875
vt 0.6875 0.546875
vt 0.71875 0.546875
vt 0.75 0.71875
vt 0.71875 0.71875
vt 0.71875 0.546875
vt 0.75 0.546875
vt 0.65625 0.71875
vt 0.625 0.71875
vt 0.625 0.546875
vt 0.65625 0.546875
vt 0.65625 0.71875
vt 0.6875 0.71875
vt 0.6875 0.75
vt 0.65625 0.75
vt 0.6875 0.75
vt 0.71875 0.75
vt 0.71875 0.71875
vt 0.6875 0.71875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 36/100/25 39/99/25 37/98/25 34/97/25
f 35/104/26 36/103/26 34/102/26 33/101/26
f 40/108/27 35/107/27 33/106/27 38/105/27
f 39/112/28 40/111/28 38/110/28 37/109/28
f 38/116/29 33/115/29 34/114/29 37/113/29
f 39/120/30 36/119/30 35/118/30 40/117/30
o right_leg
v 0.19062500000000004 0.75 0.0625
v 0.19062500000000004 0.75 -0.0625
v 0.19062500000000004 0.0625 0.0625
v 0.19062500000000004 0.0625 -0.0625
v 0.06562500000000004 0.75 -0.0625
v 0.06562500000000004 0.75 0.0625
v 0.06562500000000004 0.0625 -0.0625
v 0.06562500000000004 0.0625 0.0625
vt 0.15625 0.96875
vt 0.1875 0.96875
vt 0.1875 0.796875
vt 0.15625 0.796875
vt 0.125 0.96875
vt 0.15625 0.96875
vt 0.15625 0.796875
vt 0.125 0.796875
vt 0.21875 0.96875
vt 0.25 0.96875
vt 0.25 0.796875
vt 0.21875 0.796875
vt 0.1875 0.96875
vt 0.21875 0.96875
vt 0.21875 0.796875
vt 0.1875 0.796875
vt 0.1875 0.96875
vt 0.15625 0.96875
vt 0.15625 1
vt 0.1875 1
vt 0.21875 1
vt 0.1875 1
vt 0.1875 0.96875
vt 0.21875 0.96875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 44/124/31 47/123/31 45/122/31 42/121/31
f 43/128/32 44/127/32 42/126/32 41/125/32
f 48/132/33 43/131/33 41/130/33 46/129/33
f 47/136/34 48/135/34 46/134/34 45/133/34
f 46/140/35 41/139/35 42/138/35 45/137/35
f 47/144/36 44/143/36 43/142/36 48/141/36
o right
v -0.0625 1.3125 0.0625
v -0.0625 1.3125 -0.0625
v -0.0625 0.875 0.0625
v -0.0625 0.875 -0.0625
v -0.1875 1.3125 -0.0625
v -0.1875 1.3125 0.0625
v -0.1875 0.875 -0.0625
v -0.1875 0.875 0.0625
vt 0.78125 0.71875
vt 0.8125 0.71875
vt 0.8125 0.609375
vt 0.78125 0.609375
vt 0.75 0.71875
vt 0.78125 0.71875
vt 0.78125 0.609375
vt 0.75 0.609375
vt 0.84375 0.71875
vt 0.875 0.71875
vt 0.875 0.609375
vt 0.84375 0.609375
vt 0.8125 0.71875
vt 0.84375 0.71875
vt 0.84375 0.609375
vt 0.8125 0.609375
vt 0.8125 0.71875
vt 0.78125 0.71875
vt 0.78125 0.75
vt 0.8125 0.75
vt 0.84375 0.75
vt 0.8125 0.75
vt 0.8125 0.71875
vt 0.84375 0.71875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 52/148/37 55/147/37 53/146/37 50/145/37
f 51/152/38 52/151/38 50/150/38 49/149/38
f 56/156/39 51/155/39 49/154/39 54/153/39
f 55/160/40 56/159/40 54/158/40 53/157/40
f 54/164/41 49/163/41 50/162/41 53/161/41
f 55/168/42 52/167/42 51/166/42 56/165/42
o left
v 0.1875 1.3125 0.0625
v 0.1875 1.3125 -0.0625
v 0.1875 0.875 0.0625
v 0.1875 0.875 -0.0625
v 0.0625 1.3125 -0.0625
v 0.0625 1.3125 0.0625
v 0.0625 0.875 -0.0625
v 0.0625 0.875 0.0625
vt 0.28125 0.96875
vt 0.3125 0.96875
vt 0.3125 0.859375
vt 0.28125 0.859375
vt 0.25 0.96875
vt 0.28125 0.96875
vt 0.28125 0.859375
vt 0.25 0.859375
vt 0.34375 0.96875
vt 0.375 0.96875
vt 0.375 0.859375
vt 0.34375 0.859375
vt 0.3125 0.96875
vt 0.34375 0.96875
vt 0.34375 0.859375
vt 0.3125 0.859375
vt 0.3125 0.96875
vt 0.28125 0.96875
vt 0.28125 1
vt 0.3125 1
vt 0.34375 1
vt 0.3125 1
vt 0.3125 0.96875
vt 0.34375 0.96875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 60/172/43 63/171/43 61/170/43 58/169/43
f 59/176/44 60/175/44 58/174/44 57/173/44
f 64/180/45 59/179/45 57/178/45 62/177/45
f 63/184/46 64/183/46 62/182/46 61/181/46
f 62/188/47 57/187/47 58/186/47 61/185/47
f 63/192/48 60/191/48 59/190/48 64/189/48
o waist
v 0.25 0.875 0.0625
v 0.25 0.875 -0.0625
v 0.25 0.75 0.0625
v 0.25 0.75 -0.0625
v -0.25 0.875 -0.0625
v -0.25 0.875 0.0625
v -0.25 0.75 -0.0625
v -0.25 0.75 0.0625
vt 0.03125 0.21875
vt 0.15625 0.21875
vt 0.15625 0.1875
vt 0.03125 0.1875
vt 0 0.21875
vt 0.03125 0.21875
vt 0.03125 0.1875
vt 0 0.1875
vt 0.1875 0.21875
vt 0.3125 0.21875
vt 0.3125 0.1875
vt 0.1875 0.1875
vt 0.15625 0.21875
vt 0.1875 0.21875
vt 0.1875 0.1875
vt 0.15625 0.1875
vt 0.15625 0.21875
vt 0.03125 0.21875
vt 0.03125 0.25
vt 0.15625 0.25
vt 0.28125 0.25
vt 0.15625 0.25
vt 0.15625 0.21875
vt 0.28125 0.21875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 68/196/49 71/195/49 69/194/49 66/193/49
f 67/200/50 68/199/50 66/198/50 65/197/50
f 72/204/51 67/203/51 65/202/51 70/201/51
f 71/208/52 72/207/52 70/206/52 69/205/52
f 70/212/53 65/211/53 66/210/53 69/209/53
f 71/216/54 68/215/54 67/214/54 72/213/54
o base
v 0.375 0.0625 0.375
v 0.375 0.0625 -0.375
v 0.375 0 0.375
v 0.375 0 -0.375
v -0.375 0.0625 -0.375
v -0.375 0.0625 0.375
v -0.375 0 -0.375
v -0.375 0 0.375
vt 0.1875 0.3125
vt 0.375 0.3125
vt 0.375 0.296875
vt 0.1875 0.296875
vt 0 0.3125
vt 0.1875 0.3125
vt 0.1875 0.296875
vt 0 0.296875
vt 0.5625 0.3125
vt 0.75 0.3125
vt 0.75 0.296875
vt 0.5625 0.296875
vt 0.375 0.3125
vt 0.5625 0.3125
vt 0.5625 0.296875
vt 0.375 0.296875
vt 0.375 0.3125
vt 0.1875 0.3125
vt 0.1875 0.5
vt 0.375 0.5
vt 0.5625 0.5
vt 0.375 0.5
vt 0.375 0.3125
vt 0.5625 0.3125
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_008ca971-b56b-ee8d-d41a-6f8b49501f97
f 76/220/55 79/219/55 77/218/55 74/217/55
f 75/224/56 76/223/56 74/222/56 73/221/56
f 80/228/57 75/227/57 73/226/57 78/225/57
f 79/232/58 80/231/58 78/230/58 77/229/58
f 78/236/59 73/235/59 74/234/59 77/233/59
f 79/240/60 76/239/60 75/238/60 80/237/60

BIN
test/Assets/armor_stand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

601
test/Assets/blaze.obj Normal file
View File

@@ -0,0 +1,601 @@
# Made in Blockbench 4.7.4
mtllib blaze.mtl
o head
v 0.25 1.75 0.25
v 0.25 1.75 -0.25
v 0.25 1.25 0.25
v 0.25 1.25 -0.25
v -0.25 1.75 -0.25
v -0.25 1.75 0.25
v -0.25 1.25 -0.25
v -0.25 1.25 0.25
vt 0.125 0.75
vt 0.25 0.75
vt 0.25 0.5
vt 0.125 0.5
vt 0 0.75
vt 0.125 0.75
vt 0.125 0.5
vt 0 0.5
vt 0.375 0.75
vt 0.5 0.75
vt 0.5 0.5
vt 0.375 0.5
vt 0.25 0.75
vt 0.375 0.75
vt 0.375 0.5
vt 0.25 0.5
vt 0.25 0.75
vt 0.125 0.75
vt 0.125 1
vt 0.25 1
vt 0.375 1
vt 0.25 1
vt 0.25 0.75
vt 0.375 0.75
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 4/4/1 7/3/1 5/2/1 2/1/1
f 3/8/2 4/7/2 2/6/2 1/5/2
f 8/12/3 3/11/3 1/10/3 6/9/3
f 7/16/4 8/15/4 6/14/4 5/13/4
f 6/20/5 1/19/5 2/18/5 5/17/5
f 7/24/6 4/23/6 3/22/6 8/21/6
o stick1
v 0.5 1.625 -0.375
v 0.5 1.625 -0.5
v 0.5 1.125 -0.375
v 0.5 1.125 -0.5
v 0.375 1.625 -0.5
v 0.375 1.625 -0.375
v 0.375 1.125 -0.5
v 0.375 1.125 -0.375
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 12/28/7 15/27/7 13/26/7 10/25/7
f 11/32/8 12/31/8 10/30/8 9/29/8
f 16/36/9 11/35/9 9/34/9 14/33/9
f 15/40/10 16/39/10 14/38/10 13/37/10
f 14/44/11 9/43/11 10/42/11 13/41/11
f 15/48/12 12/47/12 11/46/12 16/45/12
o stick2
v -0.375 1.625 -0.375
v -0.375 1.625 -0.5
v -0.375 1.125 -0.375
v -0.375 1.125 -0.5
v -0.5 1.625 -0.5
v -0.5 1.625 -0.375
v -0.5 1.125 -0.5
v -0.5 1.125 -0.375
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 20/52/13 23/51/13 21/50/13 18/49/13
f 19/56/14 20/55/14 18/54/14 17/53/14
f 24/60/15 19/59/15 17/58/15 22/57/15
f 23/64/16 24/63/16 22/62/16 21/61/16
f 22/68/17 17/67/17 18/66/17 21/65/17
f 23/72/18 20/71/18 19/70/18 24/69/18
o stick3
v -0.375 1.625 0.5
v -0.375 1.625 0.375
v -0.375 1.125 0.5
v -0.375 1.125 0.375
v -0.5 1.625 0.375
v -0.5 1.625 0.5
v -0.5 1.125 0.375
v -0.5 1.125 0.5
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 28/76/19 31/75/19 29/74/19 26/73/19
f 27/80/20 28/79/20 26/78/20 25/77/20
f 32/84/21 27/83/21 25/82/21 30/81/21
f 31/88/22 32/87/22 30/86/22 29/85/22
f 30/92/23 25/91/23 26/90/23 29/89/23
f 31/96/24 28/95/24 27/94/24 32/93/24
o stick4
v 0.5 1.625 0.5
v 0.5 1.625 0.375
v 0.5 1.125 0.5
v 0.5 1.125 0.375
v 0.375 1.625 0.375
v 0.375 1.625 0.5
v 0.375 1.125 0.375
v 0.375 1.125 0.5
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 36/100/25 39/99/25 37/98/25 34/97/25
f 35/104/26 36/103/26 34/102/26 33/101/26
f 40/108/27 35/107/27 33/106/27 38/105/27
f 39/112/28 40/111/28 38/110/28 37/109/28
f 38/116/29 33/115/29 34/114/29 37/113/29
f 39/120/30 36/119/30 35/118/30 40/117/30
o stick5
v 0.375 1.375 -0.25
v 0.375 1.375 -0.375
v 0.375 0.875 -0.25
v 0.375 0.875 -0.375
v 0.25 1.375 -0.375
v 0.25 1.375 -0.25
v 0.25 0.875 -0.375
v 0.25 0.875 -0.25
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 44/124/31 47/123/31 45/122/31 42/121/31
f 43/128/32 44/127/32 42/126/32 41/125/32
f 48/132/33 43/131/33 41/130/33 46/129/33
f 47/136/34 48/135/34 46/134/34 45/133/34
f 46/140/35 41/139/35 42/138/35 45/137/35
f 47/144/36 44/143/36 43/142/36 48/141/36
o stick6
v -0.25 1.375 -0.25
v -0.25 1.375 -0.375
v -0.25 0.875 -0.25
v -0.25 0.875 -0.375
v -0.375 1.375 -0.375
v -0.375 1.375 -0.25
v -0.375 0.875 -0.375
v -0.375 0.875 -0.25
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 52/148/37 55/147/37 53/146/37 50/145/37
f 51/152/38 52/151/38 50/150/38 49/149/38
f 56/156/39 51/155/39 49/154/39 54/153/39
f 55/160/40 56/159/40 54/158/40 53/157/40
f 54/164/41 49/163/41 50/162/41 53/161/41
f 55/168/42 52/167/42 51/166/42 56/165/42
o stick7
v -0.25 1.375 0.375
v -0.25 1.375 0.25
v -0.25 0.875 0.375
v -0.25 0.875 0.25
v -0.375 1.375 0.25
v -0.375 1.375 0.375
v -0.375 0.875 0.25
v -0.375 0.875 0.375
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 60/172/43 63/171/43 61/170/43 58/169/43
f 59/176/44 60/175/44 58/174/44 57/173/44
f 64/180/45 59/179/45 57/178/45 62/177/45
f 63/184/46 64/183/46 62/182/46 61/181/46
f 62/188/47 57/187/47 58/186/47 61/185/47
f 63/192/48 60/191/48 59/190/48 64/189/48
o stick8
v 0.375 1.375 0.375
v 0.375 1.375 0.25
v 0.375 0.875 0.375
v 0.375 0.875 0.25
v 0.25 1.375 0.25
v 0.25 1.375 0.375
v 0.25 0.875 0.25
v 0.25 0.875 0.375
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 68/196/49 71/195/49 69/194/49 66/193/49
f 67/200/50 68/199/50 66/198/50 65/197/50
f 72/204/51 67/203/51 65/202/51 70/201/51
f 71/208/52 72/207/52 70/206/52 69/205/52
f 70/212/53 65/211/53 66/210/53 69/209/53
f 71/216/54 68/215/54 67/214/54 72/213/54
o stick9
v 0.25 0.875 -0.125
v 0.25 0.875 -0.25
v 0.25 0.375 -0.125
v 0.25 0.375 -0.25
v 0.125 0.875 -0.25
v 0.125 0.875 -0.125
v 0.125 0.375 -0.25
v 0.125 0.375 -0.125
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 76/220/55 79/219/55 77/218/55 74/217/55
f 75/224/56 76/223/56 74/222/56 73/221/56
f 80/228/57 75/227/57 73/226/57 78/225/57
f 79/232/58 80/231/58 78/230/58 77/229/58
f 78/236/59 73/235/59 74/234/59 77/233/59
f 79/240/60 76/239/60 75/238/60 80/237/60
o stick10
v -0.125 0.875 -0.125
v -0.125 0.875 -0.25
v -0.125 0.375 -0.125
v -0.125 0.375 -0.25
v -0.25 0.875 -0.25
v -0.25 0.875 -0.125
v -0.25 0.375 -0.25
v -0.25 0.375 -0.125
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 84/244/61 87/243/61 85/242/61 82/241/61
f 83/248/62 84/247/62 82/246/62 81/245/62
f 88/252/63 83/251/63 81/250/63 86/249/63
f 87/256/64 88/255/64 86/254/64 85/253/64
f 86/260/65 81/259/65 82/258/65 85/257/65
f 87/264/66 84/263/66 83/262/66 88/261/66
o stick11
v -0.125 0.875 0.25
v -0.125 0.875 0.125
v -0.125 0.375 0.25
v -0.125 0.375 0.125
v -0.25 0.875 0.125
v -0.25 0.875 0.25
v -0.25 0.375 0.125
v -0.25 0.375 0.25
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 92/268/67 95/267/67 93/266/67 90/265/67
f 91/272/68 92/271/68 90/270/68 89/269/68
f 96/276/69 91/275/69 89/274/69 94/273/69
f 95/280/70 96/279/70 94/278/70 93/277/70
f 94/284/71 89/283/71 90/282/71 93/281/71
f 95/288/72 92/287/72 91/286/72 96/285/72
o stick12
v 0.25 0.875 0.25
v 0.25 0.875 0.125
v 0.25 0.375 0.25
v 0.25 0.375 0.125
v 0.125 0.875 0.125
v 0.125 0.875 0.25
v 0.125 0.375 0.125
v 0.125 0.375 0.25
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.1875
vt 0.03125 0.1875
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.1875
vt 0 0.1875
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.1875
vt 0.09375 0.1875
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.1875
vt 0.0625 0.1875
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_dfbdbb41-abfe-86cc-78e9-f18aaa3f6ee0
f 100/292/73 103/291/73 101/290/73 98/289/73
f 99/296/74 100/295/74 98/294/74 97/293/74
f 104/300/75 99/299/75 97/298/75 102/297/75
f 103/304/76 104/303/76 102/302/76 101/301/76
f 102/308/77 97/307/77 98/306/77 101/305/77
f 103/312/78 100/311/78 99/310/78 104/309/78

BIN
test/Assets/blaze.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

279
test/Assets/creeper.obj Normal file
View File

@@ -0,0 +1,279 @@
# Made in Blockbench 4.7.4
mtllib creeper.mtl
o head
v 0.25 1.625 0.25
v 0.25 1.625 -0.25
v 0.25 1.125 0.25
v 0.25 1.125 -0.25
v -0.25 1.625 -0.25
v -0.25 1.625 0.25
v -0.25 1.125 -0.25
v -0.25 1.125 0.25
vt 0.125 0.75
vt 0.25 0.75
vt 0.25 0.5
vt 0.125 0.5
vt 0 0.75
vt 0.125 0.75
vt 0.125 0.5
vt 0 0.5
vt 0.375 0.75
vt 0.5 0.75
vt 0.5 0.5
vt 0.375 0.5
vt 0.25 0.75
vt 0.375 0.75
vt 0.375 0.5
vt 0.25 0.5
vt 0.25 0.75
vt 0.125 0.75
vt 0.125 1
vt 0.25 1
vt 0.375 1
vt 0.25 1
vt 0.25 0.75
vt 0.375 0.75
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_a9261af0-f547-5510-e36d-58546f0c746f
f 4/4/1 7/3/1 5/2/1 2/1/1
f 3/8/2 4/7/2 2/6/2 1/5/2
f 8/12/3 3/11/3 1/10/3 6/9/3
f 7/16/4 8/15/4 6/14/4 5/13/4
f 6/20/5 1/19/5 2/18/5 5/17/5
f 7/24/6 4/23/6 3/22/6 8/21/6
o body
v 0.25 1.125 0.125
v 0.25 1.125 -0.125
v 0.25 0.375 0.125
v 0.25 0.375 -0.125
v -0.25 1.125 -0.125
v -0.25 1.125 0.125
v -0.25 0.375 -0.125
v -0.25 0.375 0.125
vt 0.3125 0.375
vt 0.4375 0.375
vt 0.4375 0
vt 0.3125 0
vt 0.25 0.375
vt 0.3125 0.375
vt 0.3125 0
vt 0.25 0
vt 0.5 0.375
vt 0.625 0.375
vt 0.625 0
vt 0.5 0
vt 0.4375 0.375
vt 0.5 0.375
vt 0.5 0
vt 0.4375 0
vt 0.4375 0.375
vt 0.3125 0.375
vt 0.3125 0.5
vt 0.4375 0.5
vt 0.5625 0.5
vt 0.4375 0.5
vt 0.4375 0.375
vt 0.5625 0.375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_a9261af0-f547-5510-e36d-58546f0c746f
f 12/28/7 15/27/7 13/26/7 10/25/7
f 11/32/8 12/31/8 10/30/8 9/29/8
f 16/36/9 11/35/9 9/34/9 14/33/9
f 15/40/10 16/39/10 14/38/10 13/37/10
f 14/44/11 9/43/11 10/42/11 13/41/11
f 15/48/12 12/47/12 11/46/12 16/45/12
o leg1
v 0.25 0.375 0.375
v 0.25 0.375 0.125
v 0.25 0 0.375
v 0.25 0 0.125
v 0 0.375 0.125
v 0 0.375 0.375
v 0 0 0.125
v 0 0 0.375
vt 0.0625 0.375
vt 0.125 0.375
vt 0.125 0.1875
vt 0.0625 0.1875
vt 0 0.375
vt 0.0625 0.375
vt 0.0625 0.1875
vt 0 0.1875
vt 0.1875 0.375
vt 0.25 0.375
vt 0.25 0.1875
vt 0.1875 0.1875
vt 0.125 0.375
vt 0.1875 0.375
vt 0.1875 0.1875
vt 0.125 0.1875
vt 0.125 0.375
vt 0.0625 0.375
vt 0.0625 0.5
vt 0.125 0.5
vt 0.1875 0.5
vt 0.125 0.5
vt 0.125 0.375
vt 0.1875 0.375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_a9261af0-f547-5510-e36d-58546f0c746f
f 20/52/13 23/51/13 21/50/13 18/49/13
f 19/56/14 20/55/14 18/54/14 17/53/14
f 24/60/15 19/59/15 17/58/15 22/57/15
f 23/64/16 24/63/16 22/62/16 21/61/16
f 22/68/17 17/67/17 18/66/17 21/65/17
f 23/72/18 20/71/18 19/70/18 24/69/18
o leg2
v 0 0.375 0.375
v 0 0.375 0.125
v 0 0 0.375
v 0 0 0.125
v -0.25 0.375 0.125
v -0.25 0.375 0.375
v -0.25 0 0.125
v -0.25 0 0.375
vt 0.0625 0.375
vt 0.125 0.375
vt 0.125 0.1875
vt 0.0625 0.1875
vt 0 0.375
vt 0.0625 0.375
vt 0.0625 0.1875
vt 0 0.1875
vt 0.1875 0.375
vt 0.25 0.375
vt 0.25 0.1875
vt 0.1875 0.1875
vt 0.125 0.375
vt 0.1875 0.375
vt 0.1875 0.1875
vt 0.125 0.1875
vt 0.125 0.375
vt 0.0625 0.375
vt 0.0625 0.5
vt 0.125 0.5
vt 0.1875 0.5
vt 0.125 0.5
vt 0.125 0.375
vt 0.1875 0.375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_a9261af0-f547-5510-e36d-58546f0c746f
f 28/76/19 31/75/19 29/74/19 26/73/19
f 27/80/20 28/79/20 26/78/20 25/77/20
f 32/84/21 27/83/21 25/82/21 30/81/21
f 31/88/22 32/87/22 30/86/22 29/85/22
f 30/92/23 25/91/23 26/90/23 29/89/23
f 31/96/24 28/95/24 27/94/24 32/93/24
o leg3
v 0.25 0.375 -0.125
v 0.25 0.375 -0.375
v 0.25 0 -0.125
v 0.25 0 -0.375
v 0 0.375 -0.375
v 0 0.375 -0.125
v 0 0 -0.375
v 0 0 -0.125
vt 0.0625 0.375
vt 0.125 0.375
vt 0.125 0.1875
vt 0.0625 0.1875
vt 0 0.375
vt 0.0625 0.375
vt 0.0625 0.1875
vt 0 0.1875
vt 0.1875 0.375
vt 0.25 0.375
vt 0.25 0.1875
vt 0.1875 0.1875
vt 0.125 0.375
vt 0.1875 0.375
vt 0.1875 0.1875
vt 0.125 0.1875
vt 0.125 0.375
vt 0.0625 0.375
vt 0.0625 0.5
vt 0.125 0.5
vt 0.1875 0.5
vt 0.125 0.5
vt 0.125 0.375
vt 0.1875 0.375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_a9261af0-f547-5510-e36d-58546f0c746f
f 36/100/25 39/99/25 37/98/25 34/97/25
f 35/104/26 36/103/26 34/102/26 33/101/26
f 40/108/27 35/107/27 33/106/27 38/105/27
f 39/112/28 40/111/28 38/110/28 37/109/28
f 38/116/29 33/115/29 34/114/29 37/113/29
f 39/120/30 36/119/30 35/118/30 40/117/30
o leg4
v 0 0.375 -0.125
v 0 0.375 -0.375
v 0 0 -0.125
v 0 0 -0.375
v -0.25 0.375 -0.375
v -0.25 0.375 -0.125
v -0.25 0 -0.375
v -0.25 0 -0.125
vt 0.0625 0.375
vt 0.125 0.375
vt 0.125 0.1875
vt 0.0625 0.1875
vt 0 0.375
vt 0.0625 0.375
vt 0.0625 0.1875
vt 0 0.1875
vt 0.1875 0.375
vt 0.25 0.375
vt 0.25 0.1875
vt 0.1875 0.1875
vt 0.125 0.375
vt 0.1875 0.375
vt 0.1875 0.1875
vt 0.125 0.1875
vt 0.125 0.375
vt 0.0625 0.375
vt 0.0625 0.5
vt 0.125 0.5
vt 0.1875 0.5
vt 0.125 0.5
vt 0.125 0.375
vt 0.1875 0.375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_a9261af0-f547-5510-e36d-58546f0c746f
f 44/124/31 47/123/31 45/122/31 42/121/31
f 43/128/32 44/127/32 42/126/32 41/125/32
f 48/132/33 43/131/33 41/130/33 46/129/33
f 47/136/34 48/135/34 46/134/34 45/133/34
f 46/140/35 41/139/35 42/138/35 45/137/35
f 47/144/36 44/143/36 43/142/36 48/141/36

BIN
test/Assets/creeper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

325
test/Assets/giant.obj Normal file
View File

@@ -0,0 +1,325 @@
# Made in Blockbench 4.7.4
mtllib giant.mtl
o head
v 0.25 2 0.25
v 0.25 2 -0.25
v 0.25 1.5 0.25
v 0.25 1.5 -0.25
v -0.25 2 -0.25
v -0.25 2 0.25
v -0.25 1.5 -0.25
v -0.25 1.5 0.25
vt 0.125 0.875
vt 0.25 0.875
vt 0.25 0.75
vt 0.125 0.75
vt 0 0.875
vt 0.125 0.875
vt 0.125 0.75
vt 0 0.75
vt 0.375 0.875
vt 0.5 0.875
vt 0.5 0.75
vt 0.375 0.75
vt 0.25 0.875
vt 0.375 0.875
vt 0.375 0.75
vt 0.25 0.75
vt 0.25 0.875
vt 0.125 0.875
vt 0.125 1
vt 0.25 1
vt 0.375 1
vt 0.25 1
vt 0.25 0.875
vt 0.375 0.875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_4f713d88-ddbc-dda2-ab2d-ab4dd8d59032
f 4/4/1 7/3/1 5/2/1 2/1/1
f 3/8/2 4/7/2 2/6/2 1/5/2
f 8/12/3 3/11/3 1/10/3 6/9/3
f 7/16/4 8/15/4 6/14/4 5/13/4
f 6/20/5 1/19/5 2/18/5 5/17/5
f 7/24/6 4/23/6 3/22/6 8/21/6
o headwear
v 0.28125 2.03125 0.28125
v 0.28125 2.03125 -0.28125
v 0.28125 1.46875 0.28125
v 0.28125 1.46875 -0.28125
v -0.28125 2.03125 -0.28125
v -0.28125 2.03125 0.28125
v -0.28125 1.46875 -0.28125
v -0.28125 1.46875 0.28125
vt 0.625 0.875
vt 0.75 0.875
vt 0.75 0.75
vt 0.625 0.75
vt 0.5 0.875
vt 0.625 0.875
vt 0.625 0.75
vt 0.5 0.75
vt 0.875 0.875
vt 1 0.875
vt 1 0.75
vt 0.875 0.75
vt 0.75 0.875
vt 0.875 0.875
vt 0.875 0.75
vt 0.75 0.75
vt 0.75 0.875
vt 0.625 0.875
vt 0.625 1
vt 0.75 1
vt 0.875 1
vt 0.75 1
vt 0.75 0.875
vt 0.875 0.875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_4f713d88-ddbc-dda2-ab2d-ab4dd8d59032
f 12/28/7 15/27/7 13/26/7 10/25/7
f 11/32/8 12/31/8 10/30/8 9/29/8
f 16/36/9 11/35/9 9/34/9 14/33/9
f 15/40/10 16/39/10 14/38/10 13/37/10
f 14/44/11 9/43/11 10/42/11 13/41/11
f 15/48/12 12/47/12 11/46/12 16/45/12
o body
v 0.25 1.5 0.125
v 0.25 1.5 -0.125
v 0.25 0.75 0.125
v 0.25 0.75 -0.125
v -0.25 1.5 -0.125
v -0.25 1.5 0.125
v -0.25 0.75 -0.125
v -0.25 0.75 0.125
vt 0.3125 0.6875
vt 0.4375 0.6875
vt 0.4375 0.5
vt 0.3125 0.5
vt 0.25 0.6875
vt 0.3125 0.6875
vt 0.3125 0.5
vt 0.25 0.5
vt 0.5 0.6875
vt 0.625 0.6875
vt 0.625 0.5
vt 0.5 0.5
vt 0.4375 0.6875
vt 0.5 0.6875
vt 0.5 0.5
vt 0.4375 0.5
vt 0.4375 0.6875
vt 0.3125 0.6875
vt 0.3125 0.75
vt 0.4375 0.75
vt 0.5625 0.75
vt 0.4375 0.75
vt 0.4375 0.6875
vt 0.5625 0.6875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_4f713d88-ddbc-dda2-ab2d-ab4dd8d59032
f 20/52/13 23/51/13 21/50/13 18/49/13
f 19/56/14 20/55/14 18/54/14 17/53/14
f 24/60/15 19/59/15 17/58/15 22/57/15
f 23/64/16 24/63/16 22/62/16 21/61/16
f 22/68/17 17/67/17 18/66/17 21/65/17
f 23/72/18 20/71/18 19/70/18 24/69/18
o left_arm
v -0.25 1.5 0.125
v -0.25 1.5 -0.125
v -0.25 0.75 0.125
v -0.25 0.75 -0.125
v -0.5 1.5 -0.125
v -0.5 1.5 0.125
v -0.5 0.75 -0.125
v -0.5 0.75 0.125
vt 0.75 0.6875
vt 0.6875 0.6875
vt 0.6875 0.5
vt 0.75 0.5
vt 0.8125 0.6875
vt 0.75 0.6875
vt 0.75 0.5
vt 0.8125 0.5
vt 0.875 0.6875
vt 0.8125 0.6875
vt 0.8125 0.5
vt 0.875 0.5
vt 0.6875 0.6875
vt 0.625 0.6875
vt 0.625 0.5
vt 0.6875 0.5
vt 0.6875 0.6875
vt 0.75 0.6875
vt 0.75 0.75
vt 0.6875 0.75
vt 0.75 0.75
vt 0.8125 0.75
vt 0.8125 0.6875
vt 0.75 0.6875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_4f713d88-ddbc-dda2-ab2d-ab4dd8d59032
f 28/76/19 31/75/19 29/74/19 26/73/19
f 27/80/20 28/79/20 26/78/20 25/77/20
f 32/84/21 27/83/21 25/82/21 30/81/21
f 31/88/22 32/87/22 30/86/22 29/85/22
f 30/92/23 25/91/23 26/90/23 29/89/23
f 31/96/24 28/95/24 27/94/24 32/93/24
o right_arm
v 0.5 1.5 0.125
v 0.5 1.5 -0.125
v 0.5 0.75 0.125
v 0.5 0.75 -0.125
v 0.25 1.5 -0.125
v 0.25 1.5 0.125
v 0.25 0.75 -0.125
v 0.25 0.75 0.125
vt 0.6875 0.6875
vt 0.75 0.6875
vt 0.75 0.5
vt 0.6875 0.5
vt 0.625 0.6875
vt 0.6875 0.6875
vt 0.6875 0.5
vt 0.625 0.5
vt 0.8125 0.6875
vt 0.875 0.6875
vt 0.875 0.5
vt 0.8125 0.5
vt 0.75 0.6875
vt 0.8125 0.6875
vt 0.8125 0.5
vt 0.75 0.5
vt 0.75 0.6875
vt 0.6875 0.6875
vt 0.6875 0.75
vt 0.75 0.75
vt 0.8125 0.75
vt 0.75 0.75
vt 0.75 0.6875
vt 0.8125 0.6875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_4f713d88-ddbc-dda2-ab2d-ab4dd8d59032
f 36/100/25 39/99/25 37/98/25 34/97/25
f 35/104/26 36/103/26 34/102/26 33/101/26
f 40/108/27 35/107/27 33/106/27 38/105/27
f 39/112/28 40/111/28 38/110/28 37/109/28
f 38/116/29 33/115/29 34/114/29 37/113/29
f 39/120/30 36/119/30 35/118/30 40/117/30
o left_leg
v 0 0.75 0.125
v 0 0.75 -0.125
v 0 0 0.125
v 0 0 -0.125
v -0.25 0.75 -0.125
v -0.25 0.75 0.125
v -0.25 0 -0.125
v -0.25 0 0.125
vt 0.125 0.6875
vt 0.0625 0.6875
vt 0.0625 0.5
vt 0.125 0.5
vt 0.1875 0.6875
vt 0.125 0.6875
vt 0.125 0.5
vt 0.1875 0.5
vt 0.25 0.6875
vt 0.1875 0.6875
vt 0.1875 0.5
vt 0.25 0.5
vt 0.0625 0.6875
vt 0 0.6875
vt 0 0.5
vt 0.0625 0.5
vt 0.0625 0.6875
vt 0.125 0.6875
vt 0.125 0.75
vt 0.0625 0.75
vt 0.125 0.75
vt 0.1875 0.75
vt 0.1875 0.6875
vt 0.125 0.6875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_4f713d88-ddbc-dda2-ab2d-ab4dd8d59032
f 44/124/31 47/123/31 45/122/31 42/121/31
f 43/128/32 44/127/32 42/126/32 41/125/32
f 48/132/33 43/131/33 41/130/33 46/129/33
f 47/136/34 48/135/34 46/134/34 45/133/34
f 46/140/35 41/139/35 42/138/35 45/137/35
f 47/144/36 44/143/36 43/142/36 48/141/36
o right_leg
v 0.25 0.75 0.125
v 0.25 0.75 -0.125
v 0.25 0 0.125
v 0.25 0 -0.125
v 0 0.75 -0.125
v 0 0.75 0.125
v 0 0 -0.125
v 0 0 0.125
vt 0.0625 0.6875
vt 0.125 0.6875
vt 0.125 0.5
vt 0.0625 0.5
vt 0 0.6875
vt 0.0625 0.6875
vt 0.0625 0.5
vt 0 0.5
vt 0.1875 0.6875
vt 0.25 0.6875
vt 0.25 0.5
vt 0.1875 0.5
vt 0.125 0.6875
vt 0.1875 0.6875
vt 0.1875 0.5
vt 0.125 0.5
vt 0.125 0.6875
vt 0.0625 0.6875
vt 0.0625 0.75
vt 0.125 0.75
vt 0.1875 0.75
vt 0.125 0.75
vt 0.125 0.6875
vt 0.1875 0.6875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_4f713d88-ddbc-dda2-ab2d-ab4dd8d59032
f 52/148/37 55/147/37 53/146/37 50/145/37
f 51/152/38 52/151/38 50/150/38 49/149/38
f 56/156/39 51/155/39 49/154/39 54/153/39
f 55/160/40 56/159/40 54/158/40 53/157/40
f 54/164/41 49/163/41 50/162/41 53/161/41
f 55/168/42 52/167/42 51/166/42 56/165/42

BIN
test/Assets/giant.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

463
test/Assets/silverfish.obj Normal file
View File

@@ -0,0 +1,463 @@
# Made in Blockbench 4.7.4
mtllib silverfish.mtl
o body1
v 0.09375 0.125 -0.375
v 0.09375 0.125 -0.5
v 0.09375 0 -0.375
v 0.09375 0 -0.5
v -0.09375 0.125 -0.5
v -0.09375 0.125 -0.375
v -0.09375 0 -0.5
v -0.09375 0 -0.375
vt 0.03125 0.9375
vt 0.078125 0.9375
vt 0.078125 0.875
vt 0.03125 0.875
vt 0 0.9375
vt 0.03125 0.9375
vt 0.03125 0.875
vt 0 0.875
vt 0.109375 0.9375
vt 0.15625 0.9375
vt 0.15625 0.875
vt 0.109375 0.875
vt 0.078125 0.9375
vt 0.109375 0.9375
vt 0.109375 0.875
vt 0.078125 0.875
vt 0.078125 0.9375
vt 0.03125 0.9375
vt 0.03125 1
vt 0.078125 1
vt 0.125 1
vt 0.078125 1
vt 0.078125 0.9375
vt 0.125 0.9375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 4/4/1 7/3/1 5/2/1 2/1/1
f 3/8/2 4/7/2 2/6/2 1/5/2
f 8/12/3 3/11/3 1/10/3 6/9/3
f 7/16/4 8/15/4 6/14/4 5/13/4
f 6/20/5 1/19/5 2/18/5 5/17/5
f 7/24/6 4/23/6 3/22/6 8/21/6
o body2
v 0.125 0.1875 -0.25
v 0.125 0.1875 -0.375
v 0.125 0 -0.25
v 0.125 0 -0.375
v -0.125 0.1875 -0.375
v -0.125 0.1875 -0.25
v -0.125 0 -0.375
v -0.125 0 -0.25
vt 0.03125 0.8125
vt 0.09375 0.8125
vt 0.09375 0.71875
vt 0.03125 0.71875
vt 0 0.8125
vt 0.03125 0.8125
vt 0.03125 0.71875
vt 0 0.71875
vt 0.125 0.8125
vt 0.1875 0.8125
vt 0.1875 0.71875
vt 0.125 0.71875
vt 0.09375 0.8125
vt 0.125 0.8125
vt 0.125 0.71875
vt 0.09375 0.71875
vt 0.09375 0.8125
vt 0.03125 0.8125
vt 0.03125 0.875
vt 0.09375 0.875
vt 0.15625 0.875
vt 0.09375 0.875
vt 0.09375 0.8125
vt 0.15625 0.8125
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 12/28/7 15/27/7 13/26/7 10/25/7
f 11/32/8 12/31/8 10/30/8 9/29/8
f 16/36/9 11/35/9 9/34/9 14/33/9
f 15/40/10 16/39/10 14/38/10 13/37/10
f 14/44/11 9/43/11 10/42/11 13/41/11
f 15/48/12 12/47/12 11/46/12 16/45/12
o body3
v 0.1875 0.25 -0.0625
v 0.1875 0.25 -0.25
v 0.1875 0 -0.0625
v 0.1875 0 -0.25
v -0.1875 0.25 -0.25
v -0.1875 0.25 -0.0625
v -0.1875 0 -0.25
v -0.1875 0 -0.0625
vt 0.046875 0.625
vt 0.140625 0.625
vt 0.140625 0.5
vt 0.046875 0.5
vt 0 0.625
vt 0.046875 0.625
vt 0.046875 0.5
vt 0 0.5
vt 0.1875 0.625
vt 0.28125 0.625
vt 0.28125 0.5
vt 0.1875 0.5
vt 0.140625 0.625
vt 0.1875 0.625
vt 0.1875 0.5
vt 0.140625 0.5
vt 0.140625 0.625
vt 0.046875 0.625
vt 0.046875 0.71875
vt 0.140625 0.71875
vt 0.234375 0.71875
vt 0.140625 0.71875
vt 0.140625 0.625
vt 0.234375 0.625
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 20/52/13 23/51/13 21/50/13 18/49/13
f 19/56/14 20/55/14 18/54/14 17/53/14
f 24/60/15 19/59/15 17/58/15 22/57/15
f 23/64/16 24/63/16 22/62/16 21/61/16
f 22/68/17 17/67/17 18/66/17 21/65/17
f 23/72/18 20/71/18 19/70/18 24/69/18
o body4
v 0.09375 0.1875 0.125
v 0.09375 0.1875 -0.0625
v 0.09375 0 0.125
v 0.09375 0 -0.0625
v -0.09375 0.1875 -0.0625
v -0.09375 0.1875 0.125
v -0.09375 0 -0.0625
v -0.09375 0 0.125
vt 0.046875 0.40625
vt 0.09375 0.40625
vt 0.09375 0.3125
vt 0.046875 0.3125
vt 0 0.40625
vt 0.046875 0.40625
vt 0.046875 0.3125
vt 0 0.3125
vt 0.140625 0.40625
vt 0.1875 0.40625
vt 0.1875 0.3125
vt 0.140625 0.3125
vt 0.09375 0.40625
vt 0.140625 0.40625
vt 0.140625 0.3125
vt 0.09375 0.3125
vt 0.09375 0.40625
vt 0.046875 0.40625
vt 0.046875 0.5
vt 0.09375 0.5
vt 0.140625 0.5
vt 0.09375 0.5
vt 0.09375 0.40625
vt 0.140625 0.40625
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 28/76/19 31/75/19 29/74/19 26/73/19
f 27/80/20 28/79/20 26/78/20 25/77/20
f 32/84/21 27/83/21 25/82/21 30/81/21
f 31/88/22 32/87/22 30/86/22 29/85/22
f 30/92/23 25/91/23 26/90/23 29/89/23
f 31/96/24 28/95/24 27/94/24 32/93/24
o body5
v 0.0625 0.125 0.3125
v 0.0625 0.125 0.125
v 0.0625 0 0.3125
v 0.0625 0 0.125
v -0.0625 0.125 0.125
v -0.0625 0.125 0.3125
v -0.0625 0 0.125
v -0.0625 0 0.3125
vt 0.046875 0.21875
vt 0.078125 0.21875
vt 0.078125 0.15625
vt 0.046875 0.15625
vt 0 0.21875
vt 0.046875 0.21875
vt 0.046875 0.15625
vt 0 0.15625
vt 0.125 0.21875
vt 0.15625 0.21875
vt 0.15625 0.15625
vt 0.125 0.15625
vt 0.078125 0.21875
vt 0.125 0.21875
vt 0.125 0.15625
vt 0.078125 0.15625
vt 0.078125 0.21875
vt 0.046875 0.21875
vt 0.046875 0.3125
vt 0.078125 0.3125
vt 0.109375 0.3125
vt 0.078125 0.3125
vt 0.078125 0.21875
vt 0.109375 0.21875
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 36/100/25 39/99/25 37/98/25 34/97/25
f 35/104/26 36/103/26 34/102/26 33/101/26
f 40/108/27 35/107/27 33/106/27 38/105/27
f 39/112/28 40/111/28 38/110/28 37/109/28
f 38/116/29 33/115/29 34/114/29 37/113/29
f 39/120/30 36/119/30 35/118/30 40/117/30
o body6
v 0.0625 0.0625 0.4375
v 0.0625 0.0625 0.3125
v 0.0625 0 0.4375
v 0.0625 0 0.3125
v -0.0625 0.0625 0.3125
v -0.0625 0.0625 0.4375
v -0.0625 0 0.3125
v -0.0625 0 0.4375
vt 0.203125 0.9375
vt 0.234375 0.9375
vt 0.234375 0.90625
vt 0.203125 0.90625
vt 0.171875 0.9375
vt 0.203125 0.9375
vt 0.203125 0.90625
vt 0.171875 0.90625
vt 0.265625 0.9375
vt 0.296875 0.9375
vt 0.296875 0.90625
vt 0.265625 0.90625
vt 0.234375 0.9375
vt 0.265625 0.9375
vt 0.265625 0.90625
vt 0.234375 0.90625
vt 0.234375 0.9375
vt 0.203125 0.9375
vt 0.203125 1
vt 0.234375 1
vt 0.265625 1
vt 0.234375 1
vt 0.234375 0.9375
vt 0.265625 0.9375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 44/124/31 47/123/31 45/122/31 42/121/31
f 43/128/32 44/127/32 42/126/32 41/125/32
f 48/132/33 43/131/33 41/130/33 46/129/33
f 47/136/34 48/135/34 46/134/34 45/133/34
f 46/140/35 41/139/35 42/138/35 45/137/35
f 47/144/36 44/143/36 43/142/36 48/141/36
o body7
v 0.03125 0.0625 0.5625
v 0.03125 0.0625 0.4375
v 0.03125 0 0.5625
v 0.03125 0 0.4375
v -0.03125 0.0625 0.4375
v -0.03125 0.0625 0.5625
v -0.03125 0 0.4375
v -0.03125 0 0.5625
vt 0.234375 0.8125
vt 0.25 0.8125
vt 0.25 0.78125
vt 0.234375 0.78125
vt 0.203125 0.8125
vt 0.234375 0.8125
vt 0.234375 0.78125
vt 0.203125 0.78125
vt 0.28125 0.8125
vt 0.296875 0.8125
vt 0.296875 0.78125
vt 0.28125 0.78125
vt 0.25 0.8125
vt 0.28125 0.8125
vt 0.28125 0.78125
vt 0.25 0.78125
vt 0.25 0.8125
vt 0.234375 0.8125
vt 0.234375 0.875
vt 0.25 0.875
vt 0.265625 0.875
vt 0.25 0.875
vt 0.25 0.8125
vt 0.265625 0.8125
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 52/148/37 55/147/37 53/146/37 50/145/37
f 51/152/38 52/151/38 50/150/38 49/149/38
f 56/156/39 51/155/39 49/154/39 54/153/39
f 55/160/40 56/159/40 54/158/40 53/157/40
f 54/164/41 49/163/41 50/162/41 53/161/41
f 55/168/42 52/167/42 51/166/42 56/165/42
o wing1
v 0.3125 0.5 -0.0625
v 0.3125 0.5 -0.25
v 0.3125 0 -0.0625
v 0.3125 0 -0.25
v -0.3125 0.5 -0.25
v -0.3125 0.5 -0.0625
v -0.3125 0 -0.25
v -0.3125 0 -0.0625
vt 0.359375 0.90625
vt 0.515625 0.90625
vt 0.515625 0.65625
vt 0.359375 0.65625
vt 0.3125 0.90625
vt 0.359375 0.90625
vt 0.359375 0.65625
vt 0.3125 0.65625
vt 0.5625 0.90625
vt 0.71875 0.90625
vt 0.71875 0.65625
vt 0.5625 0.65625
vt 0.515625 0.90625
vt 0.5625 0.90625
vt 0.5625 0.65625
vt 0.515625 0.65625
vt 0.515625 0.90625
vt 0.359375 0.90625
vt 0.359375 1
vt 0.515625 1
vt 0.671875 1
vt 0.515625 1
vt 0.515625 0.90625
vt 0.671875 0.90625
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 60/172/43 63/171/43 61/170/43 58/169/43
f 59/176/44 60/175/44 58/174/44 57/173/44
f 64/180/45 59/179/45 57/178/45 62/177/45
f 63/184/46 64/183/46 62/182/46 61/181/46
f 62/188/47 57/187/47 58/186/47 61/185/47
f 63/192/48 60/191/48 59/190/48 64/189/48
o wing2
v 0.1875 0.25 0.3125
v 0.1875 0.25 0.125
v 0.1875 0 0.3125
v 0.1875 0 0.125
v -0.1875 0.25 0.125
v -0.1875 0.25 0.3125
v -0.1875 0 0.125
v -0.1875 0 0.3125
vt 0.359375 0.5625
vt 0.453125 0.5625
vt 0.453125 0.4375
vt 0.359375 0.4375
vt 0.3125 0.5625
vt 0.359375 0.5625
vt 0.359375 0.4375
vt 0.3125 0.4375
vt 0.5 0.5625
vt 0.59375 0.5625
vt 0.59375 0.4375
vt 0.5 0.4375
vt 0.453125 0.5625
vt 0.5 0.5625
vt 0.5 0.4375
vt 0.453125 0.4375
vt 0.453125 0.5625
vt 0.359375 0.5625
vt 0.359375 0.65625
vt 0.453125 0.65625
vt 0.546875 0.65625
vt 0.453125 0.65625
vt 0.453125 0.5625
vt 0.546875 0.5625
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 68/196/49 71/195/49 69/194/49 66/193/49
f 67/200/50 68/199/50 66/198/50 65/197/50
f 72/204/51 67/203/51 65/202/51 70/201/51
f 71/208/52 72/207/52 70/206/52 69/205/52
f 70/212/53 65/211/53 66/210/53 69/209/53
f 71/216/54 68/215/54 67/214/54 72/213/54
o wing3
v 0.1875 0.3125 -0.28125
v 0.1875 0.3125 -0.40625
v 0.1875 0 -0.28125
v 0.1875 0 -0.40625
v -0.1875 0.3125 -0.40625
v -0.1875 0.3125 -0.28125
v -0.1875 0 -0.40625
v -0.1875 0 -0.28125
vt 0.34375 0.375
vt 0.4375 0.375
vt 0.4375 0.21875
vt 0.34375 0.21875
vt 0.3125 0.375
vt 0.34375 0.375
vt 0.34375 0.21875
vt 0.3125 0.21875
vt 0.46875 0.375
vt 0.5625 0.375
vt 0.5625 0.21875
vt 0.46875 0.21875
vt 0.4375 0.375
vt 0.46875 0.375
vt 0.46875 0.21875
vt 0.4375 0.21875
vt 0.4375 0.375
vt 0.34375 0.375
vt 0.34375 0.4375
vt 0.4375 0.4375
vt 0.53125 0.4375
vt 0.4375 0.4375
vt 0.4375 0.375
vt 0.53125 0.375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_97e571f3-1c58-7068-758a-c07b2eba7a6a
f 76/220/55 79/219/55 77/218/55 74/217/55
f 75/224/56 76/223/56 74/222/56 73/221/56
f 80/228/57 75/227/57 73/226/57 78/225/57
f 79/232/58 80/231/58 78/230/58 77/229/58
f 78/236/59 73/235/59 74/234/59 77/233/59
f 79/240/60 76/239/60 75/238/60 80/237/60

BIN
test/Assets/silverfish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

325
test/Assets/skeleton.obj Normal file
View File

@@ -0,0 +1,325 @@
# Made in Blockbench 4.7.4
mtllib skeleton.mtl
o head
v 0.25 2 0.25
v 0.25 2 -0.25
v 0.25 1.5 0.25
v 0.25 1.5 -0.25
v -0.25 2 -0.25
v -0.25 2 0.25
v -0.25 1.5 -0.25
v -0.25 1.5 0.25
vt 0.125 0.75
vt 0.25 0.75
vt 0.25 0.5
vt 0.125 0.5
vt 0 0.75
vt 0.125 0.75
vt 0.125 0.5
vt 0 0.5
vt 0.375 0.75
vt 0.5 0.75
vt 0.5 0.5
vt 0.375 0.5
vt 0.25 0.75
vt 0.375 0.75
vt 0.375 0.5
vt 0.25 0.5
vt 0.25 0.75
vt 0.125 0.75
vt 0.125 1
vt 0.25 1
vt 0.375 1
vt 0.25 1
vt 0.25 0.75
vt 0.375 0.75
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_71787a2c-953f-372c-0ba8-125703cbb767
f 4/4/1 7/3/1 5/2/1 2/1/1
f 3/8/2 4/7/2 2/6/2 1/5/2
f 8/12/3 3/11/3 1/10/3 6/9/3
f 7/16/4 8/15/4 6/14/4 5/13/4
f 6/20/5 1/19/5 2/18/5 5/17/5
f 7/24/6 4/23/6 3/22/6 8/21/6
o headwear
v 0.28125 2.03125 0.28125
v 0.28125 2.03125 -0.28125
v 0.28125 1.46875 0.28125
v 0.28125 1.46875 -0.28125
v -0.28125 2.03125 -0.28125
v -0.28125 2.03125 0.28125
v -0.28125 1.46875 -0.28125
v -0.28125 1.46875 0.28125
vt 0.625 0.75
vt 0.75 0.75
vt 0.75 0.5
vt 0.625 0.5
vt 0.5 0.75
vt 0.625 0.75
vt 0.625 0.5
vt 0.5 0.5
vt 0.875 0.75
vt 1 0.75
vt 1 0.5
vt 0.875 0.5
vt 0.75 0.75
vt 0.875 0.75
vt 0.875 0.5
vt 0.75 0.5
vt 0.75 0.75
vt 0.625 0.75
vt 0.625 1
vt 0.75 1
vt 0.875 1
vt 0.75 1
vt 0.75 0.75
vt 0.875 0.75
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_71787a2c-953f-372c-0ba8-125703cbb767
f 12/28/7 15/27/7 13/26/7 10/25/7
f 11/32/8 12/31/8 10/30/8 9/29/8
f 16/36/9 11/35/9 9/34/9 14/33/9
f 15/40/10 16/39/10 14/38/10 13/37/10
f 14/44/11 9/43/11 10/42/11 13/41/11
f 15/48/12 12/47/12 11/46/12 16/45/12
o body
v 0.25 1.5 0.125
v 0.25 1.5 -0.125
v 0.25 0.75 0.125
v 0.25 0.75 -0.125
v -0.25 1.5 -0.125
v -0.25 1.5 0.125
v -0.25 0.75 -0.125
v -0.25 0.75 0.125
vt 0.3125 0.375
vt 0.4375 0.375
vt 0.4375 0
vt 0.3125 0
vt 0.25 0.375
vt 0.3125 0.375
vt 0.3125 0
vt 0.25 0
vt 0.5 0.375
vt 0.625 0.375
vt 0.625 0
vt 0.5 0
vt 0.4375 0.375
vt 0.5 0.375
vt 0.5 0
vt 0.4375 0
vt 0.4375 0.375
vt 0.3125 0.375
vt 0.3125 0.5
vt 0.4375 0.5
vt 0.5625 0.5
vt 0.4375 0.5
vt 0.4375 0.375
vt 0.5625 0.375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_71787a2c-953f-372c-0ba8-125703cbb767
f 20/52/13 23/51/13 21/50/13 18/49/13
f 19/56/14 20/55/14 18/54/14 17/53/14
f 24/60/15 19/59/15 17/58/15 22/57/15
f 23/64/16 24/63/16 22/62/16 21/61/16
f 22/68/17 17/67/17 18/66/17 21/65/17
f 23/72/18 20/71/18 19/70/18 24/69/18
o left_arm
v -0.25 1.5 0.0625
v -0.25 1.5 -0.0625
v -0.25 0.75 0.0625
v -0.25 0.75 -0.0625
v -0.375 1.5 -0.0625
v -0.375 1.5 0.0625
v -0.375 0.75 -0.0625
v -0.375 0.75 0.0625
vt 0.6875 0.4375
vt 0.65625 0.4375
vt 0.65625 0.0625
vt 0.6875 0.0625
vt 0.71875 0.4375
vt 0.6875 0.4375
vt 0.6875 0.0625
vt 0.71875 0.0625
vt 0.75 0.4375
vt 0.71875 0.4375
vt 0.71875 0.0625
vt 0.75 0.0625
vt 0.65625 0.4375
vt 0.625 0.4375
vt 0.625 0.0625
vt 0.65625 0.0625
vt 0.65625 0.4375
vt 0.6875 0.4375
vt 0.6875 0.5
vt 0.65625 0.5
vt 0.6875 0.5
vt 0.71875 0.5
vt 0.71875 0.4375
vt 0.6875 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_71787a2c-953f-372c-0ba8-125703cbb767
f 28/76/19 31/75/19 29/74/19 26/73/19
f 27/80/20 28/79/20 26/78/20 25/77/20
f 32/84/21 27/83/21 25/82/21 30/81/21
f 31/88/22 32/87/22 30/86/22 29/85/22
f 30/92/23 25/91/23 26/90/23 29/89/23
f 31/96/24 28/95/24 27/94/24 32/93/24
o right_arm
v 0.375 1.5 0.0625
v 0.375 1.5 -0.0625
v 0.375 0.75 0.0625
v 0.375 0.75 -0.0625
v 0.25 1.5 -0.0625
v 0.25 1.5 0.0625
v 0.25 0.75 -0.0625
v 0.25 0.75 0.0625
vt 0.65625 0.4375
vt 0.6875 0.4375
vt 0.6875 0.0625
vt 0.65625 0.0625
vt 0.625 0.4375
vt 0.65625 0.4375
vt 0.65625 0.0625
vt 0.625 0.0625
vt 0.71875 0.4375
vt 0.75 0.4375
vt 0.75 0.0625
vt 0.71875 0.0625
vt 0.6875 0.4375
vt 0.71875 0.4375
vt 0.71875 0.0625
vt 0.6875 0.0625
vt 0.6875 0.4375
vt 0.65625 0.4375
vt 0.65625 0.5
vt 0.6875 0.5
vt 0.71875 0.5
vt 0.6875 0.5
vt 0.6875 0.4375
vt 0.71875 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_71787a2c-953f-372c-0ba8-125703cbb767
f 36/100/25 39/99/25 37/98/25 34/97/25
f 35/104/26 36/103/26 34/102/26 33/101/26
f 40/108/27 35/107/27 33/106/27 38/105/27
f 39/112/28 40/111/28 38/110/28 37/109/28
f 38/116/29 33/115/29 34/114/29 37/113/29
f 39/120/30 36/119/30 35/118/30 40/117/30
o left_leg
v -0.0625 0.75 0.0625
v -0.0625 0.75 -0.0625
v -0.0625 0 0.0625
v -0.0625 0 -0.0625
v -0.1875 0.75 -0.0625
v -0.1875 0.75 0.0625
v -0.1875 0 -0.0625
v -0.1875 0 0.0625
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.0625
vt 0.0625 0.0625
vt 0.09375 0.4375
vt 0.0625 0.4375
vt 0.0625 0.0625
vt 0.09375 0.0625
vt 0.125 0.4375
vt 0.09375 0.4375
vt 0.09375 0.0625
vt 0.125 0.0625
vt 0.03125 0.4375
vt 0 0.4375
vt 0 0.0625
vt 0.03125 0.0625
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.5
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.09375 0.4375
vt 0.0625 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_71787a2c-953f-372c-0ba8-125703cbb767
f 44/124/31 47/123/31 45/122/31 42/121/31
f 43/128/32 44/127/32 42/126/32 41/125/32
f 48/132/33 43/131/33 41/130/33 46/129/33
f 47/136/34 48/135/34 46/134/34 45/133/34
f 46/140/35 41/139/35 42/138/35 45/137/35
f 47/144/36 44/143/36 43/142/36 48/141/36
o right_leg
v 0.1875 0.75 0.0625
v 0.1875 0.75 -0.0625
v 0.1875 0 0.0625
v 0.1875 0 -0.0625
v 0.0625 0.75 -0.0625
v 0.0625 0.75 0.0625
v 0.0625 0 -0.0625
v 0.0625 0 0.0625
vt 0.03125 0.4375
vt 0.0625 0.4375
vt 0.0625 0.0625
vt 0.03125 0.0625
vt 0 0.4375
vt 0.03125 0.4375
vt 0.03125 0.0625
vt 0 0.0625
vt 0.09375 0.4375
vt 0.125 0.4375
vt 0.125 0.0625
vt 0.09375 0.0625
vt 0.0625 0.4375
vt 0.09375 0.4375
vt 0.09375 0.0625
vt 0.0625 0.0625
vt 0.0625 0.4375
vt 0.03125 0.4375
vt 0.03125 0.5
vt 0.0625 0.5
vt 0.09375 0.5
vt 0.0625 0.5
vt 0.0625 0.4375
vt 0.09375 0.4375
vn 0 0 -1
vn 1 0 0
vn 0 0 1
vn -1 0 0
vn 0 1 0
vn 0 -1 0
usemtl m_71787a2c-953f-372c-0ba8-125703cbb767
f 52/148/37 55/147/37 53/146/37 50/145/37
f 51/152/38 52/151/38 50/150/38 49/149/38
f 56/156/39 51/155/39 49/154/39 54/153/39
f 55/160/40 56/159/40 54/158/40 53/157/40
f 54/164/41 49/163/41 50/162/41 53/161/41
f 55/168/42 52/167/42 51/166/42 56/165/42

Some files were not shown because too many files have changed in this diff Show More