Merge remote-tracking branch 'origin/master' into ResolutionChange
This commit is contained in:
@@ -78,13 +78,21 @@ bool AABBvsTriangles(const AABB& box,
|
|||||||
bool& isOnGround,
|
bool& isOnGround,
|
||||||
glm::vec3& outResolutionVector);
|
glm::vec3& outResolutionVector);
|
||||||
|
|
||||||
|
//Detects collision, but does not resolve.
|
||||||
|
bool AABBvsTriangles(const AABB& box,
|
||||||
|
const RawModel::Vertex* modelVertices,
|
||||||
|
const std::vector<unsigned int>& modelIndices,
|
||||||
|
const glm::mat4& modelMatrix);
|
||||||
|
|
||||||
//Return true if the boxes are intersecting.
|
//Return true if the boxes are intersecting.
|
||||||
bool AABBVsAABB(const AABB& a, const AABB& b);
|
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);
|
||||||
|
|
||||||
// Calculates an absolute AABB from an entity AABB component
|
// Calculates an absolute AABB from an entity AABB component or Model component.
|
||||||
|
// if takeModelBox is true, the AABB component will be ignored and box is calculated from Model.
|
||||||
|
// if takeModelBox is false, the AABB component will be prefered, if it exists.
|
||||||
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity, bool takeModelBox = false);
|
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity, bool takeModelBox = false);
|
||||||
boost::optional<EntityAABB> AbsoluteAABBExplosionEffect(EntityWrapper& entity);
|
boost::optional<EntityAABB> AbsoluteAABBExplosionEffect(EntityWrapper& entity);
|
||||||
//Returns the first entity hit by the input ray. entitiesPotentiallyHitSorted needs to be sorted
|
//Returns the first entity hit by the input ray. entitiesPotentiallyHitSorted needs to be sorted
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef PerformanceTimer_h__
|
||||||
|
#define PerformanceTimer_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include <boost/timer/timer.hpp>
|
||||||
|
using boost::timer::cpu_timer;
|
||||||
|
|
||||||
|
class PerformanceTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void StartTimer(std::string nameOfTimer);
|
||||||
|
static void StartTimerAndStopPrevious(std::string nameOfTimer);
|
||||||
|
static void StopTimer(std::string nameOfTimer);
|
||||||
|
static void SetFrameNumber(int frameNumber);
|
||||||
|
|
||||||
|
static void ResetAllTimers();
|
||||||
|
static void CreateExcelData();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::map<std::string, cpu_timer> timers;
|
||||||
|
static cpu_timer m_Timer;
|
||||||
|
static std::string currentTimerRunning;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "System.h"
|
#include "System.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "EPause.h"
|
#include "EPause.h"
|
||||||
|
#include "PerformanceTimer.h"
|
||||||
|
|
||||||
class SystemPipeline
|
class SystemPipeline
|
||||||
{
|
{
|
||||||
@@ -72,7 +73,10 @@ public:
|
|||||||
|
|
||||||
// Update
|
// Update
|
||||||
for (auto& system : group.ImpureSystems) {
|
for (auto& system : group.ImpureSystems) {
|
||||||
|
auto className = (std::string)typeid(*system).name();
|
||||||
|
PerformanceTimer::StartTimer(className);
|
||||||
system->Update(dt);
|
system->Update(dt);
|
||||||
|
PerformanceTimer::StopTimer(className);
|
||||||
}
|
}
|
||||||
for (auto& pair : group.PureSystems) {
|
for (auto& pair : group.PureSystems) {
|
||||||
const std::string& componentName = pair.first;
|
const std::string& componentName = pair.first;
|
||||||
@@ -83,7 +87,10 @@ public:
|
|||||||
}
|
}
|
||||||
for (auto& component : *pool) {
|
for (auto& component : *pool) {
|
||||||
for (auto& system : systems) {
|
for (auto& system : systems) {
|
||||||
|
auto className = (std::string)typeid(*system).name();
|
||||||
|
PerformanceTimer::StartTimer(className);
|
||||||
system->UpdateComponent(EntityWrapper(m_World, component.EntityID), component, dt);
|
system->UpdateComponent(EntityWrapper(m_World, component.EntityID), component, dt);
|
||||||
|
PerformanceTimer::StopTimer(className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,9 +113,9 @@ private:
|
|||||||
std::vector<UnorderedSystems> m_OrderedSystemGroups;
|
std::vector<UnorderedSystems> m_OrderedSystemGroups;
|
||||||
|
|
||||||
EventRelay<SystemPipeline, Events::Pause> m_EPause;
|
EventRelay<SystemPipeline, Events::Pause> m_EPause;
|
||||||
bool OnPause(const Events::Pause& e) {
|
bool OnPause(const Events::Pause& e) {
|
||||||
if (e.World == m_World) {
|
if (e.World == m_World) {
|
||||||
m_Paused = true;
|
m_Paused = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ namespace Events
|
|||||||
{
|
{
|
||||||
|
|
||||||
struct ButtonClicked : public Event {
|
struct ButtonClicked : public Event {
|
||||||
std::string EntityName = "DEFAULT STRING USED";
|
std::string EntityName;
|
||||||
|
EntityWrapper Entity;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ namespace Events
|
|||||||
{
|
{
|
||||||
|
|
||||||
struct ButtonPressed : public Event {
|
struct ButtonPressed : public Event {
|
||||||
std::string EntityName = "DEFAULT STRING USED";
|
std::string EntityName;
|
||||||
|
EntityWrapper Entity;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
namespace Events
|
namespace Events
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ButtonReleased : public Event { };
|
struct ButtonReleased : public Event {
|
||||||
|
std::string EntityName;
|
||||||
|
EntityWrapper Entity;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ struct ModelJob : RenderJob
|
|||||||
EndIndex = matGroup->EndIndex;
|
EndIndex = matGroup->EndIndex;
|
||||||
Matrix = matrix;
|
Matrix = matrix;
|
||||||
Color = modelComponent["Color"];
|
Color = modelComponent["Color"];
|
||||||
GlowIntencity = ((double)modelComponent["GlowIntensity"]);
|
GlowIntensity = ((double)modelComponent["GlowIntensity"]);
|
||||||
Entity = modelComponent.EntityID;
|
Entity = modelComponent.EntityID;
|
||||||
glm::vec3 abspos = Transform::AbsolutePosition(world, modelComponent.EntityID);
|
glm::vec3 abspos = Transform::AbsolutePosition(world, modelComponent.EntityID);
|
||||||
glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1));
|
glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1));
|
||||||
@@ -171,7 +171,7 @@ struct ModelJob : RenderJob
|
|||||||
::Skeleton::AnimationOffset AnimationOffset;
|
::Skeleton::AnimationOffset AnimationOffset;
|
||||||
|
|
||||||
|
|
||||||
float GlowIntencity = 8.0;
|
float GlowIntensity = 8.0;
|
||||||
glm::vec4 DiffuseColor;
|
glm::vec4 DiffuseColor;
|
||||||
glm::vec4 SpecularColor;
|
glm::vec4 SpecularColor;
|
||||||
glm::vec4 IncandescenceColor;
|
glm::vec4 IncandescenceColor;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "imgui/imgui.h"
|
#include "imgui/imgui.h"
|
||||||
#include "TextPass.h"
|
#include "TextPass.h"
|
||||||
#include "Util/CommonFunctions.h"
|
#include "Util/CommonFunctions.h"
|
||||||
|
#include "Core/PerformanceTimer.h"
|
||||||
|
|
||||||
class Renderer : public IRenderer
|
class Renderer : public IRenderer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
#include "Sound/SoundManager.h"
|
#include "Sound/SoundManager.h"
|
||||||
#include "Systems/SoundSystem.h"
|
#include "Systems/SoundSystem.h"
|
||||||
|
|
||||||
|
//Performance
|
||||||
|
#include "Core/PerformanceTimer.h"
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -15,11 +15,16 @@ class SpawnerSystem : public System
|
|||||||
public:
|
public:
|
||||||
SpawnerSystem(SystemParams params);
|
SpawnerSystem(SystemParams params);
|
||||||
|
|
||||||
static EntityWrapper Spawn(EntityWrapper spawner, EntityWrapper parent = EntityWrapper::Invalid);
|
// If dontCollideComponent is set, to e.g. "Player", then all the spawner
|
||||||
|
// will try to pick a spawn location so that the spawned entity doesn't
|
||||||
|
// collide with anything that has that component and is collidable.
|
||||||
|
static EntityWrapper Spawn(EntityWrapper spawner, EntityWrapper parent = EntityWrapper::Invalid, const std::string& dontCollideComponent = "");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventRelay<SpawnerSystem, Events::SpawnerSpawn> m_OnSpawnerSpawn;
|
EventRelay<SpawnerSystem, Events::SpawnerSpawn> m_OnSpawnerSpawn;
|
||||||
bool OnSpawnerSpawn(Events::SpawnerSpawn& e);
|
bool OnSpawnerSpawn(Events::SpawnerSpawn& e);
|
||||||
|
static void transformEntityToSpawnPoint(EntityWrapper spawnedEntity, EntityWrapper spawnPoint);
|
||||||
|
static bool spawnedEntityIsColliding(EntityWrapper spawnedEntity, EntityWrapper spawnPoint, const std::string& dontCollideComponent);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -25,4 +25,6 @@ C=ConnectToServer
|
|||||||
N=SwitchToServer
|
N=SwitchToServer
|
||||||
M=SwitchToClient
|
M=SwitchToClient
|
||||||
P=SwitchToPlayer
|
P=SwitchToPlayer
|
||||||
K=TakeDamage,1500
|
K=TakeDamage,1500
|
||||||
|
F2=PerformanceTimingResetAllTimers
|
||||||
|
F3=PerformanceTimingCreateExcelData
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
</Team>
|
</Team>
|
||||||
</c:Team>
|
</c:Team>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="57.7363472" Y="2.38900018" Z="79.5"/>
|
<Position X="57.7363472" Y="4.98900032" Z="79.5"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
@@ -206,14 +206,16 @@
|
|||||||
</Team>
|
</Team>
|
||||||
</c:Team>
|
</c:Team>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-60.2567062" Y="3.4000001" Z="-78.1000061"/>
|
<Position X="-60.2567062" Y="9.40000057" Z="-78.1000061"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:SpawnPoint/>
|
<c:SpawnPoint/>
|
||||||
<c:Transform/>
|
<c:Transform>
|
||||||
|
<Position X="0" Y="2.10000014" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ project(TacticalZ-Engine)
|
|||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(GLEW REQUIRED)
|
find_package(GLEW REQUIRED)
|
||||||
find_package(GLFW REQUIRED)
|
find_package(GLFW REQUIRED)
|
||||||
find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono program_options)
|
find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono timer program_options)
|
||||||
find_package(assimp REQUIRED)
|
find_package(assimp REQUIRED)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
find_package(PNG REQUIRED)
|
find_package(PNG REQUIRED)
|
||||||
|
|||||||
@@ -366,7 +366,8 @@ bool AABBvsTriangle(const AABB& box,
|
|||||||
float verticalStepHeight,
|
float verticalStepHeight,
|
||||||
bool& isOnGround,
|
bool& isOnGround,
|
||||||
glm::vec3& boxVelocity,
|
glm::vec3& boxVelocity,
|
||||||
glm::vec3& outResolution)
|
glm::vec3& outResolution,
|
||||||
|
bool resolveCollision)
|
||||||
{
|
{
|
||||||
//Check so we don't have a zero area triangle when calculating the normal.
|
//Check so we don't have a zero area triangle when calculating the normal.
|
||||||
//Also, don't check a triangle facing away from the player.
|
//Also, don't check a triangle facing away from the player.
|
||||||
@@ -426,7 +427,7 @@ bool AABBvsTriangle(const AABB& box,
|
|||||||
//if projections don't overlap, return false.
|
//if projections don't overlap, return false.
|
||||||
if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist, pushedFromTriangleLine)) {
|
if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist, pushedFromTriangleLine)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else if (resolveCollision) {
|
||||||
//Overwrite the smallest resolution if this is smaller.
|
//Overwrite the smallest resolution if this is smaller.
|
||||||
if (resolutionDist < resolveShortest.DistanceSq) {
|
if (resolutionDist < resolveShortest.DistanceSq) {
|
||||||
resolveShortest.Vector = glm::vec3(0.f);
|
resolveShortest.Vector = glm::vec3(0.f);
|
||||||
@@ -463,6 +464,11 @@ bool AABBvsTriangle(const AABB& box,
|
|||||||
if (glm::abs(t) > 1) {
|
if (glm::abs(t) > 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!resolveCollision) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 cornerResolution = (1+t) * diagonal;
|
glm::vec3 cornerResolution = (1+t) * diagonal;
|
||||||
//Overwrite the smallest resolution if cornerResolution is smaller.
|
//Overwrite the smallest resolution if cornerResolution is smaller.
|
||||||
float lenSq = glm::length2(cornerResolution);
|
float lenSq = glm::length2(cornerResolution);
|
||||||
@@ -537,7 +543,8 @@ bool AABBvsTriangles(const AABB& box,
|
|||||||
glm::vec3& boxVelocity,
|
glm::vec3& boxVelocity,
|
||||||
float verticalStepHeight,
|
float verticalStepHeight,
|
||||||
bool& isOnGround,
|
bool& isOnGround,
|
||||||
glm::vec3& outResolutionVector)
|
glm::vec3& outResolutionVector,
|
||||||
|
bool resolveCollision)
|
||||||
{
|
{
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
|
||||||
@@ -553,7 +560,7 @@ bool AABBvsTriangles(const AABB& box,
|
|||||||
};
|
};
|
||||||
glm::vec3 outVec;
|
glm::vec3 outVec;
|
||||||
bool collideWithGround = isOnGround;
|
bool collideWithGround = isOnGround;
|
||||||
if (AABBvsTriangle(newBox, triVertices, originalBoxVelocity, verticalStepHeight, collideWithGround, boxVelocity, outVec)) {
|
if (AABBvsTriangle(newBox, triVertices, originalBoxVelocity, verticalStepHeight, collideWithGround, boxVelocity, outVec, resolveCollision)) {
|
||||||
hit = true;
|
hit = true;
|
||||||
outResolutionVector += outVec;
|
outResolutionVector += outVec;
|
||||||
newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size());
|
newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size());
|
||||||
@@ -569,6 +576,44 @@ bool AABBvsTriangles(const AABB& box,
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AABBvsTriangles(const AABB& box,
|
||||||
|
const RawModel::Vertex* modelVertices,
|
||||||
|
const std::vector<unsigned int>& modelIndices,
|
||||||
|
const glm::mat4& modelMatrix,
|
||||||
|
glm::vec3& boxVelocity,
|
||||||
|
float verticalStepHeight,
|
||||||
|
bool& isOnGround,
|
||||||
|
glm::vec3& outResolutionVector)
|
||||||
|
{
|
||||||
|
return AABBvsTriangles(box,
|
||||||
|
modelVertices,
|
||||||
|
modelIndices,
|
||||||
|
modelMatrix,
|
||||||
|
boxVelocity,
|
||||||
|
verticalStepHeight,
|
||||||
|
isOnGround,
|
||||||
|
outResolutionVector,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AABBvsTriangles(const AABB& box,
|
||||||
|
const RawModel::Vertex* modelVertices,
|
||||||
|
const std::vector<unsigned int>& modelIndices,
|
||||||
|
const glm::mat4& modelMatrix)
|
||||||
|
{
|
||||||
|
glm::vec3 vel, outres;
|
||||||
|
bool g;
|
||||||
|
return AABBvsTriangles(box,
|
||||||
|
modelVertices,
|
||||||
|
modelIndices,
|
||||||
|
modelMatrix,
|
||||||
|
vel,
|
||||||
|
0.f,
|
||||||
|
g,
|
||||||
|
outres,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity, bool takeModelBox)
|
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity, bool takeModelBox)
|
||||||
{
|
{
|
||||||
AABB modelSpaceBox;
|
AABB modelSpaceBox;
|
||||||
@@ -648,8 +693,9 @@ boost::optional<EntityAABB> EntityFirstHitByRay(const Ray& ray, std::vector<Enti
|
|||||||
if (!entityBox.Entity.HasComponent("Model")) {
|
if (!entityBox.Entity.HasComponent("Model")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::string res = entityBox.Entity["Model"]["Resource"];
|
auto& cModel = entityBox.Entity["Model"];
|
||||||
if (res.empty()) {
|
std::string res = cModel["Resource"];
|
||||||
|
if (res.empty() || (bool)cModel["Transparent"] || !((bool)cModel["Visible"])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Model* model;
|
Model* model;
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#include "Core/PerformanceTimer.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
cpu_timer PerformanceTimer::m_Timer;
|
||||||
|
std::map<std::string, cpu_timer> PerformanceTimer::timers;
|
||||||
|
std::string PerformanceTimer::currentTimerRunning = "";
|
||||||
|
|
||||||
|
void PerformanceTimer::StartTimer(std::string nameOfTimer)
|
||||||
|
{
|
||||||
|
timers[nameOfTimer].stop();
|
||||||
|
timers[nameOfTimer].start();
|
||||||
|
currentTimerRunning = nameOfTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceTimer::StartTimerAndStopPrevious(std::string nameOfTimer)
|
||||||
|
{
|
||||||
|
//stop the current timer and start some other - useful to not have to stop timers all the time
|
||||||
|
if (currentTimerRunning != "") {
|
||||||
|
timers[currentTimerRunning].stop();
|
||||||
|
}
|
||||||
|
timers[nameOfTimer].stop();
|
||||||
|
timers[nameOfTimer].start();
|
||||||
|
currentTimerRunning = nameOfTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceTimer::StopTimer(std::string nameOfTimer)
|
||||||
|
{
|
||||||
|
timers[nameOfTimer].stop();
|
||||||
|
currentTimerRunning = nameOfTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceTimer::SetFrameNumber(int frameNumber)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceTimer::ResetAllTimers()
|
||||||
|
{
|
||||||
|
//stop all timers
|
||||||
|
for (auto aTimer : timers)
|
||||||
|
{
|
||||||
|
aTimer.second.stop();
|
||||||
|
}
|
||||||
|
currentTimerRunning = "";
|
||||||
|
timers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceTimer::CreateExcelData()
|
||||||
|
{
|
||||||
|
//get time
|
||||||
|
std::time_t t = std::time(NULL);
|
||||||
|
char tStr[16];
|
||||||
|
std::strftime(tStr, 32, " %a %H-%M-%S", std::localtime(&t));
|
||||||
|
std::string time(tStr);
|
||||||
|
std::string path("TacticalZ");
|
||||||
|
path += time + ".csv";
|
||||||
|
std::ofstream someFileStream;
|
||||||
|
someFileStream.open(path, std::ofstream::out);
|
||||||
|
someFileStream << "classname" << ',' << "walltime" << ',' << "userTime" << ',' << "systemTime" << '\n';
|
||||||
|
|
||||||
|
//write all timers to file
|
||||||
|
for (auto aTimer : timers)
|
||||||
|
{
|
||||||
|
//remove the "class" name in front of the string
|
||||||
|
auto className = aTimer.first;
|
||||||
|
if (className.find("class ") != std::string::npos) {
|
||||||
|
className.replace(0, 6, "");
|
||||||
|
}
|
||||||
|
auto wallTime = (double)aTimer.second.elapsed().wall*1e-3;
|
||||||
|
auto userTime = (double)aTimer.second.elapsed().user*1e-3;
|
||||||
|
auto systemTime = (double)aTimer.second.elapsed().system*1e-3;
|
||||||
|
|
||||||
|
someFileStream << className << "," << wallTime << ',' << userTime << ',' << systemTime << '\n';
|
||||||
|
}
|
||||||
|
someFileStream.close();
|
||||||
|
}
|
||||||
@@ -225,6 +225,12 @@ bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
|
|||||||
Enable();
|
Enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (e.Command == "PerformanceTimingResetAllTimers" && e.Value > 0) {
|
||||||
|
PerformanceTimer::ResetAllTimers();
|
||||||
|
}
|
||||||
|
if (e.Command == "PerformanceTimingCreateExcelData" && e.Value > 0) {
|
||||||
|
PerformanceTimer::CreateExcelData();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ bool ButtonSystem::OnMousePress(const Events::MousePress& e)
|
|||||||
|
|
||||||
//You have clicked on a button entity, send pressed event.
|
//You have clicked on a button entity, send pressed event.
|
||||||
Events::ButtonPressed ePressed;
|
Events::ButtonPressed ePressed;
|
||||||
|
ePressed.Entity = m_PickEntity;
|
||||||
ePressed.EntityName = m_PickEntity.Name();
|
ePressed.EntityName = m_PickEntity.Name();
|
||||||
m_EventBroker->Publish(ePressed);
|
m_EventBroker->Publish(ePressed);
|
||||||
}
|
}
|
||||||
@@ -50,15 +51,20 @@ bool ButtonSystem::OnMouseRelease(const Events::MouseRelease& e)
|
|||||||
{
|
{
|
||||||
if(!m_MouseIsLocked) {
|
if(!m_MouseIsLocked) {
|
||||||
//Mouse is not locked, send release event.
|
//Mouse is not locked, send release event.
|
||||||
Events::ButtonReleased eReleased;
|
|
||||||
m_EventBroker->Publish(eReleased);
|
|
||||||
m_PickData = m_Renderer->Pick(glm::vec2(e.X, e.Y));
|
m_PickData = m_Renderer->Pick(glm::vec2(e.X, e.Y));
|
||||||
if(m_PickData.Entity != EntityID_Invalid && m_PickData.World == m_World) {
|
if(m_PickData.Entity != EntityID_Invalid && m_PickData.World == m_World) {
|
||||||
|
EntityWrapper ent = EntityWrapper(m_World, m_PickData.Entity);
|
||||||
|
|
||||||
|
Events::ButtonReleased eReleased;
|
||||||
|
eReleased.EntityName = m_PickEntity.Name();
|
||||||
|
eReleased.Entity = m_PickEntity;
|
||||||
|
m_EventBroker->Publish(eReleased);
|
||||||
|
|
||||||
if(m_World->HasComponent(m_PickData.Entity, "Button")) {
|
if(m_World->HasComponent(m_PickData.Entity, "Button")) {
|
||||||
EntityWrapper ent = EntityWrapper(m_World, m_PickData.Entity);
|
|
||||||
if (ent == m_PickEntity) {
|
if (ent == m_PickEntity) {
|
||||||
//The entity you released the mouse button on is the same as you pressed it on. "Clicked"
|
//The entity you released the mouse button on is the same as you pressed it on. "Clicked"
|
||||||
Events::ButtonClicked eClicked;
|
Events::ButtonClicked eClicked;
|
||||||
|
eClicked.Entity = m_PickEntity;
|
||||||
eClicked.EntityName = m_PickEntity.Name();
|
eClicked.EntityName = m_PickEntity.Name();
|
||||||
m_EventBroker->Publish(eClicked);
|
m_EventBroker->Publish(eClicked);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -757,7 +757,7 @@ void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<E
|
|||||||
GLERROR("Bind 19 uniform");
|
GLERROR("Bind 19 uniform");
|
||||||
glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||||
GLERROR("Bind 20 uniform");
|
GLERROR("Bind 20 uniform");
|
||||||
glUniform1f(glGetUniformLocation(shaderHandle, "GlowIntensity"), job->GlowIntencity);
|
glUniform1f(glGetUniformLocation(shaderHandle, "GlowIntensity"), job->GlowIntensity);
|
||||||
GLERROR("END");
|
GLERROR("END");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -796,7 +796,7 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr<Model
|
|||||||
GLERROR("Bind 10 uniform");
|
GLERROR("Bind 10 uniform");
|
||||||
GLint Location_GlowIntensity = glGetUniformLocation(shaderHandle, "GlowIntensity");
|
GLint Location_GlowIntensity = glGetUniformLocation(shaderHandle, "GlowIntensity");
|
||||||
|
|
||||||
glUniform1f(Location_GlowIntensity, job->GlowIntencity);
|
glUniform1f(Location_GlowIntensity, job->GlowIntensity);
|
||||||
|
|
||||||
GLERROR("END");
|
GLERROR("END");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,34 +114,48 @@ void Renderer::Draw(RenderFrame& frame)
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
//Clear other buffers
|
//Clear other buffers
|
||||||
|
PerformanceTimer::StartTimer("Renderer-ClearBuffers");
|
||||||
m_PickingPass->ClearPicking();
|
m_PickingPass->ClearPicking();
|
||||||
m_DrawFinalPass->ClearBuffer();
|
m_DrawFinalPass->ClearBuffer();
|
||||||
m_DrawBloomPass->ClearBuffer();
|
m_DrawBloomPass->ClearBuffer();
|
||||||
|
PerformanceTimer::StopTimer("Renderer-ClearBuffers");
|
||||||
|
|
||||||
for (auto scene : frame.RenderScenes){
|
for (auto scene : frame.RenderScenes){
|
||||||
|
|
||||||
|
PerformanceTimer::StartTimer("Renderer-Depth");
|
||||||
SortRenderJobsByDepth(*scene);
|
SortRenderJobsByDepth(*scene);
|
||||||
GLERROR("SortByDepth");
|
GLERROR("SortByDepth");
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Drawing PickingPass");
|
||||||
m_PickingPass->Draw(*scene);
|
m_PickingPass->Draw(*scene);
|
||||||
GLERROR("Drawing pickingpass");
|
GLERROR("Drawing pickingpass");
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums");
|
||||||
m_LightCullingPass->GenerateNewFrustum(*scene);
|
m_LightCullingPass->GenerateNewFrustum(*scene);
|
||||||
GLERROR("Generate frustums");
|
GLERROR("Generate frustums");
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Filling Light List");
|
||||||
m_LightCullingPass->FillLightList(*scene);
|
m_LightCullingPass->FillLightList(*scene);
|
||||||
GLERROR("Filling light list");
|
GLERROR("Filling light list");
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Light Culling");
|
||||||
m_LightCullingPass->CullLights(*scene);
|
m_LightCullingPass->CullLights(*scene);
|
||||||
GLERROR("LightCulling");
|
GLERROR("LightCulling");
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light");
|
||||||
m_DrawFinalPass->Draw(*scene);
|
m_DrawFinalPass->Draw(*scene);
|
||||||
GLERROR("Draw Geometry+Light");
|
GLERROR("Draw Geometry+Light");
|
||||||
//m_DrawScenePass->Draw(*scene);
|
//m_DrawScenePass->Draw(*scene);
|
||||||
|
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Text");
|
||||||
m_TextPass->Draw(*scene, *m_DrawFinalPass->FinalPassFrameBuffer());
|
m_TextPass->Draw(*scene, *m_DrawFinalPass->FinalPassFrameBuffer());
|
||||||
GLERROR("Draw Text");
|
GLERROR("Draw Text");
|
||||||
|
PerformanceTimer::StopTimer("Renderer-Draw Text");
|
||||||
}
|
}
|
||||||
|
PerformanceTimer::StartTimer("Renderer-Draw Bloom");
|
||||||
m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture());
|
m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture());
|
||||||
|
PerformanceTimer::StopTimer("Renderer-Draw Bloom");
|
||||||
if (m_DebugTextureToDraw == 0) {
|
if (m_DebugTextureToDraw == 0) {
|
||||||
|
PerformanceTimer::StartTimer("Renderer-Color Correction Pass");
|
||||||
m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure);
|
m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure);
|
||||||
|
PerformanceTimer::StopTimer("Renderer-Color Correction Pass");
|
||||||
}
|
}
|
||||||
|
PerformanceTimer::StartTimer("Renderer-Misc Debug Draws");
|
||||||
if (m_DebugTextureToDraw == 1) {
|
if (m_DebugTextureToDraw == 1) {
|
||||||
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTexture());
|
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTexture());
|
||||||
}
|
}
|
||||||
@@ -160,10 +174,13 @@ void Renderer::Draw(RenderFrame& frame)
|
|||||||
if (m_DebugTextureToDraw == 6) {
|
if (m_DebugTextureToDraw == 6) {
|
||||||
m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture());
|
m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture());
|
||||||
}
|
}
|
||||||
|
PerformanceTimer::StopTimer("Renderer-Misc Debug Draws");
|
||||||
|
|
||||||
|
PerformanceTimer::StartTimer("Renderer-ImGuiRenderPass");
|
||||||
m_ImGuiRenderPass->Draw();
|
m_ImGuiRenderPass->Draw();
|
||||||
GLERROR("Imgui draw");
|
GLERROR("Imgui draw");
|
||||||
glfwSwapBuffers(m_Window);
|
glfwSwapBuffers(m_Window);
|
||||||
|
PerformanceTimer::StopTimer("Renderer-ImGuiRenderPass");
|
||||||
}
|
}
|
||||||
|
|
||||||
PickData Renderer::Pick(glm::vec2 screenCoord)
|
PickData Renderer::Pick(glm::vec2 screenCoord)
|
||||||
|
|||||||
@@ -185,16 +185,20 @@ void Game::Tick()
|
|||||||
// Handle input in a weird looking but responsive way
|
// Handle input in a weird looking but responsive way
|
||||||
m_EventBroker->Process<InputManager>();
|
m_EventBroker->Process<InputManager>();
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
|
PerformanceTimer::StartTimer("InputManager");
|
||||||
m_InputManager->Update(dt);
|
m_InputManager->Update(dt);
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("InputProxy");
|
||||||
m_InputProxy->Update(dt);
|
m_InputProxy->Update(dt);
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_InputProxy->Process();
|
m_InputProxy->Process();
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
|
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("SoundManager");
|
||||||
m_SoundManager->Update(dt);
|
m_SoundManager->Update(dt);
|
||||||
|
|
||||||
// Update network
|
// Update network
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("Network");
|
||||||
m_EventBroker->Process<MultiplayerSnapshotFilter>();
|
m_EventBroker->Process<MultiplayerSnapshotFilter>();
|
||||||
if (m_NetworkClient != nullptr) {
|
if (m_NetworkClient != nullptr) {
|
||||||
m_NetworkClient->Update();
|
m_NetworkClient->Update();
|
||||||
@@ -205,10 +209,14 @@ void Game::Tick()
|
|||||||
//m_SoundManager->Update(dt);
|
//m_SoundManager->Update(dt);
|
||||||
|
|
||||||
// Iterate through systems and update world!
|
// Iterate through systems and update world!
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("SystemPipeline");
|
||||||
m_EventBroker->Process<SystemPipeline>();
|
m_EventBroker->Process<SystemPipeline>();
|
||||||
m_SystemPipeline->Update(dt);
|
m_SystemPipeline->Update(dt);
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("RendererUpdate");
|
||||||
m_Renderer->Update(dt);
|
m_Renderer->Update(dt);
|
||||||
|
PerformanceTimer::StartTimerAndStopPrevious("RendererDraw");
|
||||||
m_Renderer->Draw(*m_RenderFrame);
|
m_Renderer->Draw(*m_RenderFrame);
|
||||||
|
PerformanceTimer::StopTimer("RendererDraw");
|
||||||
m_RenderFrame->Clear();
|
m_RenderFrame->Clear();
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_EventBroker->Clear();
|
m_EventBroker->Clear();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//This should be set by the config anyway.
|
//This should be set by the config anyway.
|
||||||
float PlayerSpawnSystem::m_RespawnTime = 15.0f;
|
float PlayerSpawnSystem::m_RespawnTime = 15.0f;
|
||||||
|
|
||||||
PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params)
|
PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params)
|
||||||
: System(params)
|
: System(params)
|
||||||
, m_Timer(0.f)
|
, m_Timer(0.f)
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ void PlayerSpawnSystem::Update(double dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Spawn the player!
|
// Spawn the player!
|
||||||
EntityWrapper player = SpawnerSystem::Spawn(spawner);
|
EntityWrapper player = SpawnerSystem::Spawn(spawner, EntityWrapper::Invalid, "Player");
|
||||||
// Set the player team affiliation
|
// Set the player team affiliation
|
||||||
player["Team"]["Team"] = req.Team;
|
player["Team"]["Team"] = req.Team;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#include "Systems/SpawnerSystem.h"
|
#include "Systems/SpawnerSystem.h"
|
||||||
|
#include "Collision/Collision.h"
|
||||||
|
|
||||||
SpawnerSystem::SpawnerSystem(SystemParams params)
|
SpawnerSystem::SpawnerSystem(SystemParams params)
|
||||||
: System(params)
|
: System(params)
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_OnSpawnerSpawn, &SpawnerSystem::OnSpawnerSpawn);
|
EVENT_SUBSCRIBE_MEMBER(m_OnSpawnerSpawn, &SpawnerSystem::OnSpawnerSpawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /*= EntityWrapper::Invalid*/)
|
EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /*= EntityWrapper::Invalid*/, const std::string& dontCollideComponent)
|
||||||
{
|
{
|
||||||
// Spawn the entity in the parent's world if it exists, otherwise in the spawner's world
|
// Spawn the entity in the parent's world if it exists, otherwise in the spawner's world
|
||||||
World* world = parent.World;
|
World* world = parent.World;
|
||||||
@@ -14,17 +15,41 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
|
|||||||
world = spawner.World;
|
world = spawner.World;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the entity file and parse it
|
||||||
|
const std::string& entityFilePath = spawner["Spawner"]["EntityFile"];
|
||||||
|
auto entityFile = ResourceManager::Load<EntityFile>(entityFilePath);
|
||||||
|
if (entityFile == nullptr) {
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
EntityFileParser parser(entityFile);
|
||||||
|
EntityWrapper spawnedEntity(world, parser.MergeEntities(world, parent.ID));
|
||||||
|
|
||||||
|
//If the spawned entity is collideable, then we must not spawn it where it collides with something that
|
||||||
|
//has a dontCollideComponent attached.
|
||||||
|
bool spawnOnCollidable = dontCollideComponent.empty() || !spawnedEntity.HasComponent("Collidable");
|
||||||
|
if (!spawnOnCollidable) {
|
||||||
|
boost::optional<EntityAABB> optBox = Collision::EntityAbsoluteAABB(spawnedEntity);
|
||||||
|
//If we can't calculate the box for some reason, then just spawn somewhere anyway.
|
||||||
|
if (!optBox) {
|
||||||
|
spawnOnCollidable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find any SpawnPoints existing as children of spawner
|
// Find any SpawnPoints existing as children of spawner
|
||||||
auto children = spawner.World->GetChildren(spawner.ID);
|
auto children = spawner.World->GetChildren(spawner.ID);
|
||||||
std::vector<EntityWrapper> spawnPoints;
|
std::vector<EntityWrapper> spawnPoints;
|
||||||
for (auto kv = children.first; kv != children.second; ++kv) {
|
for (auto kv = children.first; kv != children.second; ++kv) {
|
||||||
const EntityID& child = kv->second;
|
const EntityID& child = kv->second;
|
||||||
if (spawner.World->HasComponent(child, "SpawnPoint")) {
|
if (spawner.World->HasComponent(child, "SpawnPoint")) {
|
||||||
spawnPoints.push_back(EntityWrapper(spawner.World, child));
|
EntityWrapper spawnPoint = EntityWrapper(spawner.World, child);
|
||||||
|
if (spawnOnCollidable || !spawnedEntityIsColliding(spawnedEntity, spawnPoint, dontCollideComponent)) {
|
||||||
|
spawnPoints.push_back(spawnPoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose a random SpawnPoint
|
// Choose a random SpawnPoint
|
||||||
|
// If there are no children, or if they are all blocked, then the entity will be spawned at the spawner itself.
|
||||||
EntityWrapper spawnPoint = spawner;
|
EntityWrapper spawnPoint = spawner;
|
||||||
if (!spawnPoints.empty()) {
|
if (!spawnPoints.empty()) {
|
||||||
if (spawnPoints.size() > 1) {
|
if (spawnPoints.size() > 1) {
|
||||||
@@ -39,25 +64,61 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the entity file and parse it
|
|
||||||
const std::string& entityFilePath = spawner["Spawner"]["EntityFile"];
|
|
||||||
auto entityFile = ResourceManager::Load<EntityFile>(entityFilePath);
|
|
||||||
if (entityFile == nullptr) {
|
|
||||||
return EntityWrapper::Invalid;
|
|
||||||
}
|
|
||||||
EntityFileParser parser(entityFile);
|
|
||||||
EntityWrapper spawnedEntity(world, parser.MergeEntities(world, parent.ID));
|
|
||||||
|
|
||||||
if (spawnPoint != parent) {
|
if (spawnPoint != parent) {
|
||||||
// Set its position and orientation to that of the SpawnPoint
|
transformEntityToSpawnPoint(spawnedEntity, spawnPoint);
|
||||||
spawnedEntity["Transform"]["Position"] = Transform::AbsolutePosition(spawnPoint.World, spawnPoint.ID);
|
|
||||||
// TODO: Quaternions, bitch
|
|
||||||
spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return spawnedEntity;
|
return spawnedEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpawnerSystem::transformEntityToSpawnPoint(EntityWrapper spawnedEntity, EntityWrapper spawnPoint)
|
||||||
|
{
|
||||||
|
// Set its position and orientation to that of the SpawnPoint
|
||||||
|
spawnedEntity["Transform"]["Position"] = Transform::AbsolutePosition(spawnPoint.World, spawnPoint.ID);
|
||||||
|
// TODO: Quaternions, bitch
|
||||||
|
spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpawnerSystem::spawnedEntityIsColliding(EntityWrapper spawnedEntity, EntityWrapper spawnPoint, const std::string& dontCollideComponent)
|
||||||
|
{
|
||||||
|
transformEntityToSpawnPoint(spawnedEntity, spawnPoint);
|
||||||
|
//Check if the spawned entity collides with anything, and if so, continue to the next spawnpoint.
|
||||||
|
EntityAABB spawnedBox = *Collision::EntityAbsoluteAABB(spawnedEntity);
|
||||||
|
const ComponentPool* otherSpawnedEntities = spawnPoint.World->GetComponents(dontCollideComponent);
|
||||||
|
for (const auto& obj : *otherSpawnedEntities) {
|
||||||
|
if (spawnedEntity.ID == obj.EntityID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntityWrapper otherEntity = EntityWrapper(spawnPoint.World, obj.EntityID);
|
||||||
|
if (!otherEntity.HasComponent("Collidable")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto otherBox = Collision::EntityAbsoluteAABB(otherEntity);
|
||||||
|
if (!otherBox) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Collision::AABBVsAABB(spawnedBox, *otherBox)) {
|
||||||
|
if (!spawnedBox.Entity.HasComponent("Model")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
RawModel* model = nullptr;
|
||||||
|
try {
|
||||||
|
model = ResourceManager::Load<RawModel, true>(otherEntity["Model"]["Resource"]);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model != nullptr && Collision::AABBvsTriangles(
|
||||||
|
spawnedBox,
|
||||||
|
model->Vertices(),
|
||||||
|
model->m_Indices,
|
||||||
|
Transform::ModelMatrix(otherEntity))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool SpawnerSystem::OnSpawnerSpawn(Events::SpawnerSpawn& e)
|
bool SpawnerSystem::OnSpawnerSpawn(Events::SpawnerSpawn& e)
|
||||||
{
|
{
|
||||||
EntityWrapper spawnedEntity = Spawn(e.Spawner, e.Parent);
|
EntityWrapper spawnedEntity = Spawn(e.Spawner, e.Parent);
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ CapturePointTest::CapturePointTest(int runTestNumber)
|
|||||||
m_World = new World();
|
m_World = new World();
|
||||||
|
|
||||||
// Create system pipeline
|
// Create system pipeline
|
||||||
m_SystemPipeline = new SystemPipeline(m_World,m_EventBroker);
|
m_SystemPipeline = new SystemPipeline(m_World,m_EventBroker, true, false);
|
||||||
m_SystemPipeline->AddSystem<HealthSystem>(0);
|
m_SystemPipeline->AddSystem<HealthSystem>(0);
|
||||||
m_SystemPipeline->AddSystem<CapturePointSystem>(1);
|
m_SystemPipeline->AddSystem<CapturePointSystem>(1);
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ void RayTest(std::string fileName) {
|
|||||||
ResourceManager::RegisterType<RawModel>("RawModel");
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
auto unitBox = ResourceManager::Load<RawModel>(fileName);
|
auto unitBox = ResourceManager::Load<RawModel>(fileName);
|
||||||
BOOST_REQUIRE(unitBox != nullptr);
|
BOOST_REQUIRE(unitBox != nullptr);
|
||||||
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
bool hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices, glm::mat4(1));
|
||||||
BOOST_CHECK(hit);
|
BOOST_CHECK(hit);
|
||||||
ray.SetDirection(glm::vec3(-1, 0, 0));
|
ray.SetDirection(glm::vec3(-1, 0, 0));
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices, glm::mat4(1));
|
||||||
BOOST_CHECK(!hit);
|
BOOST_CHECK(!hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,12 +146,12 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
z = Collision::RayVsAABB(ray, someAABB);
|
z = Collision::RayVsAABB(ray, someAABB);
|
||||||
if (z) {
|
if (z) {
|
||||||
//hit
|
//hit
|
||||||
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
bool hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices,glm::mat4(1));
|
||||||
if (!hit) {
|
if (!hit) {
|
||||||
//if rayvsaabb hit but rayvvmodel didnt hit, we get to here
|
//if rayvsaabb hit but rayvvmodel didnt hit, we get to here
|
||||||
glm::vec3 outtttttttt;
|
glm::mat4 outtttttttt;
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt);
|
hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices, glm::mat4(1));
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices, glm::mat4(1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hit = hit;
|
hit = hit;
|
||||||
@@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
// z = z;
|
// z = z;
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
bool hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices, glm::mat4(1));
|
||||||
////breakpoint test
|
////breakpoint test
|
||||||
//if (!hit) {
|
//if (!hit) {
|
||||||
// hit = hit;
|
// hit = hit;
|
||||||
@@ -175,8 +175,8 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
//if rayvsmodel hit but rayvsaabb didnt hit then we get to here
|
//if rayvsmodel hit but rayvsaabb didnt hit then we get to here
|
||||||
z = Collision::RayVsAABB(ray, someAABB);
|
z = Collision::RayVsAABB(ray, someAABB);
|
||||||
glm::vec3 outtttttttt;
|
glm::vec3 outtttttttt;
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt);
|
hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices, glm::mat4(1));
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
hit = Collision::RayVsModel(ray, unitBox->Vertices(), unitBox->m_Indices, glm::mat4(1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
z = z;
|
z = z;
|
||||||
|
|||||||
@@ -48,26 +48,21 @@ GameHealthSystemTest::GameHealthSystemTest()
|
|||||||
fp.MergeEntities(m_World);
|
fp.MergeEntities(m_World);
|
||||||
|
|
||||||
// Create system pipeline
|
// Create system pipeline
|
||||||
m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker);
|
m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker, false, false);
|
||||||
m_SystemPipeline->AddSystem<HealthSystem>(0);
|
m_SystemPipeline->AddSystem<HealthSystem>(0);
|
||||||
|
|
||||||
//The Test
|
//The Test
|
||||||
//create entity which has transform,player,model,health in it. i.e. is a player
|
//create entity which has transform,player,model,health in it. i.e. is a player
|
||||||
EntityID playerID = m_World->CreateEntity();
|
EntityID playerID = m_World->CreateEntity();
|
||||||
ComponentWrapper player = m_World->AttachComponent(playerID, "Player");
|
ComponentWrapper player = m_World->AttachComponent(playerID, "Player");
|
||||||
ComponentWrapper health = m_World->AttachComponent(playerID, "Health");
|
ComponentWrapper& health = m_World->AttachComponent(playerID, "Health");
|
||||||
healthsID = playerID;
|
health["Health"] = 100.0;
|
||||||
|
m_PlayersID = playerID;
|
||||||
|
|
||||||
EntityID playerID2 = m_World->CreateEntity();
|
EntityID playerID2 = m_World->CreateEntity();
|
||||||
ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player");
|
ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player");
|
||||||
ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health");
|
ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health");
|
||||||
|
|
||||||
//heal player with 40
|
|
||||||
Events::PlayerHealthPickup e3;
|
|
||||||
e3.HealthAmount = 40.0f;
|
|
||||||
e3.Player = EntityWrapper(m_World, player.EntityID);
|
|
||||||
m_EventBroker->Publish(e3);
|
|
||||||
|
|
||||||
//damage player with 50
|
//damage player with 50
|
||||||
Events::PlayerDamage e;
|
Events::PlayerDamage e;
|
||||||
e.Damage = 50.0f;
|
e.Damage = 50.0f;
|
||||||
@@ -103,9 +98,18 @@ void GameHealthSystemTest::Tick()
|
|||||||
|
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_EventBroker->Clear();
|
m_EventBroker->Clear();
|
||||||
|
|
||||||
//if health reaches 90 then we know the test has succeeded (start with 100hp, remove 50hp, add 40hp)
|
double currentHealth = (double)m_World->GetComponent(m_PlayersID, "Health")["Health"];
|
||||||
double currentHealth = (double)m_World->GetComponent(healthsID, "Health")["Health"];
|
//if players health reach 50 means he got damaged by 50
|
||||||
if (currentHealth == 90)
|
if (currentHealth == 50.0) {
|
||||||
|
m_TestStage1Success = true;
|
||||||
|
//heal player with 40
|
||||||
|
Events::PlayerHealthPickup e3;
|
||||||
|
e3.HealthAmount = 40.0f;
|
||||||
|
e3.Player = EntityWrapper(m_World, m_PlayersID);
|
||||||
|
m_EventBroker->Publish(e3);
|
||||||
|
}
|
||||||
|
if (m_TestStage1Success && currentHealth == 90.0f) {
|
||||||
TestSucceeded = true;
|
TestSucceeded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ private:
|
|||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
World* m_World;
|
World* m_World;
|
||||||
SystemPipeline* m_SystemPipeline;
|
SystemPipeline* m_SystemPipeline;
|
||||||
int healthsID;
|
int m_PlayersID;
|
||||||
|
bool m_TestStage1Success = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,214 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
using boost::unit_test_framework::test_suite;
|
||||||
|
using boost::unit_test_framework::test_case;
|
||||||
|
|
||||||
|
#include "PickupSpawnTest.h"
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(PickupSpawnTestSuite)
|
||||||
|
|
||||||
|
//dont use the same name as the classname in test cases...
|
||||||
|
BOOST_AUTO_TEST_CASE(PickupSpawnTest_HealthPickupRespawns_PlayerHealthPickupEventTriggers)
|
||||||
|
{
|
||||||
|
PickupSpawnTest game(1);
|
||||||
|
bool success = game.Game_Loop_OneHundredTimes();
|
||||||
|
BOOST_TEST(success);
|
||||||
|
}
|
||||||
|
BOOST_AUTO_TEST_CASE(PickupSpawnTest_APlayerAtMaxHealth_CantTakeHealthPickup)
|
||||||
|
{
|
||||||
|
PickupSpawnTest game(2);
|
||||||
|
bool success = game.Game_Loop_OneHundredTimes();
|
||||||
|
BOOST_TEST(success);
|
||||||
|
}
|
||||||
|
BOOST_AUTO_TEST_CASE(PickupSpawnTest_APickupCanRespawnSlowly)
|
||||||
|
{
|
||||||
|
PickupSpawnTest game(3);
|
||||||
|
bool success = game.Game_Loop_OneHundredTimes();
|
||||||
|
BOOST_TEST(success);
|
||||||
|
}
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
|
PickupSpawnTest::PickupSpawnTest(int runTestNumber)
|
||||||
|
{
|
||||||
|
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
||||||
|
ResourceManager::RegisterType<EntityFile>("EntityFile");
|
||||||
|
|
||||||
|
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
|
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
|
||||||
|
|
||||||
|
m_EventBroker = new EventBroker();
|
||||||
|
m_World = new World();
|
||||||
|
|
||||||
|
// Create system pipeline
|
||||||
|
m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker, false, false);
|
||||||
|
m_SystemPipeline->AddSystem<HealthSystem>(0);
|
||||||
|
m_SystemPipeline->AddSystem<PickupSpawnSystem>(1);
|
||||||
|
|
||||||
|
//must register components (Components.xsd), else you cant create entities. Easiest done by loading a test xsd file
|
||||||
|
auto file = ResourceManager::Load<EntityFile>("Schema/Entities/HealthPickup.xml");
|
||||||
|
EntityFilePreprocessor fpp(file);
|
||||||
|
fpp.RegisterComponents(m_World);
|
||||||
|
EntityFileParser fp(file);
|
||||||
|
//connect the healthpickup to the world
|
||||||
|
m_HealthPickupID = fp.MergeEntities(m_World);
|
||||||
|
|
||||||
|
//create a player
|
||||||
|
m_PlayerID = m_World->CreateEntity();
|
||||||
|
auto& player = m_World->AttachComponent(m_PlayerID, "Player");
|
||||||
|
|
||||||
|
m_RunTestNumber = runTestNumber;
|
||||||
|
|
||||||
|
//further testsetups
|
||||||
|
TestSetup(m_RunTestNumber);
|
||||||
|
|
||||||
|
//init glfw so dt works
|
||||||
|
glfwInit();
|
||||||
|
|
||||||
|
//listen to the 2 events that are related to PickupSpawn
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_HP, &PickupSpawnTest::OnHealthPickup);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_PS, &PickupSpawnTest::OnPickupSpawned);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PickupSpawnTest::OnHealthPickup(Events::PlayerHealthPickup& e) {
|
||||||
|
switch (m_RunTestNumber)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
//verify that the event has the correct healthgain number and playerid
|
||||||
|
if (e.HealthAmount == 22.0 && e.Player.ID == m_PlayerID) {
|
||||||
|
m_TestStage1Success = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m_TestStage1Success = false;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
//verify that the event has the correct healthgain number and playerid
|
||||||
|
if (e.HealthAmount == 50.0 && e.Player.ID == m_PlayerID) {
|
||||||
|
m_TestStage1Success = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool PickupSpawnTest::OnPickupSpawned(Events::PickupSpawned& e) {
|
||||||
|
switch (m_RunTestNumber)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
//verify that the newly spawned pickup has the same variable values as the original one
|
||||||
|
if ((double)e.Pickup["HealthPickup"]["HealthGain"] == 22.0 && (double)e.Pickup["HealthPickup"]["RespawnTimer"] == 2.0) {
|
||||||
|
m_TestStage2Success = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m_TestStage2Success = false;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
m_TestStage2Success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickupSpawnTest::TestSetup(int testNumber)
|
||||||
|
{
|
||||||
|
switch (m_RunTestNumber)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
//PickupSpawnTest_HealthPickupRespawns_PlayerHealthPickupEventTriggers
|
||||||
|
auto& healthPickupEW = EntityWrapper(m_World, m_HealthPickupID);
|
||||||
|
healthPickupEW["HealthPickup"]["RespawnTimer"] = 2.0;
|
||||||
|
healthPickupEW["HealthPickup"]["HealthGain"] = 22.0;
|
||||||
|
|
||||||
|
//create a player
|
||||||
|
auto& health = m_World->AttachComponent(m_PlayerID, "Health");
|
||||||
|
health["Health"] = 20.0;
|
||||||
|
health["MaxHealth"] = 100.0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
//PickupSpawnTest_APlayerAtMaxHealth_CantTakeHealthPickup
|
||||||
|
auto& healthPickupEW = EntityWrapper(m_World, m_HealthPickupID);
|
||||||
|
healthPickupEW["HealthPickup"]["RespawnTimer"] = 1.0;
|
||||||
|
healthPickupEW["HealthPickup"]["HealthGain"] = 50.0;
|
||||||
|
|
||||||
|
//create a player at max health
|
||||||
|
auto& health = m_World->AttachComponent(m_PlayerID, "Health");
|
||||||
|
health["Health"] = 100.0;
|
||||||
|
health["MaxHealth"] = 100.0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
//PickupSpawnTest_APickupCanRespawnSlowly
|
||||||
|
auto& healthPickupEW = EntityWrapper(m_World, m_HealthPickupID);
|
||||||
|
healthPickupEW["HealthPickup"]["RespawnTimer"] = 100.0;
|
||||||
|
healthPickupEW["HealthPickup"]["HealthGain"] = 50.0;
|
||||||
|
|
||||||
|
//create a player
|
||||||
|
auto& health = m_World->AttachComponent(m_PlayerID, "Health");
|
||||||
|
health["Health"] = 1.0;
|
||||||
|
health["MaxHealth"] = 100.0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//do the triggerTouch event to get the pickupSpawnTest started
|
||||||
|
Events::TriggerTouch eTriggerTouch;
|
||||||
|
DoTouchEvent(m_PlayerID, m_HealthPickupID);
|
||||||
|
}
|
||||||
|
|
||||||
|
//generic stuff
|
||||||
|
void PickupSpawnTest::Tick()
|
||||||
|
{
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
//just set dt to 1.0 since we want fast testing
|
||||||
|
double dt = 1.0;
|
||||||
|
|
||||||
|
// Iterate through systems and update world!
|
||||||
|
m_SystemPipeline->Update(dt);
|
||||||
|
|
||||||
|
m_EventBroker->Swap();
|
||||||
|
m_EventBroker->Clear();
|
||||||
|
|
||||||
|
//verify that healthgain event has been published and pickup has respawned
|
||||||
|
if (m_RunTestNumber == 1 && m_TestStage1Success && m_TestStage2Success) {
|
||||||
|
m_TestSucceeded = true;
|
||||||
|
}
|
||||||
|
//verify that no healthgain event has been published and that no pickup has respawned
|
||||||
|
if (m_NumLoops > 90 && m_RunTestNumber == 2 && !m_TestStage1Success && !m_TestStage2Success) {
|
||||||
|
m_TestSucceeded = true;
|
||||||
|
}
|
||||||
|
//3: verify that the pickup hasnt spawned
|
||||||
|
if (m_NumLoops > 90 && m_RunTestNumber == 3 && m_TestStage1Success && !m_TestStage2Success) {
|
||||||
|
m_TestSucceeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool PickupSpawnTest::Game_Loop_OneHundredTimes() {
|
||||||
|
//100 loops will be more than enough to do the test
|
||||||
|
int loops = 100;
|
||||||
|
bool success = false;
|
||||||
|
while (loops > 0) {
|
||||||
|
Tick();
|
||||||
|
m_NumLoops++;
|
||||||
|
if (m_TestSucceeded) {
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
loops--;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
PickupSpawnTest::~PickupSpawnTest()
|
||||||
|
{
|
||||||
|
delete m_SystemPipeline;
|
||||||
|
delete m_World;
|
||||||
|
}
|
||||||
|
void PickupSpawnTest::DoTouchEvent(EntityID whoDidSomething, EntityID onWhatObject) {
|
||||||
|
Events::TriggerTouch touchEvent;
|
||||||
|
touchEvent.Entity = EntityWrapper(m_World, whoDidSomething);
|
||||||
|
touchEvent.Trigger = EntityWrapper(m_World, onWhatObject);
|
||||||
|
m_EventBroker->Publish(touchEvent);
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef PickupSpawnTest_h__
|
||||||
|
#define PickupSpawnTest_h__
|
||||||
|
|
||||||
|
#include "Core/ResourceManager.h"
|
||||||
|
#include "Core/ConfigFile.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Core/World.h"
|
||||||
|
#include "Input/InputProxy.h"
|
||||||
|
#include "Input/KeyboardInputHandler.h"
|
||||||
|
#include "Input/MouseInputHandler.h"
|
||||||
|
#include "Core/EKeyDown.h"
|
||||||
|
#include "Core/EntityFile.h"
|
||||||
|
#include "Core/SystemPipeline.h"
|
||||||
|
|
||||||
|
#include "Core/EntityFilePreprocessor.h"
|
||||||
|
#include "Core/EntityFileParser.h"
|
||||||
|
#include "Core/EntityFileWriter.h"
|
||||||
|
|
||||||
|
#include "Engine/Collision/ETrigger.h"
|
||||||
|
|
||||||
|
//#include "Core/System.h"
|
||||||
|
//#include "Core/Transform.h"
|
||||||
|
//#include "Core/ResourceManager.h"
|
||||||
|
//#include "Core/EntityFileParser.h"
|
||||||
|
//#include "Core/EPickupSpawned.h"
|
||||||
|
//#include "Core/EPlayerHealthPickup.h"
|
||||||
|
#include "Engine/Collision/ETrigger.h"
|
||||||
|
//#include "Common.h"
|
||||||
|
//#include <tuple>
|
||||||
|
#include "Collision/TriggerSystem.h"
|
||||||
|
#include "Collision/CollisionSystem.h"
|
||||||
|
#include "Core/EntityFileWriter.h"
|
||||||
|
#include "Game/Systems/HealthSystem.h"
|
||||||
|
#include "Game/Systems/PickupSpawnSystem.h"
|
||||||
|
|
||||||
|
#include "Core/ResourceManager.h"
|
||||||
|
|
||||||
|
class PickupSpawnTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PickupSpawnTest(int runTestNumber);
|
||||||
|
~PickupSpawnTest();
|
||||||
|
|
||||||
|
void Tick();
|
||||||
|
|
||||||
|
bool Game_Loop_OneHundredTimes();
|
||||||
|
void TestSetup(int testNumber);
|
||||||
|
void DoTouchEvent(EntityID whoDidSomething, EntityID onWhatObject);
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_LastTime;
|
||||||
|
ConfigFile* m_Config = nullptr;
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
World* m_World;
|
||||||
|
SystemPipeline* m_SystemPipeline;
|
||||||
|
EntityID m_PlayerID, m_HealthPickupID;
|
||||||
|
int m_RunTestNumber;
|
||||||
|
|
||||||
|
EventRelay<PickupSpawnSystem, Events::PlayerHealthPickup> m_HP;
|
||||||
|
bool OnHealthPickup(Events::PlayerHealthPickup& e);
|
||||||
|
EventRelay<PickupSpawnSystem, Events::PickupSpawned> m_PS;
|
||||||
|
bool OnPickupSpawned(Events::PickupSpawned& e);
|
||||||
|
|
||||||
|
bool m_TestStage1Success = false;
|
||||||
|
bool m_TestStage2Success = false;
|
||||||
|
|
||||||
|
bool m_TestSucceeded = false;
|
||||||
|
int m_NumLoops = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user