Compare commits

..

2 Commits

Author SHA1 Message Date
Teejoon a806f9b1e3 WIP 2016-03-01 12:04:26 +01:00
Teejoon 22748f6594 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into RenderSettings
Conflicts:
	src/Engine/Rendering/CubeMapPass.cpp
2016-02-29 11:46:08 +01:00
39 changed files with 297 additions and 732 deletions
@@ -104,11 +104,6 @@ protected:
if (!m_Enabled) {
return false;
}
ImGuiIO& io = ImGui::GetIO();
if (io.WantCaptureMouse || io.WantCaptureKeyboard) {
return false;
}
m_SpeedMultiplier += e.DeltaY * (0.1 * m_SpeedMultiplier);
m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier);
-1
View File
@@ -22,7 +22,6 @@
#include "../Core/ELockMouse.h"
#include "../Core/EFileDropped.h"
#include "../Rendering/Texture.h"
#include "Game/Events/ESpawnerSpawn.h"
class EditorGUI
{
+7
View File
@@ -41,6 +41,8 @@ private:
void DrawShieldedModelRenderQueue(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene);
void DrawToDepthBuffer(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene);
void MergeLayers();
void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<ExplosionEffectJob>& job, RenderScene& scene);
void BindModelUniforms(GLuint shaderHandle, std::shared_ptr<ModelJob>& job, RenderScene& scene);
@@ -53,6 +55,9 @@ private:
Texture* m_GreyTexture;
Texture* m_ErrorTexture;
Model* m_ScreenQuad;
FrameBuffer m_MergeFrameBuffer;
FrameBuffer m_FinalPassFrameBuffer;
FrameBuffer m_FinalPassFrameBufferLowRes;
GLuint m_BloomTexture;
@@ -71,6 +76,8 @@ private:
const CubeMapPass* m_CubeMapPass;
const SSAOPass* m_SSAOPass;
ShaderProgram* m_MergeProgram;
ShaderProgram* m_ForwardPlusProgram;
ShaderProgram* m_ExplosionEffectProgram;
ShaderProgram* m_ExplosionEffectSplatMapProgram;
+4 -2
View File
@@ -13,6 +13,8 @@ public:
PlayerSpawnSystem(SystemParams params);
virtual void Update(double dt) override;
static void SetRespawnTime(float respawnTime) { m_RespawnTime = respawnTime; };
private:
struct SpawnRequest
@@ -29,8 +31,8 @@ private:
//EntityWrapper ID -> Player ID.
std::map<EntityID, int> m_PlayerIDs;
float m_ForcedRespawnTime;
bool m_DbgConfigForceRespawn;
static float m_RespawnTime;
float m_Timer;
EventRelay<PlayerSpawnSystem, Events::InputCommand> m_OnInputCommand;
bool OnInputCommand(Events::InputCommand& e);
@@ -1,6 +1,7 @@
#include "WeaponBehaviour.h"
#include "Collision/Collision.h"
#include "Core/EPlayerDamage.h"
#include "Rendering/ESetCamera.h"
class DefenderWeaponBehaviour : public WeaponBehaviour<DefenderWeaponBehaviour>
{
@@ -9,22 +10,29 @@ public:
: System(systemParams)
, WeaponBehaviour(systemParams, "DefenderWeapon", renderer, collisionOctree)
, m_RandomEngine(m_RandomDevice())
{ }
{
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &DefenderWeaponBehaviour::OnSetCamera);
}
void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) override;
void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) override;
void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override;
void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override;
bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) override;
void UpdateWeapon(WeaponInfo& wi, double dt) override;
void OnPrimaryFire(WeaponInfo& wi) override;
void OnCeasePrimaryFire(WeaponInfo& wi) override;
bool OnInputCommand(WeaponInfo& wi, const Events::InputCommand& e) override;
private:
std::random_device m_RandomDevice;
std::mt19937 m_RandomEngine;
EntityWrapper m_CurrentCamera;
EventRelay<DefenderWeaponBehaviour, Events::SetCamera> m_ESetCamera;
bool OnSetCamera(const Events::SetCamera& e);
// Weapon functions
void fireShell(ComponentWrapper cWeapon, WeaponInfo& wi);
void dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage);
void fireShell(WeaponInfo& wi);
void dealDamage(WeaponInfo& wi, glm::vec3 direction, double damage);
// Utility
float traceRayDistance(glm::vec3 origin, glm::vec3 direction);
Camera cameraFromEntity(EntityWrapper camera);
};
@@ -1,33 +0,0 @@
#include "WeaponBehaviour.h"
#include "Collision/Collision.h"
#include "Core/EPlayerDamage.h"
class SidearmWeaponBehaviour : public WeaponBehaviour<SidearmWeaponBehaviour>
{
public:
SidearmWeaponBehaviour(SystemParams systemParams, IRenderer* renderer, Octree<EntityAABB>* collisionOctree)
: System(systemParams)
, WeaponBehaviour(systemParams, "SidearmWeapon", renderer, collisionOctree)
, m_RandomEngine(m_RandomDevice())
{ }
void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) override;
void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) override;
void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override;
void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override;
void OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) override;
void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) override;
private:
std::random_device m_RandomDevice;
std::mt19937 m_RandomEngine;
// Weapon functions
void fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi);
//void dealDamage(WeaponInfo& wi, glm::vec3 direction, double damage);
// Utility
bool canFire(ComponentWrapper cWeapon);
bool playerInFirstPerson(EntityWrapper player);
//float traceRayDistance(glm::vec3 origin, glm::vec3 direction);
};
+31 -98
View File
@@ -7,7 +7,6 @@
#include "Collision/EntityAABB.h"
#include "Input/EInputCommand.h"
#include "Systems/SpawnerSystem.h"
#include "Rendering/ESetCamera.h"
template <typename ETYPE>
class WeaponBehaviour : public PureSystem
@@ -22,81 +21,41 @@ public:
, m_CollisionOctree(collisionOctree)
{
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponBehaviour::_OnInputCommand)
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &WeaponBehaviour::_OnSetCamera)
}
virtual ~WeaponBehaviour() = default;
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) override
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override
{
auto weapon = getActiveWeapon(entity);
if (!weapon) {
return;
} else {
UpdateWeapon(cWeapon, *weapon, dt);
UpdateWeapon(*weapon, dt);
}
}
protected:
struct WeaponInfo
{
std::string WeaponComponent;
EntityWrapper Player;
EntityWrapper WeaponEntity;
EntityWrapper FirstPersonEntity;
EntityWrapper ThirdPersonEntity;
ComponentWrapper GetComponent() { return WeaponEntity[WeaponComponent]; }
};
IRenderer* m_Renderer;
EntityWrapper m_CurrentCamera;
Octree<EntityAABB>* m_CollisionOctree;
std::unordered_map<EntityWrapper, WeaponInfo> m_ActiveWeapons;
virtual void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { }
virtual void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { }
virtual void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { }
virtual void OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) { }
virtual void OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) { }
virtual void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) { }
virtual bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) { return false; }
bool isPlayerInFirstPerson(EntityWrapper player)
{
if (!m_CurrentCamera.Valid()) {
return false;
} else {
return m_CurrentCamera == player || m_CurrentCamera.IsChildOf(player);
}
}
// Returns wi.FirstPersonEntity or wi.ThirdPersonEntity depending on
// if the player is in first person mode or not.
EntityWrapper getRelevantWeaponModelEntity(WeaponInfo& wi)
{
if (isPlayerInFirstPerson(wi.Player)) {
return wi.FirstPersonEntity;
} else {
return wi.ThirdPersonEntity;
}
}
float traceRayDistance(glm::vec3 origin, glm::vec3 direction)
{
float distance;
glm::vec3 pos;
auto entity = Collision::EntityFirstHitByRay(Ray(origin, direction), m_CollisionOctree, distance, pos);
if (entity) {
return distance;
} else {
return 100.f;
}
}
virtual void UpdateWeapon(WeaponInfo& wi, double dt) { }
virtual void OnPrimaryFire(WeaponInfo& wi) { }
virtual void OnCeasePrimaryFire(WeaponInfo& wi) { }
virtual void OnReload(WeaponInfo& wi) { }
virtual bool OnInputCommand(WeaponInfo& wi, const Events::InputCommand& e) { return false; }
private:
EventRelay<ETYPE, Events::SetCamera> m_ESetCamera;
bool _OnSetCamera(const Events::SetCamera& e)
{
m_CurrentCamera = e.CameraEntity;
return true;
}
EventRelay<ETYPE, Events::InputCommand> m_EInputCommand;
bool _OnInputCommand(const Events::InputCommand& e)
{
@@ -111,19 +70,15 @@ private:
}
// Make sure the player has this weapon
auto cWeapon = getWeaponComponent(player);
if (!cWeapon) {
auto weapon = getWeaponComponent(player);
if (!weapon) {
return false;
}
// Weapon selection
if (e.Command == "SelectWeapon") {
if (e.Value > 0) {
if (static_cast<ComponentInfo::EnumType>(e.Value) == static_cast<ComponentInfo::EnumType>((*cWeapon)["Slot"])) {
selectWeapon(*cWeapon, player);
} else {
holsterWeapon(*cWeapon, player);
}
if (static_cast<ComponentInfo::EnumType>(e.Value) == static_cast<ComponentInfo::EnumType>((*weapon)["Slot"])) {
selectWeapon(player);
}
}
@@ -136,18 +91,18 @@ private:
// Fire
if (e.Command == "PrimaryFire") {
if (e.Value > 0) {
OnPrimaryFire(*cWeapon, *activeWeapon);
OnPrimaryFire(*activeWeapon);
} else {
OnCeasePrimaryFire(*cWeapon, *activeWeapon);
OnCeasePrimaryFire(*activeWeapon);
}
}
// Reload
if (e.Command == "Reload" && e.Value != 0) {
OnReload(*cWeapon, *activeWeapon);
OnReload(*activeWeapon);
}
return OnInputCommand(*cWeapon, *activeWeapon, e);
return OnInputCommand(*activeWeapon, e);
}
boost::optional<ComponentWrapper> getWeaponComponent(EntityWrapper player)
@@ -174,13 +129,8 @@ private:
return activeWeapon;
}
void selectWeapon(ComponentWrapper cWeapon, EntityWrapper player)
void selectWeapon(EntityWrapper player)
{
// Don't reselect weapon if it's already active
if (getActiveWeapon(player)) {
return;
}
// Find the weapon attachments matching the weapon type
std::vector<EntityWrapper> weaponAttachments = player.ChildrenWithComponent("WeaponAttachment");
EntityWrapper firstPersonAttachment;
@@ -202,6 +152,14 @@ private:
return;
}
// Purge other weapon entities
for (auto& attachment : weaponAttachments) {
//if (attachment == firstPersonAttachment || attachment == thirdPersonAttachment) {
// continue;
//}
attachment.DeleteChildren();
}
// Spawn the weapon(s)
EntityWrapper firstPersonWeapon;
EntityWrapper thirdPersonWeapon;
@@ -212,36 +170,11 @@ private:
thirdPersonWeapon = SpawnerSystem::Spawn(thirdPersonAttachment, thirdPersonAttachment);
}
WeaponInfo& wi = m_ActiveWeapons[player];
wi.Player = player;
wi.WeaponEntity = player;
wi.FirstPersonEntity = firstPersonWeapon;
wi.ThirdPersonEntity = thirdPersonWeapon;
OnEquip(cWeapon, wi);
}
void holsterWeapon(ComponentWrapper cWeapon, EntityWrapper player)
{
auto activeWeapon = getActiveWeapon(player);
if (!activeWeapon) {
return;
}
WeaponInfo& wi = *activeWeapon;
// Send holster event
OnHolster(cWeapon, wi);
// Delete weapon entities
if (wi.FirstPersonEntity.Valid()) {
m_World->DeleteEntity(wi.FirstPersonEntity.ID);
}
if (wi.ThirdPersonEntity.Valid()) {
m_World->DeleteEntity(wi.ThirdPersonEntity.ID);
}
// Make weapon inactive
m_ActiveWeapons.erase(player);
m_ActiveWeapons[player].WeaponComponent = m_ComponentType;
m_ActiveWeapons[player].Player = player;
m_ActiveWeapons[player].WeaponEntity = player;
m_ActiveWeapons[player].FirstPersonEntity = firstPersonWeapon;
m_ActiveWeapons[player].ThirdPersonEntity = thirdPersonWeapon;
}
};
-3
View File
@@ -46,9 +46,6 @@
<xs:include schemaLocation="Components/Page.xsd"/>
<xs:include schemaLocation="Components/SpriteIndicator.xsd"/>
<xs:include schemaLocation="Components/Button.xsd"/>
<xs:include schemaLocation="Components/DoubleJump.xsd"/>
<xs:include schemaLocation="Components/WeaponAttachment.xsd"/>
<xs:include schemaLocation="Components/DefenderWeapon.xsd"/>
<xs:include schemaLocation="Components/SidearmWeapon.xsd"/>
<xs:include schemaLocation="Components/CapturePointGameMode.xsd"/>
</xs:schema>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<CapturePointGameMode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CapturePointGameMode.xsd">
<RespawnTime>0.0</RespawnTime>
<MaxRespawnTime>8.0</MaxRespawnTime>
</CapturePointGameMode>
@@ -1,18 +0,0 @@
<?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="CapturePointGameMode">
<xs:complexType>
<xs:all>
<xs:element name="RespawnTime" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>The time since the last respawn wave. Players will be spawned when this reaches MaxRespawnTime.</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="MaxRespawnTime" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>Players will be spawned when RespawnTime reaches this.</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -4,18 +4,6 @@
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:include schemaLocation="../Types/WeaponSlotEnum.xsd"/>
<xs:complexType name="WeaponStateEnum" mixed="true">
<xs:complexContent>
<xs:extension base="t:enum">
<xs:choice>
<xs:element name="Idle" type="t:int" fixed="0" minOccurs="0"/>
<xs:element name="Firing" type="t:int" fixed="1" minOccurs="0"/>
<xs:element name="Reloading" type="t:int" fixed="2" minOccurs="0"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="DefenderWeapon">
<xs:complexType>
<xs:all>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<DoubleJump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="DoubleJump.xsd">
<DoubleJumpSpeed>4.0</DoubleJumpSpeed>
</DoubleJump>
@@ -1,16 +0,0 @@
<?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="DoubleJump">
<xs:annotation><xs:documentation>Enables a Player to double jump.</xs:documentation></xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="DoubleJumpSpeed" type="t:float" minOccurs="0">
<xs:annotation><xs:documentation>Vertical velocity set on double jump.</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
-1
View File
@@ -2,7 +2,6 @@
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
<MovementSpeed>3</MovementSpeed>
<CrouchSpeed>1.5</CrouchSpeed>
<JumpSpeed>4.0</JumpSpeed>
<CurrentWishDirection X="0" Y="0" Z="0"/>
<CurrentWeapon></CurrentWeapon>
</Player>
-3
View File
@@ -11,9 +11,6 @@
<xs:all>
<xs:element name="MovementSpeed" type="t:float" minOccurs="0"/>
<xs:element name="CrouchSpeed" type="t:float" minOccurs="0"/>
<xs:element name="JumpSpeed" type="t:float" minOccurs="0">
<xs:annotation><xs:documentation>Vertical velocity set when jumping.</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="CurrentWishDirection" type="t:Vector" minOccurs="0"/>
<xs:element name="CurrentWeapon" type="t:string" minOccurs="0"/>
</xs:all>
@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<SidearmWeapon xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SidearmWeapon.xsd">
<MagazineAmmo>16</MagazineAmmo>
<MagazineSize>16</MagazineSize>
<BaseDamage>20</BaseDamage>
<RPM>500</RPM>
<Automatic>false</Automatic>
<ViewPunch>0.01</ViewPunch>
<ReloadTime>0.5</ReloadTime>
<EquipTime>0.5</EquipTime>
<Slot><Secondary/></Slot>
<TriggerHeld>false</TriggerHeld>
<FireCooldown>0</FireCooldown>
<IsReloading>false</IsReloading>
<ReloadTimer>0</ReloadTimer>
</SidearmWeapon>
@@ -1,52 +0,0 @@
<?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:include schemaLocation="../Types/WeaponSlotEnum.xsd"/>
<xs:complexType name="WeaponStateEnum" mixed="true">
<xs:complexContent>
<xs:extension base="t:enum">
<xs:choice>
<xs:element name="Idle" type="t:int" fixed="0" minOccurs="0"/>
<xs:element name="Firing" type="t:int" fixed="1" minOccurs="0"/>
<xs:element name="Reloading" type="t:int" fixed="2" minOccurs="0"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="SidearmWeapon">
<xs:complexType>
<xs:all>
<xs:element name="MagazineAmmo" type="t:int" minOccurs="0">
<xs:annotation><xs:documentation>Ammo currently loaded into the magazine</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="MagazineSize" type="t:int" minOccurs="0">
<xs:annotation><xs:documentation>Max number of rounds in a magazine</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="BaseDamage" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>Damage dealt if all shotgun pellets hit</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="RPM" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>Rate of fire in rounds per minute</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Automatic" type="t:bool" minOccurs="0"/>
<xs:element name="ViewPunch" type="t:float" minOccurs="0">
<xs:annotation><xs:documentation>View punch in radians for each shell fired</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="ReloadTime" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>Time it takes to load ONE SHELL into the weapon in seconds</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="EquipTime" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>Time it takes from selecting the weapon until it's ready to fire</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Slot" type="WeaponSlotEnum" minOccurs="0"/>
<xs:element name="TriggerHeld" type="t:bool" minOccurs="0"/>
<xs:element name="FireCooldown" type="t:double" minOccurs="0"/>
<xs:element name="IsReloading" type="t:bool" minOccurs="0"/>
<xs:element name="ReloadTimer" type="t:double" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -1,12 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="DefenderWeapon" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Entity name="WeaponModel" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:BoneAttachment>
<BoneName>R_Arm_Weapon_Joint</BoneName>
<PositionOffset X="0" Y="0.0480000004" Z="-0.183000013"/>
</c:BoneAttachment>
<c:Model>
<Resource>Models/Weapons/Blue/DefenderGunBlue.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0.0350000001" Z="-0.295000017"/>
<Position X="0.120430306" Y="0.775375426" Z="1.36542225"/>
</c:Transform>
</Components>
+25 -41
View File
@@ -6,12 +6,15 @@
<Origin X="0" Y="0.772000015" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/>
</c:AABB>
<c:AssaultWeapon>
<Slot>
<Secondary/>
</Slot>
</c:AssaultWeapon>
<c:Collidable/>
<c:DefenderWeapon>
<TimeSinceLastFire>102.85760837900634</TimeSinceLastFire>
<TimeSinceLastFire>1.6944730461160304</TimeSinceLastFire>
</c:DefenderWeapon>
<c:DoubleJump/>
<c:SidearmWeapon/>
<c:Health/>
<c:Physics>
<Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
@@ -368,7 +371,7 @@
<Components>
<c:Animation>
<AnimationName1>Idle</AnimationName1>
<Time1>1.8348644854054612</Time1>
<Time1>0.67172915251515519</Time1>
<Speed1>1</Speed1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
@@ -382,37 +385,25 @@
<Children>
<Entity name="PrimaryAttachment">
<Components>
<c:BoneAttachment>
<BoneName>R_Arm_Weapon_Joint</BoneName>
</c:BoneAttachment>
<c:WeaponAttachment>
<Weapon>DefenderWeapon</Weapon>
</c:WeaponAttachment>
<c:Spawner>
<EntityFile>Schema/Entities/DefenderWeaponView.xml</EntityFile>
</c:Spawner>
<c:Transform>
<Position X="0.120430619" Y="-0.229639441" Z="-0.181454554"/>
<Orientation X="0.0104045719" Y="-0.00268170005" Z="0.0428441055"/>
</c:Transform>
<c:Transform/>
<c:WeaponAttachment>
<Weapon>DefenderWeapon</Weapon>
</c:WeaponAttachment>
</Components>
<Children/>
</Entity>
<Entity name="SecondaryAttachment">
<Components>
<c:BoneAttachment>
<BoneName>R_Arm_Weapon_Joint</BoneName>
</c:BoneAttachment>
<c:WeaponAttachment>
<Weapon>SidearmWeapon</Weapon>
</c:WeaponAttachment>
<c:Spawner>
<EntityFile>Schema/Entities/SidearmWeaponView.xml</EntityFile>
<EntityFile>Schema/Entities/AssaultWeaponView.xml</EntityFile>
</c:Spawner>
<c:Transform>
<Position X="0.120430619" Y="-0.229639441" Z="-0.181454554"/>
<Orientation X="0.0104045719" Y="-0.00268170005" Z="0.0428441055"/>
</c:Transform>
<c:Transform/>
<c:WeaponAttachment>
<Weapon>AssaultWeapon</Weapon>
</c:WeaponAttachment>
</Components>
<Children/>
</Entity>
@@ -438,7 +429,6 @@
<Components>
<c:Animation>
<AnimationName1>Idle</AnimationName1>
<Time1>0.013134522267137072</Time1>
<Speed1>1</Speed1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
@@ -458,37 +448,31 @@
<Children>
<Entity name="PrimaryAttachment">
<Components>
<c:Spawner>
<EntityFile>Schema/Entities/DefenderWeaponWorld.xml</EntityFile>
</c:Spawner>
<c:Transform/>
<c:WeaponAttachment>
<Weapon>DefenderWeapon</Weapon>
<Person>
<ThirdPerson/>
</Person>
</c:WeaponAttachment>
<c:Spawner>
<EntityFile>Schema/Entities/DefenderWeaponWorld.xml</EntityFile>
</c:Spawner>
<c:Transform/>
</Components>
<Children/>
</Entity>
<Entity name="SecondaryAttachment">
<Components>
<c:BoneAttachment>
<BoneName>R_Arm_Weapon_Joint</BoneName>
</c:BoneAttachment>
<c:Spawner>
<EntityFile>Schema/Entities/AssaultWeaponWorld.xml</EntityFile>
</c:Spawner>
<c:Transform/>
<c:WeaponAttachment>
<Weapon>SidearmWeapon</Weapon>
<Weapon>AssaultWeapon</Weapon>
<Person>
<ThirdPerson/>
</Person>
</c:WeaponAttachment>
<c:Spawner>
<EntityFile>Schema/Entities/SidearmWeaponWorld.xml</EntityFile>
</c:Spawner>
<c:Transform>
<Position X="0.156846598" Y="1.03287792" Z="-0.216207206"/>
<Orientation X="-0.0626498386" Y="-0.0301200207" Z="0.12067578"/>
</c:Transform>
</Components>
<Children/>
</Entity>
-1
View File
@@ -15,7 +15,6 @@
<c:DefenderWeapon>
<TimeSinceLastFire>1.6944730461160304</TimeSinceLastFire>
</c:DefenderWeapon>
<c:DoubleJump/>
<c:Health/>
<c:Physics>
<Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Effects/Ray.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="1" B="0" G="0" R="1"/>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0.690654039" Z="2.69841838"/>
<Scale X="2" Y="0.0260000005" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
-43
View File
@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform>
<Scale X="0" Y="1" Z="1"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Effects/Ray.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="1" B="0" G="0" R="1"/>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="-50"/>
<Scale X="100" Y="0.0260000005" Z="0"/>
<Orientation X="0" Y="-1.57099998" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Effects/Ray.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="1" B="0" G="0" R="1"/>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="-50"/>
<Scale X="100" Y="0.0260000005" Z="0"/>
<Orientation X="0" Y="-1.57099998" Z="3.1400001"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
@@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="SidearmWeapon" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Model>
<Resource>Models/Weapons/SecondaryWeapon.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-0.00200000009" Y="0.0600000024" Z="-0.297000021"/>
</c:Transform>
</Components>
<Children>
<Entity name="WeaponMuzzle">
<Components>
<c:Spawner>
<EntityFile>Schema/Entities/Ray2Red.xml</EntityFile>
</c:Spawner>
<c:Transform>
<Position X="0" Y="0.105000004" Z="-0.256000012"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="AmmunitionHUD">
<Components>
<c:AmmunitionHUD/>
<c:Transform>
<Position X="-0.0300000012" Y="0.077000007" Z="-0.063000001"/>
<Scale X="0.400000006" Y="0.400000006" Z="0.400000006"/>
</c:Transform>
</Components>
<Children>
<Entity name="AmmunitionHUDBackground">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0" G="0" R="0"/>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="-0.00300000003"/>
<Scale X="0.119999997" Y="0.119999997" Z="0.119999997"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="AmmunitionText">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity name="MagazineAmmo">
<Components>
<c:Text>
<Content>16</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
</c:Text>
<c:Transform>
<Position X="0" Y="-0.00600000005" Z="0"/>
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Infinity!">
<Components>
<c:Text>
<Content>8</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
</c:Text>
<c:Transform>
<Position X="0.0150000006" Y="-0.029000001" Z="0"/>
<Scale X="0.0399999991" Y="0.0399999991" Z="0.0399999991"/>
<Orientation X="0" Y="0" Z="1.5710001"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="SidearmWeapon" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Model>
<Resource>Models/Weapons/SecondaryWeapon.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-0.0160000008" Y="0.0800000057" Z="-0.275000006"/>
</c:Transform>
</Components>
<Children>
<Entity name="WeaponMuzzle">
<Components>
<c:Spawner>
<EntityFile>Schema/Entities/RayBlue.xml</EntityFile>
</c:Spawner>
<c:Transform>
<Position X="0.0123999491" Y="0.102453232" Z="-0.273824364"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
-1
View File
@@ -52,7 +52,6 @@
<xs:element ref="c:Button" minOccurs="0"/>
<xs:element ref="c:WeaponAttachment" minOccurs="0"/>
<xs:element ref="c:DefenderWeapon" minOccurs="0"/>
<xs:element ref="c:SidearmWeapon" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
+3 -4
View File
@@ -171,8 +171,7 @@ void main()
vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed);
color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel));
float specularResult = (specularTexel.r + specularTexel.g + specularTexel.b)/3.0;
vec4 reflectionTotal = reflectionColor * (1-specularTexel.a) * color_result.a;
color_result = color_result * clamp(1/specularTexel.a, 0, 1) + reflectionTotal;
color_result = color_result * clamp(1/specularTexel, 0, 1)*2 + reflectionColor * clamp(specularTexel, 0, 1)/2;
//vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color;
@@ -183,9 +182,9 @@ void main()
}
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
//sceneColor = vec4(reflectionColor.xyz, 1);
color_result.xyz += glowTexel.xyz*GlowIntensity;
color_result += glowTexel*GlowIntensity;
bloomColor = vec4(max(color_result.xyz - 1.0, 0.0), clamp(color_result.a, 0, 1));
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), clamp(color_result.a, 0, 1));
//Tiled Debug Code
/*
+27
View File
@@ -0,0 +1,27 @@
#version 430
layout (binding = 1) uniform sampler2D DepthStencilTexture;
layout (binding = 2) uniform sampler2D SceneTexture;
layout (binding = 3) uniform sampler2D BloomTexture;
in VertexData{
vec2 TextureCoordinate;
}Input;
out vec4 sceneColor;
out vec4 bloomColor;
void main()
{
float texel = texelFetch(DepthStencilTexture, ivec2(gl_FragCoord.xy / 8.0f), 0).g;
if(texel >= 0.9f)
{
discard;
}
sceneColor = vec4(texture2D(SceneTexture, Input.TextureCoordinate).rgb * texel, 1.0f);
bloomColor = vec4(texture2D(BloomTexture, Input.TextureCoordinate).rgb * texel, 1.0f);
//sceneColor = texel;
//bloomColor = vec4(1,0.5,0.7,1);
}
+1 -4
View File
@@ -12,7 +12,6 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
if (!boundingBox) {
return;
}
ComponentWrapper& cTransform = entity["Transform"];
EntityAABB& boxA = *boundingBox;
bool everHitTheGround = false;
@@ -87,12 +86,10 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity);
glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"];
bool notMovingxz = glm::all(glm::lessThan(glm::abs(glm::vec2(inOutVelocity.x, inOutVelocity.z)), glm::vec2(0.01f))) && prevPosIt != m_PrevPositions.end();
bool isOnGround = (bool)cPhysics["IsOnGround"];
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
//Move the position to previous position if it is not moving in the xz-plane, else resolve with the resolution vector.
(glm::vec3&)cTransform["Position"] += notMovingxz ? prevPosIt->second - boxA.Origin() : resolutionVector;
(glm::vec3&)cTransform["Position"] += resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
cPhysics["Velocity"] = inOutVelocity;
if (isOnGround) {
+2 -2
View File
@@ -33,8 +33,8 @@ void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int
va_end(args);
if (logLevel == LOG_LEVEL_ERROR) {
std::cerr << file << ":" << line << " " << func << std::endl;
std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
//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;
}
+7 -59
View File
@@ -338,15 +338,6 @@ bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci)
}
}
if (ci.Name == "Spawner") {
if (ImGui::Button("Activate")) {
Events::SpawnerSpawn e;
e.Spawner = entity;
e.Parent = entity;
m_EventBroker->Publish(e);
}
}
return true;
}
@@ -390,52 +381,14 @@ bool EditorGUI::drawComponentField_Vector(ComponentWrapper &c, const ComponentIn
// Limit scale values to a minimum of 0
return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits<float>::max());
} else if (field.Name == "Orientation") {
//glm::vec3 tempVal = val;
glm::vec3 originalVal = val;
ImVec2 cursorPos = ImGui::GetCursorScreenPos();
glm::tvec3<bool> isSnapping(false, false, false);
bool changed = ImGui::DragFloat3("", glm::value_ptr(val), 0.066666f);
if (changed) {
// Make orentations have a period of 2*Pi
val = glm::fmod(val, glm::vec3(glm::two_pi<float>()));
for (int i = 0; i < 3; i++) {
if (val[i] < 0) {
val[i] += glm::two_pi<float>();
}
}
// Make orentations have a period of 2*Pi
glm::vec3 tempVal = glm::fmod(val, glm::vec3(glm::two_pi<float>()));
if (ImGui::SliderFloat3("", glm::value_ptr(tempVal), 0.f, glm::two_pi<float>())) {
val = tempVal;
return true;
} else {
return false;
}
// Snap to angle
//float snapRange = glm::pi<float>() / 15.f;
//float snapAngle = glm::quarter_pi<float>();
//glm::vec3 snap = glm::fmod(val, glm::vec3(snapAngle));
//for (int i = 0; i < 3; i++) {
// isSnapping[i] = glm::abs(snap[i] - (snapRange / 2.f)) < snapRange;
//}
//if (changed && ImGui::IsMouseDown(0)) {
// glm::vec3 change = val - originalVal;
// for (int i = 0; i < 3; i++) {
// if (isSnapping[i] && glm::abs(change[i]) < snapRange) {
// val[i] -= snap[i] - snapRange;
// }
// }
//}
// Draw snapping outline
float width = ImGui::CalcItemWidth() / 3.f;;
float spacing = GImGui->Style.ItemInnerSpacing.x;
for (int i = 0; i < 3; i++) {
if (isSnapping[i]) {
ImVec2 pos = cursorPos + ImVec2(i * (width + spacing), 0.f);
ImRect bb(pos - ImVec2(1, 1), pos + ImVec2(width, 17));
auto window = ImGui::GetCurrentWindow();
const ImU32 col = window->Color(ImGuiCol_HeaderActive);
window->DrawList->AddRect(bb.Min, bb.Max, col, 3.f);
}
}
return changed;
} else {
return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
}
@@ -627,11 +580,6 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode)
bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
{
ImGuiIO& io = ImGui::GetIO();
if (io.WantCaptureKeyboard) {
return false;
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_S) {
if (m_CurrentSelection.Valid()) {
EntityWrapper baseParent = m_CurrentSelection;
+110 -34
View File
@@ -11,6 +11,7 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCulling
InitializeTextures();
InitializeShaderPrograms();
InitializeFrameBuffers();
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
}
void DrawFinalPass::InitializeTextures()
@@ -36,24 +37,34 @@ void DrawFinalPass::InitializeFrameBuffers()
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1)));
m_FinalPassFrameBuffer.Generate();
GLERROR("FBO generation");
glGenRenderbuffers(1, &m_DepthBufferLowRes);
/* glGenRenderbuffers(1, &m_DepthBufferLowRes);
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBufferLowRes);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, (int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate));
GLERROR("RenderBufferLowRes generation");
GLERROR("RenderBufferLowRes generation");*/
CommonFunctions::GenerateTexture(&m_DepthBufferLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST,
glm::vec2((int)(m_Renderer->GetViewportSize().Width / m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height / m_ShieldPixelRate)),
GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
CommonFunctions::GenerateTexture(&m_SceneTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), 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);
CommonFunctions::GenerateTexture(&m_BloomTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), 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_StencilTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_STENCIL, GL_STENCIL_INDEX8, GL_INT);
m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBufferLowRes, GL_DEPTH_STENCIL_ATTACHMENT)));
m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_DepthBufferLowRes, GL_DEPTH_STENCIL_ATTACHMENT)));
//m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_StencilTexture, GL_STENCIL_ATTACHMENT)));
m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SceneTextureLowRes, GL_COLOR_ATTACHMENT0)));
m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_BloomTextureLowRes, GL_COLOR_ATTACHMENT1)));
m_FinalPassFrameBufferLowRes.Generate();
GLERROR("FBO2 generation");
m_FinalPassFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(m_DepthBuffer, GL_DEPTH_STENCIL_ATTACHMENT)));
m_MergeFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_SceneTexture, GL_COLOR_ATTACHMENT0)));
m_MergeFrameBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1)));
m_MergeFrameBuffer.Generate();
GLERROR("FBO3 generation");
}
void DrawFinalPass::InitializeShaderPrograms()
@@ -168,6 +179,15 @@ void DrawFinalPass::InitializeShaderPrograms()
m_FillDepthBufferSkinnedProgram->Compile();
m_FillDepthBufferSkinnedProgram->Link();
GLERROR("Creating DepthFill program");
m_MergeProgram = ResourceManager::Load<ShaderProgram>("#MergeProgram");
m_MergeProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
m_MergeProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/MergeProgram.frag.glsl")));
m_MergeProgram->Compile();
m_MergeProgram->BindFragDataLocation(0, "sceneColor");
m_MergeProgram->BindFragDataLocation(1, "bloomColor");
m_MergeProgram->Link();
GLERROR("Creating merge program");
}
void DrawFinalPass::Draw(RenderScene& scene)
@@ -179,40 +199,39 @@ void DrawFinalPass::Draw(RenderScene& scene)
state->Disable(GL_DEPTH_TEST);
}
//TODO: Do we need check for this or will it be per scene always?
state->Enable(GL_STENCIL_TEST);
glClearStencil(0x00);
glClear(GL_STENCIL_BUFFER_BIT);
//Fill depth buffer
//Draw Opaque shielded objects
state->Disable(GL_STENCIL_TEST);
DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene);
GLERROR("OpaqueObjects");
DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene); //might need changing
GLERROR("Shielded Opaque object");
//DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle());
//Draw shields to stencil pass
state->Enable(GL_STENCIL_TEST);
state->StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
state->StencilFunc(GL_ALWAYS, 1, 0xFF);
state->StencilMask(0xFF);
DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene);
GLERROR("StencilPass");
state->StencilMask(0x00);
DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene);
GLERROR("OpaqueObjects");
//state->BlendFunc(GL_ONE, GL_ONE);
state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene);
GLERROR("TransparentObjects");
//state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawSprites(scene.Jobs.SpriteJob, scene);
GLERROR("SpriteJobs");
//state->BlendFunc(GL_ONE, GL_ONE);
//DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene);
//GLERROR("TransparentObjects");
//DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle());
//Draw shields to stencil pass
state->StencilFunc(GL_ALWAYS, 1, 0xFF);
state->StencilMask(0xFF);
DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene);
GLERROR("StencilPass");
////Draw Transparen Shielded objects
//DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene); //might need changing
//GLERROR("Shielded Transparent objects");
//Draw Opaque shielded objects
state->StencilFunc(GL_NOTEQUAL, 1, 0xFF);
state->StencilMask(0x00);
DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene); //might need changing
GLERROR("Shielded Opaque object");
//Draw Transparen Shielded objects
DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene); //might need changing
GLERROR("Shielded Transparent objects");
// state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// DrawSprites(scene.Jobs.SpriteJob, scene);
// GLERROR("SpriteJobs");
GLERROR("END");
delete state;
@@ -222,6 +241,11 @@ void DrawFinalPass::Draw(RenderScene& scene)
//Draw the lowres texture that will be shown behind the shield.
stateLowRes->Enable(GL_SCISSOR_TEST);
stateLowRes->Enable(GL_DEPTH_TEST);
stateLowRes->DepthMask(GL_TRUE);
stateLowRes->Enable(GL_STENCIL_TEST);
stateLowRes->StencilFunc(GL_NOTEQUAL, 1, 0xFF);
stateLowRes->StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
stateLowRes->StencilMask(0xFF);
//TODO: Viewports and scissor should be in state
glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_ShieldPixelRate, m_Renderer->GetViewportSize().Height/m_ShieldPixelRate);
glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
@@ -233,18 +257,20 @@ void DrawFinalPass::Draw(RenderScene& scene)
stateLowRes->StencilFunc(GL_ALWAYS, 1, 0xFF);
stateLowRes->StencilMask(0x00);
DrawToDepthBuffer(scene.Jobs.OpaqueObjects, scene);
DrawToDepthBuffer(scene.Jobs.TransparentObjects, scene);
//DrawToDepthBuffer(scene.Jobs.TransparentObjects, scene);
//Draw shields to stencil pass
stateLowRes->StencilFunc(GL_ALWAYS, 1, 0xFF);
stateLowRes->StencilFunc(GL_NOTEQUAL, 1, 0xFF);
stateLowRes->StencilMask(0xFF);
stateLowRes->Enable(GL_DEPTH_TEST);
stateLowRes->DepthMask(GL_FALSE);
DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene);
GLERROR("StencilPass");
//glClear(GL_DEPTH_BUFFER_BIT);
stateLowRes->Enable(GL_DEPTH_TEST);
//stateLowRes->DepthMask(GL_TRUE);
stateLowRes->DepthFunc(GL_LEQUAL);
stateLowRes->StencilFunc(GL_LEQUAL, 1, 0xFF);
stateLowRes->StencilMask(0x00);
DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene);
@@ -254,6 +280,34 @@ void DrawFinalPass::Draw(RenderScene& scene)
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
delete stateLowRes;
m_FinalPassFrameBuffer.Unbind();
m_FinalPassFrameBufferLowRes.Unbind();
state = new DrawFinalPassState(m_MergeFrameBuffer.GetHandle());
state->Disable(GL_DEPTH_TEST);
state->Enable(GL_STENCIL_TEST);
state->StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
state->StencilFunc(GL_LEQUAL, 1, 0xFF);
state->StencilMask(0x00);
MergeLayers();
delete state;
state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle());
//Draw Transparancy
state->BlendFunc(GL_ONE, GL_ONE);
DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene);
GLERROR("TransparentObjects");
//Draw Transparen Shielded objects
DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene); //might need changing
GLERROR("Shielded Transparent objects");
state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawSprites(scene.Jobs.SpriteJob, scene);
GLERROR("SpriteJobs");
GLERROR("END");
delete state;
}
@@ -720,6 +774,28 @@ void DrawFinalPass::DrawSprites(std::list<std::shared_ptr<RenderJob>>&jobs, Rend
// m_SpriteProgram->Unbind();
}
void DrawFinalPass::MergeLayers()
{
GLuint shaderHandle = m_MergeProgram->GetHandle();
m_MergeProgram->Bind();
GLERROR("MergeLayers 1");
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_DepthBufferLowRes);
GLERROR("MergeLayers 2");
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, m_SceneTextureLowRes);
GLERROR("MergeLayers 3");
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, m_BloomTextureLowRes);
GLERROR("MergeLayers 4");
glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
GLERROR("MergeLayers 5");
}
void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<ExplosionEffectJob>& job, RenderScene& scene)
{
glUniform1i(glGetUniformLocation(shaderHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
+4 -4
View File
@@ -11,10 +11,10 @@ DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer)
DepthMask(GL_FALSE);
DepthFunc(GL_LEQUAL);
Enable(GL_CULL_FACE);
Enable(GL_STENCIL_TEST);
StencilFunc(GL_NOTEQUAL, 1, 0xFF);
StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
StencilMask(0xFF);
//Enable(GL_STENCIL_TEST);
//StencilFunc(GL_NOTEQUAL, 1, 0xFF);
//StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
//StencilMask(0xFF);
ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f));
}
@@ -9,6 +9,7 @@ PickingPassState::PickingPassState(GLuint frameBuffer)
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
Disable(GL_BLEND);
glm::vec4 clearColor = glm::vec4(0.f);
//ClearColor(clearColor);
//Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+1 -1
View File
@@ -17,7 +17,7 @@ void Renderer::Initialize()
m_TextPass->Initialize();
/* m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_UnitQuad = ResourceManager::Load<Model>(sModels/Core/UnitQuad.obj");
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");*/
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
+2 -5
View File
@@ -17,7 +17,6 @@
#include "Game/Systems/AmmoPickupSystem.h"
#include "Game/Systems/DamageIndicatorSystem.h"
#include "Game/Systems/Weapon/DefenderWeaponBehaviour.h"
#include "Game/Systems/Weapon/SidearmWeaponBehaviour.h"
#include "Rendering/AnimationSystem.h"
#include "Game/Systems/HealthHUDSystem.h"
#include "Rendering/BoneAttachmentSystem.h"
@@ -49,6 +48,7 @@ Game::Game(int argc, char* argv[])
ResourceManager::UseThreading = m_Config->Get<bool>("Multithreading.ResourceLoading", true);
DisableMemoryPool::Value = m_Config->Get<bool>("Debug.DisableMemoryPool", false);
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
PlayerSpawnSystem::SetRespawnTime(m_Config->Get<float>("Debug.RespawnTime", 15.0f));
// Create the core event broker
m_EventBroker = new EventBroker();
@@ -125,7 +125,6 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<DefenderWeaponBehaviour>(updateOrderLevel, m_Renderer, m_OctreeCollision);
m_SystemPipeline->AddSystem<SidearmWeaponBehaviour>(updateOrderLevel, m_Renderer, m_OctreeCollision);
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CapturePointHUDSystem>(updateOrderLevel);
@@ -140,6 +139,7 @@ Game::Game(int argc, char* argv[])
++updateOrderLevel;
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeTrigger, "Player");
m_SystemPipeline->AddSystem<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<UniformScaleSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<HealthHUDSystem>(updateOrderLevel);
@@ -149,9 +149,6 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<BoneAttachmentSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
m_SystemPipeline->AddSystem<TriggerSystem>(updateOrderLevel, m_OctreeTrigger);
// Octree for frustum culling must be updated after collisions, otherwise players frustum may be moved after tree is filled, and wrong things are culled.
++updateOrderLevel;
m_SystemPipeline->AddSystem<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
++updateOrderLevel;
m_SystemPipeline->AddSystem<RenderSystem>(updateOrderLevel, m_Renderer, m_RenderFrame, m_OctreeFrustrumCulling);
++updateOrderLevel;
+6 -11
View File
@@ -116,18 +116,12 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity));
}
if (isOnGround) {
controller->SetDoubleJumping(false);
}
//If player presses Jump and is not crouching.
if (controller->Jumping() && !controller->Crouching()) {
//you cant jump and dash at the same time - since there is no friction in the air and we would thus dash much further in the air
if (!controller->PlayerIsDashing() && controller->Jumping() && !controller->Crouching() && (isOnGround || !controller->DoubleJumping())) {
(bool)cPhysics["IsOnGround"] = false;
if (isOnGround) {
(bool)cPhysics["IsOnGround"] = false;
velocity.y = player["Player"]["JumpSpeed"];
} else if (player.HasComponent("DoubleJump") && !controller->DoubleJumping()) {
//Enter here if player can double jump and is doing so.
(bool)cPhysics["IsOnGround"] = false;
velocity.y = player["DoubleJump"]["DoubleJumpSpeed"];
controller->SetDoubleJumping(false);
} else {
// If IsServer and network is off this will not work
if (IsClient) {
//put a hexagon at the players feet
@@ -139,6 +133,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
m_EventBroker->Publish(e);
}
}
velocity.y = 4.f;
}
if (player.HasComponent("AABB")) {
+12 -23
View File
@@ -1,40 +1,29 @@
#include "Systems/PlayerSpawnSystem.h"
//This should be set by the config anyway.
float PlayerSpawnSystem::m_RespawnTime = 15.0f;
PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params)
: System(params)
, m_DbgConfigForceRespawn(false)
, m_Timer(0.f)
{
EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerSpawnSystem::OnPlayerDeath);
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
m_NetworkEnabled = config->Get("Networking.StartNetwork", false);
m_ForcedRespawnTime = config->Get("Debug.RespawnTime", -1.0f);
m_DbgConfigForceRespawn = m_ForcedRespawnTime > 0;
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
}
void PlayerSpawnSystem::Update(double dt)
{
// If there are no CapturePointGameMode components we will just spawn immediately.
// Should be able to support older maps with this.
// TODO: In the future we might want to return instead, to avoid spawning in the menu for instance.
auto pool = m_World->GetComponents("CapturePointGameMode");
if (pool != nullptr && pool->size() > 0)
{
// Take the first CapturePointGameMode component found.
ComponentWrapper& modeComponent = *pool->begin();
// Increase timer.
double& timer = (double&)modeComponent["RespawnTime"];
timer += dt;
double maxRespawnTime = m_DbgConfigForceRespawn ? m_ForcedRespawnTime : (double)modeComponent["MaxRespawnTime"];
if (timer < maxRespawnTime) {
return;
}
// If respawn time has passed, we spawn all players that have requested to be spawned.
timer = 0;
//Increase timer.
m_Timer += dt;
if (m_Timer < m_RespawnTime) {
return;
}
//If respawn time has passed, we spawn all players that have requested to be spawned.
m_Timer = 0.f;
// If there are no spawn requests, return immediately, if we are client the SpawnRequests should always be empty.
//If there are no spawn requests, return immediately, if we are client the SpawnRequests should always be empty.
if (m_SpawnRequests.size() == 0) {
return;
}
@@ -6,32 +6,36 @@ void DefenderWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWr
WeaponBehaviour::UpdateComponent(entity, cWeapon, dt);
}
void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt)
void DefenderWeaponBehaviour::UpdateWeapon(WeaponInfo& wi, double dt)
{
ComponentWrapper cWeapon = wi.GetComponent();
bool isFiring = cWeapon["IsFiring"];
bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]);
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
if (isFiring && cooldownPassed && isNotShielding) {
fireShell(cWeapon, wi);
fireShell(wi);
}
}
void DefenderWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
void DefenderWeaponBehaviour::OnPrimaryFire(WeaponInfo& wi)
{
ComponentWrapper cWeapon = wi.GetComponent();
cWeapon["IsFiring"] = true;
bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]);
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
if (cooldownPassed && isNotShielding) {
fireShell(cWeapon, wi);
fireShell(wi);
}
}
void DefenderWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
void DefenderWeaponBehaviour::OnCeasePrimaryFire(WeaponInfo& wi)
{
ComponentWrapper cWeapon = wi.GetComponent();
cWeapon["IsFiring"] = false;
}
bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e)
bool DefenderWeaponBehaviour::OnInputCommand(WeaponInfo& wi, const Events::InputCommand& e)
{
if (e.Command == "SpecialAbility" && IsServer) {
EntityWrapper attachment = wi.Player.FirstChildByName("ShieldAttachment");
@@ -47,8 +51,16 @@ bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInf
return false;
}
void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi)
bool DefenderWeaponBehaviour::OnSetCamera(const Events::SetCamera& e)
{
m_CurrentCamera = e.CameraEntity;
return true;
}
void DefenderWeaponBehaviour::fireShell(WeaponInfo& wi)
{
ComponentWrapper cWeapon = wi.GetComponent();
cWeapon["TimeSinceLastFire"] = 0.0;
int numPellets = cWeapon["NumPellets"];
float spreadAngle = cWeapon["SpreadAngle"];
@@ -83,13 +95,13 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi
orientation.x += angles.x;
orientation.y += angles.y;
glm::vec3 trajectory = direction * distance;
dealDamage(cWeapon, wi, direction, pelletDamage);
dealDamage(wi, direction, pelletDamage);
}
}
}
void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage)
void DefenderWeaponBehaviour::dealDamage(WeaponInfo& wi, glm::vec3 direction, double damage)
{
// Only deal damage client side
if (!IsClient) {
@@ -148,6 +160,18 @@ void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& w
LOG_DEBUG("Damage: %f", damage);
}
float DefenderWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direction)
{
float distance;
glm::vec3 pos;
auto entity = Collision::EntityFirstHitByRay(Ray(origin, direction), m_CollisionOctree, distance, pos);
if (entity) {
return distance;
} else {
return 100.f;
}
}
Camera DefenderWeaponBehaviour::cameraFromEntity(EntityWrapper camera)
{
ComponentWrapper cTransform = camera["Transform"];
@@ -1,79 +0,0 @@
#include "Systems/Weapon/SidearmWeaponBehaviour.h"
void SidearmWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt)
{
double& cooldown = cWeapon["FireCooldown"];
if (cooldown > 0) {
cooldown -= dt;
if (cooldown < 0) {
cooldown = 0;
}
}
WeaponBehaviour::UpdateComponent(entity, cWeapon, dt);
}
void SidearmWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt)
{
if ((bool)cWeapon["Automatic"] && canFire(cWeapon)) {
fireBullet(cWeapon, wi);
}
}
void SidearmWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["TriggerHeld"] = true;
if (canFire(cWeapon)) {
fireBullet(cWeapon, wi);
}
}
void SidearmWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["TriggerHeld"] = false;
}
void SidearmWeaponBehaviour::OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["FireCooldown"] = (double)cWeapon["EquipTime"];
}
void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi)
{
// Make sure the trigger is released if weapon is holstered while firing
cWeapon["TriggerHeld"] = false;
// Cancel any reload
cWeapon["IsReloading"] = false;
cWeapon["ReloadTimer"] = 0.0;
LOG_DEBUG("HOLSTER");
}
void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"];
// Get weapon model based on current person
EntityWrapper weaponModelEntity = getRelevantWeaponModelEntity(wi);
if (!weaponModelEntity.Valid()) {
return;
}
// Tracer
EntityWrapper tracerSpawner = weaponModelEntity.FirstChildByName("WeaponMuzzle");
if (tracerSpawner.Valid()) {
glm::vec3 origin = Transform::AbsolutePosition(tracerSpawner);
glm::vec3 direction = Transform::AbsoluteOrientation(tracerSpawner) * glm::vec3(0, 0, -1);
float distance = traceRayDistance(origin, direction);
EntityWrapper ray = SpawnerSystem::Spawn(tracerSpawner);
((glm::vec3&)ray["Transform"]["Scale"]).z = (distance / 100.f);
}
}
bool SidearmWeaponBehaviour::canFire(ComponentWrapper cWeapon)
{
bool triggerHeld = cWeapon["TriggerHeld"];
double& cooldown = cWeapon["FireCooldown"];
// TODO: Ammo checks
return triggerHeld && cooldown <= 0.0;
}