Character controller working better

Moved ECS systems to separate folders
better raycast normal result
This commit is contained in:
Antoine Pilote
2021-06-18 16:44:54 -04:00
parent 8f238cd4ca
commit 5b56e2ff9a
73 changed files with 1179 additions and 489 deletions

View File

@@ -1,19 +1,27 @@
#pragma once
#include <src/Scene/Systems/ScriptingSystem.h>
#include <src/Scene/Systems/PhysicsSystem.h>
#include "Scene.h"
#include "Entities/Entity.h"
#include "Entities/Components.h"
#include "../Rendering/Renderer.h"
#include "../Core/MaterialManager.h"
#include "../Core/Physics/PhysicsManager.h"
#include "../Core/Core.h"
#include <GL/glew.h>
#include "Entities/Components/BoxCollider.h"
#include "../../Engine.h"
#include "../Core/FileSystem.h"
#include "../Scene/Entities/Components/LuaScriptComponent.h"
#include "Components/Components.h"
#include "Components/BoxCollider.h"
#include "Components/LuaScriptComponent.h"
#include "Components/WrenScriptComponent.h"
#include <fstream>
#include <streambuf>
#include "../Scene/Entities/Components/WrenScriptComponent.h"
Ref<Scene> Scene::New()
{
return CreateRef<Scene>();
@@ -21,9 +29,14 @@ Ref<Scene> Scene::New()
Scene::Scene()
{
m_Systems = std::vector<Ref<System>>();
m_EditorCamera = CreateRef<EditorCamera>();
m_Environement = CreateRef<Environment>();
m_Interfaces = std::vector<Ref<UI::UserInterface>>();
// Adding systems
m_Systems.push_back(CreateRef<ScriptingSystem>(this));
m_Systems.push_back(CreateRef<PhysicsSystem>(this));
}
Scene::~Scene() {}
@@ -37,155 +50,41 @@ bool Scene::SetName(std::string& newName)
{
if (newName == "")
return false;
this->Name = newName;
return true;
}
void Scene::OnInit()
{
ScriptingEngine::Init();
// Create physic world.
auto view = m_Registry.view<TransformComponent, RigidBodyComponent>();
for (auto e : view)
{
auto [transform, rigidbody] = view.get<TransformComponent, RigidBodyComponent>(e);
Entity ent = Entity({ e, this });
if (ent.HasComponent<BoxColliderComponent>())
{
float mass = rigidbody.mass;
BoxColliderComponent& boxComponent = ent.GetComponent<BoxColliderComponent>();
Ref<Physics::Box> boxShape = CreateRef<Physics::Box>(boxComponent.Size);
Ref<Physics::RigidBody> btRigidbody = CreateRef<Physics::RigidBody>(mass, transform.Translation, boxShape);
rigidbody.m_Rigidbody = btRigidbody;
btRigidbody->SetKinematic(rigidbody.IsKinematic);
PhysicsManager::Get()->RegisterBody(btRigidbody);
}
}
// character controllers
auto ccview = m_Registry.view<TransformComponent, CharacterControllerComponent>();
for (auto e : ccview)
{
auto [transform, cc] = ccview.get<TransformComponent, CharacterControllerComponent>(e);
cc.CharacterController = CreateRef<Physics::CharacterController>(cc.Height, cc.Radius, cc.Mass, transform.Translation);
Entity ent = Entity({ e, this });
PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController);
}
auto quakeMapview = m_Registry.view<TransformComponent, QuakeMapComponent>();
for (auto e : quakeMapview)
{
auto [transform, quake] = quakeMapview.get<TransformComponent, QuakeMapComponent>(e);
if (quake.HasCollisions)
{
for (auto m : quake.m_Meshes)
{
Ref<Physics::MeshShape> meshShape = CreateRef<Physics::MeshShape>(m);
Ref<Physics::RigidBody> btRigidbody = CreateRef<Physics::RigidBody>(0.0f, transform.Translation, meshShape);
PhysicsManager::Get()->RegisterBody(btRigidbody);
}
}
}
// Instanciate scripts.
{
auto entities = m_Registry.view<WrenScriptComponent>();
for (auto& e : entities)
{
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
if (wren.Script != "" && wren.Class != "")
wren.WrenScript = CreateRef<WrenScript>(wren.Script, wren.Class, true);
if (wren.WrenScript != nullptr)
{
wren.WrenScript->SetScriptableEntityID((int)e);
wren.WrenScript->CallInit();
}
}
}
for (auto& system : m_Systems)
system->Init();
}
void Scene::OnExit()
{
PhysicsManager::Get()->Reset();
// destroy scripts.
auto entities = m_Registry.view<WrenScriptComponent>();
for (auto& e : entities)
{
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
if (wren.WrenScript != nullptr)
{
wren.WrenScript->CallExit();
}
}
ScriptingEngine::Close();
for (auto& system : m_Systems)
system->Exit();
}
// update entities and some components.
void Scene::Update(Timestep ts)
{
// Update scripts
{
m_Registry.view<NativeScriptComponent>().each([=](auto entity, auto& nsc)
{
nsc.Instance->OnUpdate(ts);
});
}
// destroy scripts.
auto entities = m_Registry.view<WrenScriptComponent>();
for (auto& e : entities)
{
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
if (wren.WrenScript != nullptr)
wren.WrenScript->CallUpdate(ts);
}
// Update rigidbodies
PhysicsManager::Get()->Step(ts);
auto physicGroup = m_Registry.view<TransformComponent, RigidBodyComponent>();
for (auto e : physicGroup) {
auto [transform, rb] = physicGroup.get<TransformComponent, RigidBodyComponent>(e);
rb.SyncTransformComponent(&m_Registry.get<TransformComponent>(e));
}
auto ccGroup = m_Registry.view<TransformComponent, CharacterControllerComponent>();
for (auto e : ccGroup) {
auto [transform, rb] = ccGroup.get<TransformComponent, CharacterControllerComponent>(e);
rb.SyncWithTransform(m_Registry.get<TransformComponent>(e));
}
for (auto& system : m_Systems)
system->Update(ts);
}
void Scene::FixedUpdate(Timestep ts)
{
for (auto& system : m_Systems)
system->FixedUpdate(ts);
}
void Scene::EditorUpdate(Timestep ts)
{
m_EditorCamera->Update(ts);
for (auto i : m_Interfaces)
{
i->Update(ts);
}
}
@@ -194,7 +93,7 @@ void Scene::DrawShadows()
auto modelView = m_Registry.view<TransformComponent, ModelComponent>();
auto quakeView = m_Registry.view<TransformComponent, QuakeMapComponent>();
auto view = m_Registry.view<TransformComponent, LightComponent>();
Ref<Camera> cam = nullptr;
if (Engine::IsPlayMode)
{
@@ -209,9 +108,9 @@ void Scene::DrawShadows()
{
cam = m_EditorCamera;
}
glm::mat4 perspective = cam->GetPerspective();
for (auto l : view) {
auto [lightTransform, light] = view.get<TransformComponent, LightComponent>(l);
if (light.Type != LightType::Directional)
@@ -229,16 +128,16 @@ void Scene::DrawShadows()
model.Draw();
}
for (auto e : quakeView) {
auto [transform, model] = quakeView.get<TransformComponent, QuakeMapComponent>(e);
glm::vec3 pos = lightTransform.Translation;
glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f));
Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView);
Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform());
model.Draw();
}
light.EndDrawShadow();
@@ -262,22 +161,22 @@ void Scene::Draw()
auto view = m_Registry.view<TransformComponent, CameraComponent, ParentComponent>();
for (auto e : view) {
auto [transform, camera, parent] = view.get<TransformComponent, CameraComponent, ParentComponent>(e);
TransformComponent copyT = transform;
if (parent.HasParent)
{
Entity currentParent = Entity{ e, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
cam = camera.CameraInstance;
cam->Translation = copyT.Translation;
break;
@@ -285,52 +184,52 @@ void Scene::Draw()
}
glDisable(GL_DEPTH_TEST);
Ref<Environment> env = GetEnvironment();
if (env->ProceduralSkybox)
{
env->ProceduralSkybox->Draw(cam);
}
Renderer::m_Shader->Bind();
env->Push();
glEnable(GL_DEPTH_TEST);
// Push lights
{
auto view = m_Registry.view<TransformComponent, LightComponent, ParentComponent>();
for (auto l : view) {
auto [transform, light, parent] = view.get<TransformComponent, LightComponent, ParentComponent>(l);
TransformComponent copyT = transform;
if (parent.HasParent)
{
Entity currentParent = Entity{ l, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
if (light.SyncDirectionWithSky)
light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection();
light.Draw(copyT, m_EditorCamera);
}
}
Renderer::m_Shader->Bind();
Renderer::m_Shader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z);
Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0);
if (cam)
{
Renderer::m_Shader->SetUniform1f("u_Exposure", cam->Exposure);
auto view = m_Registry.view<TransformComponent, ModelComponent, ParentComponent>();
for (auto e : view) {
auto [transform, model, parent] = view.get<TransformComponent, ModelComponent, ParentComponent>(e);
@@ -339,39 +238,39 @@ void Scene::Draw()
{
Entity currentParent = Entity{ e, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform());
Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective());
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
model.Draw();
}
auto quakeView = m_Registry.view<TransformComponent, QuakeMapComponent, ParentComponent>();
for (auto e : quakeView) {
auto [transform, model, parent] = quakeView.get<TransformComponent, QuakeMapComponent, ParentComponent>(e);
TransformComponent copyT = transform;
if (parent.HasParent)
{
Entity currentParent = Entity{ e, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform());
@@ -379,12 +278,12 @@ void Scene::Draw()
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
model.Draw();
}
Renderer::m_DebugShader->SetUniformMat4f("u_View", cam->GetTransform());
Renderer::m_DebugShader->SetUniformMat4f("u_Projection", cam->GetPerspective());
PhysicsManager::Get()->DrawDebug();
}
}
@@ -392,16 +291,16 @@ void Scene::EditorDraw()
{
glDisable(GL_DEPTH_TEST);
Ref<Environment> env = GetEnvironment();
if (env->ProceduralSkybox)
{
env->ProceduralSkybox->Draw(m_EditorCamera);
}
Renderer::m_Shader->Bind();
env->Push();
glEnable(GL_DEPTH_TEST);
// Push lights
{
auto view = m_Registry.view<TransformComponent, LightComponent, ParentComponent>();
@@ -413,23 +312,23 @@ void Scene::EditorDraw()
{
Entity currentParent = Entity{ l, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
if (light.SyncDirectionWithSky)
light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection();
light.Draw(copyT, m_EditorCamera);
}
}
Renderer::m_Shader->Bind();
Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0);
if (m_EditorCamera)
@@ -439,74 +338,74 @@ void Scene::EditorDraw()
auto view = m_Registry.view<TransformComponent, ModelComponent, ParentComponent>();
for (auto e : view) {
auto [transform, model, parent] = view.get<TransformComponent, ModelComponent, ParentComponent>(e);
TransformComponent copyT = transform;
if (parent.HasParent)
{
Entity currentParent = Entity{ e, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
model.Draw();
}
auto quakeView = m_Registry.view<TransformComponent, QuakeMapComponent, ParentComponent>();
for (auto e : quakeView) {
auto [transform, model, parent] = quakeView.get<TransformComponent, QuakeMapComponent, ParentComponent>(e);
TransformComponent copyT = transform;
if (parent.HasParent)
{
Entity currentParent = Entity{ e, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
model.Draw();
}
auto boxCollider = m_Registry.view<TransformComponent, BoxColliderComponent, ParentComponent>();
for (auto e : boxCollider) {
auto [transform, box, parent] = boxCollider.get<TransformComponent, BoxColliderComponent, ParentComponent>(e);
TransformComponent copyT = transform;
if (parent.HasParent)
{
Entity currentParent = Entity{ e, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
Renderer::m_DebugShader->SetUniformMat4f("u_Model", copyT.GetTransform());
@@ -515,31 +414,31 @@ void Scene::EditorDraw()
t.Scale = (box.Size * 2.f) * transform.Scale;
Renderer::DrawCube(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f));
}
auto sphereCollider = m_Registry.view<TransformComponent, SphereColliderComponent, ParentComponent>();
for (auto e : sphereCollider) {
auto [transform, box, parent] = sphereCollider.get<TransformComponent, SphereColliderComponent, ParentComponent>(e);
TransformComponent copyT = transform;
if (parent.HasParent)
{
Entity currentParent = Entity{ e, this };
glm::vec3 globalOffset = copyT.Translation;
while (currentParent.GetComponent<ParentComponent>().HasParent)
{
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
globalOffset += currentParent.GetComponent<TransformComponent>().Translation;
}
copyT.Translation = globalOffset;
}
Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform());
Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective());
Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform());
TransformComponent t = transform;
t.Scale = (box.Radius * 2.f) * transform.Scale;
Renderer::DrawSphere(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f));
@@ -565,7 +464,7 @@ glm::vec3 Scene::GetGlobalPosition(Entity ent)
globalPos += currentParent.GetComponent<TransformComponent>().Translation;
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
}
return globalPos;
}
@@ -594,9 +493,9 @@ Entity Scene::CreateEntity(const std::string& name) {
NameComponent& nameComponent = entity.AddComponent<NameComponent>();
nameComponent.Name = name;
ParentComponent& parentComponent = entity.AddComponent<ParentComponent>();
Logger::Log("Created entity: " + nameComponent.Name + "\n");
return entity;
}
@@ -623,7 +522,7 @@ Ref<Camera> Scene::GetCurrentCamera()
cam = m_EditorCamera;
return cam;
}
return m_EditorCamera;
}
@@ -635,7 +534,7 @@ bool Scene::Save()
{
if (Path == "")
Path = FileSystem::AbsoluteToRelative(FileDialog::SaveFile("*.scene") + ".scene");
return SaveAs(Path);
}
@@ -645,7 +544,7 @@ bool Scene::SaveAs(const std::string& path)
sceneFile.open(FileSystem::Root + path);
sceneFile << Serialize().dump(4);
sceneFile.close();
Logger::Log("Scene saved successfully");
return true;
}
@@ -667,12 +566,12 @@ void Scene::AddInterface(Ref<UI::UserInterface> interface)
json Scene::Serialize()
{
BEGIN_SERIALIZE();
SERIALIZE_VAL(Name);
SERIALIZE_OBJECT(m_Environement)
SERIALIZE_VAL(Name);
SERIALIZE_OBJECT(m_Environement)
std::vector<json> entities = std::vector<json>();
for (Entity e : GetAllEntities())
entities.push_back(e.Serialize());
SERIALIZE_VAL_LBL("Entities", entities);
for (Entity e : GetAllEntities())
entities.push_back(e.Serialize());
SERIALIZE_VAL_LBL("Entities", entities);
END_SERIALIZE();
}
@@ -681,13 +580,13 @@ bool Scene::Deserialize(const std::string& str)
{
if (str == "")
return false;
BEGIN_DESERIALIZE();
if (!j.contains("Name"))
return false;
Name = j["Name"];
m_Environement = CreateRef<Environment>();
if (j.contains("m_Environement"))
{
@@ -695,7 +594,7 @@ bool Scene::Deserialize(const std::string& str)
std::string env = j["m_Environement"].dump();
m_Environement->Deserialize(env);
}
// Parse entities
{
if (j.contains("Entities"))
@@ -708,6 +607,6 @@ bool Scene::Deserialize(const std::string& str)
}
}
}
return true;
}