Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9090be8acf | |||
| a3d4eb65d5 | |||
| 9b2a4be707 | |||
| 5474a18753 | |||
| 0a43f8104e | |||
| ca8b7cbee8 | |||
| be3cfef65f | |||
| 65f5bc673f | |||
| a22bc00d46 | |||
| 5bfcffc142 | |||
| ee92200300 | |||
| d3b1053f21 | |||
| 13f020ddf5 | |||
| 65da634c71 | |||
| c519ba2536 | |||
| 4b7613a659 | |||
| 7408da401b | |||
| a63ecb8133 | |||
| 788407b709 | |||
| 0e70dc6fa3 | |||
| 44302bb0f3 | |||
| 181017313d | |||
| 6615fe9438 | |||
| 113448dbf0 | |||
| 5c9616d4af | |||
| a954cbbf50 | |||
| dec2234019 | |||
| 0334ec3fa7 | |||
| 5fcd26cd3e | |||
| 8102f3a2ea | |||
| cbb17d22d4 | |||
| 8bed5194d8 | |||
| eb42217885 | |||
| 7e12d00874 | |||
| d12246833e | |||
| 44baa47bba | |||
| 6aeb281249 | |||
| 382e00cff4 | |||
| 77e1dacb6f | |||
| 37aa1eaa18 | |||
| 1411964dcf | |||
| 35269315cc | |||
| 8f8b64f99c | |||
| 923589524b | |||
| 00eeed2e20 | |||
| 0630885d92 | |||
| 3467315aef |
@@ -14,6 +14,9 @@ endif()
|
|||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
||||||
|
elseif(MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#set(BUILD_SHARED_LIBS FALSE)
|
#set(BUILD_SHARED_LIBS FALSE)
|
||||||
@@ -34,6 +37,12 @@ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
|
|||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
|
||||||
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
|
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
|
||||||
|
|
||||||
|
# DEBUG definition
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
|
||||||
|
$<$<CONFIG:Debug>:DEBUG>
|
||||||
|
$<$<CONFIG:RelWithDebInfo>:DEBUG>
|
||||||
|
)
|
||||||
|
|
||||||
include(cotire)
|
include(cotire)
|
||||||
add_subdirectory(src/Engine)
|
add_subdirectory(src/Engine)
|
||||||
add_subdirectory(src/Game)
|
add_subdirectory(src/Game)
|
||||||
|
|||||||
+1
-1
Submodule assets updated: e4dc9529f2...091ad5c01b
@@ -4,11 +4,12 @@
|
|||||||
#include "../Core/System.h"
|
#include "../Core/System.h"
|
||||||
#include "../Core/Octree.h"
|
#include "../Core/Octree.h"
|
||||||
#include "Collision.h"
|
#include "Collision.h"
|
||||||
|
#include "EntityAABB.h"
|
||||||
|
|
||||||
class CollidableOctreeSystem : public ImpureSystem, public PureSystem
|
class CollidableOctreeSystem : public ImpureSystem, public PureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CollidableOctreeSystem(World* world, EventBroker* eventBroker, Octree<AABB>* octree)
|
CollidableOctreeSystem(World* world, EventBroker* eventBroker, Octree<EntityAABB>* octree)
|
||||||
: System(world, eventBroker)
|
: System(world, eventBroker)
|
||||||
, PureSystem("Collidable")
|
, PureSystem("Collidable")
|
||||||
, m_Octree(octree)
|
, m_Octree(octree)
|
||||||
@@ -18,7 +19,7 @@ public:
|
|||||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Octree<AABB>* m_Octree;
|
Octree<EntityAABB>* m_Octree;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "../Core/Transform.h"
|
#include "../Core/Transform.h"
|
||||||
#include "../Core/Entity.h"
|
#include "../Core/Entity.h"
|
||||||
#include "../Core/EntityWrapper.h"
|
#include "../Core/EntityWrapper.h"
|
||||||
|
#include "EntityAABB.h"
|
||||||
|
|
||||||
class World;
|
class World;
|
||||||
struct ComponentWrapper;
|
struct ComponentWrapper;
|
||||||
@@ -58,10 +59,9 @@ bool AABBVsAABB(const AABB& a, const AABB& b);
|
|||||||
//Return true if the boxes are intersecting.
|
//Return true if the boxes are intersecting.
|
||||||
//Also outputs the minimum translation that box [a] would need in order to resolve collision.
|
//Also outputs the minimum translation that box [a] would need in order to resolve collision.
|
||||||
bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation);
|
bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation);
|
||||||
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon = 0.0001f);
|
|
||||||
|
|
||||||
// Calculates an absolute AABB from an entity AABB component
|
// Calculates an absolute AABB from an entity AABB component
|
||||||
boost::optional<AABB> EntityAbsoluteAABB(EntityWrapper& entity);
|
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,30 +7,23 @@
|
|||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../Core/System.h"
|
#include "../Core/System.h"
|
||||||
#include "../Core/EventBroker.h"
|
#include "../Core/EventBroker.h"
|
||||||
#include "../Core/EKeyUp.h"
|
|
||||||
#include "../Core/Octree.h"
|
#include "../Core/Octree.h"
|
||||||
|
#include "EntityAABB.h"
|
||||||
|
|
||||||
class CollisionSystem : public PureSystem
|
class CollisionSystem : public PureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CollisionSystem(World* world, EventBroker* eventBroker, Octree<AABB>* octree)
|
CollisionSystem(World* world, EventBroker* eventBroker, Octree<EntityAABB>* octree)
|
||||||
: System(world, eventBroker)
|
: System(world, eventBroker)
|
||||||
, PureSystem("Collidable")
|
, PureSystem("Collidable")
|
||||||
, m_Octree(octree)
|
, m_Octree(octree)
|
||||||
, zPress(false)
|
{ }
|
||||||
{
|
|
||||||
//TODO: Debug stuff, remove later.
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Octree<AABB>* m_Octree;
|
Octree<EntityAABB>* m_Octree;
|
||||||
bool zPress;
|
std::vector<EntityAABB> m_OctreeResult;
|
||||||
|
|
||||||
EventRelay<CollisionSystem, Events::KeyUp> m_EKeyUp;
|
|
||||||
bool OnKeyUp(const Events::KeyUp &event);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#define Events_TriggerEnter_h__
|
#define Events_TriggerEnter_h__
|
||||||
|
|
||||||
#include "../Core/EventBroker.h"
|
#include "../Core/EventBroker.h"
|
||||||
#include "../Core/Entity.h"
|
#include "../Core/EntityWrapper.h"
|
||||||
|
|
||||||
namespace Events
|
namespace Events
|
||||||
{
|
{
|
||||||
@@ -11,27 +11,27 @@ namespace Events
|
|||||||
struct TriggerTouch : Event
|
struct TriggerTouch : Event
|
||||||
{
|
{
|
||||||
/** The id of the entity that touches the trigger. */
|
/** The id of the entity that touches the trigger. */
|
||||||
EntityID Entity;
|
EntityWrapper Entity;
|
||||||
/** The id of the trigger entity. */
|
/** The id of the trigger entity. */
|
||||||
EntityID Trigger;
|
EntityWrapper Trigger;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Thrown once, when an entity has completely left a trigger. */
|
/** Thrown once, when an entity has completely left a trigger. */
|
||||||
struct TriggerLeave : Event
|
struct TriggerLeave : Event
|
||||||
{
|
{
|
||||||
/** The id of the entity that left the trigger. */
|
/** The id of the entity that left the trigger. */
|
||||||
EntityID Entity;
|
EntityWrapper Entity;
|
||||||
/** The id of the trigger entity. */
|
/** The id of the trigger entity. */
|
||||||
EntityID Trigger;
|
EntityWrapper Trigger;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Thrown once, when an entity is completely contained inside a trigger. */
|
/** Thrown once, when an entity is completely contained inside a trigger. */
|
||||||
struct TriggerEnter : Event
|
struct TriggerEnter : Event
|
||||||
{
|
{
|
||||||
/** The id of the entity that entered the trigger. */
|
/** The id of the entity that entered the trigger. */
|
||||||
EntityID Entity;
|
EntityWrapper Entity;
|
||||||
/** The id of the trigger entity. */
|
/** The id of the trigger entity. */
|
||||||
EntityID Trigger;
|
EntityWrapper Trigger;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef EntityAABB_h__
|
||||||
|
#define EntityAABB_h__
|
||||||
|
|
||||||
|
#include "../Core/AABB.h"
|
||||||
|
#include "../Core/EntityWrapper.h"
|
||||||
|
|
||||||
|
struct EntityAABB : AABB
|
||||||
|
{
|
||||||
|
EntityAABB() = default;
|
||||||
|
|
||||||
|
EntityAABB(const glm::vec3& minPos, const glm::vec3& maxPos)
|
||||||
|
: AABB(minPos, maxPos)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
EntityAABB(const AABB& aabb)
|
||||||
|
: AABB(aabb)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
EntityWrapper Entity;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -8,13 +8,14 @@
|
|||||||
#include "../Core/EventBroker.h"
|
#include "../Core/EventBroker.h"
|
||||||
#include "../Core/Octree.h"
|
#include "../Core/Octree.h"
|
||||||
#include "ETrigger.h"
|
#include "ETrigger.h"
|
||||||
|
#include "EntityAABB.h"
|
||||||
|
|
||||||
class AABB;
|
class AABB;
|
||||||
|
|
||||||
class TriggerSystem : public PureSystem
|
class TriggerSystem : public PureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TriggerSystem(World* world, EventBroker* eventBroker, Octree<AABB>* octree)
|
TriggerSystem(World* world, EventBroker* eventBroker, Octree<EntityAABB>* octree)
|
||||||
: System(world, eventBroker)
|
: System(world, eventBroker)
|
||||||
, PureSystem("Trigger")
|
, PureSystem("Trigger")
|
||||||
, m_Octree(octree)
|
, m_Octree(octree)
|
||||||
@@ -27,9 +28,10 @@ public:
|
|||||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Octree<AABB>* m_Octree;
|
Octree<EntityAABB>* m_Octree;
|
||||||
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesTouchingTrigger;
|
std::vector<EntityAABB> m_OctreeOut;
|
||||||
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesCompletelyInTrigger;
|
std::unordered_map<EntityWrapper, std::unordered_set<EntityWrapper>> m_EntitiesTouchingTrigger;
|
||||||
|
std::unordered_map<EntityWrapper, std::unordered_set<EntityWrapper>> m_EntitiesCompletelyInTrigger;
|
||||||
|
|
||||||
//TODO: Only exists for debug purposes, remove later.
|
//TODO: Only exists for debug purposes, remove later.
|
||||||
EventRelay<TriggerSystem, Events::TriggerEnter> m_EEnter;
|
EventRelay<TriggerSystem, Events::TriggerEnter> m_EEnter;
|
||||||
@@ -40,13 +42,13 @@ private:
|
|||||||
bool OnLeave(const Events::TriggerLeave &event);
|
bool OnLeave(const Events::TriggerLeave &event);
|
||||||
|
|
||||||
//True if leave event was thrown.
|
//True if leave event was thrown.
|
||||||
bool throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& triggerSet, EntityID pId, EntityID tId);
|
bool throwLeaveIfWasInTrigger(std::unordered_set<EntityWrapper>& triggerSet, EntityWrapper colliderENtity, EntityWrapper triggerEntity);
|
||||||
template<typename Event>
|
template<typename Event>
|
||||||
void publish(EntityID pId, EntityID tId)
|
void publish(EntityWrapper collider, EntityWrapper trigger)
|
||||||
{
|
{
|
||||||
Event e;
|
Event e;
|
||||||
e.Trigger = tId;
|
e.Trigger = trigger;
|
||||||
e.Entity = pId;
|
e.Entity = collider;
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "Core/Util/Logging.h"
|
#include "Core/Util/Logging.h"
|
||||||
#include "Core/Util/IfDebug.h"
|
#include "Core/Util/IfDebug.h"
|
||||||
@@ -9,7 +9,6 @@ public:
|
|||||||
AABB() = default;
|
AABB() = default;
|
||||||
//No checks are made. Values in minPos must be less than values in maxPos, i.e. min.x < max.x, etc.
|
//No checks are made. Values in minPos must be less than values in maxPos, i.e. min.x < max.x, etc.
|
||||||
AABB(const glm::vec3& minPos, const glm::vec3& maxPos);
|
AABB(const glm::vec3& minPos, const glm::vec3& maxPos);
|
||||||
AABB(const glm::vec4& minPos, const glm::vec4& maxPos);
|
|
||||||
//No checks are made. Size must consist of non-negative numbers.
|
//No checks are made. Size must consist of non-negative numbers.
|
||||||
static AABB FromOriginSize(const glm::vec3& origin, const glm::vec3& size);
|
static AABB FromOriginSize(const glm::vec3& origin, const glm::vec3& size);
|
||||||
virtual ~AABB();
|
virtual ~AABB();
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class ComponentWrapperFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ComponentWrapperFactory() = default;
|
ComponentWrapperFactory() = default;
|
||||||
ComponentWrapperFactory(std::string componentTypeName, std::size_t allocation = 0)
|
ComponentWrapperFactory(std::string componentTypeName, unsigned int allocation = 0)
|
||||||
{
|
{
|
||||||
m_ComponentInfo.Name = componentTypeName;
|
m_ComponentInfo.Name = componentTypeName;
|
||||||
m_ComponentInfo.Meta->Allocation = allocation;
|
m_ComponentInfo.Meta->Allocation = allocation;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ private:
|
|||||||
~EntityFile();
|
~EntityFile();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::size_t GetTypeStride(std::string typeName);
|
static unsigned int GetTypeStride(std::string typeName);
|
||||||
static void WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map<std::string, std::string>& attributes);
|
static void WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map<std::string, std::string>& attributes);
|
||||||
static void WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData);
|
static void WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData);
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ struct EntityWrapper
|
|||||||
bool operator==(const EntityWrapper& e) const;
|
bool operator==(const EntityWrapper& e) const;
|
||||||
bool operator!=(const EntityWrapper& e) const;
|
bool operator!=(const EntityWrapper& e) const;
|
||||||
explicit operator EntityID() const;
|
explicit operator EntityID() const;
|
||||||
operator bool();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent);
|
EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent);
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ template<typename T>
|
|||||||
template<typename Box>
|
template<typename Box>
|
||||||
void Octree<T>::ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects)
|
void Octree<T>::ObjectsInSameRegion(const Box& box, std::vector<T>& outObjects)
|
||||||
{
|
{
|
||||||
static_assert(std::is_base_of<AABB, Box>::value, "template argument type Box in Octree<T>::ObjectsInSameRegion must be a subclass of AABB.");
|
//static_assert(std::is_base_of<AABB, Box>::value, "template argument type Box in Octree<T>::ObjectsInSameRegion must be a subclass of AABB.");
|
||||||
falsifyObjectChecks();
|
falsifyObjectChecks();
|
||||||
m_Root->ObjectsInSameRegion(box, outObjects);
|
m_Root->ObjectsInSameRegion(box, outObjects);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ enum class FileWatcher::FileEventFlags
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline FileWatcher::FileEventFlags operator|(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast<FileWatcher::FileEventFlags>(static_cast<int>(a) | static_cast<int>(b)); }
|
inline FileWatcher::FileEventFlags operator|(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast<FileWatcher::FileEventFlags>(static_cast<int>(a) | static_cast<int>(b)); }
|
||||||
inline bool operator&(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast<int>(a)& static_cast<int>(b); }
|
inline bool operator&(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return (static_cast<int>(a) & static_cast<int>(b)) != 0; }
|
||||||
|
|
||||||
class FileWatcher::Worker
|
class FileWatcher::Worker
|
||||||
{
|
{
|
||||||
@@ -54,7 +54,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct FileInfo
|
struct FileInfo
|
||||||
{
|
{
|
||||||
int Size;
|
std::size_t Size;
|
||||||
std::time_t Timestamp;
|
std::time_t Timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,41 +29,9 @@ enum _LOG_LEVEL
|
|||||||
|
|
||||||
extern _LOG_LEVEL LOG_LEVEL;
|
extern _LOG_LEVEL LOG_LEVEL;
|
||||||
|
|
||||||
const static char* _LOG_LEVEL_PREFIX[] =
|
extern const char* _LOG_LEVEL_PREFIX[];
|
||||||
{
|
|
||||||
"EE: ",
|
|
||||||
"",
|
|
||||||
"WW: ",
|
|
||||||
"DD: "
|
|
||||||
};
|
|
||||||
|
|
||||||
static void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int line, const char* format, ...)
|
extern void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int line, const char* format, ...);
|
||||||
{
|
|
||||||
if (logLevel > LOG_LEVEL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* message = nullptr;
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
size_t size = vsnprintf(message, 0, format, args) + 1;
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
message = new char[size];
|
|
||||||
vsnprintf(message, size, format, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
if (logLevel == LOG_LEVEL_ERROR) {
|
|
||||||
std::cerr << file << ":" << line << " " << func << std::endl;
|
|
||||||
std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] message;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOG(logLevel, format, ...) \
|
#define LOG(logLevel, format, ...) \
|
||||||
_LOG(logLevel, __BASE_FILE__, __func__, __LINE__, format, ##__VA_ARGS__)
|
_LOG(logLevel, __BASE_FILE__, __func__, __LINE__, format, ##__VA_ARGS__)
|
||||||
@@ -77,7 +45,11 @@ static void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsign
|
|||||||
#define LOG_INFO(format, ...) \
|
#define LOG_INFO(format, ...) \
|
||||||
LOG(LOG_LEVEL_INFO, format, ##__VA_ARGS__)
|
LOG(LOG_LEVEL_INFO, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
#define LOG_DEBUG(format, ...) \
|
#define LOG_DEBUG(format, ...) \
|
||||||
LOG(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
|
LOG(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOG_DEBUG(format, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // Logging_h__
|
#endif // Logging_h__
|
||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
m_SpeedMultiplier = m_Config->Get<float>("Editor.CameraSpeed", 3.f);
|
m_SpeedMultiplier = m_Config->Get<float>("Editor.CameraSpeed", 3.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const glm::vec3 Movement() const override { return m_Movement * m_SpeedMultiplier; }
|
virtual const glm::vec3 Movement() const override { return m_Movement * static_cast<float>(m_SpeedMultiplier); }
|
||||||
|
|
||||||
void Enable() { m_Enabled = true; }
|
void Enable() { m_Enabled = true; }
|
||||||
void Disable() { m_Enabled = false; }
|
void Disable() { m_Enabled = false; }
|
||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
ConfigFile* m_Config;
|
ConfigFile* m_Config;
|
||||||
bool m_Enabled = false;
|
bool m_Enabled = false;
|
||||||
float m_SpeedMultiplier = 1.f;
|
double m_SpeedMultiplier = 1.f;
|
||||||
|
|
||||||
EventRelay<EventContext, Events::MousePress> m_EMousePress;
|
EventRelay<EventContext, Events::MousePress> m_EMousePress;
|
||||||
bool OnMousePress(const Events::MousePress& e)
|
bool OnMousePress(const Events::MousePress& e)
|
||||||
@@ -105,7 +105,7 @@ protected:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier);
|
m_SpeedMultiplier += e.DeltaY * (0.1 * m_SpeedMultiplier);
|
||||||
m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier);
|
m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier);
|
||||||
m_Config->SaveToDisk();
|
m_Config->SaveToDisk();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <nativefiledialog/nfd.h>
|
#include <nativefiledialog/nfd.h>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/any.hpp>
|
#include <boost/any.hpp>
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../GLM.h"
|
#include "../GLM.h"
|
||||||
#include <glm/gtx/common.hpp>
|
#include <glm/gtx/common.hpp>
|
||||||
@@ -18,6 +19,8 @@
|
|||||||
#include "../Core/ResourceManager.h"
|
#include "../Core/ResourceManager.h"
|
||||||
#include "../Core/EPause.h"
|
#include "../Core/EPause.h"
|
||||||
#include "../Core/EKeyDown.h"
|
#include "../Core/EKeyDown.h"
|
||||||
|
#include "../Core/ELockMouse.h"
|
||||||
|
#include "../Core/EFileDropped.h"
|
||||||
#include "../Rendering/Texture.h"
|
#include "../Rendering/Texture.h"
|
||||||
|
|
||||||
class EditorGUI
|
class EditorGUI
|
||||||
@@ -32,6 +35,12 @@ public:
|
|||||||
Scale
|
Scale
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class WidgetSpace
|
||||||
|
{
|
||||||
|
Global,
|
||||||
|
Local
|
||||||
|
};
|
||||||
|
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
void SelectEntity(EntityWrapper entity);
|
void SelectEntity(EntityWrapper entity);
|
||||||
@@ -73,6 +82,9 @@ public:
|
|||||||
// Called when the user selects a widget mode.
|
// Called when the user selects a widget mode.
|
||||||
typedef std::function<void(WidgetMode)> OnWidgetMode_t;
|
typedef std::function<void(WidgetMode)> OnWidgetMode_t;
|
||||||
void SetWidgetModeCallback(OnWidgetMode_t f) { m_OnWidgetMode = f; }
|
void SetWidgetModeCallback(OnWidgetMode_t f) { m_OnWidgetMode = f; }
|
||||||
|
// Called when the user selects a widget space.
|
||||||
|
typedef std::function<void(WidgetSpace)> OnWidgetSpace_t;
|
||||||
|
void SetWidgetSpaceCallback(OnWidgetSpace_t f) { m_OnWidgetSpace = f; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
World* m_World;
|
World* m_World;
|
||||||
@@ -93,8 +105,12 @@ private:
|
|||||||
EntityWrapper m_CurrentlyDragging = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentlyDragging = EntityWrapper::Invalid;
|
||||||
std::string m_LastErrorMessage;
|
std::string m_LastErrorMessage;
|
||||||
WidgetMode m_CurrentWidgetMode = WidgetMode::Translate;
|
WidgetMode m_CurrentWidgetMode = WidgetMode::Translate;
|
||||||
|
WidgetSpace m_CurrentWidgetSpace = WidgetSpace::Global;
|
||||||
std::set<std::string> m_ModalsToOpen;
|
std::set<std::string> m_ModalsToOpen;
|
||||||
std::map<std::string, boost::any> m_ModalData;
|
std::map<std::string, boost::any> m_ModalData;
|
||||||
|
std::string m_DroppedFile = "";
|
||||||
|
bool m_Paused = false;
|
||||||
|
bool m_MouseLocked = false;
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
|
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
|
||||||
@@ -107,10 +123,21 @@ private:
|
|||||||
OnComponentAttach_t m_OnComponentAttach = nullptr;
|
OnComponentAttach_t m_OnComponentAttach = nullptr;
|
||||||
OnComponentDelete_t m_OnComponentDelete = nullptr;
|
OnComponentDelete_t m_OnComponentDelete = nullptr;
|
||||||
OnWidgetMode_t m_OnWidgetMode = nullptr;
|
OnWidgetMode_t m_OnWidgetMode = nullptr;
|
||||||
|
OnWidgetSpace_t m_OnWidgetSpace = nullptr;
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown;
|
EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown;
|
||||||
bool OnKeyDown(const Events::KeyDown& e);
|
bool OnKeyDown(const Events::KeyDown& e);
|
||||||
|
EventRelay<EditorGUI, Events::FileDropped> m_EFileDropped;
|
||||||
|
bool OnFileDropped(const Events::FileDropped& e);
|
||||||
|
EventRelay<EditorGUI, Events::Pause> m_EPause;
|
||||||
|
bool OnPause(const Events::Pause& e);
|
||||||
|
EventRelay<EditorGUI, Events::Resume> m_EResume;
|
||||||
|
bool OnResume(const Events::Resume& e);
|
||||||
|
EventRelay<EditorGUI, Events::LockMouse> m_ELockMouse;
|
||||||
|
bool OnLockMouse(const Events::LockMouse& e);
|
||||||
|
EventRelay<EditorGUI, Events::UnlockMouse> m_EUnlockMouse;
|
||||||
|
bool OnUnlockMouse(const Events::UnlockMouse& e);
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
boost::filesystem::path fileOpenDialog();
|
boost::filesystem::path fileOpenDialog();
|
||||||
@@ -118,6 +145,9 @@ private:
|
|||||||
const std::string formatEntityName(EntityWrapper entity);
|
const std::string formatEntityName(EntityWrapper entity);
|
||||||
GLuint tryLoadTexture(std::string filePath);
|
GLuint tryLoadTexture(std::string filePath);
|
||||||
void openModal(const std::string& modal);
|
void openModal(const std::string& modal);
|
||||||
|
void setWidgetMode(WidgetMode mode);
|
||||||
|
void toggleWidgetSpace();
|
||||||
|
static bool compareCharArray(const char* c1, const char* c2);
|
||||||
|
|
||||||
// Entity file handling methods
|
// Entity file handling methods
|
||||||
void entityImport(World* world);
|
void entityImport(World* world);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ private:
|
|||||||
double m_LastTime = 0.f;
|
double m_LastTime = 0.f;
|
||||||
bool m_Enabled = true;
|
bool m_Enabled = true;
|
||||||
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
|
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
|
||||||
|
EditorGUI::WidgetSpace m_WidgetSpace = EditorGUI::WidgetSpace::Global;
|
||||||
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
||||||
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ private:
|
|||||||
void OnEntityChangeName(EntityWrapper entity, const std::string& name);
|
void OnEntityChangeName(EntityWrapper entity, const std::string& name);
|
||||||
void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
|
void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
|
||||||
void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
|
void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
|
||||||
|
void OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace);
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
|
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
|
||||||
|
|||||||
@@ -30,9 +30,18 @@ public:
|
|||||||
private:
|
private:
|
||||||
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
|
||||||
void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const;
|
void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const;
|
||||||
|
void DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>& job, RenderScene& scene);
|
||||||
|
|
||||||
|
void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<ExplosionEffectJob>& job, RenderScene& scene);
|
||||||
|
void BindModelUniforms(GLuint shaderHandle, std::shared_ptr<ModelJob>& job, RenderScene& scene);
|
||||||
|
|
||||||
|
void BindExplosionTextures(std::shared_ptr<ExplosionEffectJob>& job);
|
||||||
|
void BindModelTextures(std::shared_ptr<ModelJob>& job);
|
||||||
|
|
||||||
Texture* m_WhiteTexture;
|
Texture* m_WhiteTexture;
|
||||||
Texture* m_BlackTexture;
|
Texture* m_BlackTexture;
|
||||||
|
Texture* m_NeutralNormalTexture;
|
||||||
|
Texture* m_GreyTexture;
|
||||||
|
|
||||||
FrameBuffer m_FinalPassFrameBuffer;
|
FrameBuffer m_FinalPassFrameBuffer;
|
||||||
GLuint m_BloomTexture;
|
GLuint m_BloomTexture;
|
||||||
@@ -43,6 +52,7 @@ private:
|
|||||||
const LightCullingPass* m_LightCullingPass;
|
const LightCullingPass* m_LightCullingPass;
|
||||||
|
|
||||||
ShaderProgram* m_ForwardPlusProgram;
|
ShaderProgram* m_ForwardPlusProgram;
|
||||||
|
ShaderProgram* m_ExplosionEffectProgram;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
#ifndef ExplosionEffectJob_h__
|
||||||
|
#define ExplosionEffectJob_h__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "../Core/ComponentWrapper.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "RenderJob.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "../Core/World.h"
|
||||||
|
|
||||||
|
struct ExplosionEffectJob : ModelJob
|
||||||
|
{
|
||||||
|
ExplosionEffectJob(ComponentWrapper explosionEffectComponent, ::Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, ::World* world, glm::vec4 fillColor, float fillPercentage)
|
||||||
|
: ModelJob(model, camera, matrix, matGroup, modelComponent, world, fillColor, fillPercentage)
|
||||||
|
{
|
||||||
|
ExplosionOrigin = (glm::vec3)explosionEffectComponent["ExplosionOrigin"];
|
||||||
|
TimeSinceDeath = (double)explosionEffectComponent["TimeSinceDeath"];
|
||||||
|
ExplosionDuration = (double)explosionEffectComponent["ExplosionDuration"];
|
||||||
|
EndColor = (glm::vec4)explosionEffectComponent["EndColor"];
|
||||||
|
Randomness = (bool)explosionEffectComponent["Randomness"];
|
||||||
|
RandomnessScalar = (double)explosionEffectComponent["RandomnessScalar"];
|
||||||
|
Velocity = (glm::vec2)explosionEffectComponent["Velocity"];
|
||||||
|
ColorByDistance = (bool)explosionEffectComponent["ColorByDistance"];
|
||||||
|
ExponentialAccelaration = (bool)explosionEffectComponent["ExponentialAccelaration"];
|
||||||
|
};
|
||||||
|
|
||||||
|
glm::vec3 ExplosionOrigin;
|
||||||
|
double TimeSinceDeath = 0.f; //Seconds
|
||||||
|
double ExplosionDuration = 2.f;
|
||||||
|
//bool Gravity = true;
|
||||||
|
//double GravityForce = 1.f; // Speed
|
||||||
|
//double ObjectRadius = 2.f; // TODO: Change this for object radius when it's available
|
||||||
|
glm::vec4 EndColor;
|
||||||
|
bool Randomness = false;
|
||||||
|
|
||||||
|
float RandomnessScalar = 1.f;
|
||||||
|
glm::vec2 Velocity;
|
||||||
|
bool ColorByDistance = false;
|
||||||
|
//bool ReverseAnimation = false;
|
||||||
|
//bool Wireframe = false;
|
||||||
|
bool ExponentialAccelaration = false;
|
||||||
|
|
||||||
|
std::array<float, 50> RandomNumbers = {
|
||||||
|
0.3257552917701f,
|
||||||
|
0.07601508315467f,
|
||||||
|
0.57408909014151f,
|
||||||
|
0.0f,
|
||||||
|
0.8618231368539f,
|
||||||
|
0.074957156588769f,
|
||||||
|
0.39413607511396f,
|
||||||
|
0.54579346698979f,
|
||||||
|
0.83222648353885f,
|
||||||
|
0.83635707285086f,
|
||||||
|
0.34473986148124f,
|
||||||
|
0.98092448710507f,
|
||||||
|
0.46346380070944f,
|
||||||
|
0.7308761201477f,
|
||||||
|
0.70832470371776f,
|
||||||
|
0.28268750909841f,
|
||||||
|
0.26291620883295f,
|
||||||
|
0.07685032816457f,
|
||||||
|
0.30760929515008f,
|
||||||
|
0.2781575388639f ,
|
||||||
|
0.016950582161988f ,
|
||||||
|
0.25787915254844f ,
|
||||||
|
0.76293767279151f ,
|
||||||
|
0.67730279903733f ,
|
||||||
|
0.49042877018937f ,
|
||||||
|
0.13002237823327f ,
|
||||||
|
0.62803373841012f ,
|
||||||
|
0.94525353747665f ,
|
||||||
|
0.32893980076953f ,
|
||||||
|
0.95952951719962f ,
|
||||||
|
0.056386206790985f ,
|
||||||
|
0.012030893476694f ,
|
||||||
|
0.93090049220757f,
|
||||||
|
0.83579883064879f,
|
||||||
|
0.79733513938139f,
|
||||||
|
0.8796381046435f ,
|
||||||
|
0.94160434600972f ,
|
||||||
|
0.76901855588379f ,
|
||||||
|
0.50253688101775f ,
|
||||||
|
0.82457069578793f ,
|
||||||
|
0.80157403359263f ,
|
||||||
|
0.87291810189975f ,
|
||||||
|
0.64679548919517f ,
|
||||||
|
0.42664138899494f ,
|
||||||
|
0.77171308303797f ,
|
||||||
|
0.75567959237643f ,
|
||||||
|
0.45190826265696f ,
|
||||||
|
0.59844922628181f ,
|
||||||
|
0.56534937655802f ,
|
||||||
|
0.195656257307f};
|
||||||
|
|
||||||
|
void CalculateHash() override
|
||||||
|
{
|
||||||
|
Hash = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -25,21 +25,23 @@ class IRenderer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GLFWwindow* Window() const { return m_Window; }
|
GLFWwindow* Window() const { return m_Window; }
|
||||||
|
//Returns screen size including window border and header
|
||||||
Rectangle Resolution() const { return m_Resolution; }
|
Rectangle Resolution() const { return m_Resolution; }
|
||||||
void SetResolution(const Rectangle& resolution) { m_Resolution = resolution; }
|
virtual void SetResolution(const Rectangle& resolution) { m_Resolution = resolution; }
|
||||||
bool Fullscreen() { return m_Fullscreen; }
|
bool Fullscreen() { return m_Fullscreen; }
|
||||||
void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; }
|
virtual void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; }
|
||||||
bool VSYNC() const { return m_VSYNC; }
|
bool VSYNC() const { return m_VSYNC; }
|
||||||
void SetVSYNC(bool vsync) { m_VSYNC = vsync; }
|
virtual void SetVSYNC(bool vsync) { m_VSYNC = vsync; }
|
||||||
|
//Returns screen size excluding window border and header
|
||||||
|
Rectangle GetViewportSize() const { return m_ViewportSize; }
|
||||||
virtual void Initialize() = 0;
|
virtual void Initialize() = 0;
|
||||||
virtual void Update(double dt) = 0;
|
virtual void Update(double dt) = 0;
|
||||||
virtual void Draw(RenderFrame& rq) = 0;
|
virtual void Draw(RenderFrame& rq) = 0;
|
||||||
virtual PickData Pick(glm::vec2 screenCord) = 0;
|
virtual PickData Pick(glm::vec2 screenCord) = 0;
|
||||||
|
|
||||||
World* m_World; //Temp world, untill viktor merge.
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720);
|
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720);
|
||||||
|
Rectangle m_ViewportSize = Rectangle::Rectangle(1280, 720);
|
||||||
bool m_Fullscreen = false;
|
bool m_Fullscreen = false;
|
||||||
bool m_VSYNC = false;
|
bool m_VSYNC = false;
|
||||||
int m_GLVersion[2];
|
int m_GLVersion[2];
|
||||||
|
|||||||
@@ -22,10 +22,26 @@ struct ModelJob : RenderJob
|
|||||||
{
|
{
|
||||||
Model = model;
|
Model = model;
|
||||||
TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0;
|
TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0;
|
||||||
DiffuseTexture = matGroup.Texture.get();
|
if (modelComponent["DiffuseTexture"]) {
|
||||||
NormalTexture = matGroup.NormalMap.get();
|
DiffuseTexture = matGroup.Texture.get();
|
||||||
SpecularTexture = matGroup.SpecularMap.get();
|
} else {
|
||||||
IncandescenceTexture = matGroup.IncandescenceMap.get();
|
DiffuseTexture = nullptr;
|
||||||
|
}
|
||||||
|
if (modelComponent["NormalMap"]) {
|
||||||
|
NormalTexture = matGroup.NormalMap.get();
|
||||||
|
} else {
|
||||||
|
NormalTexture = nullptr;
|
||||||
|
}
|
||||||
|
if (modelComponent["SpecularMap"]) {
|
||||||
|
SpecularTexture = matGroup.SpecularMap.get();
|
||||||
|
} else {
|
||||||
|
SpecularTexture = nullptr;
|
||||||
|
}
|
||||||
|
if (modelComponent["GlowMap"]) {
|
||||||
|
IncandescenceTexture = matGroup.IncandescenceMap.get();
|
||||||
|
} else {
|
||||||
|
IncandescenceTexture = nullptr;
|
||||||
|
}
|
||||||
DiffuseColor = matGroup.DiffuseColor;
|
DiffuseColor = matGroup.DiffuseColor;
|
||||||
SpecularColor = matGroup.SpecularColor;
|
SpecularColor = matGroup.SpecularColor;
|
||||||
IncandescenceColor = matGroup.IncandescenceColor;
|
IncandescenceColor = matGroup.IncandescenceColor;
|
||||||
@@ -39,7 +55,6 @@ struct ModelJob : RenderJob
|
|||||||
Depth = worldpos.z;
|
Depth = worldpos.z;
|
||||||
World = world;
|
World = world;
|
||||||
|
|
||||||
|
|
||||||
FillColor = fillColor;
|
FillColor = fillColor;
|
||||||
FillPercentage = fillPercentage;
|
FillPercentage = fillPercentage;
|
||||||
Skeleton = Model->m_RawModel->m_Skeleton;
|
Skeleton = Model->m_RawModel->m_Skeleton;
|
||||||
|
|||||||
@@ -75,21 +75,21 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
void ReadMeshFile(std::string filePath);
|
void ReadMeshFile(std::string filePath);
|
||||||
void ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
void ReadMeshFileHeader(std::size_t& offset, char* fileData);
|
||||||
void ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
void ReadMesh(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
void ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
void ReadVertices(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
void ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
void ReadIndices(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
|
|
||||||
void ReadMaterialFile(std::string filePath);
|
void ReadMaterialFile(std::string filePath);
|
||||||
void ReadMaterials(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
void ReadMaterials(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
void ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
void ReadMaterialSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
|
|
||||||
void ReadAnimationFile(std::string filePath);
|
void ReadAnimationFile(std::string filePath);
|
||||||
void ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
void ReadAnimationBindPoses(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
void ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
void ReadAnimationJoint(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
void ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips);
|
void ReadAnimationClips(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int numberOfClips);
|
||||||
void ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex);
|
void ReadAnimationClipSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int clipIndex);
|
||||||
void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfJoints, Skeleton::Animation& animation);
|
void ReadAnimationKeyFrame(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int numberOfJoints, Skeleton::Animation& animation);
|
||||||
|
|
||||||
//void CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID);
|
//void CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,11 +14,13 @@
|
|||||||
#include "TextJob.h"
|
#include "TextJob.h"
|
||||||
#include "PointLightJob.h"
|
#include "PointLightJob.h"
|
||||||
#include "DirectionalLightJob.h"
|
#include "DirectionalLightJob.h"
|
||||||
|
#include "ExplosionEffectJob.h"
|
||||||
|
|
||||||
struct RenderScene
|
struct RenderScene
|
||||||
{
|
{
|
||||||
::Camera* Camera = nullptr;
|
::Camera* Camera = nullptr;
|
||||||
std::list<std::shared_ptr<RenderJob>> ForwardJobs;
|
std::list<std::shared_ptr<RenderJob>> OpaqueObjects;
|
||||||
|
std::list<std::shared_ptr<RenderJob>> TransparentObjects;
|
||||||
std::list<std::shared_ptr<RenderJob>> PointLightJobs;
|
std::list<std::shared_ptr<RenderJob>> PointLightJobs;
|
||||||
std::list<std::shared_ptr<RenderJob>> TextJobs;
|
std::list<std::shared_ptr<RenderJob>> TextJobs;
|
||||||
std::list<std::shared_ptr<RenderJob>> DirectionalLightJobs;
|
std::list<std::shared_ptr<RenderJob>> DirectionalLightJobs;
|
||||||
@@ -27,7 +29,8 @@ struct RenderScene
|
|||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
ForwardJobs.clear();
|
OpaqueObjects.clear();
|
||||||
|
TransparentObjects.clear();
|
||||||
PointLightJobs.clear();
|
PointLightJobs.clear();
|
||||||
TextJobs.clear();
|
TextJobs.clear();
|
||||||
DirectionalLightJobs.clear();
|
DirectionalLightJobs.clear();
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ private:
|
|||||||
EventRelay<RenderSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
EventRelay<RenderSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
|
|
||||||
|
void fillModels(std::list<std::shared_ptr<RenderJob>>& opaqueJobs, std::list<std::shared_ptr<RenderJob>>& transparentJobs);
|
||||||
void fillText(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
void fillText(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||||
void fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
void fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||||
void fillDirectionalLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
void fillDirectionalLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||||
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs);
|
|
||||||
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs);
|
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs);
|
||||||
bool isChildOfACamera(EntityWrapper entity);
|
bool isChildOfACamera(EntityWrapper entity);
|
||||||
bool isChildOfCurrentCamera(EntityWrapper entity);
|
bool isChildOfCurrentCamera(EntityWrapper entity);
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ private:
|
|||||||
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
||||||
//--------------------ShaderPrograms-------------------//
|
//--------------------ShaderPrograms-------------------//
|
||||||
ShaderProgram* m_BasicForwardProgram;
|
ShaderProgram* m_BasicForwardProgram;
|
||||||
|
ShaderProgram* m_ExplosionEffectProgram;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
|
class ExplosionEffectSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExplosionEffectSystem(World* world, EventBroker* eventBroker)
|
||||||
|
: System(world, eventBroker)
|
||||||
|
, PureSystem("ExplosionEffect")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((double)component["TimeSinceDeath"] > (double)component["ExplosionDuration"]) {
|
||||||
|
(double)component["TimeSinceDeath"] = 0.f;
|
||||||
|
}
|
||||||
|
(double&)component["TimeSinceDeath"] += dt;
|
||||||
|
|
||||||
|
//if ((bool)Component["Gravity"] == true) {
|
||||||
|
// (bool)Component["ExponentialAccelaration"] = false;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
};
|
||||||
+4
-2
@@ -14,6 +14,7 @@
|
|||||||
#include "Core/EKeyDown.h"
|
#include "Core/EKeyDown.h"
|
||||||
#include "Core/EntityFilePreprocessor.h"
|
#include "Core/EntityFilePreprocessor.h"
|
||||||
#include "Core/SystemPipeline.h"
|
#include "Core/SystemPipeline.h"
|
||||||
|
#include "ExplosionEffectSystem.h"
|
||||||
#include "Editor/EditorSystem.h"
|
#include "Editor/EditorSystem.h"
|
||||||
#include "Core/EntityFile.h"
|
#include "Core/EntityFile.h"
|
||||||
#include "Rendering/RenderSystem.h"
|
#include "Rendering/RenderSystem.h"
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
#include "Core/Octree.h"
|
#include "Core/Octree.h"
|
||||||
#include "Rendering/Font.h"
|
#include "Rendering/Font.h"
|
||||||
#include "Systems/InterpolationSystem.h"
|
#include "Systems/InterpolationSystem.h"
|
||||||
|
#include "Collision/EntityAABB.h"
|
||||||
// Network
|
// Network
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include "Network/Network.h"
|
#include "Network/Network.h"
|
||||||
@@ -48,8 +50,8 @@ private:
|
|||||||
InputProxy* m_InputProxy;
|
InputProxy* m_InputProxy;
|
||||||
GUI::Frame* m_FrameStack;
|
GUI::Frame* m_FrameStack;
|
||||||
World* m_World;
|
World* m_World;
|
||||||
Octree<AABB>* m_OctreeCollision;
|
Octree<EntityAABB>* m_OctreeCollision;
|
||||||
Octree<AABB>* m_OctreeFrustrumCulling;
|
Octree<EntityAABB>* m_OctreeFrustrumCulling;
|
||||||
SystemPipeline* m_SystemPipeline;
|
SystemPipeline* m_SystemPipeline;
|
||||||
RenderFrame* m_RenderFrame;
|
RenderFrame* m_RenderFrame;
|
||||||
// Network variables
|
// Network variables
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ private:
|
|||||||
int m_BlueTeamHomeCapturePoint = m_NotACapturePoint;
|
int m_BlueTeamHomeCapturePoint = m_NotACapturePoint;
|
||||||
|
|
||||||
int m_NumberOfCapturePoints = 0;
|
int m_NumberOfCapturePoints = 0;
|
||||||
std::map<int, EntityID> m_CapturePointNumberToEntityIDMap;
|
std::map<int, EntityWrapper> m_CapturePointNumberToEntityMap;
|
||||||
|
|
||||||
//std::vector<ComponentWrapper>
|
//std::vector<ComponentWrapper>
|
||||||
|
|
||||||
@@ -48,8 +48,8 @@ private:
|
|||||||
bool m_ResetTimers = false;
|
bool m_ResetTimers = false;
|
||||||
|
|
||||||
//vectors which will keep track of enter/leave changes
|
//vectors which will keep track of enter/leave changes
|
||||||
std::vector<std::tuple<EntityID, EntityID>> m_ETriggerTouchVector;
|
std::vector<std::tuple<EntityWrapper, EntityWrapper>> m_ETriggerTouchVector;
|
||||||
std::vector<std::tuple<EntityID, EntityID>> m_ETriggerLeaveVector;
|
std::vector<std::tuple<EntityWrapper, EntityWrapper>> m_ETriggerLeaveVector;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -15,10 +15,6 @@ Space=Jump
|
|||||||
LeftControl=Crouch
|
LeftControl=Crouch
|
||||||
LeftShift=Sprint
|
LeftShift=Sprint
|
||||||
F1=ToggleEditor
|
F1=ToggleEditor
|
||||||
1=EditorToolMove
|
|
||||||
2=EditorToolRotate
|
|
||||||
3=EditorToolScale
|
|
||||||
X=EditorToggleTransformSpace
|
|
||||||
C=ConnectToServer
|
C=ConnectToServer
|
||||||
N=SwitchToServer
|
N=SwitchToServer
|
||||||
M=SwitchToClient
|
M=SwitchToClient
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<xs:include schemaLocation="Components/PointLight.xsd"/>
|
<xs:include schemaLocation="Components/PointLight.xsd"/>
|
||||||
<xs:include schemaLocation="Components/DirectionalLight.xsd"/>
|
<xs:include schemaLocation="Components/DirectionalLight.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Trigger.xsd"/>
|
<xs:include schemaLocation="Components/Trigger.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/ExplosionEffect.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Health.xsd"/>
|
<xs:include schemaLocation="Components/Health.xsd"/>
|
||||||
<xs:include schemaLocation="Components/CapturePoint.xsd"/>
|
<xs:include schemaLocation="Components/CapturePoint.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Listener.xsd"/>
|
<xs:include schemaLocation="Components/Listener.xsd"/>
|
||||||
@@ -27,4 +28,5 @@
|
|||||||
<xs:include schemaLocation="Components/Animation.xsd"/>
|
<xs:include schemaLocation="Components/Animation.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Fill.xsd"/>
|
<xs:include schemaLocation="Components/Fill.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Lifetime.xsd"/>
|
<xs:include schemaLocation="Components/Lifetime.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/HiddenForLocalPlayer.xsd"/>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<Animation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
|
<Animation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
|
||||||
|
<Name></Name>
|
||||||
<Time>0</Time>
|
<Time>0</Time>
|
||||||
<Speed>0</Speed>
|
<Speed>0</Speed>
|
||||||
<Loop>true</Loop>
|
<Loop>true</Loop>
|
||||||
|
|||||||
@@ -2,18 +2,7 @@
|
|||||||
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
<xs:include schemaLocation="../Types/TeamEnum.xsd"/>
|
||||||
<xs:complexType name="TeamEnum" mixed="true">
|
|
||||||
<xs:complexContent>
|
|
||||||
<xs:extension base="t:enum">
|
|
||||||
<xs:choice>
|
|
||||||
<xs:element name="Spectator" type="xs:integer" fixed="1" minOccurs="0"/>
|
|
||||||
<xs:element name="Red" type="xs:integer" fixed="2" minOccurs="0"/>
|
|
||||||
<xs:element name="Blue" type="xs:integer" fixed="3" minOccurs="0"/>
|
|
||||||
</xs:choice>
|
|
||||||
</xs:extension>
|
|
||||||
</xs:complexContent>
|
|
||||||
</xs:complexType>
|
|
||||||
|
|
||||||
<xs:element name="CapturePoint">
|
<xs:element name="CapturePoint">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<ExplosionEffect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ExplosionEffect.xsd">
|
||||||
|
<ExplosionOrigin X="0" Y="0" Z="0"/>
|
||||||
|
<TimeSinceDeath>0</TimeSinceDeath>
|
||||||
|
<ExplosionDuration>2</ExplosionDuration>
|
||||||
|
<!--<Gravity>1</Gravity>-->
|
||||||
|
<!--<GravityForce>1</GravityForce>-->
|
||||||
|
<!--<ObjectRadius>2</ObjectRadius>-->
|
||||||
|
<EndColor R="0" G="0" B="0" A="0"/>
|
||||||
|
<Randomness>0</Randomness>
|
||||||
|
<RandomnessScalar>1</RandomnessScalar>
|
||||||
|
<Velocity X="2" Y="2"/>
|
||||||
|
<ColorByDistance>0</ColorByDistance>
|
||||||
|
<!--<ReverseAnimation>0</ReverseAnimation>-->
|
||||||
|
<!--<Wireframe>0</Wireframe>-->
|
||||||
|
<ExponentialAccelaration>0</ExponentialAccelaration>
|
||||||
|
</ExplosionEffect>
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="ExplosionEffect">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A component that trigger the death effect</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="ExplosionOrigin" type="t:Vector" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>The position in which to spawn the component</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="TimeSinceDeath" type="t:double" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Seconds since death</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="ExplosionDuration" type="t:double" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>How many seconds the death animation should be</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<!--<xs:element name="Gravity" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Enable/disable gravity</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>-->
|
||||||
|
<!--<xs:element name="GravityForce" type="t:double" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>The force of the gravity</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>-->
|
||||||
|
<!--<xs:element name="ObjectRadius" type="t:double" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Object radius (TO BE REMOVED AND AUTOMATED)</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>-->
|
||||||
|
<xs:element name="EndColor" type="t:Color" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>The tint the polys end with</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="Randomness" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Add some randomness to the explosion</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="RandomnessScalar" type="t:double" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Alter the power of the randomness</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="Velocity" type="t:Vector" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>The velocity factors (start/end)</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="ColorByDistance" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Change the color by its moved distance instead of by its time</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<!--<xs:element name="ReverseAnimation" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Implosions are cooler</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>-->
|
||||||
|
<!--<xs:element name="Wireframe" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Enable/disable wireframe</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>-->
|
||||||
|
<xs:element name="ExponentialAccelaration" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Linear/Exponential accelaration</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<Listener xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Listener.xsd"/>
|
<HealthHUD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="HealthHUD.xsd"/>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<HiddenForLocalPlayer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="HiddenForLocalPlayer.xsd"/>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="HiddenForLocalPlayer">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to make the entity invisible if it's parented to the current local player entity (for first person player model and such)</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<Lifetime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
|
<Lifetime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Lifetime.xsd">
|
||||||
<Lifetime>0</Lifetime>
|
<Lifetime>0</Lifetime>
|
||||||
</Animation>
|
</Lifetime>
|
||||||
@@ -2,5 +2,10 @@
|
|||||||
<Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Model.xsd">
|
<Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Model.xsd">
|
||||||
<Resource></Resource>
|
<Resource></Resource>
|
||||||
<Color R="1" G="1" B="1" A="1"/>
|
<Color R="1" G="1" B="1" A="1"/>
|
||||||
|
<Transparent>false</Transparent>
|
||||||
<Visible>true</Visible>
|
<Visible>true</Visible>
|
||||||
|
<DiffuseTexture>true</DiffuseTexture>
|
||||||
|
<NormalMap>true</NormalMap>
|
||||||
|
<SpecularMap>true</SpecularMap>
|
||||||
|
<GlowMap>true</GlowMap>
|
||||||
</Model>
|
</Model>
|
||||||
@@ -15,8 +15,23 @@
|
|||||||
<xs:element name="Color" type="t:Color" minOccurs="0">
|
<xs:element name="Color" type="t:Color" minOccurs="0">
|
||||||
<xs:annotation><xs:documentation>Color tint</xs:documentation></xs:annotation>
|
<xs:annotation><xs:documentation>Color tint</xs:documentation></xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="Transparent" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Wether the model is transparent or not</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
<xs:element name="Visible" type="t:bool" minOccurs="0">
|
<xs:element name="Visible" type="t:bool" minOccurs="0">
|
||||||
<xs:annotation><xs:documentation>Wether the model is visible or not</xs:documentation></xs:annotation>
|
<xs:annotation><xs:documentation>Whether the model is visible or not</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="DiffuseTexture" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Whether the model should use the Diffuse texture or not</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="NormalMap" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Whether the model should use the Normalmap or not</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="SpecularMap" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Whether the model should use the Specularmap or not</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="GlowMap" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Whether the model should use the Glowmap or not</xs:documentation></xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|||||||
@@ -2,18 +2,7 @@
|
|||||||
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
<xs:include schemaLocation="../Types/TeamEnum.xsd"/>
|
||||||
<xs:complexType name="TeamEnum" mixed="true">
|
|
||||||
<xs:complexContent>
|
|
||||||
<xs:extension base="t:enum">
|
|
||||||
<xs:choice>
|
|
||||||
<xs:element name="Spectator" type="xs:integer" fixed="1" minOccurs="0"/>
|
|
||||||
<xs:element name="Red" type="xs:integer" fixed="2" minOccurs="0"/>
|
|
||||||
<xs:element name="Blue" type="xs:integer" fixed="3" minOccurs="0"/>
|
|
||||||
</xs:choice>
|
|
||||||
</xs:extension>
|
|
||||||
</xs:complexContent>
|
|
||||||
</xs:complexType>
|
|
||||||
|
|
||||||
<xs:element name="Team">
|
<xs:element name="Team">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
<Children>
|
<Children>
|
||||||
<Entity>
|
<Entity name="Ground">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.mesh</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
@@ -18,69 +18,51 @@
|
|||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
|
||||||
<Components>
|
|
||||||
<c:Model>
|
|
||||||
<Resource>An error</Resource>
|
|
||||||
</c:Model>
|
|
||||||
<c:Transform>
|
|
||||||
<Position X="1" Y="1" Z="0"/>
|
|
||||||
<Orientation X="0" Y="0.785390019" Z="0"/>
|
|
||||||
</c:Transform>
|
|
||||||
</Components>
|
|
||||||
<Children>
|
|
||||||
<Entity>
|
|
||||||
<Components>
|
|
||||||
<c:Model>
|
|
||||||
<Resource>An error</Resource>
|
|
||||||
</c:Model>
|
|
||||||
<c:Transform>
|
|
||||||
<Position X="2" Y="0" Z="0"/>
|
|
||||||
<Orientation X="0" Y="0.785390019" Z="0"/>
|
|
||||||
</c:Transform>
|
|
||||||
</Components>
|
|
||||||
<Children/>
|
|
||||||
</Entity>
|
|
||||||
</Children>
|
|
||||||
</Entity>
|
|
||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Camera/>
|
<c:Camera/>
|
||||||
<c:Listener/>
|
<c:Listener/>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="1.36896265" Y="4.4259491" Z="10.6640663"/>
|
<Position X="1.36896265" Y="4.10503054" Z="10.6640663"/>
|
||||||
<Orientation X="-0.0349078141" Y="0.157154545" Z="-2.60252193e-07"/>
|
<Orientation X="-0.0349078141" Y="0.157154545" Z="-2.60252193e-07"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity name="DirectionalLight">
|
||||||
<Components>
|
<Components>
|
||||||
<c:DirectionalLight/>
|
<c:DirectionalLight>
|
||||||
|
<Intensity>0.80000001192092896</Intensity>
|
||||||
|
</c:DirectionalLight>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/DirectionalLightWidget.mesh</Resource>
|
<Resource>Models/DirectionalLightWidget.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>1.0499999523162842</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
|
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
|
||||||
<Orientation X="4.32000017" Y="4.6340003" Z="0"/>
|
<Orientation X="4.16300011" Y="1422.89319" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity name="AssaultTPose">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Assault.mesh</Resource>
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-2.00568962" Y="0.527161121" Z="0"/>
|
<Position X="-1.68900967" Y="0.527161121" Z="-1.59648728"/>
|
||||||
|
<Orientation X="0" Y="1.64900005" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
<Entity>
|
<Entity name="SecondaryWeapon">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/SecondaryWeapon.fbx</Resource>
|
<Resource>Models/SecondaryWeapon.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-0.546139359" Y="0.853016734" Z="0.177482292"/>
|
<Position X="-0.546139359" Y="0.853016734" Z="0.177482292"/>
|
||||||
@@ -91,17 +73,219 @@
|
|||||||
</Entity>
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity name="AnimationGroupOrigin">
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.11190474" Y="0.490183681" Z="0"/>
|
||||||
|
<Orientation X="0" Y="1.02100003" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="RunAnim">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<Name>Run</Name>
|
||||||
|
<Time>0.62051775215976157</Time>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
</c:Animation>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/AssaultAnimated.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.786919653" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Walkanim">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<Name>Walk</Name>
|
||||||
|
<Time>0.28779680073140668</Time>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
</c:Animation>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/AssaultAnimated.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="UnitSphere">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
|
<Color A="0.294117659" B="19.6078434" G="1.17647064" R="0.0392156877"/>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.754540265" Z="0"/>
|
||||||
|
<Scale X="0.800000012" Y="1.9000001" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Log">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
<Resource>Models/Log.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="3.70000029" Z="0"/>
|
<Position X="-4" Y="0.698000014" Z="-1"/>
|
||||||
|
<Orientation X="0" Y="2.74900007" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity name="SpheresOrigin">
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="6.80000019" Y="4.9000001" Z="-5.9000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="NormalSphere">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/NormalMapSphere.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.82700014" Y="0" Z="-0.166000009"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="SpecularSphere">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/SpecularMapSphere.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.06487739" Y="0" Z="1.52336037"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="Rotationpoint">
|
||||||
|
<Components>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
<Axis X="0.699999988" Y="1" Z="0.300000012"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Orientation X="404.200684" Y="577.428955" Z="173.228897"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="PointLight">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="3.92156863" R="3.92156863"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>3</Radius>
|
||||||
|
<Intensity>1.1399998664855957</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.600000024" Y="0.5" Z="0"/>
|
||||||
|
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="GlowMap">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/IncandescenceMapSphere.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.10000002" Y="0" Z="-1.80000007"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="CombinedSpheres">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/NormSpecIncdMapSphere.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="RotationPoint">
|
||||||
|
<Components>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
<Axis X="1" Y="1" Z="1"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Orientation X="53.9495354" Y="53.9495354" Z="53.9495354"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="PointLight">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="3.92156863" R="3.92156863"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>3</Radius>
|
||||||
|
<Intensity>1.1399998664855957</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.70000005" Y="0" Z="0"/>
|
||||||
|
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="PointLight">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="3.92156863" R="3.92156863"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>5.0100002288818359</Radius>
|
||||||
|
<Intensity>0.69999998807907104</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.900000036" Y="1.10000002" Z="0"/>
|
||||||
|
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="PointLight">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="3.92156863" R="3.92156863"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>4</Radius>
|
||||||
|
<Intensity>0.80000001192092896</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.400000006" Y="-1" Z="-1.50000012"/>
|
||||||
|
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
|
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -25,10 +25,16 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<Name>Crouch Walk</Name>
|
<Name>Run</Name>
|
||||||
<Time>701.10570384634161</Time>
|
<Time>0.56277947897317659</Time>
|
||||||
<Speed>32</Speed>
|
<Speed>1</Speed>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
|
<c:ExplosionEffect>
|
||||||
|
<Velocity X="0" Y="1.10000002" Z="3.30000019"/>
|
||||||
|
<ExplosionOrigin X="-0.600000024" Y="1" Z="0"/>
|
||||||
|
<TimeSinceDeath>0.95625903442123672</TimeSinceDeath>
|
||||||
|
<EndColor A="0" B="0.815686285" G="1" R="0"/>
|
||||||
|
</c:ExplosionEffect>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/AssaultAnimated.mesh</Resource>
|
<Resource>Models/AssaultAnimated.mesh</Resource>
|
||||||
<Color A="1" B="392156.875" G="1" R="1"/>
|
<Color A="1" B="392156.875" G="1" R="1"/>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
</Team>
|
</Team>
|
||||||
</c:Team>
|
</c:Team>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Orientation X="0" Y="2.24449515" Z="0"/>
|
<Position X="8.60201447e-23" Y="0" Z="3.9201616e-23"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
@@ -141,9 +141,10 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<Name>Hold Pos</Name>
|
<Name>Hold Pos</Name>
|
||||||
<Time>0.9779997896222552</Time>
|
<Time>0.73515426169631848</Time>
|
||||||
<Speed>1</Speed>
|
<Speed>1</Speed>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
|
<c:HiddenForLocalPlayer/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/AssaultAnimated.mesh</Resource>
|
<Resource>Models/AssaultAnimated.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0" R="1"/>
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="PointLight" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="3.92156863" R="3.92156863"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>3</Radius>
|
||||||
|
<Intensity>1.1399998664855957</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children/>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -18,6 +18,23 @@
|
|||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Camera>
|
<c:Camera>
|
||||||
</c:Camera>
|
</c:Camera>
|
||||||
|
<Orientation X="0.0" Y="0.0" Z="0"/>
|
||||||
|
<c:ExplosionEffect>
|
||||||
|
<ExplosionOrigin X="0" Y="0" Z="0"/>
|
||||||
|
<TimeSinceDeath>0</TimeSinceDeath>
|
||||||
|
<ExplosionDuration>2</ExplosionDuration>
|
||||||
|
<!--<Gravity>1</Gravity>-->
|
||||||
|
<!--<GravityForce>1</GravityForce>-->
|
||||||
|
<!--<ObjectRadius>2</ObjectRadius>-->
|
||||||
|
<EndColor R="0" G="0" B="0" A="0"/>
|
||||||
|
<Randomness>0</Randomness>
|
||||||
|
<RandomnessScalar>1</RandomnessScalar>
|
||||||
|
<Velocity X="2" Y="2"/>
|
||||||
|
<ColorByDistance>0</ColorByDistance>
|
||||||
|
<!--<ReverseAnimation>0</ReverseAnimation>-->
|
||||||
|
<!--<Wireframe>0</Wireframe>-->
|
||||||
|
<ExponentialAccelaration>0</ExponentialAccelaration>
|
||||||
|
</c:ExplosionEffect>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Camera.mesh</Resource>
|
<Resource>Models/Camera.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<xs:element ref="c:Model" minOccurs="0"/>
|
<xs:element ref="c:Model" minOccurs="0"/>
|
||||||
<xs:element ref="c:RaptorCopter" minOccurs="0"/>
|
<xs:element ref="c:RaptorCopter" minOccurs="0"/>
|
||||||
<xs:element ref="c:Player" minOccurs="0"/>
|
<xs:element ref="c:Player" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:ExplosionEffect" minOccurs="0"/>
|
||||||
<xs:element ref="c:Camera" minOccurs="0"/>
|
<xs:element ref="c:Camera" minOccurs="0"/>
|
||||||
<xs:element ref="c:Text" minOccurs="0"/>
|
<xs:element ref="c:Text" minOccurs="0"/>
|
||||||
<xs:element ref="c:AABB" minOccurs="0"/>
|
<xs:element ref="c:AABB" minOccurs="0"/>
|
||||||
@@ -33,6 +34,9 @@
|
|||||||
<xs:element ref="c:UniformScale" minOccurs="0"/>
|
<xs:element ref="c:UniformScale" minOccurs="0"/>
|
||||||
<xs:element ref="c:EditorWidget" minOccurs="0"/>
|
<xs:element ref="c:EditorWidget" minOccurs="0"/>
|
||||||
<xs:element ref="c:Lifetime" minOccurs="0"/>
|
<xs:element ref="c:Lifetime" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:HiddenForLocalPlayer" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:Fill" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:Animation" minOccurs="0"/>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
@@ -43,7 +47,7 @@
|
|||||||
<xs:element ref="Entity" minOccurs="0" maxOccurs="unbounded"/>
|
<xs:element ref="Entity" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
<xs:element name="EntityRef" minOccurs="0" maxOccurs="unbounded">
|
<xs:element name="EntityRef" minOccurs="0" maxOccurs="unbounded">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:attribute name="file" type="xs:string" minOccurs="0"/>
|
<xs:attribute name="file" type="xs:string"/>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
@@ -51,7 +55,7 @@
|
|||||||
</xs:element>
|
</xs:element>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
<xs:attribute ref="xml:base"/>
|
<xs:attribute ref="xml:base"/>
|
||||||
<xs:attribute name="name" type="xs:string" minOccurs="0" default=""/>
|
<xs:attribute name="name" type="xs:string" default=""/>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:complexType name="TeamEnum" mixed="true">
|
||||||
|
<xs:complexContent>
|
||||||
|
<xs:extension base="t:enum">
|
||||||
|
<xs:choice>
|
||||||
|
<xs:element name="Spectator" type="t:int" fixed="1" minOccurs="0"/>
|
||||||
|
<xs:element name="Red" type="t:int" fixed="2" minOccurs="0"/>
|
||||||
|
<xs:element name="Blue" type="t:int" fixed="3" minOccurs="0"/>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:extension>
|
||||||
|
</xs:complexContent>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
uniform mat4 M;
|
||||||
|
uniform mat4 V;
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform vec4 Color;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
|
||||||
|
in VertexData{
|
||||||
|
vec3 Position;
|
||||||
|
vec3 Normal;
|
||||||
|
vec2 TextureCoordinate;
|
||||||
|
vec4 DiffuseColor;
|
||||||
|
vec4 ExplosionColor;
|
||||||
|
}Input;
|
||||||
|
|
||||||
|
out vec4 fragmentColor;
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texel = texture2D(texture0, Input.TextureCoordinate);
|
||||||
|
fragmentColor = texel * Input.DiffuseColor * Color + Input.ExplosionColor;
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
uniform mat4 M;
|
||||||
|
uniform mat4 V;
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform vec3 ExplosionOrigin;
|
||||||
|
uniform float TimeSinceDeath;
|
||||||
|
uniform float ExplosionDuration;
|
||||||
|
uniform vec4 EndColor;
|
||||||
|
uniform bool Randomness;
|
||||||
|
uniform float RandomNumbers[50];
|
||||||
|
uniform float RandomnessScalar;
|
||||||
|
uniform vec2 Velocity;
|
||||||
|
uniform bool ColorByDistance;
|
||||||
|
uniform bool ExponentialAccelaration;
|
||||||
|
|
||||||
|
in VertexData{
|
||||||
|
vec3 Position;
|
||||||
|
vec3 Normal;
|
||||||
|
vec2 TextureCoordinate;
|
||||||
|
vec4 ExplosionColor;
|
||||||
|
}Input[];
|
||||||
|
|
||||||
|
out VertexData{
|
||||||
|
vec3 Position;
|
||||||
|
vec3 Normal;
|
||||||
|
vec2 TextureCoordinate;
|
||||||
|
vec4 ExplosionColor;
|
||||||
|
}Output;
|
||||||
|
|
||||||
|
layout(triangles) in;
|
||||||
|
layout(triangle_strip, max_vertices = 3) out;
|
||||||
|
|
||||||
|
// returns a "random" number based on input parameter
|
||||||
|
float GetRandomNumber(int polygon_index)
|
||||||
|
{
|
||||||
|
int randomIndex = int(mod(polygon_index, 50));
|
||||||
|
|
||||||
|
return RandomNumbers[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
float randomNumber = 0.0;
|
||||||
|
float randomDistance = 0.0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// calculate middle of vectors
|
||||||
|
vec3 v1 = Input[1].Position - Input[0].Position;
|
||||||
|
vec3 v2 = Input[2].Position - Input[0].Position;
|
||||||
|
vec3 v3 = Input[2].Position - (v1 / 2);
|
||||||
|
vec3 v4 = Input[1].Position - (v2 / 2);
|
||||||
|
|
||||||
|
// calculate intersection
|
||||||
|
|
||||||
|
// normalize direction
|
||||||
|
vec3 dir1 = normalize(v1);
|
||||||
|
vec3 dir2 = normalize(v2);
|
||||||
|
|
||||||
|
vec3 vecA = Input[2].Position - Input[1].Position; //o2 - o1
|
||||||
|
vec3 vecB = cross(dir1, dir2);
|
||||||
|
|
||||||
|
mat3 matrisA = mat3(vecA, dir2, vecB);
|
||||||
|
|
||||||
|
float lengthA = length(vecB);
|
||||||
|
lengthA = lengthA * lengthA;
|
||||||
|
|
||||||
|
float s = determinant(matrisA) / lengthA;
|
||||||
|
|
||||||
|
// center position of triangle
|
||||||
|
vec3 centerOfTriangle = Input[1].Position + (s * dir1);
|
||||||
|
|
||||||
|
// center position of triangle to origin vector
|
||||||
|
vec3 origin2TriangleCenterVector = centerOfTriangle - ExplosionOrigin;
|
||||||
|
vec3 normalizedOrigin2TriangleCenterVector = normalize(origin2TriangleCenterVector);
|
||||||
|
|
||||||
|
// time percentage until end of explosion (0.0-1.0)
|
||||||
|
float timePercetage = TimeSinceDeath / ExplosionDuration;
|
||||||
|
|
||||||
|
// get a random number if randomness is enabled, otherwise the random number will be zero and won't affect the other algorithms
|
||||||
|
if (Randomness == true)
|
||||||
|
{
|
||||||
|
randomDistance = GetRandomNumber(gl_PrimitiveIDIn) * RandomnessScalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 randomVelocity = Velocity * (randomDistance + 1.0);
|
||||||
|
|
||||||
|
// accelaration to use on current frame. is a interpolation between start and end value
|
||||||
|
float currentVelocity = mix(randomVelocity.x, randomVelocity.y, timePercetage);
|
||||||
|
|
||||||
|
if (ExponentialAccelaration == true)
|
||||||
|
{
|
||||||
|
currentVelocity = pow(currentVelocity, 2) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// distance between origin and the center of the current triangle
|
||||||
|
float origin2TriangleCenterDistance = length(origin2TriangleCenterVector);
|
||||||
|
|
||||||
|
// the distance from origin to the triangle center with eventual randomness added
|
||||||
|
float fullDistanceWithRandomness = origin2TriangleCenterDistance + randomDistance;
|
||||||
|
|
||||||
|
// vector from the triangle center to the explosion's shockwave
|
||||||
|
vec3 triangleCenter2ExplosionRadius = (normalizedOrigin2TriangleCenterVector * (TimeSinceDeath * currentVelocity)) - (normalizedOrigin2TriangleCenterVector * fullDistanceWithRandomness);
|
||||||
|
|
||||||
|
// if the triangle is inside the blast radius...
|
||||||
|
if (fullDistanceWithRandomness <= (TimeSinceDeath * currentVelocity))
|
||||||
|
{
|
||||||
|
float maxRadius = max(TimeSinceDeath * currentVelocity, (ExplosionDuration * currentVelocity));
|
||||||
|
|
||||||
|
float a = (randomVelocity.y - randomVelocity.x) / ExplosionDuration;
|
||||||
|
//float t = sqrt((2 * origin2TriangleCenterDistance) / a);
|
||||||
|
|
||||||
|
// if explosion color should be affected by distance instead of time...
|
||||||
|
if (ColorByDistance == true)
|
||||||
|
{
|
||||||
|
// calculate the max distance (s) the triangle will move
|
||||||
|
float s = (randomVelocity.x * ExplosionDuration) + (0.5 * a * pow(ExplosionDuration, 2));
|
||||||
|
|
||||||
|
Output.ExplosionColor = EndColor * (length(triangleCenter2ExplosionRadius) / s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Output.ExplosionColor = EndColor * timePercetage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for every vertex on the triangle...
|
||||||
|
for (int i = 0; i < gl_in.length(); i++)
|
||||||
|
{
|
||||||
|
// move the triangle to the blast radius
|
||||||
|
vec3 ExplodedPosition = Input[i].Position + triangleCenter2ExplosionRadius;
|
||||||
|
|
||||||
|
// pass through vertex data
|
||||||
|
Output.Normal = Input[i].Normal;
|
||||||
|
Output.Position = Input[i].Position;
|
||||||
|
Output.TextureCoordinate = Input[i].TextureCoordinate;
|
||||||
|
|
||||||
|
// convert to model space for the gravity to always be in -y
|
||||||
|
vec4 ExplodedPositionInModelSpace = M * vec4(ExplodedPosition, 1.0);
|
||||||
|
|
||||||
|
// if there is gravity, apply it
|
||||||
|
//if (Gravity == true)
|
||||||
|
//{
|
||||||
|
// // ---DO THIS----> //ExplodedPositionInModelSpace.y = ExplodedPositionInModelSpace.y - TimeSinceHit;
|
||||||
|
//
|
||||||
|
// ExplodedPositionInModelSpace.y = ExplodedPositionInModelSpace.y - pow(TimeSinceDeath, 2);
|
||||||
|
//}
|
||||||
|
|
||||||
|
// convert to screen space
|
||||||
|
gl_Position = P*V * ExplodedPositionInModelSpace;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if explosion color should be affected by distance instead of time...
|
||||||
|
if (ColorByDistance == true)
|
||||||
|
{
|
||||||
|
Output.ExplosionColor = vec4(0.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Output.ExplosionColor = EndColor * timePercetage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for every vertex on the triangle...
|
||||||
|
for(int i = 0; i < gl_in.length(); i++)
|
||||||
|
{
|
||||||
|
// pass through vertex data
|
||||||
|
Output.Normal = Input[i].Normal;
|
||||||
|
Output.Position = Input[i].Position;
|
||||||
|
Output.TextureCoordinate = Input[i].TextureCoordinate;
|
||||||
|
|
||||||
|
// no change in position, pass through vertex
|
||||||
|
gl_Position = gl_in[i].gl_Position;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//EndPrimitive();
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
uniform mat4 M;
|
||||||
|
uniform mat4 V;
|
||||||
|
uniform mat4 P;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 Position;
|
||||||
|
layout(location = 1) in vec3 Normal;
|
||||||
|
layout(location = 2) in vec3 Tangent;
|
||||||
|
layout(location = 3) in vec3 BiTangent;
|
||||||
|
layout(location = 4) in vec2 TextureCoords;
|
||||||
|
layout(location = 5) in vec4 DiffuseVertexColor;
|
||||||
|
layout(location = 6) in vec4 SpecularVertexColor;
|
||||||
|
layout(location = 7) in vec4 BoneIndices1;
|
||||||
|
layout(location = 8) in vec4 BoneIndices2;
|
||||||
|
layout(location = 9) in vec4 BoneWeights1;
|
||||||
|
layout(location = 10) in vec4 BoneWeights2;
|
||||||
|
|
||||||
|
out VertexData{
|
||||||
|
vec3 Position;
|
||||||
|
vec3 Normal;
|
||||||
|
vec2 TextureCoordinate;
|
||||||
|
vec4 DiffuseColor;
|
||||||
|
vec4 ExplosionColor;
|
||||||
|
}Output;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = P*V*M * vec4(Position, 1.0);
|
||||||
|
|
||||||
|
Output.Position = Position;
|
||||||
|
Output.TextureCoordinate = TextureCoords;
|
||||||
|
Output.Normal = Normal;
|
||||||
|
Output.DiffuseColor = DiffuseVertexColor;
|
||||||
|
Output.ExplosionColor = vec4(0.0);
|
||||||
|
}
|
||||||
@@ -9,7 +9,9 @@ uniform vec2 ScreenDimensions;
|
|||||||
uniform vec4 FillColor;
|
uniform vec4 FillColor;
|
||||||
uniform float FillPercentage;
|
uniform float FillPercentage;
|
||||||
layout (binding = 0) uniform sampler2D DiffuseTexture;
|
layout (binding = 0) uniform sampler2D DiffuseTexture;
|
||||||
layout (binding = 1) uniform sampler2D GlowMap;
|
layout (binding = 1) uniform sampler2D NormalMapTexture;
|
||||||
|
layout (binding = 2) uniform sampler2D SpecularMapTexture;
|
||||||
|
layout (binding = 3) uniform sampler2D GlowMapTexture;
|
||||||
|
|
||||||
|
|
||||||
#define TILE_SIZE 16
|
#define TILE_SIZE 16
|
||||||
@@ -49,7 +51,10 @@ layout (std430, binding = 4) buffer LightIndexBuffer
|
|||||||
in VertexData{
|
in VertexData{
|
||||||
vec3 Position;
|
vec3 Position;
|
||||||
vec3 Normal;
|
vec3 Normal;
|
||||||
|
vec3 Tangent;
|
||||||
|
vec3 BiTangent;
|
||||||
vec2 TextureCoordinate;
|
vec2 TextureCoordinate;
|
||||||
|
vec4 ExplosionColor;
|
||||||
}Input;
|
}Input;
|
||||||
|
|
||||||
out vec4 sceneColor;
|
out vec4 sceneColor;
|
||||||
@@ -101,13 +106,21 @@ LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensi
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textureCoordinate, sampler2D normalMap)
|
||||||
|
{
|
||||||
|
mat3 TBN = mat3(tangent, bitangent, normal);
|
||||||
|
vec3 NormalMap = texture(normalMap, textureCoordinate).xyz * 2.0 - vec3(1.0);
|
||||||
|
return vec4(TBN * normalize(NormalMap), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate);
|
vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate);
|
||||||
vec4 glowTexel = texture2D(GlowMap, Input.TextureCoordinate);
|
vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate);
|
||||||
|
vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate);
|
||||||
vec4 position = V * M * vec4(Input.Position, 1.0);
|
vec4 position = V * M * vec4(Input.Position, 1.0);
|
||||||
vec4 normal = normalize(V * vec4(Input.Normal, 0.0));
|
vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, NormalMapTexture);
|
||||||
|
//vec4 normal = normalize(V * vec4(Input.Normal, 0.0));
|
||||||
vec4 viewVec = normalize(-position);
|
vec4 viewVec = normalize(-position);
|
||||||
|
|
||||||
vec2 tilePos;
|
vec2 tilePos;
|
||||||
@@ -137,8 +150,8 @@ void main()
|
|||||||
totalLighting.Specular += light_result.Specular;
|
totalLighting.Specular += light_result.Specular;
|
||||||
}
|
}
|
||||||
|
|
||||||
//sceneColor += Input.DiffuseColor;
|
|
||||||
vec4 color_result = DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color;
|
vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color;
|
||||||
|
|
||||||
|
|
||||||
float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0;
|
float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0;
|
||||||
@@ -146,27 +159,10 @@ void main()
|
|||||||
if(pos <= FillPercentage) {
|
if(pos <= FillPercentage) {
|
||||||
color_result += FillColor;
|
color_result += FillColor;
|
||||||
}
|
}
|
||||||
//bloomColor = vec4(0.3, 0.8, 0.6, 1.0);
|
|
||||||
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
|
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
|
||||||
//These if statements should be removed if they are slow.
|
|
||||||
color_result += glowTexel;
|
color_result += glowTexel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0);
|
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0);
|
||||||
/*
|
|
||||||
if(color_result.x > 1 || color_result.y > 1 || color_result.z > 1) {
|
|
||||||
bloomColor = vec4(color_result.xyz, 1.0);
|
|
||||||
} else {
|
|
||||||
bloomColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
||||||
} */
|
|
||||||
|
|
||||||
//sceneColor += Input.DiffuseColor * (totalLighting.Diffuse) * diffuseTexel * Color;
|
|
||||||
//sceneColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Tiled Debug Code
|
//Tiled Debug Code
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ layout(location = 6) in vec4 BoneWeights;
|
|||||||
out VertexData{
|
out VertexData{
|
||||||
vec3 Position;
|
vec3 Position;
|
||||||
vec3 Normal;
|
vec3 Normal;
|
||||||
|
vec3 Tangent;
|
||||||
|
vec3 BiTangent;
|
||||||
vec2 TextureCoordinate;
|
vec2 TextureCoordinate;
|
||||||
|
vec4 ExplosionColor;
|
||||||
}Output;
|
}Output;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
@@ -36,4 +39,7 @@ void main()
|
|||||||
Output.Position = (boneTransform * vec4(Position, 1.0)).xyz;
|
Output.Position = (boneTransform * vec4(Position, 1.0)).xyz;
|
||||||
Output.TextureCoordinate = TextureCoords;
|
Output.TextureCoordinate = TextureCoords;
|
||||||
Output.Normal = vec3(M * vec4(Normal, 0.0));
|
Output.Normal = vec3(M * vec4(Normal, 0.0));
|
||||||
|
Output.Tangent = vec3(M * vec4(Tangent, 0.0));
|
||||||
|
Output.BiTangent = vec3(M * vec4(BiTangent, 0.0));
|
||||||
|
Output.ExplosionColor = vec4(0.0);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#version 430
|
#version 430
|
||||||
|
#extension GL_EXT_gpu_shader4 : enable
|
||||||
|
|
||||||
layout (binding = 0) uniform sampler2D Texture;
|
layout (binding = 0) uniform sampler2D Texture;
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ uniform float weight[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.01
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec2 tex_offset = 1.0 / textureSize(Texture, 0);
|
vec2 tex_offset = 1.0 / textureSize2D(Texture, 0);
|
||||||
vec3 result = texture(Texture, Input.TextureCoordinate).rgb * weight[0];
|
vec3 result = texture(Texture, Input.TextureCoordinate).rgb * weight[0];
|
||||||
|
|
||||||
for(int i = 1; i < 5; ++i) {
|
for(int i = 1; i < 5; ++i) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#version 430
|
#version 430
|
||||||
|
#extension GL_EXT_gpu_shader4 : enable
|
||||||
|
|
||||||
layout (binding = 0) uniform sampler2D Texture;
|
layout (binding = 0) uniform sampler2D Texture;
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ uniform float weight[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.01
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec2 tex_offset = 1.0 / textureSize(Texture, 0);
|
vec2 tex_offset = 1.0 / textureSize2D(Texture, 0);
|
||||||
vec3 result = texture(Texture, Input.TextureCoordinate).rgb * weight[0];
|
vec3 result = texture(Texture, Input.TextureCoordinate).rgb * weight[0];
|
||||||
|
|
||||||
for(int i = 1; i < 5; ++i) {
|
for(int i = 1; i < 5; ++i) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ void CollidableOctreeSystem::Update(double dt)
|
|||||||
void CollidableOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
void CollidableOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||||
{
|
{
|
||||||
if (entity.HasComponent("AABB")) {
|
if (entity.HasComponent("AABB")) {
|
||||||
boost::optional<AABB> absoluteAABB = Collision::EntityAbsoluteAABB(entity);
|
boost::optional<EntityAABB> absoluteAABB = Collision::EntityAbsoluteAABB(entity);
|
||||||
if (absoluteAABB) {
|
if (absoluteAABB) {
|
||||||
m_Octree->AddDynamicObject(*absoluteAABB);
|
m_Octree->AddDynamicObject(*absoluteAABB);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,20 +239,6 @@ bool AABBvsTriangles(const AABB& box, const std::vector<RawModel::Vertex>& model
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon)
|
|
||||||
{
|
|
||||||
const glm::vec3& ma1 = first.MaxCorner();
|
|
||||||
const glm::vec3& ma2 = second.MaxCorner();
|
|
||||||
const glm::vec3& mi1 = first.MinCorner();
|
|
||||||
const glm::vec3& mi2 = second.MinCorner();
|
|
||||||
return (std::abs(ma1.x - ma2.x) < epsilon) &&
|
|
||||||
(std::abs(mi1.x - mi2.x) < epsilon) &&
|
|
||||||
(std::abs(ma1.z - ma2.z) < epsilon) &&
|
|
||||||
(std::abs(mi1.z - mi2.z) < epsilon) &&
|
|
||||||
(std::abs(ma1.y - ma2.y) < epsilon) &&
|
|
||||||
(std::abs(mi1.y - mi2.y) < epsilon);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool attachAABBComponentFromModel(World* world, EntityID id)
|
bool attachAABBComponentFromModel(World* world, EntityID id)
|
||||||
{
|
{
|
||||||
if (!world->HasComponent(id, "Model")) {
|
if (!world->HasComponent(id, "Model")) {
|
||||||
@@ -283,7 +269,7 @@ bool attachAABBComponentFromModel(World* world, EntityID id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<AABB> EntityAbsoluteAABB(EntityWrapper& entity)
|
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity)
|
||||||
{
|
{
|
||||||
if (!entity.HasComponent("AABB")) {
|
if (!entity.HasComponent("AABB")) {
|
||||||
return boost::none;
|
return boost::none;
|
||||||
@@ -294,7 +280,11 @@ boost::optional<AABB> EntityAbsoluteAABB(EntityWrapper& entity)
|
|||||||
glm::vec3 absScale = Transform::AbsoluteScale(entity.World, entity.ID);
|
glm::vec3 absScale = Transform::AbsoluteScale(entity.World, entity.ID);
|
||||||
glm::vec3 origin = absPosition + (glm::vec3)cAABB["Origin"];
|
glm::vec3 origin = absPosition + (glm::vec3)cAABB["Origin"];
|
||||||
glm::vec3 size = (glm::vec3)cAABB["Size"] * absScale;
|
glm::vec3 size = (glm::vec3)cAABB["Size"] * absScale;
|
||||||
return AABB::FromOriginSize(origin, size);
|
|
||||||
|
EntityAABB aabb = EntityAABB::FromOriginSize(origin, size);
|
||||||
|
aabb.Entity = entity;
|
||||||
|
|
||||||
|
return aabb;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,29 +9,27 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
|||||||
}
|
}
|
||||||
ComponentWrapper& cPhysics = entity["Physics"];
|
ComponentWrapper& cPhysics = entity["Physics"];
|
||||||
|
|
||||||
boost::optional<AABB> boundingBox = Collision::EntityAbsoluteAABB(entity);
|
boost::optional<EntityAABB> boundingBox = Collision::EntityAbsoluteAABB(entity);
|
||||||
if (!boundingBox) {
|
if (!boundingBox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ComponentWrapper& cTransform = entity["Transform"];
|
ComponentWrapper& cTransform = entity["Transform"];
|
||||||
AABB& boxA = *boundingBox;
|
EntityAABB& boxA = *boundingBox;
|
||||||
|
|
||||||
//Press 'Z' to enable/disable collision.
|
// Collide against octree items
|
||||||
if (zPress) {
|
m_OctreeResult.clear();
|
||||||
return;
|
m_Octree->ObjectsInSameRegion(*boundingBox, m_OctreeResult);
|
||||||
}
|
for (auto& boxB : m_OctreeResult) {
|
||||||
|
|
||||||
// Collide against octree
|
|
||||||
std::vector<AABB> octreeResult;
|
|
||||||
m_Octree->ObjectsInSameRegion(*boundingBox, octreeResult);
|
|
||||||
for (auto& boxB : octreeResult) {
|
|
||||||
glm::vec3 resolutionVector;
|
glm::vec3 resolutionVector;
|
||||||
if (Collision::IsSameBoxProbably(boxA, boxB)) {
|
if (boxA.Entity == boxB.Entity) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
|
if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
|
||||||
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
||||||
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
|
if (resolutionVector.y > 0) {
|
||||||
|
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,12 +54,4 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
|||||||
// (glm::vec3&)cTransform["Position"] += resolutionVector;
|
// (glm::vec3&)cTransform["Position"] += resolutionVector;
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CollisionSystem::OnKeyUp(const Events::KeyUp & event)
|
|
||||||
{
|
|
||||||
if (event.KeyCode == GLFW_KEY_Z) {
|
|
||||||
zPress = !zPress;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -3,79 +3,72 @@
|
|||||||
#include "Core/AABB.h"
|
#include "Core/AABB.h"
|
||||||
#include "Rendering/Model.h"
|
#include "Rendering/Model.h"
|
||||||
|
|
||||||
void TriggerSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapper& cTrigger, double dt)
|
||||||
{
|
{
|
||||||
//Currently only players can trigger things.
|
// The trigger *should* have a bounding box, or something, to test against so it can be triggered.
|
||||||
auto players = m_World->GetComponents("Player");
|
boost::optional<EntityAABB> triggerBox = Collision::EntityAbsoluteAABB(triggerEntity);
|
||||||
if (players == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
EntityID tId = component.EntityID;
|
|
||||||
boost::optional<AABB> triggerBox = Collision::EntityAbsoluteAABB(entity);
|
|
||||||
//The trigger *should* have a bounding box, or something, to test against so it can be triggered.
|
|
||||||
if (!triggerBox) {
|
if (!triggerBox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto& pc : *players) {
|
|
||||||
EntityID pId = pc.EntityID;
|
m_OctreeOut.clear();
|
||||||
boost::optional<AABB> playerBox = Collision::EntityAbsoluteAABB(EntityWrapper(m_World, pId));
|
m_Octree->ObjectsInSameRegion(*triggerBox, m_OctreeOut);
|
||||||
//The player can't trigger anything without an AABB.
|
|
||||||
if (!playerBox) {
|
for (EntityAABB& colliderBox : m_OctreeOut) {
|
||||||
continue;
|
EntityWrapper colliderEntity = colliderBox.Entity;
|
||||||
}
|
|
||||||
if (!Collision::AABBVsAABB(*triggerBox, *playerBox)) {
|
if (Collision::AABBVsAABB(*triggerBox, colliderBox)) {
|
||||||
//Entity is not touching the trigger,
|
|
||||||
//Throw event if it was previously.
|
|
||||||
if (throwLeaveIfWasInTrigger(m_EntitiesTouchingTrigger[tId], pId, tId)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//This only occurs if the entity was completely inside the trigger one frame,
|
|
||||||
//then completely outside the trigger, e.g. when dying and respawning.
|
|
||||||
throwLeaveIfWasInTrigger(m_EntitiesCompletelyInTrigger[tId], pId, tId);
|
|
||||||
} else {
|
|
||||||
//Entity is at least touching the trigger.
|
|
||||||
AABB completelyInsideBox;
|
AABB completelyInsideBox;
|
||||||
bool playerFitsInTrigger = glm::all(glm::greaterThan((*triggerBox).Size(), (*playerBox).Size()));
|
bool colliderFitsInTrigger = glm::all(glm::greaterThan((*triggerBox).Size(), colliderBox.Size()));
|
||||||
if (playerFitsInTrigger) {
|
if (colliderFitsInTrigger) {
|
||||||
completelyInsideBox = AABB::FromOriginSize((*triggerBox).Origin(), (*triggerBox).Size() - 2.0f * (*playerBox).Size());
|
completelyInsideBox = AABB::FromOriginSize((*triggerBox).Origin(), (*triggerBox).Size() - 2.0f * colliderBox.Size());
|
||||||
}
|
}
|
||||||
if (playerFitsInTrigger && Collision::AABBVsAABB(completelyInsideBox, *playerBox)) {
|
if (colliderFitsInTrigger && Collision::AABBVsAABB(completelyInsideBox, colliderBox)) {
|
||||||
//Entity is completely inside the trigger.
|
// Entity is completely inside the trigger.
|
||||||
//If it was only touching before, it is erased.
|
// If it was only touching before, it is erased.
|
||||||
m_EntitiesTouchingTrigger[tId].erase(pId);
|
m_EntitiesTouchingTrigger[triggerEntity].erase(colliderEntity);
|
||||||
std::unordered_set<EntityID>& completeSet = m_EntitiesCompletelyInTrigger[tId];
|
auto& completeSet = m_EntitiesCompletelyInTrigger[triggerEntity];
|
||||||
if (completeSet.count(pId) == 0) {
|
if (completeSet.count(colliderEntity) == 0) {
|
||||||
//If it wasn't completely in the trigger, throw Enter and add to the set.
|
// If it wasn't completely in the trigger, throw Enter and add to the set.
|
||||||
completeSet.insert(pId);
|
completeSet.insert(colliderEntity);
|
||||||
publish<Events::TriggerEnter>(pId, tId);
|
publish<Events::TriggerEnter>(colliderEntity, triggerEntity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Entity is only touching the trigger.
|
// Entity is only touching the trigger.
|
||||||
std::unordered_set<EntityID>& touchSet = m_EntitiesTouchingTrigger[tId];
|
auto& touchSet = m_EntitiesTouchingTrigger[triggerEntity];
|
||||||
std::unordered_set<EntityID>& completeSet = m_EntitiesCompletelyInTrigger[tId];
|
auto& completeSet = m_EntitiesCompletelyInTrigger[triggerEntity];
|
||||||
const auto& it = completeSet.find(pId);
|
const auto& it = completeSet.find(colliderEntity);
|
||||||
//If it was completely inside before.
|
//If it was completely inside before.
|
||||||
if (it != completeSet.end()) {
|
if (it != completeSet.end()) {
|
||||||
completeSet.erase(it);
|
completeSet.erase(it);
|
||||||
touchSet.insert(pId);
|
touchSet.insert(colliderEntity);
|
||||||
//If it was completely outside before.
|
//If it was completely outside before.
|
||||||
} else if (touchSet.count(pId) == 0) {
|
} else if (touchSet.count(colliderEntity) == 0) {
|
||||||
publish<Events::TriggerTouch>(pId, tId);
|
publish<Events::TriggerTouch>(colliderEntity, triggerEntity);
|
||||||
touchSet.insert(pId);
|
touchSet.insert(colliderEntity);
|
||||||
}
|
}
|
||||||
//Else, it was touching the trigger last frame too and nothing is done.
|
// Else, it was touching the trigger last frame too and nothing is done.
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Entity is not touching the trigger,
|
||||||
|
// Throw event if it was previously.
|
||||||
|
if (throwLeaveIfWasInTrigger(m_EntitiesTouchingTrigger[triggerEntity], colliderEntity, triggerEntity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// This only occurs if the entity was completely inside the trigger one frame,
|
||||||
|
// then completely outside the trigger, e.g. when dying and respawning.
|
||||||
|
throwLeaveIfWasInTrigger(m_EntitiesCompletelyInTrigger[triggerEntity], colliderEntity, triggerEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TriggerSystem::throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& triggerSet, EntityID pId, EntityID tId)
|
bool TriggerSystem::throwLeaveIfWasInTrigger(std::unordered_set<EntityWrapper>& triggerSet, EntityWrapper colliderEntity, EntityWrapper triggerEntity)
|
||||||
{
|
{
|
||||||
const auto& it = triggerSet.find(pId);
|
const auto& it = triggerSet.find(colliderEntity);
|
||||||
if (it != triggerSet.end()) {
|
if (it != triggerSet.end()) {
|
||||||
//If it was in the trigger, but not anymore, throw leaveEvent and erase from the set.
|
//If it was in the trigger, but not anymore, throw leaveEvent and erase from the set.
|
||||||
triggerSet.erase(it);
|
triggerSet.erase(it);
|
||||||
publish<Events::TriggerLeave>(pId, tId);
|
publish<Events::TriggerLeave>(colliderEntity, triggerEntity);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -20,10 +20,6 @@ AABB::AABB(const glm::vec3& minPos, const glm::vec3& maxPos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AABB::AABB(const glm::vec4& minPos, const glm::vec4& maxPos)
|
|
||||||
: AABB(glm::vec3(minPos), glm::vec3(maxPos))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
AABB AABB::FromOriginSize(const glm::vec3& origin, const glm::vec3& size)
|
AABB AABB::FromOriginSize(const glm::vec3& origin, const glm::vec3& size)
|
||||||
{
|
{
|
||||||
return AABB(origin - (size/2.f), origin + (size/2.f));
|
return AABB(origin - (size/2.f), origin + (size/2.f));
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void EntityFile::Parse(const EntityFileHandler* handler) const
|
|||||||
{
|
{
|
||||||
using namespace xercesc;
|
using namespace xercesc;
|
||||||
|
|
||||||
EntityFileSAXHandler saxHandler(handler, nullptr);
|
EntityFileSAXHandler saxHandler(handler, m_SAX2XMLReader);
|
||||||
setReaderFeatures(m_SAX2XMLReader);
|
setReaderFeatures(m_SAX2XMLReader);
|
||||||
m_SAX2XMLReader->setContentHandler(&saxHandler);
|
m_SAX2XMLReader->setContentHandler(&saxHandler);
|
||||||
m_SAX2XMLReader->setErrorHandler(&saxHandler);
|
m_SAX2XMLReader->setErrorHandler(&saxHandler);
|
||||||
@@ -37,11 +37,12 @@ void EntityFile::setReaderFeatures(xercesc::SAX2XMLReader* reader)
|
|||||||
reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
|
reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
|
||||||
reader->setFeature(XMLUni::fgXercesSchema, true);
|
reader->setFeature(XMLUni::fgXercesSchema, true);
|
||||||
reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
|
reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
|
||||||
|
reader->setFeature(XMLUni::fgXercesCalculateSrcOfs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t EntityFile::GetTypeStride(std::string typeName)
|
unsigned int EntityFile::GetTypeStride(std::string typeName)
|
||||||
{
|
{
|
||||||
std::map<std::string, size_t> typeStrides{
|
std::map<std::string, unsigned int> typeStrides{
|
||||||
{ "bool", sizeof(bool) },
|
{ "bool", sizeof(bool) },
|
||||||
{ "int", sizeof(int) },
|
{ "int", sizeof(int) },
|
||||||
{ "float", sizeof(float) },
|
{ "float", sizeof(float) },
|
||||||
@@ -111,8 +112,9 @@ void EntityFile::WriteValueData(char* outData, const ComponentInfo::Field_t& fie
|
|||||||
} catch (const boost::bad_lexical_cast&) { }
|
} catch (const boost::bad_lexical_cast&) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityFileSAXHandler::EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader) : m_Handler(handler)
|
EntityFileSAXHandler::EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader)
|
||||||
, m_Reader(reader)
|
: m_Handler(handler)
|
||||||
|
, m_Reader(reader)
|
||||||
{
|
{
|
||||||
// 0 is imaginary base parent
|
// 0 is imaginary base parent
|
||||||
m_EntityStack.push(0);
|
m_EntityStack.push(0);
|
||||||
@@ -188,21 +190,29 @@ void EntityFileSAXHandler::characters(const XMLCh* const chars, const XMLSize_t
|
|||||||
|
|
||||||
void EntityFileSAXHandler::fatalError(const xercesc::SAXParseException& e)
|
void EntityFileSAXHandler::fatalError(const xercesc::SAXParseException& e)
|
||||||
{
|
{
|
||||||
XS::ToString s(e.getMessage());
|
std::string message = XS::ToString(e.getMessage());
|
||||||
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
|
std::string systemId = XS::ToString(e.getSystemId());
|
||||||
//throw e;
|
XMLFileLoc line = e.getLineNumber();
|
||||||
|
XMLFileLoc column = e.getColumnNumber();
|
||||||
|
LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tFatal Error: %s", systemId.c_str(), line, column, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityFileSAXHandler::error(const xercesc::SAXParseException& e)
|
void EntityFileSAXHandler::error(const xercesc::SAXParseException& e)
|
||||||
{
|
{
|
||||||
XS::ToString s(e.getMessage());
|
std::string message = XS::ToString(e.getMessage());
|
||||||
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
|
std::string systemId = XS::ToString(e.getSystemId());
|
||||||
|
XMLFileLoc line = e.getLineNumber();
|
||||||
|
XMLFileLoc column = e.getColumnNumber();
|
||||||
|
LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tError: %s", systemId.c_str(), line, column, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityFileSAXHandler::warning(const xercesc::SAXParseException& e)
|
void EntityFileSAXHandler::warning(const xercesc::SAXParseException& e)
|
||||||
{
|
{
|
||||||
XS::ToString s(e.getMessage());
|
std::string message = XS::ToString(e.getMessage());
|
||||||
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
|
std::string systemId = XS::ToString(e.getSystemId());
|
||||||
|
XMLFileLoc line = e.getLineNumber();
|
||||||
|
XMLFileLoc column = e.getColumnNumber();
|
||||||
|
LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tWarning: %s", systemId.c_str(), line, column, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityFileSAXHandler::onStartEntity(const xercesc::Attributes& attrs)
|
void EntityFileSAXHandler::onStartEntity(const xercesc::Attributes& attrs)
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ void EntityFilePreprocessor::parseComponentInfo()
|
|||||||
|
|
||||||
// Name
|
// Name
|
||||||
compInfo.Name = XS::ToString(element->getName());
|
compInfo.Name = XS::ToString(element->getName());
|
||||||
|
bool brk = compInfo.Name == "HiddenForLocalPlayer";
|
||||||
// Known allocation
|
// Known allocation
|
||||||
compInfo.Meta->Allocation = m_ComponentCounts[compInfo.Name];
|
compInfo.Meta->Allocation = m_ComponentCounts[compInfo.Name];
|
||||||
// Annotation
|
// Annotation
|
||||||
@@ -90,7 +91,7 @@ void EntityFilePreprocessor::parseComponentInfo()
|
|||||||
// <xs:all>
|
// <xs:all>
|
||||||
auto modelGroupParticle = complexTypeDefinition->getParticle();
|
auto modelGroupParticle = complexTypeDefinition->getParticle();
|
||||||
if (modelGroupParticle == nullptr || modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) {
|
if (modelGroupParticle == nullptr || modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) {
|
||||||
//LOG_ERROR("Failed to parse component definition for \"%s\": Model group particle was null or wasn't TERM_MODELGROUP!", compInfo.Name.c_str());
|
LOG_ERROR("Failed to parse component definition for \"%s\": Model group particle was null or wasn't TERM_MODELGROUP!", compInfo.Name.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto modelGroup = modelGroupParticle->getModelGroupTerm();
|
auto modelGroup = modelGroupParticle->getModelGroupTerm();
|
||||||
@@ -113,7 +114,7 @@ void EntityFilePreprocessor::parseComponentInfo()
|
|||||||
std::string baseType = XS::ToString(elementDeclaration->getTypeDefinition()->getBaseType()->getName());
|
std::string baseType = XS::ToString(elementDeclaration->getTypeDefinition()->getBaseType()->getName());
|
||||||
|
|
||||||
std::string effectiveType = type;
|
std::string effectiveType = type;
|
||||||
size_t stride = EntityFile::GetTypeStride(type);
|
unsigned int stride = EntityFile::GetTypeStride(type);
|
||||||
if (stride == 0) {
|
if (stride == 0) {
|
||||||
stride = EntityFile::GetTypeStride(baseType);
|
stride = EntityFile::GetTypeStride(baseType);
|
||||||
if (stride == 0) {
|
if (stride == 0) {
|
||||||
|
|||||||
@@ -97,11 +97,6 @@ EntityWrapper::operator EntityID() const
|
|||||||
return this->ID;
|
return this->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityWrapper::operator bool()
|
|
||||||
{
|
|
||||||
return this->Valid();
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name, EntityID parent)
|
EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name, EntityID parent)
|
||||||
{
|
{
|
||||||
if (!this->World->ValidEntity(parent)) {
|
if (!this->World->ValidEntity(parent)) {
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ void InputManager::PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis
|
|||||||
void InputManager::PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button)
|
void InputManager::PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button)
|
||||||
{
|
{
|
||||||
bool currentState = m_CurrentGamepadButtonState[gamepadID][static_cast<int>(button)];
|
bool currentState = m_CurrentGamepadButtonState[gamepadID][static_cast<int>(button)];
|
||||||
float lastState = m_LastGamepadButtonState[gamepadID][static_cast<int>(button)];
|
bool lastState = m_LastGamepadButtonState[gamepadID][static_cast<int>(button)];
|
||||||
if (currentState != lastState) {
|
if (currentState != lastState) {
|
||||||
if (currentState == true) {
|
if (currentState == true) {
|
||||||
Events::GamepadButtonDown e;
|
Events::GamepadButtonDown e;
|
||||||
|
|||||||
@@ -105,8 +105,7 @@ bool Child::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const
|
|||||||
for (int i : m_DynamicObjIndices) {
|
for (int i : m_DynamicObjIndices) {
|
||||||
if (!m_DynamicObjectsRef[i].Checked) {
|
if (!m_DynamicObjectsRef[i].Checked) {
|
||||||
const AABB& objBox = *m_DynamicObjectsRef[i].Box;
|
const AABB& objBox = *m_DynamicObjectsRef[i].Box;
|
||||||
if (!Collision::IsSameBoxProbably(boxToTest, objBox) &&
|
if (Collision::AABBVsAABB(boxToTest, objBox)) {
|
||||||
Collision::AABBVsAABB(boxToTest, objBox)) {
|
|
||||||
outBoxIntersected = objBox;
|
outBoxIntersected = objBox;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,4 +4,40 @@
|
|||||||
_LOG_LEVEL LOG_LEVEL = LOG_LEVEL_DEBUG;
|
_LOG_LEVEL LOG_LEVEL = LOG_LEVEL_DEBUG;
|
||||||
#else
|
#else
|
||||||
_LOG_LEVEL LOG_LEVEL = LOG_LEVEL_INFO;
|
_LOG_LEVEL LOG_LEVEL = LOG_LEVEL_INFO;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const char* _LOG_LEVEL_PREFIX[] =
|
||||||
|
{
|
||||||
|
"EE: ",
|
||||||
|
"",
|
||||||
|
"WW: ",
|
||||||
|
"DD: "
|
||||||
|
};
|
||||||
|
|
||||||
|
void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int line, const char* format, ...)
|
||||||
|
{
|
||||||
|
if (logLevel > LOG_LEVEL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* message = nullptr;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
size_t size = vsnprintf(message, 0, format, args) + 1;
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
message = new char[size];
|
||||||
|
vsnprintf(message, size, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (logLevel == LOG_LEVEL_ERROR) {
|
||||||
|
std::cerr << file << ":" << line << " " << func << std::endl;
|
||||||
|
std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] message;
|
||||||
|
}
|
||||||
@@ -54,8 +54,12 @@ ComponentWrapper World::AttachComponent(EntityID entity, const std::string& comp
|
|||||||
|
|
||||||
bool World::HasComponent(EntityID entity, const std::string& componentType) const
|
bool World::HasComponent(EntityID entity, const std::string& componentType) const
|
||||||
{
|
{
|
||||||
ComponentPool* pool = m_ComponentPools.at(componentType);
|
auto it = m_ComponentPools.find(componentType);
|
||||||
return pool->KnowsEntity(entity);
|
if (it == m_ComponentPools.end()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return it->second->KnowsEntity(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentWrapper World::GetComponent(EntityID entity, const std::string& componentType)
|
ComponentWrapper World::GetComponent(EntityID entity, const std::string& componentType)
|
||||||
@@ -92,6 +96,13 @@ EntityID World::GetParent(EntityID entity)
|
|||||||
|
|
||||||
void World::SetParent(EntityID entity, EntityID parent)
|
void World::SetParent(EntityID entity, EntityID parent)
|
||||||
{
|
{
|
||||||
|
// Don't allow an entity to be a child to itself!
|
||||||
|
if (entity == parent) {
|
||||||
|
// HACK: We purposely don't check the whole hierarchy of children here, since it would be way too slow.
|
||||||
|
// This might result in infinite loops if an entity somehow ends up as a child.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EntityID lastParent = m_EntityParents.at(entity);
|
EntityID lastParent = m_EntityParents.at(entity);
|
||||||
auto parentChildren = m_EntityChildren.equal_range(lastParent);
|
auto parentChildren = m_EntityChildren.equal_range(lastParent);
|
||||||
for (auto it = parentChildren.first; it != parentChildren.second; it++) {
|
for (auto it = parentChildren.first; it != parentChildren.second; it++) {
|
||||||
|
|||||||
+141
-26
@@ -6,6 +6,11 @@ EditorGUI::EditorGUI(World* world, EventBroker* eventBroker)
|
|||||||
, m_EventBroker(eventBroker)
|
, m_EventBroker(eventBroker)
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &EditorGUI::OnKeyDown);
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &EditorGUI::OnKeyDown);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EFileDropped, &EditorGUI::OnFileDropped);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPause, &EditorGUI::OnPause);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EResume, &EditorGUI::OnResume);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &EditorGUI::OnLockMouse);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &EditorGUI::OnUnlockMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorGUI::Draw()
|
void EditorGUI::Draw()
|
||||||
@@ -37,39 +42,60 @@ void EditorGUI::drawTools()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Widget modes
|
||||||
createWidgetToolButton(WidgetMode::Translate);
|
createWidgetToolButton(WidgetMode::Translate);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("Translate");
|
ImGui::SetTooltip("Translate (W)");
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
createWidgetToolButton(WidgetMode::Rotate);
|
createWidgetToolButton(WidgetMode::Rotate);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("Rotate");
|
ImGui::SetTooltip("Rotate (E)");
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
createWidgetToolButton(WidgetMode::Scale);
|
createWidgetToolButton(WidgetMode::Scale);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("Scale");
|
ImGui::SetTooltip("Scale (R)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::ItemSize(ImVec2(5, 0));
|
||||||
|
|
||||||
|
// Widget space
|
||||||
|
ImGui::SameLine();
|
||||||
|
GLuint spaceTexture = 0;
|
||||||
|
if (m_CurrentWidgetSpace == WidgetSpace::Global) {
|
||||||
|
spaceTexture = tryLoadTexture("Textures/Icons/Global.png");
|
||||||
|
} else if (m_CurrentWidgetSpace == WidgetSpace::Local) {
|
||||||
|
spaceTexture = tryLoadTexture("Textures/Icons/Local.png");
|
||||||
|
}
|
||||||
|
if (ImGui::ImageButton(reinterpret_cast<void*>(spaceTexture), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0), -1, ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) {
|
||||||
|
toggleWidgetSpace();
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
if (m_CurrentWidgetSpace == WidgetSpace::Global) {
|
||||||
|
ImGui::SetTooltip("Widget space: Global (X)");
|
||||||
|
} else if (m_CurrentWidgetSpace == WidgetSpace::Local) {
|
||||||
|
ImGui::SetTooltip("Widget space: Local (X)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::ItemSize(ImVec2(5, 0));
|
ImGui::ItemSize(ImVec2(5, 0));
|
||||||
|
|
||||||
// Play button
|
// Play button
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
static bool paused = false;
|
if (ImGui::ImageButton(reinterpret_cast<void*>(tryLoadTexture("Textures/Icons/Play.png")), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0), -1, ImVec4(0, 0, 0, 0), (!m_Paused) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1))) {
|
||||||
if (ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Play.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0), -1, ImVec4(0, 0, 0, 0), (!paused) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1))) {
|
|
||||||
Events::Resume e;
|
Events::Resume e;
|
||||||
e.World = m_World;
|
e.World = m_World;
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
paused = false;
|
|
||||||
}
|
}
|
||||||
// Pause button
|
// Pause button
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Pause.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0), -1, ImVec4(0, 0, 0, 0), (paused) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1))) {
|
if (ImGui::ImageButton(reinterpret_cast<void*>(tryLoadTexture("Textures/Icons/Pause.png")), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0), -1, ImVec4(0, 0, 0, 0), (m_Paused) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1))) {
|
||||||
Events::Pause e;
|
Events::Pause e;
|
||||||
e.World = m_World;
|
e.World = m_World;
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
paused = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
@@ -168,10 +194,7 @@ bool EditorGUI::drawEntityNode(EntityWrapper entity)
|
|||||||
ImGui::Text(formatEntityName(entity).c_str());
|
ImGui::Text(formatEntityName(entity).c_str());
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
}/* else if (m_CurrentlyDragging == entity) {
|
}
|
||||||
LOG_DEBUG("Stopped dragging %i", entity.ID);
|
|
||||||
m_CurrentlyDragging = EntityWrapper::Invalid;
|
|
||||||
}*/
|
|
||||||
// Entity context menu
|
// Entity context menu
|
||||||
std::string contextMenuUniqueID = std::string("EntityContextMenu") + std::to_string(entity.ID);
|
std::string contextMenuUniqueID = std::string("EntityContextMenu") + std::to_string(entity.ID);
|
||||||
if (hovered && ImGui::IsMouseClicked(1)) {
|
if (hovered && ImGui::IsMouseClicked(1)) {
|
||||||
@@ -234,10 +257,12 @@ void EditorGUI::drawComponents(EntityWrapper entity)
|
|||||||
componentTypes.push_back(pair.first.c_str());
|
componentTypes.push_back(pair.first.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Sort components in alphabetical order
|
||||||
|
std::sort(componentTypes.begin(), componentTypes.end(), compareCharArray);
|
||||||
// Draw combo box
|
// Draw combo box
|
||||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() - 10.f);
|
ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() - 10.f);
|
||||||
int selectedItem = -1;
|
int selectedItem = -1;
|
||||||
if (ImGui::Combo("", &selectedItem, componentTypes.data(), componentTypes.size())) {
|
if (ImGui::Combo("", &selectedItem, componentTypes.data(), static_cast<int>(componentTypes.size()), static_cast<int>(componentTypes.size()))) {
|
||||||
if (selectedItem != -1) {
|
if (selectedItem != -1) {
|
||||||
if (m_OnComponentAttach != nullptr) {
|
if (m_OnComponentAttach != nullptr) {
|
||||||
std::string chosenComponentType(componentTypes.at(selectedItem));
|
std::string chosenComponentType(componentTypes.at(selectedItem));
|
||||||
@@ -283,9 +308,8 @@ bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci)
|
|||||||
|
|
||||||
// Draw component fields
|
// Draw component fields
|
||||||
ComponentWrapper& component = entity.World->GetComponent(entity.ID, ci.Name);
|
ComponentWrapper& component = entity.World->GetComponent(entity.ID, ci.Name);
|
||||||
for (auto& kv : ci.Fields) {
|
for (auto& fieldName : ci.FieldsInOrder) {
|
||||||
const std::string& fieldName = kv.first;
|
const ComponentInfo::Field_t& field = ci.Fields.at(fieldName);
|
||||||
const ComponentInfo::Field_t& field = kv.second;
|
|
||||||
|
|
||||||
// Draw the field widget based on its type
|
// Draw the field widget based on its type
|
||||||
bool dirty = drawComponentField(component, field);
|
bool dirty = drawComponentField(component, field);
|
||||||
@@ -435,18 +459,31 @@ bool EditorGUI::drawComponentField_bool(ComponentWrapper &c, const ComponentInfo
|
|||||||
|
|
||||||
bool EditorGUI::drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field)
|
bool EditorGUI::drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field)
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
auto& val = c.Field<std::string>(field.Name);
|
auto& val = c.Field<std::string>(field.Name);
|
||||||
|
|
||||||
char tempString[1024]; // Let's just hope this is an sufficiently large buffer for strings :)
|
char tempString[1024]; // Let's just hope this is an sufficiently large buffer for strings :)
|
||||||
tempString[1023] = '\0'; // Null terminator just in case the string is larger than the buffer
|
tempString[1023] = '\0'; // Null terminator just in case the string is larger than the buffer
|
||||||
// Copy the string into the buffer, taking the null terminator into account
|
// Copy the string into the buffer, taking the null terminator into account
|
||||||
memcpy(tempString, val.c_str(), std::min(val.length() + 1, sizeof(tempString) - 1));
|
memcpy(tempString, val.c_str(), std::min(val.length() + 1, sizeof(tempString) - 1));
|
||||||
if (ImGui::InputText("", tempString, sizeof(tempString))) {
|
if (ImGui::InputText("", tempString, sizeof(tempString))) {
|
||||||
val = std::string(tempString);
|
val = std::string(tempString);
|
||||||
return true;
|
result = true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
// TODO: Handle drag and drop of files
|
|
||||||
|
// Handle file drag and drop
|
||||||
|
if (ImGui::IsItemHovered() && !m_DroppedFile.empty()) {
|
||||||
|
// Unset potential input focus or our newly set value will be overwritten!
|
||||||
|
if (ImGui::IsItemActive()) {
|
||||||
|
ImGui::SetActiveID(0, nullptr);
|
||||||
|
}
|
||||||
|
// Set the actual dropped value
|
||||||
|
val = m_DroppedFile;
|
||||||
|
m_DroppedFile = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorGUI::drawModals()
|
void EditorGUI::drawModals()
|
||||||
@@ -528,7 +565,7 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ImGui::ImageButton(
|
if (ImGui::ImageButton(
|
||||||
(void*)texture,
|
reinterpret_cast<void*>(texture),
|
||||||
ImVec2(24, 24),
|
ImVec2(24, 24),
|
||||||
ImVec2(0, 1),
|
ImVec2(0, 1),
|
||||||
ImVec2(1, 0),
|
ImVec2(1, 0),
|
||||||
@@ -537,10 +574,7 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode)
|
|||||||
(m_CurrentWidgetMode == mode) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1)
|
(m_CurrentWidgetMode == mode) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
if (m_OnWidgetMode != nullptr) {
|
setWidgetMode(mode);
|
||||||
m_OnWidgetMode(mode);
|
|
||||||
}
|
|
||||||
m_CurrentWidgetMode = mode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,6 +604,61 @@ bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_MouseLocked) {
|
||||||
|
if (e.KeyCode == GLFW_KEY_W) {
|
||||||
|
setWidgetMode(WidgetMode::Translate);
|
||||||
|
}
|
||||||
|
if (e.KeyCode == GLFW_KEY_E) {
|
||||||
|
setWidgetMode(WidgetMode::Rotate);
|
||||||
|
}
|
||||||
|
if (e.KeyCode == GLFW_KEY_R) {
|
||||||
|
setWidgetMode(WidgetMode::Scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.KeyCode == GLFW_KEY_X) {
|
||||||
|
toggleWidgetSpace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorGUI::OnFileDropped(const Events::FileDropped& e)
|
||||||
|
{
|
||||||
|
// Make a best effort to make the path relative to the working directory of the executable
|
||||||
|
m_DroppedFile = boost::filesystem::path(e.Path).lexically_relative(boost::filesystem::current_path()).string();
|
||||||
|
// Compensate for Windows retardedness
|
||||||
|
std::replace(m_DroppedFile.begin(), m_DroppedFile.end(), '\\', '/');
|
||||||
|
// Special case for when people drop from the asset folder instead of from the symlink to the asset folders in bin
|
||||||
|
boost::algorithm::replace_first(m_DroppedFile, "../assets/", "");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorGUI::OnPause(const Events::Pause& e)
|
||||||
|
{
|
||||||
|
if (e.World == m_World) {
|
||||||
|
m_Paused = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorGUI::OnResume(const Events::Resume& e)
|
||||||
|
{
|
||||||
|
if (e.World == m_World) {
|
||||||
|
m_Paused = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorGUI::OnLockMouse(const Events::LockMouse& e)
|
||||||
|
{
|
||||||
|
m_MouseLocked = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorGUI::OnUnlockMouse(const Events::UnlockMouse& e)
|
||||||
|
{
|
||||||
|
m_MouseLocked = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,6 +733,32 @@ void EditorGUI::openModal(const std::string& modal)
|
|||||||
m_ModalsToOpen.insert(modal);
|
m_ModalsToOpen.insert(modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorGUI::setWidgetMode(WidgetMode mode)
|
||||||
|
{
|
||||||
|
if (m_OnWidgetMode != nullptr) {
|
||||||
|
m_OnWidgetMode(mode);
|
||||||
|
}
|
||||||
|
m_CurrentWidgetMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorGUI::toggleWidgetSpace()
|
||||||
|
{
|
||||||
|
if (m_CurrentWidgetSpace == WidgetSpace::Global) {
|
||||||
|
m_CurrentWidgetSpace = WidgetSpace::Local;
|
||||||
|
} else if (m_CurrentWidgetSpace == WidgetSpace::Local) {
|
||||||
|
m_CurrentWidgetSpace = WidgetSpace::Global;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_OnWidgetSpace != nullptr) {
|
||||||
|
m_OnWidgetSpace(m_CurrentWidgetSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorGUI::compareCharArray(const char* c1, const char* c2)
|
||||||
|
{
|
||||||
|
return strcmp(c1, c2) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
void EditorGUI::SetDirty(EntityWrapper entity)
|
void EditorGUI::SetDirty(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
EntityWrapper baseParent = entity;
|
EntityWrapper baseParent = entity;
|
||||||
@@ -731,7 +846,7 @@ void EditorGUI::entityDelete(EntityWrapper entity)
|
|||||||
|
|
||||||
void EditorGUI::entityChangeParent(EntityWrapper entity, EntityWrapper parent)
|
void EditorGUI::entityChangeParent(EntityWrapper entity, EntityWrapper parent)
|
||||||
{
|
{
|
||||||
if (entity == parent) {
|
if (entity == parent || parent.IsChildOf(entity)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ EditorRenderSystem::EditorRenderSystem(World* m_World, EventBroker* eventBroker,
|
|||||||
|
|
||||||
void EditorRenderSystem::Update(double dt)
|
void EditorRenderSystem::Update(double dt)
|
||||||
{
|
{
|
||||||
if (m_CurrentCamera) {
|
if (m_CurrentCamera.Valid()) {
|
||||||
ComponentWrapper cameraTransform = m_CurrentCamera["Transform"];
|
ComponentWrapper cameraTransform = m_CurrentCamera["Transform"];
|
||||||
m_EditorCamera->SetPosition(cameraTransform["Position"]);
|
m_EditorCamera->SetPosition(cameraTransform["Position"]);
|
||||||
m_EditorCamera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"]));
|
m_EditorCamera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"]));
|
||||||
@@ -49,7 +49,11 @@ void EditorRenderSystem::Update(double dt)
|
|||||||
glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World);
|
glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World);
|
||||||
for (auto matGroup : model->MaterialGroups()) {
|
for (auto matGroup : model->MaterialGroups()) {
|
||||||
std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f);
|
std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f);
|
||||||
scene.ForwardJobs.push_back(modelJob);
|
if(cModel["Transparent"]) {
|
||||||
|
scene.TransparentObjects.push_back(modelJob);
|
||||||
|
} else {
|
||||||
|
scene.OpaqueObjects.push_back(modelJob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,9 +80,9 @@ bool EditorRenderSystem::OnSetCamera(Events::SetCamera& e)
|
|||||||
{
|
{
|
||||||
ComponentWrapper cTransform = e.CameraEntity["Transform"];
|
ComponentWrapper cTransform = e.CameraEntity["Transform"];
|
||||||
ComponentWrapper cCamera = e.CameraEntity["Camera"];
|
ComponentWrapper cCamera = e.CameraEntity["Camera"];
|
||||||
m_EditorCamera->SetFOV((double)cCamera["FOV"]);
|
m_EditorCamera->SetFOV(static_cast<float>((double)cCamera["FOV"]));
|
||||||
m_EditorCamera->SetNearClip((double)cCamera["NearClip"]);
|
m_EditorCamera->SetNearClip(static_cast<float>((double)cCamera["NearClip"]));
|
||||||
m_EditorCamera->SetFarClip((double)cCamera["FarClip"]);
|
m_EditorCamera->SetFarClip(static_cast<float>((double)cCamera["FarClip"]));
|
||||||
m_EditorCamera->SetPosition(cTransform["Position"]);
|
m_EditorCamera->SetPosition(cTransform["Position"]);
|
||||||
m_EditorCamera->SetOrientation(glm::quat((const glm::vec3&)cTransform["Orientation"]));
|
m_EditorCamera->SetOrientation(glm::quat((const glm::vec3&)cTransform["Orientation"]));
|
||||||
m_CurrentCamera = e.CameraEntity;
|
m_CurrentCamera = e.CameraEntity;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
|||||||
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
|
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
|
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
|
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
|
||||||
|
m_EditorGUI->SetWidgetSpaceCallback(std::bind(&EditorSystem::OnWidgetSpace, this, std::placeholders::_1));
|
||||||
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
|
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
|
||||||
@@ -65,7 +66,12 @@ void EditorSystem::Update(double dt)
|
|||||||
m_EditorStats->Draw(actualDelta);
|
m_EditorStats->Draw(actualDelta);
|
||||||
|
|
||||||
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
|
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
|
||||||
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
|
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection);
|
||||||
|
if (m_WidgetSpace == EditorGUI::WidgetSpace::Local) {
|
||||||
|
(glm::vec3&)m_Widget["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(m_CurrentSelection);
|
||||||
|
} else {
|
||||||
|
(glm::vec3&)m_Widget["Transform"]["Orientation"] = glm::vec3(0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EditorWorldSystemPipeline->Update(actualDelta);
|
m_EditorWorldSystemPipeline->Update(actualDelta);
|
||||||
@@ -82,11 +88,22 @@ void EditorSystem::Update(double dt)
|
|||||||
void EditorSystem::Enable()
|
void EditorSystem::Enable()
|
||||||
{
|
{
|
||||||
m_EditorCameraInputController->Enable();
|
m_EditorCameraInputController->Enable();
|
||||||
|
|
||||||
m_EventBroker->Publish(Events::UnlockMouse());
|
m_EventBroker->Publish(Events::UnlockMouse());
|
||||||
Events::SetCamera e;
|
|
||||||
e.CameraEntity = m_EditorCamera;
|
// Enable editor camera
|
||||||
m_EventBroker->Publish(e);
|
Events::SetCamera eSetCamera;
|
||||||
(glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera);
|
eSetCamera.CameraEntity = m_EditorCamera;
|
||||||
|
m_EventBroker->Publish(eSetCamera);
|
||||||
|
if (m_ActualCamera.Valid()) {
|
||||||
|
(glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pause the world we're editing
|
||||||
|
Events::Pause ePause;
|
||||||
|
ePause.World = m_World;
|
||||||
|
m_EventBroker->Publish(ePause);
|
||||||
|
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +171,11 @@ void EditorSystem::OnComponentDelete(EntityWrapper entity, const std::string& co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorSystem::OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace)
|
||||||
|
{
|
||||||
|
m_WidgetSpace = widgetSpace;
|
||||||
|
}
|
||||||
|
|
||||||
bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
@@ -170,12 +192,18 @@ bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
|||||||
bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
|
bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
|
||||||
{
|
{
|
||||||
if (m_CurrentSelection.Valid()) {
|
if (m_CurrentSelection.Valid()) {
|
||||||
glm::quat parentOrientation;
|
if (m_WidgetSpace == EditorGUI::WidgetSpace::Global) {
|
||||||
EntityWrapper parent = m_CurrentSelection.Parent();
|
glm::quat parentOrientation;
|
||||||
if (parent.Valid()) {
|
EntityWrapper parent = m_CurrentSelection.Parent();
|
||||||
parentOrientation = glm::inverse(Transform::AbsoluteOrientation(parent.World, parent.ID));
|
if (parent.Valid()) {
|
||||||
|
parentOrientation = glm::inverse(Transform::AbsoluteOrientation(parent));
|
||||||
|
}
|
||||||
|
(glm::vec3&)m_CurrentSelection["Transform"]["Position"] += parentOrientation * e.Translation;
|
||||||
|
} else if (m_WidgetSpace == EditorGUI::WidgetSpace::Local) {
|
||||||
|
glm::quat selectionOri = glm::quat((glm::vec3)m_CurrentSelection["Transform"]["Orientation"]);
|
||||||
|
glm::vec3 localTranslation = selectionOri * e.Translation;
|
||||||
|
(glm::vec3&)m_CurrentSelection["Transform"]["Position"] += localTranslation;
|
||||||
}
|
}
|
||||||
(glm::vec3&)m_CurrentSelection["Transform"]["Position"] += parentOrientation * e.Translation;
|
|
||||||
m_EditorGUI->SetDirty(m_CurrentSelection);
|
m_EditorGUI->SetDirty(m_CurrentSelection);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -23,14 +23,18 @@ void EditorWidgetSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
|
|||||||
|
|
||||||
Events::WidgetDelta e;
|
Events::WidgetDelta e;
|
||||||
|
|
||||||
EntityWrapper moveEntity = entity.Parent();
|
// Widget axes should have a common parent
|
||||||
if (!moveEntity.Valid()) {
|
EntityWrapper widgetBase = entity.Parent();
|
||||||
moveEntity = entity;
|
if (!widgetBase.Valid()) {
|
||||||
|
widgetBase = entity;
|
||||||
}
|
}
|
||||||
|
glm::vec3 widgetBasePos = widgetBase["Transform"]["Position"];
|
||||||
|
glm::quat widgetBaseOri = glm::quat((glm::vec3)widgetBase["Transform"]["Orientation"]);
|
||||||
|
|
||||||
auto camera = m_PickData.Camera;
|
auto camera = m_PickData.Camera;
|
||||||
glm::vec3 axis = cEditorWidget["Axis"];
|
glm::vec3 axis = (glm::vec3)cEditorWidget["Axis"];
|
||||||
glm::vec2 axisScreen = camera->WorldToScreen(axis, m_Renderer->Resolution()) - camera->WorldToScreen(glm::vec3(0, 0, 0), m_Renderer->Resolution());
|
glm::vec3 axisOriented = widgetBaseOri * axis;
|
||||||
|
glm::vec2 axisScreen = camera->WorldToScreen(widgetBasePos + axisOriented, m_Renderer->GetViewportSize()) - camera->WorldToScreen(widgetBasePos, m_Renderer->GetViewportSize());
|
||||||
float dot = glm::dot(m_MouseDelta, glm::normalize(axisScreen)) / glm::length(axisScreen);
|
float dot = glm::dot(m_MouseDelta, glm::normalize(axisScreen)) / glm::length(axisScreen);
|
||||||
glm::vec3 worldMovement = dot * axis;
|
glm::vec3 worldMovement = dot * axis;
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e)
|
|||||||
Events::InputCommand ic;
|
Events::InputCommand ic;
|
||||||
ic.PlayerID = -1;
|
ic.PlayerID = -1;
|
||||||
std::tie(ic.Command, ic.Value) = it->second;
|
std::tie(ic.Command, ic.Value) = it->second;
|
||||||
ic.Value *= e.DeltaX;
|
ic.Value *= static_cast<float>(e.DeltaX);
|
||||||
m_InputProxy->Publish(ic);
|
m_InputProxy->Publish(ic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e)
|
|||||||
Events::InputCommand ic;
|
Events::InputCommand ic;
|
||||||
ic.PlayerID = -1;
|
ic.PlayerID = -1;
|
||||||
std::tie(ic.Command, ic.Value) = it->second;
|
std::tie(ic.Command, ic.Value) = it->second;
|
||||||
ic.Value *= e.DeltaY;
|
ic.Value *= static_cast<float>(e.DeltaY);
|
||||||
m_InputProxy->Publish(ic);
|
m_InputProxy->Publish(ic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer)
|
|||||||
|
|
||||||
void DrawBloomPass::InitializeTextures()
|
void DrawBloomPass::InitializeTextures()
|
||||||
{
|
{
|
||||||
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
|
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/White.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBloomPass::InitializeShaderPrograms()
|
void DrawBloomPass::InitializeShaderPrograms()
|
||||||
@@ -34,12 +34,12 @@ void DrawBloomPass::InitializeShaderPrograms()
|
|||||||
|
|
||||||
void DrawBloomPass::InitializeBuffers()
|
void DrawBloomPass::InitializeBuffers()
|
||||||
{
|
{
|
||||||
GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||||
|
|
||||||
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0)));
|
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0)));
|
||||||
m_GaussianFrameBuffer_horiz.Generate();
|
m_GaussianFrameBuffer_horiz.Generate();
|
||||||
|
|
||||||
GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||||
|
|
||||||
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0)));
|
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0)));
|
||||||
m_GaussianFrameBuffer_vert.Generate();
|
m_GaussianFrameBuffer_vert.Generate();
|
||||||
|
|||||||
@@ -11,21 +11,23 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCulling
|
|||||||
|
|
||||||
void DrawFinalPass::InitializeTextures()
|
void DrawFinalPass::InitializeTextures()
|
||||||
{
|
{
|
||||||
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
|
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/White.png");
|
||||||
m_BlackTexture = ResourceManager::Load<Texture>("Textures/Core/Black.png");
|
m_BlackTexture = ResourceManager::Load<Texture>("Textures/Core/Black.png");
|
||||||
|
m_NeutralNormalTexture = ResourceManager::Load<Texture>("Textures/Core/NeutralNormalMap.png");
|
||||||
|
m_GreyTexture = ResourceManager::Load<Texture>("Textures/Core/Grey.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawFinalPass::InitializeFrameBuffers()
|
void DrawFinalPass::InitializeFrameBuffers()
|
||||||
{
|
{
|
||||||
glGenRenderbuffers(1, &m_DepthBuffer);
|
glGenRenderbuffers(1, &m_DepthBuffer);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||||
|
|
||||||
|
GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||||
|
//GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||||
|
GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||||
|
//GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4);
|
||||||
|
|
||||||
GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
|
||||||
//GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
|
||||||
GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
|
||||||
//GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RGB16F, GL_FLOAT, 4);
|
|
||||||
|
|
||||||
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
|
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
|
||||||
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SceneTexture, GL_COLOR_ATTACHMENT0)));
|
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SceneTexture, GL_COLOR_ATTACHMENT0)));
|
||||||
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1)));
|
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1)));
|
||||||
@@ -42,6 +44,15 @@ void DrawFinalPass::InitializeShaderPrograms()
|
|||||||
m_ForwardPlusProgram->BindFragDataLocation(0, "sceneColor");
|
m_ForwardPlusProgram->BindFragDataLocation(0, "sceneColor");
|
||||||
m_ForwardPlusProgram->BindFragDataLocation(1, "bloomColor");
|
m_ForwardPlusProgram->BindFragDataLocation(1, "bloomColor");
|
||||||
m_ForwardPlusProgram->Link();
|
m_ForwardPlusProgram->Link();
|
||||||
|
|
||||||
|
m_ExplosionEffectProgram = ResourceManager::Load<ShaderProgram>("#ExplosionEffectProgram");
|
||||||
|
m_ExplosionEffectProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/ForwardPlus.vert.glsl")));
|
||||||
|
m_ExplosionEffectProgram->AddShader(std::shared_ptr<Shader>(new GeometryShader("Shaders/ExplosionEffect.geom.glsl")));
|
||||||
|
m_ExplosionEffectProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/ForwardPlus.frag.glsl")));
|
||||||
|
m_ExplosionEffectProgram->Compile();
|
||||||
|
m_ExplosionEffectProgram->BindFragDataLocation(0, "sceneColor");
|
||||||
|
m_ExplosionEffectProgram->BindFragDataLocation(1, "bloomColor");
|
||||||
|
m_ExplosionEffectProgram->Link();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawFinalPass::Draw(RenderScene& scene)
|
void DrawFinalPass::Draw(RenderScene& scene)
|
||||||
@@ -49,69 +60,15 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
|||||||
GLERROR("DrawFinalPass::Draw: Pre");
|
GLERROR("DrawFinalPass::Draw: Pre");
|
||||||
|
|
||||||
DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle());
|
DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle());
|
||||||
|
|
||||||
m_ForwardPlusProgram->Bind();
|
|
||||||
GLuint shaderHandle = m_ForwardPlusProgram->GetHandle();
|
|
||||||
|
|
||||||
if (scene.ClearDepth) {
|
if (scene.ClearDepth) {
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO());
|
DrawModelRenderQueues(scene.OpaqueObjects, scene);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO());
|
GLERROR("DrawFinalPass::Draw: OpaqueObjects");
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO());
|
DrawModelRenderQueues(scene.TransparentObjects, scene);
|
||||||
|
GLERROR("DrawFinalPass::Draw: TransparentObjects");
|
||||||
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
|
||||||
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: Render: Add code for more jobs than modeljobs.
|
|
||||||
for (auto &job : scene.ForwardJobs) {
|
|
||||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
|
||||||
if(modelJob) {
|
|
||||||
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
|
||||||
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
|
|
||||||
glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor));
|
|
||||||
|
|
||||||
glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(modelJob->FillColor));
|
|
||||||
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), modelJob->FillPercentage);
|
|
||||||
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
if(modelJob->DiffuseTexture != nullptr) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture);
|
|
||||||
} else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
|
||||||
}
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
if (modelJob->IncandescenceTexture != nullptr) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, modelJob->IncandescenceTexture->m_Texture);
|
|
||||||
} else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if(modelJob->GlowMap != nullptr) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
|
|
||||||
} else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :)
|
|
||||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
|
||||||
|
|
||||||
if (modelJob->Animation != nullptr) {
|
|
||||||
std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones( *modelJob->Animation, modelJob->AnimationTime);
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindVertexArray(modelJob->Model->VAO);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
|
||||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GLERROR("DrawFinalPass::Draw: END");
|
GLERROR("DrawFinalPass::Draw: END");
|
||||||
delete state;
|
delete state;
|
||||||
}
|
}
|
||||||
@@ -149,4 +106,153 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm:
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
GLERROR("MipMap Texture initialization failed");
|
GLERROR("MipMap Texture initialization failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>& job, RenderScene& scene)
|
||||||
|
{
|
||||||
|
GLuint forwardHandle = m_ForwardPlusProgram->GetHandle();
|
||||||
|
GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle();
|
||||||
|
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO());
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO());
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO());
|
||||||
|
|
||||||
|
for(auto &job : job)
|
||||||
|
{
|
||||||
|
auto explosionEffectJob = std::dynamic_pointer_cast<ExplosionEffectJob>(job);
|
||||||
|
if(explosionEffectJob) {
|
||||||
|
//Bind program
|
||||||
|
m_ExplosionEffectProgram->Bind();
|
||||||
|
|
||||||
|
//Bind uniforms
|
||||||
|
BindExplosionUniforms(explosionHandle, explosionEffectJob, scene);
|
||||||
|
|
||||||
|
if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||||
|
|
||||||
|
if (explosionEffectJob->Animation != nullptr) {
|
||||||
|
std::vector<glm::mat4> frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//bind textures
|
||||||
|
BindExplosionTextures(explosionEffectJob);
|
||||||
|
//draw
|
||||||
|
glBindVertexArray(explosionEffectJob->Model->VAO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer);
|
||||||
|
glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int)));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||||
|
if (modelJob) {
|
||||||
|
//bind forward program
|
||||||
|
m_ForwardPlusProgram->Bind();
|
||||||
|
glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||||
|
|
||||||
|
//bind uniforms
|
||||||
|
BindModelUniforms(forwardHandle, modelJob, scene);
|
||||||
|
|
||||||
|
//bind textures
|
||||||
|
BindModelTextures(modelJob);
|
||||||
|
|
||||||
|
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||||
|
|
||||||
|
if (modelJob->Animation != nullptr) {
|
||||||
|
std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//draw
|
||||||
|
glBindVertexArray(modelJob->Model->VAO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||||
|
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int)));
|
||||||
|
GLERROR("DrawFinalPass::Model: END");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<ExplosionEffectJob>& job, RenderScene& scene)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||||
|
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix));
|
||||||
|
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(job->Color));
|
||||||
|
glUniform3fv(glGetUniformLocation(shaderHandle, "ExplosionOrigin"), 1, glm::value_ptr(job->ExplosionOrigin));
|
||||||
|
glUniform1f(glGetUniformLocation(shaderHandle, "TimeSinceDeath"), job->TimeSinceDeath);
|
||||||
|
glUniform1f(glGetUniformLocation(shaderHandle, "ExplosionDuration"), job->ExplosionDuration);
|
||||||
|
glUniform4fv(glGetUniformLocation(shaderHandle, "EndColor"), 1, glm::value_ptr(job->EndColor));
|
||||||
|
glUniform1i(glGetUniformLocation(shaderHandle, "Randomness"), job->Randomness);
|
||||||
|
glUniform1f(glGetUniformLocation(shaderHandle, "RandomnessScalar"), job->RandomnessScalar);
|
||||||
|
glUniform2fv(glGetUniformLocation(shaderHandle, "Velocity"), 1, glm::value_ptr(job->Velocity));
|
||||||
|
glUniform1i(glGetUniformLocation(shaderHandle, "ColorByDistance"), job->ColorByDistance);
|
||||||
|
glUniform1i(glGetUniformLocation(shaderHandle, "ExponentialAccelaration"), job->ExponentialAccelaration);
|
||||||
|
glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(job->DiffuseColor));
|
||||||
|
glUniform1fv(glGetUniformLocation(shaderHandle, "RandomNumbers"), 50, job->RandomNumbers.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr<ModelJob>& job, RenderScene& scene)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||||
|
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix));
|
||||||
|
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(job->Color));
|
||||||
|
glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(job->DiffuseColor));
|
||||||
|
glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(job->FillColor));
|
||||||
|
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), job->FillPercentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DrawFinalPass::BindExplosionTextures(std::shared_ptr<ExplosionEffectJob>& job)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
if (job->DiffuseTexture != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture->m_Texture);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
||||||
|
}
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
if (job->IncandescenceTexture != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture->m_Texture);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawFinalPass::BindModelTextures(std::shared_ptr<ModelJob>& job)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
if (job->DiffuseTexture != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture->m_Texture);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
if (job->NormalTexture != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, job->NormalTexture->m_Texture);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_NeutralNormalTexture->m_Texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
if (job->SpecularTexture != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, job->SpecularTexture->m_Texture);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_GreyTexture->m_Texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
if (job->IncandescenceTexture != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture->m_Texture);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ bool ImGuiRenderPass::OnMouseRelease(const Events::MouseRelease& e)
|
|||||||
bool ImGuiRenderPass::OnMouseMove(const Events::MouseMove& e)
|
bool ImGuiRenderPass::OnMouseMove(const Events::MouseMove& e)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.MousePos.x = e.X;
|
io.MousePos.x = static_cast<float>(e.X);
|
||||||
io.MousePos.y = e.Y;
|
io.MousePos.y = static_cast<float>(e.Y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ bool ImGuiRenderPass::createFontsTexture()
|
|||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
// Store our identifier
|
// Store our identifier
|
||||||
io.Fonts->TexID = (void*)g_FontTexture;
|
io.Fonts->TexID = reinterpret_cast<void*>(g_FontTexture);
|
||||||
|
|
||||||
// Restore state
|
// Restore state
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
@@ -291,7 +291,7 @@ void ImGuiRenderPass::newFrame()
|
|||||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||||
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
||||||
|
|
||||||
io.DeltaTime = g_DeltaTime;
|
io.DeltaTime = static_cast<float>(g_DeltaTime);
|
||||||
|
|
||||||
io.KeyCtrl = glfwGetKey(g_Window, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_CONTROL);
|
io.KeyCtrl = glfwGetKey(g_Window, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_CONTROL);
|
||||||
io.KeyShift = glfwGetKey(g_Window, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_SHIFT);
|
io.KeyShift = glfwGetKey(g_Window, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_SHIFT);
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ void LightCullingPass::GenerateNewFrustum(RenderScene& scene)
|
|||||||
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
|
||||||
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||||
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||||
glDispatchCompute((int)(m_Renderer->Resolution().Width/(TILE_SIZE*TILE_SIZE) + 1), (int)(m_Renderer->Resolution().Height/(TILE_SIZE*TILE_SIZE) + 1), 1);
|
glDispatchCompute((int)(m_Renderer->GetViewportSize().Width/(TILE_SIZE*TILE_SIZE) + 1), (int)(m_Renderer->GetViewportSize().Height/(TILE_SIZE*TILE_SIZE) + 1), 1);
|
||||||
|
|
||||||
GLERROR("CalculateFrustum Error: End");
|
GLERROR("CalculateFrustum Error: End");
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ void LightCullingPass::OnResolutionChange()
|
|||||||
|
|
||||||
void LightCullingPass::SetSSBOSizes()
|
void LightCullingPass::SetSSBOSizes()
|
||||||
{
|
{
|
||||||
m_NumberOfTiles = (int)(m_Renderer->Resolution().Width/TILE_SIZE) * (int)(m_Renderer->Resolution().Height/TILE_SIZE);
|
m_NumberOfTiles = (int)(m_Renderer->GetViewportSize().Width/TILE_SIZE) * (int)(m_Renderer->GetViewportSize().Height/TILE_SIZE);
|
||||||
|
|
||||||
m_Frustums = new Frustum[m_NumberOfTiles];
|
m_Frustums = new Frustum[m_NumberOfTiles];
|
||||||
m_LightGrid = new LightGrid[m_NumberOfTiles];
|
m_LightGrid = new LightGrid[m_NumberOfTiles];
|
||||||
@@ -67,14 +67,14 @@ void LightCullingPass::CullLights(RenderScene& scene)
|
|||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
m_LightCullProgram->Bind();
|
m_LightCullProgram->Bind();
|
||||||
glUniform2f(glGetUniformLocation(m_LightCullProgram->GetHandle(), "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
glUniform2f(glGetUniformLocation(m_LightCullProgram->GetHandle(), "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||||
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(scene.Camera->ViewMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
|
||||||
glDispatchCompute(glm::ceil(m_Renderer->Resolution().Width / TILE_SIZE), glm::ceil(m_Renderer->Resolution().Height / TILE_SIZE), 1);
|
glDispatchCompute(glm::ceil(m_Renderer->GetViewportSize().Width/ TILE_SIZE), glm::ceil(m_Renderer->GetViewportSize().Height / TILE_SIZE), 1);
|
||||||
|
|
||||||
GLERROR("CullLights Error: End");
|
GLERROR("CullLights Error: End");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,12 +71,12 @@ PNG::PNG(std::string path)
|
|||||||
png_read_update_info(png_ptr, info_ptr);
|
png_read_update_info(png_ptr, info_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr);
|
std::size_t row_bytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||||
this->Data = new unsigned char[height * row_bytes];
|
this->Data = new unsigned char[height * row_bytes];
|
||||||
png_bytep* row_pointers = new png_bytep[height];
|
png_bytep* row_pointers = new png_bytep[height];
|
||||||
|
|
||||||
// Point each row to the continuous data array
|
// Point each row to the continuous data array
|
||||||
for (int i = 0; i < height; ++i) {
|
for (unsigned int i = 0; i < height; ++i) {
|
||||||
// Invert Y for OpenGL
|
// Invert Y for OpenGL
|
||||||
row_pointers[height - 1 - i] = this->Data + i * row_bytes;
|
row_pointers[height - 1 - i] = this->Data + i * row_bytes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ PickingPass::~PickingPass()
|
|||||||
void PickingPass::InitializeTextures()
|
void PickingPass::InitializeTextures()
|
||||||
{
|
{
|
||||||
GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR,
|
GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR,
|
||||||
glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
|
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PickingPass::InitializeFrameBuffers()
|
void PickingPass::InitializeFrameBuffers()
|
||||||
{
|
{
|
||||||
glGenRenderbuffers(1, &m_DepthBuffer);
|
glGenRenderbuffers(1, &m_DepthBuffer);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||||
|
|
||||||
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
|
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
|
||||||
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0)));
|
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0)));
|
||||||
@@ -56,7 +56,7 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
}
|
}
|
||||||
m_Camera = scene.Camera;
|
m_Camera = scene.Camera;
|
||||||
|
|
||||||
for (auto &job : scene.ForwardJobs) {
|
for (auto &job : scene.OpaqueObjects) {
|
||||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||||
|
|
||||||
if (modelJob) {
|
if (modelJob) {
|
||||||
@@ -101,6 +101,52 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &job : scene.TransparentObjects) {
|
||||||
|
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||||
|
|
||||||
|
if (modelJob) {
|
||||||
|
int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] };
|
||||||
|
|
||||||
|
PickingInfo pickInfo;
|
||||||
|
pickInfo.Entity = modelJob->Entity;
|
||||||
|
pickInfo.World = modelJob->World;
|
||||||
|
pickInfo.Camera = scene.Camera;
|
||||||
|
|
||||||
|
auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera));
|
||||||
|
if (color != m_EntityColors.end()) {
|
||||||
|
pickColor[0] = color->second[0];
|
||||||
|
pickColor[1] = color->second[1];
|
||||||
|
} else {
|
||||||
|
m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]);
|
||||||
|
if (m_ColorCounter[0] > 255) {
|
||||||
|
m_ColorCounter[0] = 0;
|
||||||
|
m_ColorCounter[1] += 5;
|
||||||
|
} else {
|
||||||
|
m_ColorCounter[0] += 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
||||||
|
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||||
|
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||||
|
|
||||||
|
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||||
|
|
||||||
|
if (modelJob->Animation != nullptr) {
|
||||||
|
std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(modelJob->Model->VAO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||||
|
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_PickingBuffer.Unbind();
|
m_PickingBuffer.Unbind();
|
||||||
GLERROR("PickingPass Error");
|
GLERROR("PickingPass Error");
|
||||||
|
|||||||
@@ -22,42 +22,42 @@ void RawModelCustom::ReadMeshFile(std::string filePath)
|
|||||||
if (!in.is_open()) {
|
if (!in.is_open()) {
|
||||||
throw Resource::FailedLoadingException("Open mesh file failed");
|
throw Resource::FailedLoadingException("Open mesh file failed");
|
||||||
}
|
}
|
||||||
unsigned int fileByteSize = in.tellg();
|
unsigned int fileByteSize = static_cast<unsigned int>(in.tellg());
|
||||||
in.seekg(0, std::ios_base::beg);
|
in.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
fileData = new char[fileByteSize];
|
fileData = new char[fileByteSize];
|
||||||
in.read(fileData, fileByteSize);
|
in.read(fileData, fileByteSize);
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
unsigned int offset = 0;
|
std::size_t offset = 0;
|
||||||
if (fileByteSize > 0) {
|
if (fileByteSize > 0) {
|
||||||
ReadMeshFileHeader(offset, fileData, fileByteSize);
|
ReadMeshFileHeader(offset, fileData);
|
||||||
ReadMesh(offset, fileData, fileByteSize);
|
ReadMesh(offset, fileData, fileByteSize);
|
||||||
}
|
}
|
||||||
delete fileData;
|
delete fileData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadMeshFileHeader(std::size_t& offset, char* fileData)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
m_Vertices.resize(*(unsigned int*)(fileData + offset));
|
m_Vertices.resize(static_cast<std::size_t>(*(unsigned int*)(fileData + offset)));
|
||||||
offset += sizeof(unsigned int);
|
offset += sizeof(unsigned int);
|
||||||
m_Indices.resize(*(unsigned int*)(fileData + offset));
|
m_Indices.resize(static_cast<std::size_t>(*(unsigned int*)(fileData + offset)));
|
||||||
offset += sizeof(unsigned int);
|
offset += sizeof(unsigned int);
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadMesh(std::size_t& offset, char* fileData, const unsigned int& fileByteSize)
|
||||||
{
|
{
|
||||||
ReadVertices(offset, fileData, fileByteSize);
|
ReadVertices(offset, fileData, fileByteSize);
|
||||||
ReadIndices(offset, fileData, fileByteSize);
|
ReadIndices(offset, fileData, fileByteSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadVertices(std::size_t& offset, char* fileData, const unsigned int& fileByteSize)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) {
|
if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) {
|
||||||
throw Resource::FailedLoadingException("Reading vertices failed");
|
throw Resource::FailedLoadingException("Reading vertices failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadIndices(std::size_t& offset, char* fileData, const unsigned int& fileByteSize)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
if (offset + m_Indices.size() * sizeof(unsigned int) > fileByteSize) {
|
if (offset + m_Indices.size() * sizeof(unsigned int) > fileByteSize) {
|
||||||
@@ -90,35 +90,36 @@ void RawModelCustom::ReadMaterialFile(std::string filePath)
|
|||||||
if (!in.is_open()) {
|
if (!in.is_open()) {
|
||||||
throw Resource::FailedLoadingException("Open material file failed");
|
throw Resource::FailedLoadingException("Open material file failed");
|
||||||
}
|
}
|
||||||
unsigned int fileByteSize = in.tellg();
|
|
||||||
|
unsigned int fileByteSize = static_cast<unsigned int>(in.tellg());
|
||||||
in.seekg(0, std::ios_base::beg);
|
in.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
fileData = new char[fileByteSize];
|
fileData = new char[fileByteSize];
|
||||||
in.read(fileData, fileByteSize);
|
in.read(fileData, fileByteSize);
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
unsigned int offset = 0;
|
std::size_t offset = 0;
|
||||||
if (fileByteSize > 0) {
|
if (fileByteSize > 0) {
|
||||||
ReadMaterials(offset, fileData, fileByteSize);
|
ReadMaterials(offset, fileData, fileByteSize);
|
||||||
}
|
}
|
||||||
delete fileData;
|
delete fileData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadMaterials(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadMaterials(std::size_t& offset, char* fileData, const unsigned int& fileByteSize)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
unsigned int* numMaterials = (unsigned int*)(fileData);
|
unsigned int* numMaterials = (unsigned int*)(fileData);
|
||||||
MaterialGroups.reserve(*numMaterials);
|
MaterialGroups.reserve(*numMaterials);
|
||||||
offset += sizeof(unsigned int);
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
for (int i = 0; i < *numMaterials; i++) {
|
for (unsigned int i = 0; i < *numMaterials; i++) {
|
||||||
ReadMaterialSingle(offset, fileData, fileByteSize);
|
ReadMaterialSingle(offset, fileData, fileByteSize);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadMaterialSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize)
|
||||||
{
|
{
|
||||||
MaterialGroup newMaterial;
|
MaterialGroup newMaterial;
|
||||||
|
|
||||||
@@ -210,14 +211,14 @@ void RawModelCustom::ReadAnimationFile(std::string filePath)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int fileByteSize = in.tellg();
|
unsigned int fileByteSize = static_cast<unsigned int>(in.tellg());
|
||||||
in.seekg(0, std::ios_base::beg);
|
in.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
fileData = new char[fileByteSize];
|
fileData = new char[fileByteSize];
|
||||||
in.read(fileData, fileByteSize);
|
in.read(fileData, fileByteSize);
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
unsigned int offset = 0;
|
std::size_t offset = 0;
|
||||||
if (fileByteSize > 0) {
|
if (fileByteSize > 0) {
|
||||||
m_Skeleton = new Skeleton();
|
m_Skeleton = new Skeleton();
|
||||||
|
|
||||||
@@ -235,7 +236,7 @@ void RawModelCustom::ReadAnimationFile(std::string filePath)
|
|||||||
delete fileData;
|
delete fileData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadAnimationBindPoses(std::size_t& offset, char* fileData, const unsigned int& fileByteSize)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
unsigned int* numBones = (unsigned int*)(fileData + offset);
|
unsigned int* numBones = (unsigned int*)(fileData + offset);
|
||||||
@@ -248,7 +249,7 @@ void RawModelCustom::ReadAnimationBindPoses(unsigned int &offset, char* fileData
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
|
void RawModelCustom::ReadAnimationJoint(std::size_t& offset, char* fileData, const unsigned int& fileByteSize)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
if (offset + sizeof(unsigned int) > fileByteSize) {
|
if (offset + sizeof(unsigned int) > fileByteSize) {
|
||||||
@@ -290,14 +291,14 @@ void RawModelCustom::ReadAnimationJoint(unsigned int &offset, char* fileData, un
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips)
|
void RawModelCustom::ReadAnimationClips(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int numberOfClips)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < numberOfClips; i++) {
|
for (unsigned int i = 0; i < numberOfClips; i++) {
|
||||||
ReadAnimationClipSingle(offset, fileData, fileByteSize, i);
|
ReadAnimationClipSingle(offset, fileData, fileByteSize, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex)
|
void RawModelCustom::ReadAnimationClipSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int clipIndex)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
Skeleton::Animation newAnimation;
|
Skeleton::Animation newAnimation;
|
||||||
@@ -342,7 +343,7 @@ void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileDat
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int nrOfJoints, Skeleton::Animation& animation)
|
void RawModelCustom::ReadAnimationKeyFrame(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int numberOfJoints, Skeleton::Animation& animation)
|
||||||
{
|
{
|
||||||
Skeleton::Animation::Keyframe newKeyFrame;
|
Skeleton::Animation::Keyframe newKeyFrame;
|
||||||
|
|
||||||
@@ -358,12 +359,12 @@ void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData,
|
|||||||
newKeyFrame.Time = *(float*)(fileData + offset);
|
newKeyFrame.Time = *(float*)(fileData + offset);
|
||||||
offset += sizeof(float);
|
offset += sizeof(float);
|
||||||
|
|
||||||
if (offset + sizeof(Skeleton::Animation::Keyframe::BoneProperty) * nrOfJoints> fileByteSize) {
|
if (offset + sizeof(Skeleton::Animation::Keyframe::BoneProperty) * numberOfJoints> fileByteSize) {
|
||||||
throw Resource::FailedLoadingException("Reading AnimationKeyFrame joints failed");
|
throw Resource::FailedLoadingException("Reading AnimationKeyFrame joints failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
Skeleton::Animation::Keyframe::BoneProperty newBone;
|
Skeleton::Animation::Keyframe::BoneProperty newBone;
|
||||||
for (unsigned int i = 0; i < nrOfJoints; i++) {
|
for (unsigned int i = 0; i < numberOfJoints; i++) {
|
||||||
memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty));
|
memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty));
|
||||||
offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty);
|
offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty);
|
||||||
newKeyFrame.BoneProperties[newBone.ID] = newBone;
|
newKeyFrame.BoneProperties[newBone.ID] = newBone;
|
||||||
|
|||||||
@@ -35,43 +35,37 @@ bool RenderSystem::isChildOfACamera(EntityWrapper entity)
|
|||||||
{
|
{
|
||||||
return entity.FirstParentWithComponent("Camera").Valid();
|
return entity.FirstParentWithComponent("Camera").Valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity)
|
bool RenderSystem::isChildOfCurrentCamera(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
return entity == m_Camera || entity.IsChildOf(m_Camera);
|
return entity == m_CurrentCamera || entity.IsChildOf(m_CurrentCamera);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
|
void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& opaqueJobs, std::list<std::shared_ptr<RenderJob>>& transparentJobs)
|
||||||
{
|
{
|
||||||
auto models = m_World->GetComponents("Model");
|
auto models = m_World->GetComponents("Model");
|
||||||
if (models == nullptr) {
|
if (models == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& modelComponent : *models) {
|
for (auto& cModel : *models) {
|
||||||
bool visible = modelComponent["Visible"];
|
bool visible = cModel["Visible"];
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::string resource = modelComponent["Resource"];
|
std::string resource = cModel["Resource"];
|
||||||
if (resource.empty()) {
|
if (resource.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityWrapper entity(m_World, modelComponent.EntityID);
|
EntityWrapper entity(m_World, cModel.EntityID);
|
||||||
|
|
||||||
// Only render children of a camera if that camera is currently active
|
// Only render children of a camera if that camera is currently active
|
||||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Don't render the local player
|
|
||||||
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
|
|
||||||
if (!entity.HasComponent("HealthHUD") && entity.Name() != "Crosshair" && entity.Name() != "Weapon") { //Should work but needs to be fixed. Should only render the things "childed" to the local player camera
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((entity.Name() == "Weapon" || entity.HasComponent("HealthHUD")) && !entity.IsChildOf(m_LocalPlayer)) {
|
// Hide things parented to local player if they have the HiddenFromLocalPlayer component
|
||||||
|
if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,22 +83,58 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float fillPercentage = 0.f;
|
float fillPercentage = 0.f;
|
||||||
glm::vec4 fillColor = glm::vec4(0);
|
glm::vec4 fillColor = glm::vec4(0);
|
||||||
|
if(m_World->HasComponent(cModel.EntityID, "Fill")) {
|
||||||
if(m_World->HasComponent(modelComponent.EntityID, "Fill")) {
|
auto fillComponent = m_World->GetComponent(cModel.EntityID, "Fill");
|
||||||
auto fillComponent = m_World->GetComponent(modelComponent.EntityID, "Fill");
|
|
||||||
fillPercentage = (float)(double)fillComponent["Percentage"];
|
fillPercentage = (float)(double)fillComponent["Percentage"];
|
||||||
fillColor = (glm::vec4)fillComponent["Color"];
|
fillColor = (glm::vec4)fillComponent["Color"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 modelMatrix = Transform::ModelMatrix(cModel.EntityID, m_World);
|
||||||
|
|
||||||
glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, m_World);
|
|
||||||
for (auto matGroup : model->MaterialGroups()) {
|
for (auto matGroup : model->MaterialGroups()) {
|
||||||
std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(model, m_Camera, modelMatrix, matGroup, modelComponent, m_World, fillColor, fillPercentage));
|
if (m_World->HasComponent(cModel.EntityID, "ExplosionEffect")) {
|
||||||
jobs.push_back(modelJob);
|
auto explosionEffectComponent = m_World->GetComponent(cModel.EntityID, "ExplosionEffect");
|
||||||
|
std::shared_ptr<ExplosionEffectJob> explosionEffectJob = std::shared_ptr<ExplosionEffectJob>(new ExplosionEffectJob(
|
||||||
|
explosionEffectComponent,
|
||||||
|
model,
|
||||||
|
m_Camera,
|
||||||
|
modelMatrix,
|
||||||
|
matGroup,
|
||||||
|
cModel,
|
||||||
|
m_World,
|
||||||
|
fillColor,
|
||||||
|
fillPercentage
|
||||||
|
));
|
||||||
|
if(explosionEffectJob->Color.a != 1.f || explosionEffectJob->EndColor.a != 1.f || explosionEffectJob->DiffuseColor.a != 1.f) {
|
||||||
|
cModel["Transparent"] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cModel["Transparent"]) {
|
||||||
|
transparentJobs.push_back(explosionEffectJob);
|
||||||
|
} else {
|
||||||
|
opaqueJobs.push_back(explosionEffectJob);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(
|
||||||
|
model,
|
||||||
|
m_Camera,
|
||||||
|
modelMatrix,
|
||||||
|
matGroup,
|
||||||
|
cModel,
|
||||||
|
m_World,
|
||||||
|
fillColor,
|
||||||
|
fillPercentage
|
||||||
|
));
|
||||||
|
if (modelJob->Color.a != 1.f || modelJob->DiffuseColor.a != 1.f) {
|
||||||
|
cModel["Transparent"] = true;
|
||||||
|
}
|
||||||
|
if (cModel["Transparent"]) {
|
||||||
|
transparentJobs.push_back(modelJob);
|
||||||
|
} else {
|
||||||
|
opaqueJobs.push_back(modelJob);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,7 +244,7 @@ void RenderSystem::Update(double dt)
|
|||||||
RenderScene scene;
|
RenderScene scene;
|
||||||
scene.Camera = m_Camera;
|
scene.Camera = m_Camera;
|
||||||
scene.Viewport = Rectangle(1280, 720);
|
scene.Viewport = Rectangle(1280, 720);
|
||||||
fillModels(scene.ForwardJobs);
|
fillModels(scene.OpaqueObjects, scene.TransparentObjects);
|
||||||
fillPointLights(scene.PointLightJobs, m_World);
|
fillPointLights(scene.PointLightJobs, m_World);
|
||||||
fillDirectionalLights(scene.DirectionalLightJobs, m_World);
|
fillDirectionalLights(scene.DirectionalLightJobs, m_World);
|
||||||
fillText(scene.TextJobs, m_World);
|
fillText(scene.TextJobs, m_World);
|
||||||
|
|||||||
@@ -58,11 +58,24 @@ void Renderer::InitializeWindow()
|
|||||||
LOG_ERROR("GLEW: Initialization failed");
|
LOG_ERROR("GLEW: Initialization failed");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int windowSize[2];
|
||||||
|
glfwGetWindowSize(m_Window, &windowSize[0], &windowSize[1]);
|
||||||
|
m_ViewportSize = Rectangle(windowSize[0], windowSize[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::InitializeShaders()
|
void Renderer::InitializeShaders()
|
||||||
{
|
{
|
||||||
m_BasicForwardProgram = ResourceManager::Load<ShaderProgram>("#m_BasicForwardProgram");
|
m_BasicForwardProgram = ResourceManager::Load<ShaderProgram>("#m_BasicForwardProgram");
|
||||||
|
m_ExplosionEffectProgram = ResourceManager::Load<ShaderProgram>("#ExplosionEffectProgram");
|
||||||
|
//m_ExplosionEffectProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/ExplosionEffect.vert.glsl")));
|
||||||
|
//m_ExplosionEffectProgram->AddShader(std::shared_ptr<Shader>(new GeometryShader("Shaders/ExplosionEffect.geom.glsl")));
|
||||||
|
//m_ExplosionEffectProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/ExplosionEffect.frag.glsl")));
|
||||||
|
//m_ExplosionEffectProgram->Compile();
|
||||||
|
//m_ExplosionEffectProgram->Link();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::InputUpdate(double dt)
|
void Renderer::InputUpdate(double dt)
|
||||||
@@ -98,6 +111,7 @@ void Renderer::Draw(RenderFrame& frame)
|
|||||||
m_LightCullingPass->FillLightList(*scene);
|
m_LightCullingPass->FillLightList(*scene);
|
||||||
m_LightCullingPass->CullLights(*scene);
|
m_LightCullingPass->CullLights(*scene);
|
||||||
m_DrawFinalPass->Draw(*scene);
|
m_DrawFinalPass->Draw(*scene);
|
||||||
|
//m_DrawScenePass->Draw(*scene);
|
||||||
|
|
||||||
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
|
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
|
||||||
|
|
||||||
@@ -133,14 +147,14 @@ PickData Renderer::Pick(glm::vec2 screenCoord)
|
|||||||
void Renderer::InitializeTextures()
|
void Renderer::InitializeTextures()
|
||||||
{
|
{
|
||||||
m_ErrorTexture = ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png");
|
m_ErrorTexture = ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png");
|
||||||
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
|
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/White.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Renderer::SortRenderJobsByDepth(RenderScene &scene)
|
void Renderer::SortRenderJobsByDepth(RenderScene &scene)
|
||||||
{
|
{
|
||||||
//Sort all forward jobs so transparency is good.
|
//Sort all forward jobs so transparency is good.
|
||||||
scene.ForwardJobs.sort(Renderer::DepthSort);
|
scene.TransparentObjects.sort(Renderer::DepthSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ GLuint Shader::CompileShader(GLenum shaderType, std::string fileName)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const GLchar* shaderFiles = shaderFile.c_str();
|
const GLchar* shaderFiles = shaderFile.c_str();
|
||||||
const GLint length = shaderFile.length();
|
const GLint length = static_cast<GLint>(shaderFile.length());
|
||||||
glShaderSource(shader, 1, &shaderFiles, &length);
|
glShaderSource(shader, 1, &shaderFiles, &length);
|
||||||
if (GLERROR("glShaderSource"))
|
if (GLERROR("glShaderSource"))
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -53,11 +53,11 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation& animation, doubl
|
|||||||
|
|
||||||
const Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex];
|
const Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex];
|
||||||
const Animation::Keyframe& nextFrame = animation.Keyframes[(currentKeyframeIndex + 1) % animation.Keyframes.size()];
|
const Animation::Keyframe& nextFrame = animation.Keyframes[(currentKeyframeIndex + 1) % animation.Keyframes.size()];
|
||||||
float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
double alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||||
|
|
||||||
//auto animationFrame = Animations[""].Keyframes[frame];
|
//auto animationFrame = Animations[""].Keyframes[frame];
|
||||||
std::map<int, glm::mat4> frameBones;
|
std::map<int, glm::mat4> frameBones;
|
||||||
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1));
|
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, static_cast<float>(alpha), frameBones, RootBone, glm::mat4(1));
|
||||||
|
|
||||||
std::vector<glm::mat4> finalMatrices;
|
std::vector<glm::mat4> finalMatrices;
|
||||||
for (auto &kv : frameBones) {
|
for (auto &kv : frameBones) {
|
||||||
|
|||||||
@@ -116,7 +116,11 @@ void SoundSystem::updateEmitters(double dt)
|
|||||||
setSourcePos(it->second->ALsource, nextPos);
|
setSourcePos(it->second->ALsource, nextPos);
|
||||||
setSourceVel(it->second->ALsource, velocity);
|
setSourceVel(it->second->ALsource, velocity);
|
||||||
float gain;
|
float gain;
|
||||||
(bool)(it->second->Type) ? gain = m_SFXVolumeChannel : gain = m_BGMVolumeChannel;
|
if (it->second->Type == SoundType::SFX) {
|
||||||
|
gain = m_SFXVolumeChannel;
|
||||||
|
} else if (it->second->Type == SoundType::BGM) {
|
||||||
|
gain = m_BGMVolumeChannel;
|
||||||
|
}
|
||||||
auto emitter = m_World->GetComponent(it->first, "SoundEmitter");
|
auto emitter = m_World->GetComponent(it->first, "SoundEmitter");
|
||||||
setSoundProperties(it->second->ALsource, &emitter);
|
setSoundProperties(it->second->ALsource, &emitter);
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -1,5 +1,6 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "Collision/CollidableOctreeSystem.h"
|
#include "Collision/CollidableOctreeSystem.h"
|
||||||
|
#include "Collision/EntityAABB.h"
|
||||||
#include "Collision/TriggerSystem.h"
|
#include "Collision/TriggerSystem.h"
|
||||||
#include "Collision/CollisionSystem.h"
|
#include "Collision/CollisionSystem.h"
|
||||||
#include "Systems/RaptorCopterSystem.h"
|
#include "Systems/RaptorCopterSystem.h"
|
||||||
@@ -42,7 +43,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
0,
|
0,
|
||||||
m_Config->Get<int>("Video.Width", 1280),
|
m_Config->Get<int>("Video.Width", 1280),
|
||||||
m_Config->Get<int>("Video.Height", 720)
|
m_Config->Get<int>("Video.Height", 720)
|
||||||
));
|
));
|
||||||
m_Renderer->Initialize();
|
m_Renderer->Initialize();
|
||||||
//m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get<float>("Video.FOV", 90.f)));
|
//m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get<float>("Video.FOV", 90.f)));
|
||||||
m_RenderFrame = new RenderFrame();
|
m_RenderFrame = new RenderFrame();
|
||||||
@@ -72,14 +73,15 @@ Game::Game(int argc, char* argv[])
|
|||||||
|
|
||||||
|
|
||||||
// Create Octrees
|
// Create Octrees
|
||||||
m_OctreeCollision = new Octree<AABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
m_OctreeCollision = new Octree<EntityAABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
||||||
m_OctreeFrustrumCulling = new Octree<AABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
m_OctreeFrustrumCulling = new Octree<EntityAABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
||||||
// Create system pipeline
|
// Create system pipeline
|
||||||
m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker);
|
m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker);
|
||||||
|
|
||||||
// All systems with orderlevel 0 will be updated first.
|
// All systems with orderlevel 0 will be updated first.
|
||||||
unsigned int updateOrderLevel = 0;
|
unsigned int updateOrderLevel = 0;
|
||||||
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
|
||||||
|
m_SystemPipeline->AddSystem<ExplosionEffectSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
||||||
@@ -87,6 +89,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer);
|
m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer);
|
||||||
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
|
||||||
|
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
|
||||||
// Populate Octree with collidables
|
// Populate Octree with collidables
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<CollidableOctreeSystem>(updateOrderLevel, m_OctreeCollision);
|
m_SystemPipeline->AddSystem<CollidableOctreeSystem>(updateOrderLevel, m_OctreeCollision);
|
||||||
@@ -98,7 +101,6 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
|
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
|
||||||
m_SystemPipeline->AddSystem<TriggerSystem>(updateOrderLevel, m_OctreeCollision);
|
m_SystemPipeline->AddSystem<TriggerSystem>(updateOrderLevel, m_OctreeCollision);
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
|
|
||||||
m_SystemPipeline->AddSystem<RenderSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
m_SystemPipeline->AddSystem<RenderSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<EditorSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
m_SystemPipeline->AddSystem<EditorSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
||||||
|
|||||||
@@ -13,27 +13,27 @@ CapturePointSystem::CapturePointSystem(World* world, EventBroker* eventBroker)
|
|||||||
|
|
||||||
//here all capturepoints will update their component
|
//here all capturepoints will update their component
|
||||||
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
|
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
|
||||||
void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& capturePoint, double dt)
|
void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt)
|
||||||
{
|
{
|
||||||
if (m_WinnerWasFound) {
|
if (m_WinnerWasFound) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int capturePointNumber = capturePoint["CapturePointNumber"];
|
const int capturePointNumber = cCapturePoint["CapturePointNumber"];
|
||||||
const bool hasTeamComponent = m_World->HasComponent(capturePoint.EntityID, "Team");
|
const bool hasTeamComponent = capturePointEntity.HasComponent("Team");
|
||||||
|
|
||||||
//if point doesnt have a teamComponent yet, add one. since:
|
//if point doesnt have a teamComponent yet, add one. since:
|
||||||
//what if capture point has no team -> we cant get/use the team enum from it...
|
//what if capture point has no team -> we cant get/use the team enum from it...
|
||||||
if (!hasTeamComponent) {
|
if (!hasTeamComponent) {
|
||||||
m_World->AttachComponent(capturePoint.EntityID, "Team");
|
m_World->AttachComponent(cCapturePoint.EntityID, "Team");
|
||||||
ComponentWrapper& teamComponent = m_World->GetComponent(capturePoint.EntityID, "Team");
|
ComponentWrapper& teamComponent = capturePointEntity["Team"];
|
||||||
teamComponent["Team"] = (int)teamComponent["Team"].Enum("Spectator");
|
teamComponent["Team"] = (int)teamComponent["Team"].Enum("Spectator");
|
||||||
}
|
}
|
||||||
ComponentWrapper& teamComponent = m_World->GetComponent(capturePoint.EntityID, "Team");
|
ComponentWrapper& teamComponent = capturePointEntity["Team"];
|
||||||
const int redTeam = (int)teamComponent["Team"].Enum("Red");
|
const int redTeam = (int)teamComponent["Team"].Enum("Red");
|
||||||
const int blueTeam = (int)teamComponent["Team"].Enum("Blue");
|
const int blueTeam = (int)teamComponent["Team"].Enum("Blue");
|
||||||
const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator");
|
const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator");
|
||||||
|
|
||||||
int homePointForTeam = (int)capturePoint["HomePointForTeam"];
|
int homePointForTeam = (int)cCapturePoint["HomePointForTeam"];
|
||||||
if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) {
|
if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) {
|
||||||
m_NumberOfCapturePoints = capturePointNumber + 1;//ex 2 -> 0,1,2 = 3
|
m_NumberOfCapturePoints = capturePointNumber + 1;//ex 2 -> 0,1,2 = 3
|
||||||
if (homePointForTeam == redTeam) {
|
if (homePointForTeam == redTeam) {
|
||||||
@@ -46,8 +46,8 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if we havent received all capturepoints yet, just return
|
//if we havent received all capturepoints yet, just return
|
||||||
if (m_NumberOfCapturePoints == 0 || m_NumberOfCapturePoints != m_CapturePointNumberToEntityIDMap.size()) {
|
if (m_NumberOfCapturePoints == 0 || m_NumberOfCapturePoints != m_CapturePointNumberToEntityMap.size()) {
|
||||||
m_CapturePointNumberToEntityIDMap.insert(std::make_pair(capturePointNumber, capturePoint.EntityID));
|
m_CapturePointNumberToEntityMap.insert(std::make_pair(capturePointNumber, capturePointEntity));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,21 +55,21 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
|
|||||||
int ownedBy = teamComponent["Team"];
|
int ownedBy = teamComponent["Team"];
|
||||||
int redTeamPlayersStandingInside = 0;
|
int redTeamPlayersStandingInside = 0;
|
||||||
int blueTeamPlayersStandingInside = 0;
|
int blueTeamPlayersStandingInside = 0;
|
||||||
if (entity.HasComponent("Model")) {
|
if (capturePointEntity.HasComponent("Model")) {
|
||||||
//Now sets team color to the capturepoint, or white if it is uncaptured.
|
//Now sets team color to the capturepoint, or white if it is uncaptured.
|
||||||
entity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 1) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 1) : glm::vec4(1, 1, 1, 1);
|
capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 1) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 1) : glm::vec4(1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//calculate next possible capturePoint for both teams
|
//calculate next possible capturePoint for both teams
|
||||||
std::map<std::string, int> nextPossibleCapturePoint;
|
std::map<std::string, int> nextPossibleCapturePoint;
|
||||||
nextPossibleCapturePoint["Red"] = -1;
|
nextPossibleCapturePoint["Red"] = -1;
|
||||||
nextPossibleCapturePoint["Blue"] = -1;
|
nextPossibleCapturePoint["Blue"] = -1;
|
||||||
for (size_t i = 0; i < m_NumberOfCapturePoints; i++)
|
for (int i = 0; i < m_NumberOfCapturePoints; i++)
|
||||||
{
|
{
|
||||||
if (!m_World->HasComponent(m_CapturePointNumberToEntityIDMap[i], "Team")) {
|
if (m_CapturePointNumberToEntityMap[i].HasComponent("Team")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ComponentWrapper& capturePointOwnedBy = m_World->GetComponent(m_CapturePointNumberToEntityIDMap[i], "Team");
|
ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"];
|
||||||
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) {
|
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) {
|
||||||
nextPossibleCapturePoint["Red"] = i + 1;
|
nextPossibleCapturePoint["Red"] = i + 1;
|
||||||
}
|
}
|
||||||
@@ -79,10 +79,10 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
|
|||||||
}
|
}
|
||||||
for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--)
|
for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (!m_World->HasComponent(m_CapturePointNumberToEntityIDMap[i], "Team")) {
|
if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ComponentWrapper& capturePointOwnedBy = m_World->GetComponent(m_CapturePointNumberToEntityIDMap[i], "Team");
|
ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"];
|
||||||
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) {
|
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) {
|
||||||
nextPossibleCapturePoint["Red"] = i - 1;
|
nextPossibleCapturePoint["Red"] = i - 1;
|
||||||
}
|
}
|
||||||
@@ -93,9 +93,9 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
|
|||||||
|
|
||||||
//reset timers and reset the bool that triggers this
|
//reset timers and reset the bool that triggers this
|
||||||
if (m_ResetTimers) {
|
if (m_ResetTimers) {
|
||||||
for (size_t i = 0; i < m_NumberOfCapturePoints; i++)
|
for (int i = 0; i < m_NumberOfCapturePoints; i++)
|
||||||
{
|
{
|
||||||
ComponentWrapper& capturePoint = m_World->GetComponent(m_CapturePointNumberToEntityIDMap[i], "CapturePoint");
|
ComponentWrapper& capturePoint = m_CapturePointNumberToEntityMap[i]["CapturePoint"];
|
||||||
if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] &&
|
if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] &&
|
||||||
(int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) {
|
(int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) {
|
||||||
capturePoint["CaptureTimer"] = 0.0;
|
capturePoint["CaptureTimer"] = 0.0;
|
||||||
@@ -106,34 +106,34 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
|
|||||||
|
|
||||||
//colorize next possible capturepoint
|
//colorize next possible capturepoint
|
||||||
if (nextPossibleCapturePoint["Red"] == capturePointNumber) {
|
if (nextPossibleCapturePoint["Red"] == capturePointNumber) {
|
||||||
entity["Model"]["Color"] = glm::vec4(1, 1, 0, 1);
|
capturePointEntity["Model"]["Color"] = glm::vec4(1, 1, 0, 1);
|
||||||
}
|
}
|
||||||
if (nextPossibleCapturePoint["Blue"] == capturePointNumber) {
|
if (nextPossibleCapturePoint["Blue"] == capturePointNumber) {
|
||||||
entity["Model"]["Color"] = glm::vec4(0, 1, 1, 1);
|
capturePointEntity["Model"]["Color"] = glm::vec4(0, 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check how many players are standing inside and are healthy
|
//check how many players are standing inside and are healthy
|
||||||
for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--)
|
for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--)
|
||||||
{
|
{
|
||||||
auto triggerTouched = m_ETriggerTouchVector[i - 1];
|
auto triggerTouched = m_ETriggerTouchVector[i - 1];
|
||||||
if (std::get<1>(triggerTouched) == capturePoint.EntityID) {
|
if (std::get<1>(triggerTouched) == capturePointEntity) {
|
||||||
//some player has touched this - lets figure out: what team, health
|
//some player has touched this - lets figure out: what team, health
|
||||||
EntityID playerID = std::get<0>(triggerTouched);
|
EntityWrapper player = std::get<0>(triggerTouched);
|
||||||
if (!m_World->HasComponent(playerID, "Player")) {
|
if (!player.HasComponent("Player")) {
|
||||||
//if a non-player has entered the capturePoint, just erase that event and continue
|
//if a non-player has entered the capturePoint, just erase that event and continue
|
||||||
m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i - 1);
|
m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i - 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool hasHealthComponent = m_World->HasComponent(playerID, "Health");
|
bool hasHealthComponent = player.HasComponent("Health");
|
||||||
if (hasHealthComponent) {
|
if (hasHealthComponent) {
|
||||||
double currentHealth = m_World->GetComponent(playerID, "Health")["Health"];
|
double currentHealth = player["Health"]["Health"];
|
||||||
//check if player is dead
|
//check if player is dead
|
||||||
if ((int)currentHealth == 0) {
|
if ((int)currentHealth == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//check team - spectatorNumber = "no team"
|
//check team - spectatorNumber = "no team"
|
||||||
int teamNumber = m_World->GetComponent(playerID, "Team")["Team"];
|
int teamNumber = player["Team"]["Team"];
|
||||||
if (teamNumber == redTeam) {
|
if (teamNumber == redTeam) {
|
||||||
redTeamPlayersStandingInside++;
|
redTeamPlayersStandingInside++;
|
||||||
} else if (teamNumber == blueTeam) {
|
} else if (teamNumber == blueTeam) {
|
||||||
@@ -169,24 +169,24 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper
|
|||||||
//B. at most one of the teams have players inside
|
//B. at most one of the teams have players inside
|
||||||
//if capturePoint is not owned by the take-over team, just modify the CaptureTimer accordingly
|
//if capturePoint is not owned by the take-over team, just modify the CaptureTimer accordingly
|
||||||
if (ownedBy != currentTeam && canCapture) {
|
if (ownedBy != currentTeam && canCapture) {
|
||||||
if (abs((double)capturePoint["CaptureTimer"]) < 0.001f) {
|
if (abs((double)cCapturePoint["CaptureTimer"]) < 0.001f) {
|
||||||
LOG_DEBUG("Point is being captured by team %i", currentTeam); //Remove when we tested sufficiently.
|
LOG_DEBUG("Point is being captured by team %i", currentTeam); //Remove when we tested sufficiently.
|
||||||
}
|
}
|
||||||
capturePoint["CaptureTimer"] = (double)capturePoint["CaptureTimer"] + timerDeltaChange;
|
cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange;
|
||||||
}
|
}
|
||||||
//if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0
|
//if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0
|
||||||
if ((ownedBy == currentTeam && currentTeam == redTeam && (double)capturePoint["CaptureTimer"] < 0.0) ||
|
if ((ownedBy == currentTeam && currentTeam == redTeam && (double)cCapturePoint["CaptureTimer"] < 0.0) ||
|
||||||
(ownedBy == currentTeam && currentTeam == blueTeam && (double)capturePoint["CaptureTimer"] > 0.0)) {
|
(ownedBy == currentTeam && currentTeam == blueTeam && (double)cCapturePoint["CaptureTimer"] > 0.0)) {
|
||||||
capturePoint["CaptureTimer"] = (double)capturePoint["CaptureTimer"] + timerDeltaChange;
|
cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange;
|
||||||
}
|
}
|
||||||
//check if captureTimer > m_CaptureTimeToTakeOver and if so change owner and publish the eCaptured event
|
//check if captureTimer > m_CaptureTimeToTakeOver and if so change owner and publish the eCaptured event
|
||||||
if (abs((double)capturePoint["CaptureTimer"]) > abs(m_CaptureTimeToTakeOver) && canCapture) {
|
if (abs((double)cCapturePoint["CaptureTimer"]) > abs(m_CaptureTimeToTakeOver) && canCapture) {
|
||||||
teamComponent["Team"] = currentTeam;
|
teamComponent["Team"] = currentTeam;
|
||||||
capturePoint["CaptureTimer"] = 0.0;
|
cCapturePoint["CaptureTimer"] = 0.0;
|
||||||
//publish Captured event
|
//publish Captured event
|
||||||
LOG_DEBUG("Point is captured by team %i!", currentTeam); //Remove when we tested sufficiently.
|
LOG_DEBUG("Point is captured by team %i!", currentTeam); //Remove when we tested sufficiently.
|
||||||
Events::Captured e;
|
Events::Captured e;
|
||||||
e.CapturePointID = capturePoint.EntityID;
|
e.CapturePointID = cCapturePoint.EntityID;
|
||||||
e.TeamNumberThatCapturedCapturePoint = currentTeam;
|
e.TeamNumberThatCapturedCapturePoint = currentTeam;
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
//NextPossibleCapturePoint will be calculated in the next update...
|
//NextPossibleCapturePoint will be calculated in the next update...
|
||||||
|
|||||||
@@ -80,14 +80,14 @@ void PlayerMovementSystem::Update(double dt)
|
|||||||
velocity.y += 4.f;
|
velocity.y += 4.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (player.HasComponent("AABB")) {
|
if (player.HasComponent("AABB")) {
|
||||||
// glm::vec3& size = player["AABB"]["Size"];
|
glm::vec3& size = player["AABB"]["Size"];
|
||||||
// if (controller->Crouching()) {
|
if (controller->Crouching()) {
|
||||||
// size = glm::vec3(1.f, 1.f, 1.f);
|
size = glm::vec3(1.f, 1.f, 1.f);
|
||||||
// } else {
|
} else {
|
||||||
// size = glm::vec3(1.f, 1.6f, 1.f);
|
size = glm::vec3(1.f, 1.6f, 1.f);
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
// Animations
|
// Animations
|
||||||
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
|
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
|
|||||||
if (spawnPoints.size() > 1) {
|
if (spawnPoints.size() > 1) {
|
||||||
static std::random_device randomDevice;
|
static std::random_device randomDevice;
|
||||||
static std::mt19937 randomGenerator(randomDevice());
|
static std::mt19937 randomGenerator(randomDevice());
|
||||||
std::uniform_int_distribution<> distribution(0, std::distance(spawnPoints.begin(), spawnPoints.end()) - 1);
|
std::uniform_int_distribution<> distribution(0, static_cast<int>(std::distance(spawnPoints.begin(), spawnPoints.end())) - 1);
|
||||||
auto randomSpawnPointIt = spawnPoints.begin();
|
auto randomSpawnPointIt = spawnPoints.begin();
|
||||||
std::advance(randomSpawnPointIt, distribution(randomGenerator));
|
std::advance(randomSpawnPointIt, distribution(randomGenerator));
|
||||||
spawnPoint = *randomSpawnPointIt;
|
spawnPoint = *randomSpawnPointIt;
|
||||||
|
|||||||
@@ -25,6 +25,16 @@ bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e)
|
|||||||
|
|
||||||
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e)
|
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e)
|
||||||
{
|
{
|
||||||
|
// Only shoot client-side!
|
||||||
|
if (e.PlayerID != -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only shoot if the player is alive
|
||||||
|
if (!m_LocalPlayer.Valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.Command == "PrimaryFire" && e.Value > 0) {
|
if (e.Command == "PrimaryFire" && e.Value > 0) {
|
||||||
Events::Shoot eShoot;
|
Events::Shoot eShoot;
|
||||||
if (e.PlayerID == -1) {
|
if (e.PlayerID == -1) {
|
||||||
@@ -94,7 +104,7 @@ bool WeaponSystem::OnShoot(Events::Shoot& eShoot)
|
|||||||
|
|
||||||
// Screen center, based on current resolution!
|
// Screen center, based on current resolution!
|
||||||
// TODO: check if player has enough ammo and if weapon has a cooldown or not
|
// TODO: check if player has enough ammo and if weapon has a cooldown or not
|
||||||
Rectangle screenResolution = m_Renderer->Resolution();
|
Rectangle screenResolution = m_Renderer->GetViewportSize();
|
||||||
glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2);
|
glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2);
|
||||||
|
|
||||||
// TODO: check if player has enough ammo and if weapon has a cooldown or not
|
// TODO: check if player has enough ammo and if weapon has a cooldown or not
|
||||||
|
|||||||
Reference in New Issue
Block a user