CSEngine
Loading...
Searching...
No Matches
CameraComponent.cpp
1#include "CameraComponent.h"
2#include "TransformComponent.h"
3#include "../Manager/CameraMgr.h"
4#include "../Manager/EngineCore.h"
5#include "../Util/Render/SFrameBuffer.h"
6#include "../Util/Render/STexture.h"
7#include "../Util/Render/ShaderUtil.h"
8
9#include <mutex>
10
11using namespace CSE;
12
13GLProgramHandle* globalSkyboxHandle = nullptr;
14
15COMPONENT_CONSTRUCTOR(CameraComponent), m_eye(nullptr), m_targetObject(nullptr) {
16 auto cameraMgr = CORE->GetCore(CameraMgr);
17 cameraMgr->Register(this);
18 m_pRatio = const_cast<float*>(cameraMgr->GetProjectionRatio());
19 globalSkyboxHandle = cameraMgr->GetSkyboxProgram();
20}
21
22CameraComponent::~CameraComponent() = default;
23
24void CameraComponent::Exterminate() {
25 SAFE_DELETE(m_backgroundMap);
26 CORE->GetCore(CameraMgr)->Remove(this);
27}
28
29void CameraComponent::Init() {
30 m_eye = static_cast<TransformComponent*>(gameObject->GetTransform())->GetPosition();
31
32 m_resultTarget = vec3();
33 m_pRatio = const_cast<float*>(CORE->GetCore(CameraMgr)->GetProjectionRatio());
34 Tick(0);
35}
36
37void CameraComponent::Tick(float elapsedTime) {
38 if(m_type == CUBE) return;
39
40 if (m_targetObject == nullptr)
41 m_resultTarget = *m_eye + m_target;
42 else {
43 m_resultTarget = *static_cast<TransformComponent*>(m_targetObject->GetTransform())->GetPosition();
44 }
45 SetCameraMatrix();
46}
47
48SComponent* CameraComponent::Clone(SGameObject* object) {
49 INIT_COMPONENT_CLONE(CameraComponent, comp);
50
51 comp->m_eye = m_eye;
52 comp->m_target = m_target;
53 comp->m_up = m_up;
54
55 comp->m_cameraMatrix = m_cameraMatrix;
56 comp->m_projectionMatrix = m_projectionMatrix;
57 comp->m_resultTarget = m_resultTarget;
58 comp->m_frameBuffer = m_frameBuffer;
59
60 comp->m_type = m_type;
61 comp->m_isProjectionInited = m_isProjectionInited;
62
63 //perspective
64 comp->m_pFov = m_pFov;
65 comp->m_pRatio = m_pRatio;
66
67 //Orthographic
68 comp->m_oLeft = m_oLeft;
69 comp->m_oRight = m_oRight;
70 comp->m_oBottom = m_oBottom;
71 comp->m_oTop = m_oTop;
72
73 comp->m_Near = m_Near;
74 comp->m_Far = m_Far;
75
76 //Background
77 comp->m_backgroundType = m_backgroundType;
78 comp->m_backgroundColor = m_backgroundColor;
79 if(comp->m_backgroundMap == nullptr) comp->m_backgroundMap = new BackgroundMapStruct();
80 comp->m_backgroundMap->map = m_backgroundMap->map;
81 comp->m_backgroundMap->mapId = m_backgroundMap->mapId;
82 comp->m_backgroundMap->viewId = m_backgroundMap->viewId;
83 comp->m_backgroundMap->projectionId = m_backgroundMap->projectionId;
84
85 return comp;
86}
87
88void CameraComponent::CopyReference(SComponent* src, std::map<SGameObject*, SGameObject*> lists_obj,
89 std::map<SComponent*, SComponent*> lists_comp) {
90 if (src == nullptr) return;
91 auto convert = static_cast<CameraComponent*>(src);
92
93 //Copy GameObjects
94 FIND_OBJ_REFERENCE(m_targetObject, convert);
95
96}
97
98void CameraComponent::SetTargetVector(const vec3& target) {
99 m_target = target;
100}
101
102void CameraComponent::SetTarget(SGameObject* gameObject) {
103 m_targetObject = gameObject;
104}
105
106void CameraComponent::SetUp(const vec3& up) {
107 m_up = up;
108}
109
110void CameraComponent::SetCameraType(CAMERATYPE type) {
111 m_type = type;
112}
113
114void CameraComponent::SetPerspectiveFov(float fov) {
115 m_pFov = fov;
116}
117
118void CameraComponent::SetZDepthRange(float near, float far) {
119 m_Near = near;
120 m_Far = far;
121
122}
123
124void CameraComponent::SetPerspective(float fov, float near, float far) {
125 m_type = PERSPECTIVE;
126 m_pFov = fov;
127 m_Near = near;
128 m_Far = far;
129
130}
131
132void CameraComponent::SetOrtho(float left, float right, float top, float bottom) {
133 m_type = ORTHO;
134 m_oLeft = left;
135 m_oRight = right;
136 m_oBottom = bottom;
137 m_oTop = top;
138}
139
140void CameraComponent::SetCubeCamera() {
141 m_type = CUBE;
142}
143
144void CameraComponent::SetCameraMatrix() {
145 m_cameraMatrix = mat4::LookAt(*m_eye, m_resultTarget, m_up);
146}
147
148mat4 CameraComponent::GetCameraMatrix() const {
149 return m_cameraMatrix;
150}
151
152vec3 CameraComponent::GetCameraPosition() const {
153 mat4 matrix = static_cast<TransformComponent*>(gameObject->GetTransform())->GetMatrix();
154 return vec3{ matrix.w.x, matrix.w.y, matrix.w.z };
155}
156
157void CameraComponent::SetProjectionMatrix() const {
158 std::mutex mutex;
159 mutex.lock();
160
161 switch (m_type) {
162 case PERSPECTIVE:
163 m_projectionMatrix = mat4::Perspective(m_pFov, *m_pRatio, m_Near, m_Far);
164 break;
165 case ORTHO:
166 m_projectionMatrix = mat4::Ortho(m_oLeft, m_oRight, m_oTop, m_oBottom, m_Near, m_Far);
167 break;
168 case CUBE:
169 m_projectionMatrix = mat4::Perspective(90.0f, 1.0f, 0.1f, 10.0f);
170 break;
171 }
172
173 m_isProjectionInited = true;
174 mutex.unlock();
175}
176
177void CameraComponent::SetValue(std::string name_str, VariableBinder::Arguments value) {
178 if (name_str == "m_eye") {
179 m_eye = static_cast<TransformComponent*>(
180 SGameObject::FindByHash(value[0])->GetTransform()
181 )->GetPosition();
182 } else if (name_str == "m_target") {
183 SET_VEC3(m_target);
184 } else if (name_str == "m_up") {
185 SET_VEC3(m_up);
186 } else if (name_str == "m_targetObject") {
187 if(value.size() <= 0) return;
188 m_targetObject = SGameObject::FindByHash(value[0]);
189 } else if (name_str == "m_cameraMatrix") {
190 SET_MAT4(m_cameraMatrix);
191 } else if (name_str == "m_projectionMatrix") {
192 SET_MAT4(m_projectionMatrix);
193 } else if (name_str == "m_type") {
194 m_type = static_cast<CAMERATYPE>(std::stoi(value[0]));
195 } else if (name_str == "m_pFov") {
196 m_pFov = std::stof(value[0]);
197 } else if (name_str == "m_orthoValue") {
198 m_oLeft = std::stof(value[0]);
199 m_oRight = std::stof(value[1]);
200 m_oBottom = std::stof(value[2]);
201 m_oTop = std::stof(value[3]);
202
203 } else if (name_str == "m_distance") {
204 m_Near = std::stof(value[0]);
205 m_Far = std::stof(value[1]);
206 } else if (name_str == "m_frameBuffer") {
207 m_frameBuffer = SResource::Create<SFrameBuffer>(value[0]);
208 } else if (name_str == "m_backgroundType") {
209 m_backgroundType = static_cast<BackgroundType>(std::stoi(value[0]));
210 } else if (name_str == "m_backgroundColor") {
211 SET_VEC3(m_backgroundColor);
212 } else if (name_str == "m_backgroundMap.map") {
213 SetBackgroundSkybox(SResource::Create<STexture>(value[0]));
214 }
215
216}
217
218std::string CameraComponent::PrintValue() const {
219 PRINT_START("component");
220
221 PRINT_VALUE(m_eye, ConvertSpaceStr(gameObject->GetID(gameObject->GetComponent<TransformComponent>())));
222 PRINT_VALUE_VEC3(m_target);
223 PRINT_VALUE_VEC3(m_up);
224 PRINT_VALUE(m_targetObject, m_targetObject == nullptr ? "" : ConvertSpaceStr(m_targetObject->GetHash()));
225 PRINT_VALUE_MAT4(m_cameraMatrix);
226 PRINT_VALUE_MAT4(m_projectionMatrix);
227 PRINT_VALUE(m_type, static_cast<int>(m_type));
228 PRINT_VALUE(m_pFov, m_pFov);
229 PRINT_VALUE(m_orthoValue, m_oLeft, ' ', m_oRight, ' ', m_oBottom, ' ', m_oTop);
230 PRINT_VALUE(m_distance, m_Near, ' ', m_Far);
231 if (m_frameBuffer != nullptr) PRINT_VALUE(m_frameBuffer, ConvertSpaceStr(m_frameBuffer->GetHash()));
232
233 PRINT_VALUE(m_backgroundType, static_cast<int>(m_backgroundType));
234 PRINT_VALUE_VEC3(m_backgroundColor);
235 if (m_backgroundMap != nullptr && m_backgroundMap->map != nullptr)
236 PRINT_VALUE(m_backgroundMap.map, ConvertSpaceStr(m_backgroundMap->map->GetHash()));
237
238 PRINT_END("component");
239}
240
241CameraMatrixStruct CameraComponent::GetCameraMatrixStruct() const {
242 return { m_cameraMatrix, GetProjectionMatrix(), GetCameraPosition() };
243}
244
245SFrameBuffer* CameraComponent::GetFrameBuffer() const {
246 return m_frameBuffer;
247}
248
249void CameraComponent::SetFrameBuffer(SFrameBuffer* frameBuffer) {
250 m_frameBuffer = frameBuffer;
251}
252
253CameraBase::BackgroundType CameraComponent::GetBackgroundType() {
254 return m_backgroundType;
255}
256
257void CameraComponent::RenderBackground() const {
258 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
259
260 switch (m_backgroundType) {
261 case SOLID:
262 glClearColor(m_backgroundColor.x, m_backgroundColor.y, m_backgroundColor.z, 1.0f);
263 break;
264 case SKYBOX:
265 const auto& mapStruct = m_backgroundMap;
266 if (mapStruct->map == nullptr) return;
267
268 glUseProgram(globalSkyboxHandle->Program);
269 globalSkyboxHandle->SetUniformMat4("PROJECTION_MATRIX", m_projectionMatrix);
270 auto viewMatrix = mat4(m_cameraMatrix.ToMat3());
271 globalSkyboxHandle->SetUniformMat4("VIEW_MATRIX", viewMatrix);
272 mapStruct->map->Bind(mapStruct->mapId, 0);
273
274 glDisable(GL_CULL_FACE);
275 glDisable(GL_DEPTH_TEST);
276 ShaderUtil::BindAttributeToCubeMap();
277 glEnable(GL_DEPTH_TEST);
278 glEnable(GL_CULL_FACE);
279 break;
280 }
281}
282
283void CameraComponent::SetBackgroundSkybox(STexture* skyboxTexture) {
284 if (skyboxTexture == nullptr) {
285 skyboxTexture = SResource::Get<STexture>("envCubemap.textureCubeMap");
286 }
287 if (m_backgroundMap == nullptr) m_backgroundMap = new BackgroundMapStruct();
288
289 m_backgroundMap->map = skyboxTexture;
290 m_backgroundMap->mapId = static_cast<unsigned short>(globalSkyboxHandle->UniformLocation("ENV_MAP")->id);
291 m_backgroundMap->viewId = static_cast<unsigned short>(globalSkyboxHandle->UniformLocation("VIEW_MATRIX")->id);
292 m_backgroundMap->projectionId = static_cast<unsigned short>(globalSkyboxHandle->UniformLocation(
293 "PROJECTION_MATRIX")->id);
294}
295
296void CameraComponent::SetBackgroundColor(vec3&& color) {
297 m_backgroundColor = color;
298}
299
300void CameraComponent::SetBackgroundType(CameraBase::BackgroundType type) {
301 m_backgroundType = type;
302}