Changes to player, and mesh renderer INCOMPLETE

This commit is contained in:
onTheZero
2025-08-15 16:12:18 -04:00
parent 4bf6b02255
commit 5201ca46ec
22 changed files with 3282 additions and 228 deletions

91
Camera.cpp Normal file
View File

@@ -0,0 +1,91 @@
#include "Camera.h"
glm::vec3 CameraOffset;
float MovementSpeed;
float MouseSensitivity;
float Zoom;
Camera::Camera(GLFWwindow* Window)
: GameObject(glm::vec3(0.0f), glm::vec3(0.0f), glm::vec3(0.0f)),
Window(Window)
{
}
glm::mat4 Camera::GetViewMatrix()
{
return glm::lookAt(Position, Position + Front, Up);
}
void Camera::SetOffset(glm::vec3 Offset)
{
this->Offset = Offset;
}
void Camera::MoveCamera(glm::vec3 Position)
{
this->Position = Position + Offset;
UpdateVectors();
}
void Camera::RotateCamera(float Yaw, float Pitch, GLboolean bConstrainPitch)
{
Rotation.y += Yaw;
Rotation.x += Pitch;
if (bConstrainPitch)
{
if (Rotation.x > 89.0f)
Rotation.x = 89.0f;
if (Rotation.x < -89.0f)
Rotation.x = -89.0f;
}
UpdateVectors();
}
void Camera::ZoomCamera(float ZoomAmount)
{
Zoom -= (float)ZoomAmount;
if (Zoom < 1.0f)
Zoom = 1.0f;
if (Zoom > 45.0f)
Zoom = 45.0f;
}
void Camera::RenderScene(
LevelMap& LevelMap,
const std::vector<PointLight>& Lights,
int ScreenWidth,
int ScreenHeight)
{
// Set viewport
glViewport(0, 0, ScreenWidth, ScreenHeight);
// Clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate matrices
glm::mat4 Projection = GetProjectionMatrix(ScreenWidth, ScreenHeight);
glm::mat4 View = GetViewMatrix();
glm::mat4 Model = glm::mat4(1.0f);
// Verify matrices are valid
if (isnan(Projection[0].x) || isnan(View[0].x)) {
std::cerr << "Invalid camera matrices!" << std::endl;
return;
}
// Let LevelMap handle its own rendering
LevelMap.Update(Projection, View, Position, Lights);
}
glm::mat4 Camera::GetProjectionMatrix(int ScreenWidth, int ScreenHeight) {
return glm::perspective(
glm::radians(Zoom),
(float)ScreenWidth / (float)ScreenHeight,
0.1f,
100.0f
);
}

0
EventManager.cpp Normal file
View File

41
EventManager.h Normal file
View File

@@ -0,0 +1,41 @@
#pragma once
#include <strstream>
#include <FastDelegate.h>
// {29A32703-A3DB-4E7C-B275-3FBA7F78FE51}
// DEFINE_GUID(<< name >> ,
// 0x29a32703, 0xa3db, 0x4e7c, 0xb2, 0x75, 0x3f, 0xba, 0x7f, 0x78, 0xfe, 0x51);
class IEventData;
typedef unsigned long EventType;
typedef std::shared_ptr<IEventData> IEventDataPtr;
typedef fastdelegate::FastDelegate1<IEventDataPtr> EventListenerDelegate;
class IEventData
{
public:
virtual const EventType& VGetEventType(void) const = 0;
virtual float VGetTimeStamp(void) const = 0;
virtual void VSerialize(std::ostrstream& out) const = 0;
virtual IEventDataPtr VCopy(void) = 0;
virtual const char* GetName(void) = 0;
};
class BaseEventData : public IEventData
{
const float m_TimeStamp;
public:
explicit BaseEventData(const float timeStamp = 0.0f) :
m_TimeStamp(timeStamp) {}
virtual ~BaseEventData(void) {}
// Returns the type of the event
virtual const EventType& VGetEventType(void) const = 0;
float VGetTimeStamp(void) const { return m_TimeStamp; }
// Serializing for network out
virtual void VSerialized(std::ostrstream& out) const {}
};

0
Events.cpp Normal file
View File

42
Events.h Normal file
View File

@@ -0,0 +1,42 @@
#pragma once
#include <EventManager.h>
typedef unsigned int GameObjectID;
class EventData_Destroy_GameObject : public BaseEventData
{
GameObjectID gID;
public:
static const EventType sk_EventType;
explicit EventData_Destroy_GameObject(GameObjectID id)
: gID(id) { }
explicit EventData_Destroy_GameObject(std::istrstream& in)
{
in >> gID;
}
virtual const EventType& VGetEventType(void) const
{
return sk_EventType;
}
virtual IEventDataPtr VCopy(void) const
{
return IEventDataPtr(new EventData_Destroy_GameObject(gID));
}
virtual void VSerialize(std::ostrstream& out) const
{
out << gID;
}
virtual const char* GetName(void) const
{
return "EventData_Destroy_GameObject";
}
GameObjectID GetID(void) const { return gID; }
};

View File

@@ -2,13 +2,14 @@
#include <glm/glm.hpp>
#include <InputComponent.h>
#include <GraphicsComponent.h>
#include <PhysicsComponent.h>
class GameObject
{
public:
unsigned int GameObjectID;
glm::vec3 Position;
glm::vec3 Rotation;
@@ -16,8 +17,7 @@ public:
glm::vec3 Scale;
GameObject(glm::vec3 Position, glm::vec3 Rotation, glm::vec3 Scale)
: Input(nullptr),
Graphics(nullptr),
: Graphics(nullptr),
Physics(nullptr),
Position(Position),
Rotation(Rotation),
@@ -27,11 +27,11 @@ public:
Right(1.0f, 0.0f, 0.0f),
WorldUp(0.0f, 1.0f, 0.0f)
{
GameObjectID = 0;
}
GameObject(InputComponent* Input, GraphicsComponent* Graphics, PhysicsComponent* Physics)
: Input(Input),
Graphics(Graphics),
GameObject(GraphicsComponent* Graphics, PhysicsComponent* Physics)
: Graphics(Graphics),
Physics(Physics),
Position(0.0f, 0.0f, 0.0f),
Rotation(0.0f, 0.0f, 0.0f),
@@ -40,17 +40,17 @@ public:
Up(0.0f, 1.0f, 0.0f),
Right(1.0f, 0.0f, 0.0f),
WorldUp(0.0f, 1.0f, 0.0f)
{}
void Update()
{
Input->Update();
Graphics->Update();
Physics->Update();
GameObjectID = 0;
}
void Update(float DeltaTime)
{
//Graphics->Update();
//Physics->Update();
}
protected:
InputComponent* Input;
GraphicsComponent* Graphics;
PhysicsComponent* Physics;
@@ -58,4 +58,15 @@ protected:
glm::vec3 Up;
glm::vec3 Right;
glm::vec3 WorldUp;
void UpdateVectors()
{
glm::vec3 UpdatedFront;
UpdatedFront.x = cos(glm::radians(Rotation.y)) * cos(glm::radians(Rotation.x));
UpdatedFront.y = sin(glm::radians(Rotation.x));
UpdatedFront.z = sin(glm::radians(Rotation.y)) * cos(glm::radians(Rotation.x));
Front = glm::normalize(UpdatedFront);
Right = glm::normalize(glm::cross(Front, WorldUp));
Up = glm::normalize(glm::cross(Right, Front));
}
};

14
IInputComponent.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
class IInputComponent
{
public:
IInputComponent(GLFWwindow* Window) : Window(Window) {};
virtual ~IInputComponent() {};
virtual void Update(float DeltaTime) = 0;
protected:
GLFWwindow* Window;
};

2108
Include/FastDelegate.h Normal file

File diff suppressed because it is too large Load Diff

243
Include/FastDelegateBind.h Normal file
View File

@@ -0,0 +1,243 @@
// FastDelegateBind.h
// Helper file for FastDelegates. Provides bind() function, enabling
// FastDelegates to be rapidly compared to programs using boost::function and boost::bind.
//
// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp
//
// Original author: Jody Hagins.
// Minor changes by Don Clugston.
//
// Warning: The arguments to 'bind' are ignored! No actual binding is performed.
// The behaviour is equivalent to boost::bind only when the basic placeholder
// arguments _1, _2, _3, etc are used in order.
//
// HISTORY:
// 1.4 Dec 2004. Initial release as part of FastDelegate 1.4.
#ifndef FASTDELEGATEBIND_H
#define FASTDELEGATEBIND_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
////////////////////////////////////////////////////////////////////////////////
// FastDelegate bind()
//
// bind() helper function for boost compatibility.
// (Original author: Jody Hagins).
//
// Add another helper, so FastDelegate can be a dropin replacement
// for boost::bind (in a fair number of cases).
// Note the elipses, because boost::bind() takes place holders
// but FastDelegate does not care about them. Getting the place holder
// mechanism to work, and play well with boost is a bit tricky, so
// we do the "easy" thing...
// Assume we have the following code...
// using boost::bind;
// bind(&Foo:func, &foo, _1, _2);
// we should be able to replace the "using" with...
// using fastdelegate::bind;
// and everything should work fine...
////////////////////////////////////////////////////////////////////////////////
#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
namespace fastdelegate {
//N=0
template <class X, class Y, class RetType>
FastDelegate< RetType ( ) >
bind(
RetType (X::*func)( ),
Y * y,
...)
{
return FastDelegate< RetType ( ) >(y, func);
}
template <class X, class Y, class RetType>
FastDelegate< RetType ( ) >
bind(
RetType (X::*func)( ) const,
Y * y,
...)
{
return FastDelegate< RetType ( ) >(y, func);
}
//N=1
template <class X, class Y, class RetType, class Param1>
FastDelegate< RetType ( Param1 p1 ) >
bind(
RetType (X::*func)( Param1 p1 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1>
FastDelegate< RetType ( Param1 p1 ) >
bind(
RetType (X::*func)( Param1 p1 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1 ) >(y, func);
}
//N=2
template <class X, class Y, class RetType, class Param1, class Param2>
FastDelegate< RetType ( Param1 p1, Param2 p2 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1, class Param2>
FastDelegate< RetType ( Param1 p1, Param2 p2 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2 ) >(y, func);
}
//N=3
template <class X, class Y, class RetType, class Param1, class Param2, class Param3>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3 ) >(y, func);
}
//N=4
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) >(y, func);
}
//N=5
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) >(y, func);
}
//N=6
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) >(y, func);
}
//N=7
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) >(y, func);
}
//N=8
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ),
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >(y, func);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >
bind(
RetType (X::*func)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const,
Y * y,
...)
{
return FastDelegate< RetType ( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) >(y, func);
}
#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
} // namespace fastdelegate
#endif // !defined(FASTDELEGATEBIND_H)

27
InputCommand.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#include <GameObject.h>
class Command
{
public:
virtual ~Command() {}
virtual void Execute(GameObject& gObject) = 0;
};
class JumpCommand
{
public:
virtual void Execute(GameObject& gObject)
{
// TODO
}
};
class MoveCommand
{
public:
virtual void Execute()
{
// TODO
}
};

View File

@@ -1,8 +0,0 @@
#pragma once
class InputComponent
{
public:
virtual ~InputComponent() {};
virtual void Update() = 0;
};

9
InputEnums.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
enum EInputDirection
{
FORWARD,
BACKWARD,
LEFT,
RIGHT
};

6
InputHandler.cpp Normal file
View File

@@ -0,0 +1,6 @@
#include "InputHandler.h"
void InputHandler::HandleInput()
{
}

14
InputHandler.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include <InputCommand.h>
class InputHandler
{
public:
void HandleInput();
private:
Command* ButtonX;
Command* ButtonY;
Command* ButtonA;
Command* ButtonB;
};

View File

@@ -108,7 +108,8 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Development Projects\LearningOpenGL;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Development Projects\LearningOpenGL\Include;C:\Development Projects\LearningOpenGL;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -124,6 +125,8 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Development Projects\LearningOpenGL\Include;</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -134,17 +137,22 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\Development Tools\glad\src\glad.c" />
<ClCompile Include="Camera.cpp" />
<ClCompile Include="EventManager.cpp" />
<ClCompile Include="Events.cpp" />
<ClCompile Include="imgui\backends\imgui_impl_glfw.cpp" />
<ClCompile Include="imgui\backends\imgui_impl_opengl3.cpp" />
<ClCompile Include="imgui\imgui.cpp" />
<ClCompile Include="imgui\imgui_draw.cpp" />
<ClCompile Include="imgui\imgui_tables.cpp" />
<ClCompile Include="imgui\imgui_widgets.cpp" />
<ClCompile Include="InputHandler.cpp" />
<ClCompile Include="LevelMap.cpp" />
<ClCompile Include="Light.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="MeshRenderer.cpp" />
<ClCompile Include="Player.cpp" />
<ClCompile Include="PlayerInputComponent.cpp" />
<ClCompile Include="PointLight.cpp" />
<ClCompile Include="ResourceManager.cpp" />
<ClCompile Include="Shader.cpp" />
@@ -168,12 +176,18 @@
<ClInclude Include="Camera.h" />
<ClInclude Include="cube.h" />
<ClInclude Include="cubeFactory.h" />
<ClInclude Include="Events.h" />
<ClInclude Include="GameObject.h" />
<ClInclude Include="GraphicsComponent.h" />
<ClInclude Include="InputComponent.h" />
<ClInclude Include="EventManager.h" />
<ClInclude Include="IInputComponent.h" />
<ClInclude Include="InputCommand.h" />
<ClInclude Include="input.txt" />
<ClInclude Include="InputEnums.h" />
<ClInclude Include="InputHandler.h" />
<ClInclude Include="LevelMap.h" />
<ClInclude Include="Light.h" />
<ClInclude Include="map_reader.h" />
<ClInclude Include="MapReader.h" />
<ClInclude Include="MeshRenderer.h" />
<ClInclude Include="PhysicsComponent.h" />
<ClInclude Include="Player.h" />

View File

@@ -13,35 +13,29 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\Events">
<UniqueIdentifier>{3b390837-0087-42d6-865a-f407f4e85689}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Player">
<UniqueIdentifier>{92d02b9a-68af-46b6-8a38-2d71c807275a}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\MapReader">
<UniqueIdentifier>{b8c509e7-d52d-4bc7-b525-9dcdaa2260ca}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\3rdParty">
<UniqueIdentifier>{82df0858-8eaf-4a3d-957a-fe1eaf4f5318}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Input">
<UniqueIdentifier>{2e56c203-baba-4213-b8c3-f6b7750ff274}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Components">
<UniqueIdentifier>{87046629-81da-4f0e-8451-6bbe46ae4a32}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\Development Tools\glad\src\glad.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_draw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_tables.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_widgets.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\backends\imgui_impl_glfw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\backends\imgui_impl_opengl3.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Player.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MeshRenderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -51,15 +45,54 @@
<ClCompile Include="ResourceManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LevelMap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Light.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PointLight.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EventManager.cpp">
<Filter>Source Files\Events</Filter>
</ClCompile>
<ClCompile Include="Events.cpp">
<Filter>Source Files\Events</Filter>
</ClCompile>
<ClCompile Include="Player.cpp">
<Filter>Source Files\Player</Filter>
</ClCompile>
<ClCompile Include="LevelMap.cpp">
<Filter>Source Files\MapReader</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui.cpp">
<Filter>Source Files\3rdParty</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_draw.cpp">
<Filter>Source Files\3rdParty</Filter>
</ClCompile>
<ClCompile Include="imgui\backends\imgui_impl_glfw.cpp">
<Filter>Source Files\3rdParty</Filter>
</ClCompile>
<ClCompile Include="imgui\backends\imgui_impl_opengl3.cpp">
<Filter>Source Files\3rdParty</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_tables.cpp">
<Filter>Source Files\3rdParty</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_widgets.cpp">
<Filter>Source Files\3rdParty</Filter>
</ClCompile>
<ClCompile Include="..\..\Development Tools\glad\src\glad.c">
<Filter>Source Files\3rdParty</Filter>
</ClCompile>
<ClCompile Include="InputHandler.cpp">
<Filter>Source Files\Input</Filter>
</ClCompile>
<ClCompile Include="PlayerInputComponent.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Camera.cpp">
<Filter>Source Files\Components</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="fragment.frag" />
@@ -80,27 +113,12 @@
<ClInclude Include="cube.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Camera.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cubeFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="map_reader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GameObject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Player.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InputComponent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PlayerInputComponent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PhysicsComponent.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -116,15 +134,48 @@
<ClInclude Include="ResourceManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LevelMap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Light.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PointLight.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EventManager.h">
<Filter>Source Files\Events</Filter>
</ClInclude>
<ClInclude Include="Events.h">
<Filter>Source Files\Events</Filter>
</ClInclude>
<ClInclude Include="Player.h">
<Filter>Source Files\Player</Filter>
</ClInclude>
<ClInclude Include="LevelMap.h">
<Filter>Source Files\MapReader</Filter>
</ClInclude>
<ClInclude Include="MapReader.h">
<Filter>Source Files\MapReader</Filter>
</ClInclude>
<ClInclude Include="InputCommand.h">
<Filter>Source Files\Input</Filter>
</ClInclude>
<ClInclude Include="InputHandler.h">
<Filter>Source Files\Input</Filter>
</ClInclude>
<ClInclude Include="input.txt">
<Filter>Source Files\Input</Filter>
</ClInclude>
<ClInclude Include="InputEnums.h">
<Filter>Source Files\Input</Filter>
</ClInclude>
<ClInclude Include="IInputComponent.h">
<Filter>Source Files\Input</Filter>
</ClInclude>
<ClInclude Include="PlayerInputComponent.h">
<Filter>Source Files\Input</Filter>
</ClInclude>
<ClInclude Include="Camera.h">
<Filter>Source Files\Components</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="map_test.txt" />

View File

@@ -1,50 +1,120 @@
#include "Player.h"
#include "Camera.h"
#include "LevelMap.h"
#include "PlayerInputComponent.h"
#include <iostream>
Player::Player(glm::vec3 Position, glm::vec3 Rotation)
: GameObject(Position, Rotation, glm::vec3(1.0f, 1.0f, 1.0f)),
PlayerCamera(new Camera(glm::vec3(0.0f, 1.0f, 0.0f)))
Player::Player(glm::vec3 position, glm::vec3 rotation, std::vector<Sector>& sectors, GLFWwindow* Window)
: GameObject(position, rotation, glm::vec3(1.0f, 1.0f, 1.0f)),
PlayerCamera(std::make_unique<Camera>(Window)),
cPlayerInput(std::make_unique<PlayerInputComponent>(Window, *this)),
LevelSectors(sectors),
CurrentSector(&sectors[0])
{
PlayerCamera->Position = Position + PlayerCamera->CameraOffset;
PlayerCamera->WorldUp = this->WorldUp;
std::cout << "{" << Position.x << ", " << Position.y << ", " << Position.z << "}" << std::endl;
std::cout << "{" << PlayerCamera->Position.x << ", " << PlayerCamera->Position.y << ", " << PlayerCamera->Position.z << "}" << std::endl;
PlayerCamera->SetOffset(glm::vec3(0.0f, 1.0f, 0.0f));
PlayerCamera->MoveCamera(Position);
PlayerCamera->Rotation = Rotation;
}
void Player::Update()
void Player::Update(float DeltaTime)
{
GameObject::Update(DeltaTime);
cPlayerInput->Update(DeltaTime);
if (bJumping)
{
Position.y += JumpVelocity * DeltaTime;
JumpVelocity -= GRAVITY * DeltaTime;
if (Position.y <= CurrentSector->floor_height)
{
JumpVelocity = 0.0f;
Position.y = CurrentSector->floor_height;
bJumping = false;
std::cout << "STOP JUMPING" << std::endl;
}
}
else if (Position.y > CurrentSector->floor_height)
{
Position.y -= GRAVITY * DeltaTime;
}
else
{
Position.y = CurrentSector->floor_height;
bJumping = false;
}
PlayerCamera->MoveCamera(Position);
}
void Player::ProcessKeyboard(EInputDirection Direction, float Delta)
void Player::Move(EInputDirection Direction, float Delta)
{
float Velocity = bIsRunning ? RunSpeed : WalkSpeed;
Velocity = Velocity * Delta;
glm::vec3 newPosition = Position;
if (Direction == FORWARD)
Position += Front * Velocity;
newPosition += Front * Velocity;
if (Direction == BACKWARD)
Position -= Front * Velocity;
newPosition -= Front * Velocity;
if (Direction == LEFT)
Position -= Right * Velocity;
newPosition -= Right * Velocity;
if (Direction == RIGHT)
Position += Right * Velocity;
newPosition += Right * Velocity;
PlayerCamera->Position = Position + PlayerCamera->CameraOffset;
PlayerCamera->WorldUp = this->WorldUp;
if (!CrossingWall(newPosition))
{
Position = newPosition;
}
for (Sector& Sector : LevelSectors)
{
glm::vec2 playerPoint = { Position.x, Position.z };
if (PointInPolygon(playerPoint, Sector.walls))
{
/*if (!bJumping)
Position.y = Sector.floor_height;*/
if (CurrentSector != &Sector)
{
std::cout << "Updating CurrentSector ("
<< (CurrentSector ? CurrentSector->index : -1)
<< ") to Sector (" << Sector.index << ")" << std::endl;
CurrentSector = &Sector;
}
break;
// TO DO: Pretty sure this limits me for sectors that contain sectors, i.e. if I want multiple floor/ceiling heights within a sector it will have to be made of multiple sectors
//std::cout << "Player in: " << sector.index << " | Player Y: " << sector.floor_height << std::endl;
}
}
}
void Player::ProcessMouseMovement(float XOffset, float YOffset, GLboolean bConstrainPitch)
void Player::Jump()
{
XOffset *= MOUSE_SENSITIVITY;
YOffset *= MOUSE_SENSITIVITY;
if (bJumping) return;
Yaw += XOffset;
PlayerCamera->Yaw = Yaw;
//std::cout << "JUMP!" << std::endl;
bJumping = true;
JumpVelocity = JumpForce;
}
PlayerCamera->ProcessMouseMovement(XOffset, YOffset);
UpdatePlayerVectors();
void Player::Sprint()
{
bIsRunning = true;
}
void Player::StopSprint()
{
bIsRunning = false;
}
void Player::Look(float Yaw, float Pitch, GLboolean bConstrainPitch)
{
Yaw *= MOUSE_SENSITIVITY;
Pitch *= MOUSE_SENSITIVITY;
Rotation.y += Yaw;
PlayerCamera->RotateCamera(Yaw, Pitch);
UpdateVectors();
}
glm::mat4 Player::GetViewMatrix() const
@@ -52,13 +122,182 @@ glm::mat4 Player::GetViewMatrix() const
return PlayerCamera->GetViewMatrix();
}
void Player::UpdatePlayerVectors()
bool Player::CrossingWall(glm::vec3 NewPosition)
{
glm::vec3 UpdatedFront;
UpdatedFront.x = cos(glm::radians(Yaw)) * cos(0);
UpdatedFront.y = sin(0);
UpdatedFront.z = sin(glm::radians(Yaw)) * cos(0);
Front = glm::normalize(UpdatedFront);
Right = glm::normalize(glm::cross(Front, WorldUp));
Up = glm::normalize(glm::cross(Right, Front));
// Convert 3D positions to 2D (XZ plane) for wall collision
glm::vec2 CurrentPosition = glm::vec2(Position.x, Position.z);
glm::vec2 NextPosition = glm::vec2(NewPosition.x, NewPosition.z);
//bool bCrossed = false;
// Check each wall in the sector
for (const Wall& Wall : CurrentSector->walls)
{
glm::vec2 WallStart = Wall.a;
glm::vec2 WallEnd = Wall.b;
// Check if movement line segment intersects with wall line segment
if (LineSegmentsIntersect(CurrentPosition, NextPosition, WallStart, WallEnd))
{
if (Wall.portal == 0)
{
return true; // Collision detected
}
else if (CanFitInNextSector(LevelSectors[Wall.portal-1]))// check if valid portal (floor height < player y and floor and ceiling tall enough for player)
{
CurrentSector = &LevelSectors[Wall.portal - 1];
return false;
}
else
{
return true;
}
//return true; // Collision detected
}
}
//if (bCrossed) return bCrossed; // breakout early, attempting to move through wall
// Check outward facing sectors to ensure not moving into pillars
for (const Sector& Sector : LevelSectors)
{
if (!Sector.outward_facing)
{
continue;
}
// Check each wall in the sector
for (const Wall& Wall : Sector.walls)
{
glm::vec2 WallStart = Wall.a;
glm::vec2 WallEnd = Wall.b;
// Check if movement line segment intersects with wall line segment
if (LineSegmentsIntersect(CurrentPosition, NextPosition, WallStart, WallEnd))
{
//if (Wall.portal != 0)
//{
// return false; // Collision but to another sector
//}
return true; // Collision detected
}
}
}
return false; // No collisions detected
}
bool Player::LineSegmentsIntersect(const glm::vec2& StartPosition, const glm::vec2& EndPosition, const glm::vec2& WallPointA, const glm::vec2& WallPointB)
{
// Implementation of the cross product test for line segment intersection
auto cross = [](const glm::vec2& a, const glm::vec2& b) {
return a.x * b.y - a.y * b.x;
};
glm::vec2 PlayerNormal = EndPosition - StartPosition;
glm::vec2 WallNormal = WallPointB - WallPointA;
glm::vec2 WallToPlayerNormal = WallPointA - StartPosition;
float PlayerWallCross = cross(PlayerNormal, WallNormal);
// If lines are not parallel
if (std::abs(PlayerWallCross) >= std::numeric_limits<float>::epsilon())
{
float t = cross(WallToPlayerNormal, PlayerNormal) / PlayerWallCross;
float u = cross(WallToPlayerNormal, WallNormal) / PlayerWallCross;
// If intersection point is on both segments
if ((t >= 0 && t <= 1) && (u >= 0 && u <= 1))
return true;
}
// If no intersection, check distance from EndPosition to wall segment
return PointToLineSegmentDistance(EndPosition, WallPointA, WallPointB) <= 1.0f;
}
float Player::PointToLineSegmentDistance(const glm::vec2& point, const glm::vec2& segA, const glm::vec2& segB)
{
glm::vec2 segVec = segB - segA;
float segLengthSquared = glm::dot(segVec, segVec);
// If segment is actually a point
if (segLengthSquared < std::numeric_limits<float>::epsilon())
return glm::distance(point, segA);
// Project point onto the segment
float t = glm::dot(point - segA, segVec) / segLengthSquared;
t = glm::clamp(t, 0.0f, 1.0f);
glm::vec2 projection = segA + t * segVec;
return glm::distance(point, projection);
}
// Checking if a point is inside a polygon
bool Player::PointInPolygon(glm::vec2 point, std::vector<Wall> polygon)
{
int num_vertices = polygon.size();
double x = point.x, y = point.y;
bool inside = false;
// Store the first point in the polygon and initialize
// the second point
glm::vec2 p1 = polygon[0].a, p2;
// Loop through each edge in the polygon
for (int i = 1; i <= num_vertices; i++) {
// Get the next point in the polygon
p2 = polygon[i % num_vertices].a;
// Check if the point is above the minimum y
// coordinate of the edge
if (y > std::min(p1.y, p2.y)) {
// Check if the point is below the maximum y
// coordinate of the edge
if (y <= std::max(p1.y, p2.y)) {
// Check if the point is to the left of the
// maximum x coordinate of the edge
if (x <= std::max(p1.x, p2.x)) {
// Calculate the x-intersection of the
// line connecting the point to the edge
double x_intersection
= (y - p1.y) * (p2.x - p1.x)
/ (p2.y - p1.y)
+ p1.x;
// Check if the point is on the same
// line as the edge or to the left of
// the x-intersection
if (p1.x == p2.x
|| x <= x_intersection) {
// Flip the inside flag
inside = !inside;
}
}
}
}
// Store the current point as the first point for
// the next iteration
p1 = p2;
}
// Return the value of the inside flag
return inside;
}
bool Player::CanFitInNextSector(Sector Sector)
{
std::cout << "Checking sector " << Sector.index << " | Floor height : " << Sector.floor_height << " | Player Y : " << Position.y << " | Sector height : " << Sector.ceiling_height - Sector.floor_height << std::endl;
if (Position.y < Sector.floor_height - STEP_HEIGHT)
{
return false;
}
if (Sector.ceiling_height - Sector.floor_height < PLAYER_HEIGHT)
{
return false;
}
return true;
}

View File

@@ -3,41 +3,59 @@
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/geometric.hpp>
#include <GameObject.h>
#include <Camera.h>
#include <LevelMap.h>
#include <InputEnums.h>
#include <memory>
enum EInputDirection
{
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
class PlayerInputComponent;
class Player : public GameObject
{
public:
Player(glm::vec3 Position, glm::vec3 Rotation);
~Player() = default;
void Update();
void ProcessKeyboard(EInputDirection Direction, float Delta);
void ProcessMouseMovement(float XOffset, float YOffset, GLboolean ConstrainPitch = true);
glm::mat4 GetViewMatrix() const;
private:
Camera* PlayerCamera;
float Yaw;
float MouseSensitivity;
std::vector<Sector>& LevelSectors;
Sector* CurrentSector;
float Yaw = -90.0f;
float MouseSensitivity = 0.1f;
// movement variables
float WalkSpeed = 5.0f;
float RunSpeed = 15.0f;
bool bIsRunning = false;
void UpdatePlayerVectors();
float JumpForce = 5.0f;
float JumpVelocity = 0.0f;
bool bJumping = false;
const float GRAVITY = 9.8f;
// collision constants
const float STEP_HEIGHT = 0.25f;
const float PLAYER_HEIGHT = 2.0f;
const float PLAYER_RADIUS = 1.0f;
bool CrossingWall(glm::vec3 NewPosition);
bool LineSegmentsIntersect(const glm::vec2& p1, const glm::vec2& p2, const glm::vec2& q1, const glm::vec2& q2);
float PointToLineSegmentDistance(const glm::vec2& point, const glm::vec2& segA, const glm::vec2& segB);
bool PointInPolygon(glm::vec2 point, std::vector<Wall> polygon);
bool CanFitInNextSector(Sector Sector);
std::unique_ptr<PlayerInputComponent> cPlayerInput;
public:
std::unique_ptr<Camera> PlayerCamera;
Player(glm::vec3 Position, glm::vec3 Rotation, std::vector<Sector>& LevelSectors, GLFWwindow* Window);
~Player() = default;
void Update(float DeltaTime);
void Move(EInputDirection Direction, float Delta);
void Jump();
void Sprint();
void StopSprint();
void Look(float XOffset, float YOffset, GLboolean bConstrainPitch = true);
glm::mat4 GetViewMatrix() const;
};

112
PlayerInputComponent.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include "PlayerInputComponent.h"
#include "Player.h"
#include "InputEnums.h"
PlayerInputComponent::PlayerInputComponent(GLFWwindow* Window, Player& PlayerCharacter)
: IInputComponent(Window), PlayerCharacter(PlayerCharacter)
{
glfwSetWindowUserPointer(Window, this);
glfwSetCursorPosCallback(Window, ProcessMouse);
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
bFreeMouse = false;
}
void PlayerInputComponent::Update(float DeltaTime)
{
ProcessKeyboard(DeltaTime);
}
void PlayerInputComponent::ProcessKeyboard(float DeltaTime)
{
if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS && !bFreeMouse) {
//glfwSetWindowShouldClose(Window, true);
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
bFreeMouse = true;
}
if (glfwGetKey(Window, GLFW_KEY_W) == GLFW_PRESS)
{
PlayerCharacter.Move(FORWARD, DeltaTime);
}
if (glfwGetKey(Window, GLFW_KEY_S) == GLFW_PRESS)
{
PlayerCharacter.Move(BACKWARD, DeltaTime);
}
if (glfwGetKey(Window, GLFW_KEY_A) == GLFW_PRESS)
{
PlayerCharacter.Move(LEFT, DeltaTime);
}
if (glfwGetKey(Window, GLFW_KEY_D) == GLFW_PRESS)
{
PlayerCharacter.Move(RIGHT, DeltaTime);
}
if (glfwGetKey(Window, GLFW_KEY_SPACE) == GLFW_PRESS)
{
PlayerCharacter.Jump();
}
if (glfwGetKey(Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
{
PlayerCharacter.Sprint();
}
if (glfwGetKey(Window, GLFW_KEY_LEFT_SHIFT) == GLFW_RELEASE)
{
PlayerCharacter.StopSprint();
}
if (glfwGetMouseButton(Window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
{
if (bFreeMouse)
{
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
bFirstMouse = true;
bFreeMouse = false;
}
}
}
void PlayerInputComponent::ProcessMouse(GLFWwindow* Window, double xposIn, double yposIn)
{
PlayerInputComponent* instance = static_cast<PlayerInputComponent*>(glfwGetWindowUserPointer(Window));
if (!instance)
{
std::cout << "Player Input Component not found" << std::endl;
return;
}
//if (glfwGetMouseButton(Window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS && instance->bFreeMouse)
//{
// glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// instance->bFirstMouse = true;
// instance->bFreeMouse = false;
//}
if (instance->bFreeMouse)
{
return;
}
//std::cout << "Mouse callback" << std::endl;
float xpos = static_cast<float>(xposIn);
float ypos = static_cast<float>(yposIn);
if (instance->bFirstMouse)
{
instance->lastX = xpos;
instance->lastY = ypos;
instance->bFirstMouse = false;
}
float xoffset = xpos - instance->lastX;
float yoffset = instance->lastY - ypos;
instance->lastX = xpos;
instance->lastY = ypos;
instance->PlayerCharacter.Look(xoffset, yoffset);
}

View File

@@ -1,22 +1,22 @@
#pragma once
#include <InputComponent.h>
#include <IInputComponent.h>
#include <iostream>
#include <InputEnums.h>
enum EInputDirection
{
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
class Player;
class PlayerInputComponent : public InputComponent
class PlayerInputComponent : public IInputComponent
{
private:
Player& PlayerCharacter;
float lastX = 1600 / 2.0f;
float lastY = 900 / 2.0f;
bool bFirstMouse = true;
bool bFreeMouse = false;
public:
virtual void Update(float deltaTime)
{
}
};
PlayerInputComponent(GLFWwindow* Window, Player& PlayerCharacter);
void Update(float DeltaTime) override;
void ProcessKeyboard(float DeltaTime);
static void ProcessMouse(GLFWwindow* Window, double xposIn, double yposIn);
};

114
camera.h
View File

@@ -2,17 +2,17 @@
#ifndef CAMERA_H
#define CAMERA_H
#include <vector>
#include <sstream>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <GLFW/glfw3.h>
enum Camera_Movement
{
_FORWARD,
_BACKWARD,
_LEFT,
_RIGHT
};
#include <GameObject.h>
#include <MeshRenderer.h>
#include <LevelMap.h>
const float YAW = -90.0f;
const float PITCH = 0.0f;
@@ -20,97 +20,35 @@ const float SPEED = 5.0f;
const float MOUSE_SENSITIVITY = 0.1f;
const float ZOOM = 45.0f;
class Camera
class Camera : public GameObject
{
public:
glm::vec3 Position;
glm::vec3 Front;
glm::vec3 Up;
glm::vec3 Right;
glm::vec3 WorldUp;
glm::vec3 CameraOffset;
glm::vec3 Offset;
float Yaw;
float Pitch;
float MovementSpeed;
float MouseSensitivity;
float Zoom;
Camera(
glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3 offset = glm::vec3(0.0f, 1.0f, 0.0f),
float yaw = YAW,
float pitch = PITCH)
:
Front(glm::vec3(0.0f, 0.0f, -1.0f)),
MovementSpeed(SPEED),
MouseSensitivity(MOUSE_SENSITIVITY),
Zoom(ZOOM)
{
Position = position;
CameraOffset = offset;
WorldUp = up;
Yaw = yaw;
Pitch = pitch;
updateCameraVectors();
}
GLFWwindow* Window;
glm::mat4 GetViewMatrix()
{
return glm::lookAt(Position, Position + Front, Up);
}
public:
Camera(GLFWwindow* Window);
~Camera() = default;
void ProcessKeyboard(Camera_Movement direction, float deltaTime)
{
float velocity = MovementSpeed * deltaTime;
if (direction == _FORWARD)
Position += Front * velocity;
if (direction == _BACKWARD)
Position -= Front * velocity;
if (direction == _LEFT)
Position -= Right * velocity;
if (direction == _RIGHT)
Position += Right * velocity;
}
void ProcessMouseMovement(float XOffset, float YOffset, GLboolean bConstrainPitch = true)
{
//Yaw += XOffset;
Pitch += YOffset;
if (bConstrainPitch)
{
if (Pitch > 89.0f)
Pitch = 89.0f;
if (Pitch < -89.0f)
Pitch = -89.0f;
}
updateCameraVectors();
}
void ProcessMouseScroll(float yoffset)
{
Zoom -= (float)yoffset;
if (Zoom < 1.0f)
Zoom = 1.0f;
if (Zoom > 45.0f)
Zoom = 45.0f;
}
private:
void updateCameraVectors()
{
glm::vec3 front;
front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
front.y = sin(glm::radians(Pitch));
front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
Front = glm::normalize(front);
Right = glm::normalize(glm::cross(Front, WorldUp));
Up = glm::normalize(glm::cross(Right, Front));
}
glm::mat4 GetViewMatrix();
void SetOffset(glm::vec3 Offset);
void MoveCamera(glm::vec3 Position);
void RotateCamera(float Yaw, float Pitch, GLboolean bConstrainPitch = true);
void ZoomCamera(float ZoomAmount);
void RenderScene(
LevelMap& LevelMap,
const std::vector<PointLight>& Lights,
int ScreenWidth,
int ScreenHeight
);
glm::mat4 GetProjectionMatrix(int ScreenWidth, int ScreenHeight);
};
#endif

84
input.txt Normal file
View File

@@ -0,0 +1,84 @@
#pragma once
#include <IInputComponent.h>
#include <iostream>
#include <InputEnums.h>
class Player;
class deadPlayerInputComponent : public IInputComponent
{
Player& PlayerCharacter;
float lastX = 1600 / 2.0f;
float lastY = 900 / 2.0f;
bool bFirstMouse = true;
public:
deadPlayerInputComponent(GLFWwindow* Window, Player& PlayerCharacter)
: IInputComponent(Window),
PlayerCharacter(PlayerCharacter)
{
glfwSetWindowUserPointer(Window, this);
glfwSetCursorPosCallback(Window, ProcessMouse);
}
void Update(float DeltaTime) override
{
ProcessKeyboard(DeltaTime);
}
void ProcessKeyboard(float DeltaTime)
{
if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
//glfwSetWindowShouldClose(Window, true);
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}
;
if (glfwGetKey(Window, GLFW_KEY_W) == GLFW_PRESS)
PlayerCharacter.ProcessKeyboard(FORWARD, DeltaTime);
if (glfwGetKey(Window, GLFW_KEY_S) == GLFW_PRESS)
PlayerCharacter.ProcessKeyboard(BACKWARD, DeltaTime);
if (glfwGetKey(Window, GLFW_KEY_A) == GLFW_PRESS)
PlayerCharacter.ProcessKeyboard(LEFT, DeltaTime);
if (glfwGetKey(Window, GLFW_KEY_D) == GLFW_PRESS)
PlayerCharacter.ProcessKeyboard(RIGHT, DeltaTime);
}
static void ProcessMouse(GLFWwindow* Window, double xposIn, double yposIn)
{
deadPlayerInputComponent* instance = static_cast<deadPlayerInputComponent*>(glfwGetWindowUserPointer(Window));
if (!instance)
{
std::cout << "Player Input Component not found" << std::endl;
return;
}
if (glfwGetMouseButton(Window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
{
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
instance->bFirstMouse = true;
return;
}
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
//std::cout << "Mouse callback" << std::endl;
float xpos = static_cast<float>(xposIn);
float ypos = static_cast<float>(yposIn);
if (instance->bFirstMouse)
{
instance->lastX = xpos;
instance->lastY = ypos;
instance->bFirstMouse = false;
}
float xoffset = xpos - instance->lastX;
float yoffset = instance->lastY - ypos;
instance->lastX = xpos;
instance->lastY = ypos;
instance->PlayerCharacter.ProcessMouseMovement(xoffset, yoffset);
}
};