Merge branch 'main' of https://github.com/antopilo/Nuake into main

This commit is contained in:
unknown
2021-06-19 13:19:12 -04:00
125 changed files with 1932 additions and 16952 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: antopilo # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

18
.gitignore vendored
View File

@@ -828,4 +828,20 @@ FodyWeavers.xsd
.idea/
*.sln.iml
!freetype.lib
!freetype.lib
./docs/_build/
docs/_build
Nuake/dependencies/assimp.vcxproj
Nuake/dependencies/assimp.vcxproj.filters
DemoModule/DemoModule.vcxproj
bin-int/Debug-windows-x86_64/Nuake/Msdfgen.res
bin-int/Debug-windows-x86_64/Nuake/Nuake.vcxproj.FileListAbsolute.txt
bin-int/Release-windows-x86_64/Editor/Editor.vcxproj.FileListAbsolute.txt
bin-int/Release-windows-x86_64/Nuake/Nuake.vcxproj.FileListAbsolute.txt
Nuake.sln
Editor/Editor.vcxproj
Editor/Editor.vcxproj.filters
Editor/imgui.ini
Nuake/Nuake.vcxproj
Nuake/Nuake.vcxproj.filters

View File

@@ -2,12 +2,12 @@
#include <src/Scene/Entities/Entity.h>
#include <src/Scene/Scene.h>
#include <src/Scene/Entities/Components/QuakeMap.h>
#include <src/Scene/Components/QuakeMap.h>
#include <src/Vendors/imgui/imgui.h>
#include <src/Vendors/imgui/ImGuizmo.h>
#include <src/Scene/Entities/Components.h>
#include <src/Scene/Components/Components.h>
#include <src/Core/Physics/PhysicsManager.h>
#include "../Scene/Entities/Components/BoxCollider.h"
#include "../Scene/Components/BoxCollider.h"
#include "src/EditorInterface.h"
#include "../Core/Input.h"
#include <GLFW/glfw3.h>

View File

@@ -1,13 +1,7 @@
.hello{
width: 400px;
height: 200px;
}
.screen{
height: 100%;
width: 100%;
display: flex;
justify-content: center;
flex-direction: row;
align-content:flex-start;
@@ -16,5 +10,4 @@
.rect{
height: 200px;
width: 200px;
}

View File

@@ -1,12 +1,11 @@
<Canvas
script="Scripts/test Test"
stylesheet="Interface/Testing.css"
groups="screen"
color="25 25 25 9"
>
<p groups="header">Hello, world!</p>
<Rect onclick="hello()"
groups="rect"
color="128 128 255 255">
groups="rect">
</Rect>
</Canvas>

View File

@@ -1,20 +1,25 @@
{
"Entities": [
{
"CameraComponent": {
"CameraInstance": {
"AspectRatio": 1.774647831916809,
"Exposure": 1.0,
"Fov": 88.0,
"Speed": 1.0,
"m_Type": 1
}
},
"NameComponent": {
"Name": "Trenchbroom map"
"Name": "Camera"
},
"ParentComponent": {
"HasParent": false
},
"QuakeMapComponent": {
"HasCollisions": false,
"Path": "C:\\Dev\\Nuake\\Editor\\resources\\Maps\\texture_test.map"
},
"TransformComponent": {
"Rotation": {
"x": 0.0,
"y": 0.0,
"y": -0.0,
"z": 0.0
},
"Scale": {
@@ -23,11 +28,15 @@
"z": 1.0
},
"Translation": {
"x": 9.199999809265137,
"y": 5.599999904632568,
"z": 0.0
"x": -25.119064331054688,
"y": 19.491336822509766,
"z": 4.5285515785217285
},
"Type": "TransformComponent"
},
"WrenScriptComponent": {
"Class": "CamScript",
"Script": "Scripts/Cam.wren"
}
},
{
@@ -66,11 +75,80 @@
"z": 1.0
},
"Translation": {
"x": 7.035792350769043,
"y": 5.795107364654541,
"z": -0.9431453943252563
"x": -359.2229919433594,
"y": -1.979316234588623,
"z": -322.51702880859375
},
"Type": "TransformComponent"
},
"WrenScriptComponent": {
"Class": "TestScript",
"Script": "Scripts/entityScript.wren"
}
},
{
"NameComponent": {
"Name": "Trenchbroom map"
},
"ParentComponent": {
"HasParent": false
},
"QuakeMapComponent": {
"HasCollisions": true,
"Path": "C:\\Dev\\Nuake\\Editor\\resources\\Maps\\texture_test.map"
},
"TransformComponent": {
"Rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"Scale": {
"x": 1.0,
"y": 1.0,
"z": 1.0
},
"Translation": {
"x": 9.199999809265137,
"y": 5.599999904632568,
"z": 0.0
},
"Type": "TransformComponent"
}
},
{
"CharacterControllerComponent": {
"Height": 1.2000000476837158,
"Mass": 2500.0,
"Radius": 0.20000000298023224
},
"NameComponent": {
"Name": "Player"
},
"ParentComponent": {
"HasParent": false
},
"TransformComponent": {
"Rotation": {
"x": 0.0,
"y": -0.0,
"z": 0.0
},
"Scale": {
"x": 1.0,
"y": 1.0,
"z": 1.0
},
"Translation": {
"x": -25.119064331054688,
"y": 18.649978637695313,
"z": 4.5285515785217285
},
"Type": "TransformComponent"
},
"WrenScriptComponent": {
"Class": "PlayerScript",
"Script": "Scripts/Player.wren"
}
}
],
@@ -78,7 +156,7 @@
"m_Environement": {
"AmbientColor": {
"w": 0.0,
"x": null,
"x": 0.0,
"y": 0.0,
"z": 0.0
},

View File

@@ -0,0 +1,78 @@
import "Scripts/ScriptableEntity" for ScriptableEntity
import "Scripts/Engine" for Engine
import "Scripts/Scene" for Scene
import "Scripts/Math" for Vector3, Math
import "Scripts/Input" for Input
class CamScript is ScriptableEntity {
construct new() {
_Pitch = 0
_Yaw = 0
_mouseLastX = 0
_mouseLastY = 0
_BobHeight = 0.1
_BobSpeed = 5.0
_CamHeight = 0.5
_deltaTime = 0
Input.HideMouse()
}
init() {}
update(ts) {
_deltaTime = _deltaTime + ts
var x = Input.GetMouseX()
var y = Input.GetMouseY()
var diffx = x - _mouseLastX
var diffy = _mouseLastY - y
_mouseLastX = x
_mouseLastY = y
var sens = 0.1
diffx = diffx * sens
diffy = diffy * sens
_Yaw = _Yaw + diffx
_Pitch = _Pitch + diffy
if(_Pitch > 89) _Pitch = 89
if(_Pitch < -89) _Pitch = -89
var cam = this.GetComponent("Camera")
var rad_yaw = Math.Radians(_Yaw)
var rad_pitch = Math.Radians(_Pitch)
var camX = Math.Cos(rad_yaw) * Math.Cos(rad_pitch)
var camY = Math.Sin(rad_pitch)
var camZ = Math.Sin(rad_yaw) * Math.Cos(rad_pitch)
var newDir = Vector3.new(camX, camY, camZ)
var player = Scene.GetEntity("Player")
var playerScript = player.GetComponent("Script")
var velocity = playerScript.Velocity.Duplicate()
velocity.y = 0 // Dont count gravity in bob.
velocity = velocity.Sqrt()
var amount = (Math.Sin(_deltaTime * (velocity * 0.01)) / 2 + 1) * _BobHeight
Engine.Log("BobAmount: %(amount)")
var pTransform = player.GetComponent("Transform")
var pPos = pTransform.GetTranslation()
if(amount < 1 && amount > -1) amount = 0
var transform = this.GetComponent("Transform")
var newPos = Vector3.new(pPos.x, pPos.y + _CamHeight + amount , pPos.z)
transform.SetTranslation(newPos)
cam.SetDirection(newDir)
}
exit() {}
}

View File

@@ -1,5 +1,16 @@
class Math {
foreign static Sqrt_(x, y, z)
foreign static Sin(s)
foreign static Cos(s)
foreign static Radians(s)
foreign static Degrees(s)
static Cross(vec1, vec2) {
var result = this.Cross_(vec1.x, vec1.y, vec1.z, vec2.x, vec2.y, vec2.z)
return Vector3.new(result[0], result[1], result[2])
}
foreign static Cross_(x, y, z, x1, y2, z2)
}
class Vector3 {
@@ -7,6 +18,7 @@ class Vector3 {
x {_x}
y {_y}
z {_z}
x=(value) {
_x = value
}
@@ -37,6 +49,16 @@ class Vector3 {
}
}
/(other) {
if(other is Vector3) {
return Vector3.new(_x / other.x,
_y / other.y,
_z / other.z)
} else if(other is Num) {
return Vector3.new(_x / other, _y / other, _z / other)
}
}
+(other) {
if(other is Vector3) {
return Vector3.new(_x + other.x,
@@ -49,16 +71,36 @@ class Vector3 {
}
}
-(other) {
if(other is Vector3) {
return Vector3.new(_x - other.x,
_y - other.y,
_z - other.z)
} else if(other is Num) {
return Vector3.new(_x - other,
_y - other,
_z - other)
}
}
construct new(x, y, z) {
_x = x
_y = y
_z = z
}
Duplicate() {
return Vector3.new(_x, _y, _z)
}
Sqrt() {
return Math.Sqrt_(_x, _y, _z)
}
Cross(vec) {
Math.Cross(this, vec)
}
Normalize() {
var length = this.Sqrt()
var x = _x / length
@@ -66,4 +108,12 @@ class Vector3 {
var z = _z / length
return Vector3.new(x, y, z)
}
Angle(vec) {
this.Normalize() * vec.Normalize()
}
Length() {
this.Sqrt()
}
}

View File

@@ -0,0 +1,28 @@
import "Scripts/Math" for Vector3
class CollisionResult {
LocalPosition { _Local}
WorldPosition { _World}
Normal { _Normal}
construct new(l, w, n) {
_Local = l
_World = w
_Normal = n
}
}
class Physics {
foreign static Raycast_(x, y, z, x2, y2, z2)
static Raycast(v1, v2) {
var result = this.Raycast_(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z)
var local = Vector3.new(result[0], result[1], result[2])
var world = Vector3.new(result[3], result[4], result[5])
var normal = Vector3.new(result[6], result[7], result[8])
return CollisionResult.new(local, world, normal)
}
}

View File

@@ -0,0 +1,104 @@
import "Scripts/ScriptableEntity" for ScriptableEntity
import "Scripts/Engine" for Engine
import "Scripts/Scene" for Scene
import "Scripts/Math" for Vector3
import "Scripts/Input" for Input
import "Scripts/Physics" for Physics, CollisionResult
class PlayerScript is ScriptableEntity {
Velocity {_Velocity}
construct new() {
_InputDir = Vector3.new(0, 0, 0)
_Velocity = Vector3.new(0, 0, 0)
_Accel = 25
_Deccel = 0.92
_AirDeccel = 0.7
_Gravity = 10
_MaxSpeed = 20
_Jump = 200
//Input.HideMouse()
}
init() {
Engine.Log("Player init")
}
fixedUpdate(ts) {
this.CheckInput()
var camEntity = Scene.GetEntity("Camera")
var cam = camEntity.GetComponent("Camera")
var dir = cam.GetDirection()
dir.y = 0
dir = dir.Normalize()
var right = cam.GetRight()
right.y = 0
right = right.Normalize()
var move = _InputDir
var new_Velocity = (dir * move.z) + (right * move.x)
var controller = this.GetComponent("CharacterController")
var transform = this.GetComponent("Transform")
var from = transform.GetTranslation()
var to = from - Vector3.new(0, 1, 0)
var normal = Physics.Raycast(from, to).Normal
if(!controller.IsOnGround()) {
_Velocity.y = _Velocity.y -_Gravity
//_Velocity.x = _Velocity.x * _AirDeccel
//_Velocity.z = _Velocity.z * _AirDeccel
} else {
_Velocity.y = -10
Engine.Log("Grav: %(_Velocity.y)")
if(Input.IsKeyPressed(32)) _Velocity.y = _Jump
_Velocity.x = _Velocity.x + new_Velocity.x * _Accel
_Velocity.z = _Velocity.z + new_Velocity.z * _Accel
_Velocity.x = _Velocity.x * _Deccel
_Velocity.z = _Velocity.z * _Deccel
}
Engine.Log("Grav: %(_Velocity.y)")
controller.MoveAndSlide(_Velocity * ts)
}
CheckInput() {
/*
87 = W
65 = A
83 = S
68 = D
32 = SPACE
*/
if(Input.IsKeyDown(87)) {
_InputDir.z = 1
} else if(Input.IsKeyDown(83)) {
_InputDir.z = -1
} else {
_InputDir.z = 0
}
if(Input.IsKeyDown(65)) {
_InputDir.x = 1
} else if(Input.IsKeyDown(68)) {
_InputDir.x = -1
} else {
_InputDir.x = 0
}
}
exit() {
Engine.Log("Player exit")
}
}

View File

@@ -24,7 +24,11 @@ class Scene {
return CharacterController.new(id)
} else if (component == "Camera") {
return Camera.new(id)
}
} else if (component == "Transform") {
return TransformComponent.new(id)
} else if (component == "Script") {
return this.GetScript_(id)
}
}
@@ -32,7 +36,10 @@ class Scene {
// Components
//
// Transform
//foreign static SetTranslation_(e, x, y, z)
foreign static GetScript_(e)
foreign static GetTranslation_(e)
foreign static SetTranslation_(e, x, y, z)
//foreign static SetRotation_(e, x, y, z)
//foreign static SetScale_(e, x, y, z)
@@ -53,6 +60,7 @@ class Scene {
// Character controller
foreign static MoveAndSlide_(e, x, y, z)
foreign static IsCharacterControllerOnGround_(e)
//foreign static IsOnGround_(e)
@@ -97,6 +105,22 @@ class Entity {
*/
}
class TransformComponent {
construct new(id) {
_entityId = id
}
GetTranslation() {
var result = Scene.GetTranslation_(_entityId)
return Vector3.new(result[0], result[1], result[2])
}
SetTranslation(t) {
Scene.SetTranslation_(_entityId, t.x, t.y, t.z)
}
}
class Light {
construct new(id) {
_entityId = id
@@ -131,6 +155,10 @@ class CharacterController {
MoveAndSlide(vel) {
Scene.MoveAndSlide_(_entityId, vel.x, vel.y, vel.z)
}
IsOnGround() {
return Scene.IsCharacterControllerOnGround_(_entityId)
}
}
class Camera {

View File

@@ -0,0 +1,23 @@
import "Scripts/Engine" for Engine
import "Scripts/ScriptableEntity" for ScriptableEntity
class TestScript is ScriptableEntity {
construct new() {
_deltaTime = 0
}
init() {
Engine.Log("Hello init")
}
update(ts) {
_deltaTime = _deltaTime + ts
}
exit() {
Engine.Log("Hello exit")
}
}

View File

@@ -1,27 +1,23 @@
import "Scripts/Engine" for Engine
import "Scripts/Input" for Input
import "Scripts/Scene" for Scene, Entity
class Test {
construct new() {}
init() {
System.print("hello init")
}
update(t) {
System.print("hello update %(t)")
}
exit() {
System.print("hello exit ")
}
// Gets called on the click event.
static hello() {
// Get the entity named Light
var entity = Scene.GetEntity("Light")
var light = entity.GetComponent("Light")
light.SetIntensity(1.0)
if(Input.IsMouseButtonPressed(2) == true) {
Engine.Log("RIGHT CLICK!!!!!!")
}
// Get the component light
var light = entity.GetComponent("Light")
//light.SetIntensity(222.0) // Change intensity
var currentIntensity = light.GetIntensity() // Get new intensity
Engine.Log("Current intensity %(currentIntensity)")
}
}
}

View File

@@ -1 +1 @@
{"Description":"","Name":"", "DefaultScene":"Scenes/test.scene"}
{"DefaultScene":"Scenes/test.scene","Description":"","Name":""}

View File

@@ -3,9 +3,9 @@
#include <src/Vendors/imgui/ImGuizmo.h>
#include <src/Rendering/Textures/Texture.h>
#include <Engine.h>
#include <src/Scene/Entities/Components/LightComponent.h>
#include <src/Scene/Components/LightComponent.h>
#include <src/Core/Physics/PhysicsManager.h>
#include <src/Scene/Entities/Components.h>
#include <src/Scene/Components/Components.h>
#include <src/Vendors/glm/gtc/type_ptr.hpp>
#include <src/Vendors/glm/gtx/matrix_decompose.hpp>
#include "src/Scene/Entities/ImGuiHelper.h"
@@ -13,13 +13,14 @@
#include <src/Core/MaterialManager.h>
#include "../Resource/FontAwesome5.h"
#include <src/Scene/Entities/Components/BoxCollider.h>
#include <src/Scene/Components/BoxCollider.h>
#include <algorithm>
#include <Dependencies/GLEW/include/GL/glew.h>
#include "src/Resource/Project.h"
#include <src/Scene/Entities/Components/LuaScriptComponent.h>
#include <src/Scene/Components/LuaScriptComponent.h>
#include <src/Core/Logger.h>
#include <src/Scene/Entities/Components/WrenScriptComponent.h>
#include <src/Scene/Components/WrenScriptComponent.h>
#include <src/Rendering/MSAAFramebuffer.h>
Ref<UI::UserInterface> userInterface;
ImFont* normalFont;
ImFont* EditorInterface::bigIconFont;
@@ -35,7 +36,7 @@ void EditorInterface::Init()
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
ImGui::DockSpaceOverViewport(viewport, dockspace_flags);
this->filesystem = FileSystemUI();
//this->filesystem = FileSystemUI();
}
@@ -854,7 +855,7 @@ void EditorInterface::DrawRessourceWindow()
textureID = m_SelectedMaterial->m_Normal->GetID();
if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image3"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2,2), ImVec4(0,0,0,1), ImVec4(1, 1, 1, 1)))
{
std::string texture = FileDialog::OpenFile("*.png|*.jpg");
std::string texture = FileDialog::OpenFile("*.png");
if (texture != "")
{
m_SelectedMaterial->SetNormal(TextureManager::Get()->GetTexture(texture));
@@ -923,7 +924,7 @@ void NewProject()
void OpenProject()
{
// Parse the project and load it.
std::string projectPath = FileDialog::OpenFile(".project");
std::string projectPath = "C:/Dev/Nuake/Editor/resources/test.project";//FileDialog::OpenFile(".project");
FileSystem::SetRootDirectory(projectPath + "/../");
Ref<Project> project = Project::New();
@@ -1130,13 +1131,13 @@ void EditorInterface::Draw()
DrawRessourceWindow();
DrawViewport();
DrawSceneTree();
DrawFileSystem();
DrawDirectoryExplorer();
//DrawDirectoryExplorer();
DrawEntityPropreties();
DrawLogger();
// new stuff
filesystem.Draw();
filesystem.DrawDirectoryExplorer();
if(m_ShowImGuiDemo)
ImGui::ShowDemoWindow();

View File

@@ -9,7 +9,7 @@ class Material;
class EditorInterface
{
private:
FileSystemUI filesystem;
FileSystemUI filesystem = FileSystemUI();
Entity m_SelectedEntity;
bool m_IsEntitySelected = false;
bool m_DrawGrid = false;

View File

@@ -1,7 +1,7 @@
#include "FileSystemUI.h"
#include <src/Vendors/imgui/imgui.h>
#include <src/Resource/FontAwesome5.h>
#include <src/Scene/Entities/Components/ParentComponent.h>
#include "src/Scene/Components/ParentComponent.h"
#include <src/Rendering/Textures/Texture.h>
#include <src/Core/TextureManager.h>
#include "EditorInterface.h"
@@ -34,7 +34,7 @@ void FileSystemUI::Draw()
}
if (open)
{
//EditorInterfaceDrawFiletree(rootDirectory);
EditorInterfaceDrawFiletree(rootDirectory);
ImGui::TreePop();
}
}
@@ -88,6 +88,12 @@ void FileSystemUI::DrawDirectory(Ref<Directory> directory)
std::string id = ICON_FA_FOLDER + std::string("##") + directory->name;
if (ImGui::Button(id.c_str(), ImVec2(100, 100)))
m_CurrentDirectory = directory;
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::MenuItem("Htest"));
ImGui::EndPopup();
}
ImGui::Text(directory->name.c_str());
ImGui::PopFont();
}
@@ -199,6 +205,54 @@ void FileSystemUI::DrawDirectoryExplorer()
i++;
}
}
if (ImGui::BeginPopupContextItem("item context menu"))
{
float value;
if (ImGui::Selectable("Set to zero")) value = 0.0f;
if (ImGui::Selectable("Set to PI")) value = 3.1415f;
ImGui::SetNextItemWidth(-1);
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
ImGui::EndPopup();
}
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::Button("New Wren script"))
{
ImGui::OpenPopup("CreateNewFile");
}
if (ImGui::MenuItem("New interface script"))
{
}
if (ImGui::MenuItem("New Scene"))
{
}
if (ImGui::MenuItem("New folder"))
{
}
if (ImGui::MenuItem("New interface"))
{
}
if (ImGui::MenuItem("New stylesheet"))
{
}
if (ImGui::BeginPopup("CreateNewFile"))
{
static char name[32] = "Label1";
char buf[64];
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
ImGui::Text("Edit name:");
ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
if(ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
ImGui::EndPopup();
}
ImGui::EndTable();
}

364
Nuake/.gitignore vendored
View File

@@ -1,364 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
Res/Models/
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

View File

@@ -15,6 +15,8 @@
Ref<Project> Engine::CurrentProject;
Ref<Window> Engine::CurrentWindow;
float Engine::m_LastFrameTime = 0.0f;
float Engine::m_FixedUpdateRate = 1.0 / 60.0f;
float Engine::m_FixedUpdateDifference = 0.f;
bool Engine::IsPlayMode = false;
void Engine::Init()
@@ -46,11 +48,23 @@ void Engine::Tick()
m_LastFrameTime = time;
// Play mode update vs editor update.
if (Engine::IsPlayMode)
if (Engine::IsPlayMode) {
CurrentWindow->Update(timestep);
m_FixedUpdateDifference += timestep;
// Fixed update
if (m_FixedUpdateDifference >= m_FixedUpdateRate)
{
// call update here.
CurrentWindow->FixedUpdate(m_FixedUpdateRate);
m_FixedUpdateDifference = 0.f;
}
}
else
GetCurrentScene()->EditorUpdate(timestep);
Input::Update();
}

View File

@@ -7,13 +7,30 @@
#include "src/Scripting/ScriptLoader.h"
#include "src/Core/Logger.h"
/* TODOS:
*
* Engine:
* Trigger zones from trenchbroom
* Scripting API vectors operation
* Scripting API for all component
* Scripting API for editing UI maybe
* Launch game standalone
* Fix physics system
* trenchbroom physics element
*
* Editor:
* File browser refact
*
*/
class Engine {
private:
static float m_LastFrameTime;
static Ref<Window> CurrentWindow;
static Ref<Project> CurrentProject;
static Ref<Scene> CurrentScene;
static float m_FixedUpdateRate;
static float m_FixedUpdateDifference;
public:
static bool IsPlayMode; // True if is playing a scene

View File

@@ -99,7 +99,7 @@ void FileSystem::Scan()
RootDirectory = CreateRef<Directory>();
RootDirectory->Files = std::vector<Ref<File>>();
RootDirectory->Directories = std::vector<Ref<Directory>>();
RootDirectory->name = Root;
RootDirectory->name = FileSystem::AbsoluteToRelative(Root);
RootDirectory->fullPath = Root;
ScanDirectory(RootDirectory);
}

View File

@@ -27,7 +27,7 @@ bool Input::IsKeyPressed(int keycode)
bool result = state == GLFW_PRESS;
// First time pressed?
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == false)
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == true)
{
if (result)
m_Keys[keycode] = true;

View File

@@ -1,31 +1,11 @@
#include "CharacterController.h"
#include "../Core/Physics/PhysicsManager.h"
#include "../Core/Physics/RaycastResult.h"
namespace Physics
{
class IgnoreBodyAndGhostCast :
public btCollisionWorld::ClosestRayResultCallback
{
private:
btRigidBody* m_pBody;
btPairCachingGhostObject* m_pGhostObject;
public:
IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject)
: btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)),
m_pBody(pBody), m_pGhostObject(pGhostObject)
{
}
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
{
if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject)
return 1.0f;
return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
}
};
CharacterController::CharacterController(float height, float radius, float mass)
CharacterController::CharacterController(float height, float radius, float mass, Vector3 position)
{
m_surfaceHitNormals = std::vector<glm::vec3>();
@@ -35,12 +15,12 @@ namespace Physics
btQuaternion quat = btQuaternion(0, 0, 0);
m_Transform = new btTransform();
m_Transform->setOrigin(btVector3(0.0f, 10.0f, 0.0f));
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
m_Transform->setRotation(quat);
m_MotionState = new btDefaultMotionState(*m_Transform);
btVector3 inertia;
m_CollisionShape->calculateLocalInertia(mass, inertia);
//m_CollisionShape->calculateLocalInertia(mass, inertia);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, m_MotionState, m_CollisionShape, inertia);
@@ -52,7 +32,7 @@ namespace Physics
rigidBodyCI.m_linearDamping = 0.0f;
m_Rigidbody = new btRigidBody(rigidBodyCI);
m_Rigidbody->setGravity(btVector3(0, 0, 0));
// Keep upright
m_Rigidbody->setAngularFactor(0.0f);
@@ -71,6 +51,7 @@ namespace Physics
void CharacterController::MoveAndSlide(glm::vec3 velocity)
{
m_Rigidbody->setGravity(btVector3(0, 0, 0));
m_manualVelocity = velocity;
// Sync ghost with actually object
m_GhostObject->setWorldTransform(m_Rigidbody->getWorldTransform());
@@ -140,13 +121,15 @@ namespace Physics
}
}
void CharacterController::UpdatePosition()
{
// Ray cast, ignore rigid body
IgnoreBodyAndGhostCast rayCallBack_bottom(m_Rigidbody, m_GhostObject);
btVector3 from = m_Rigidbody->getWorldTransform().getOrigin();
btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight, 0.0f);
btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight , 0.0f);
PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(from, toBt, rayCallBack_bottom);
// Bump up if hit
@@ -154,16 +137,24 @@ namespace Physics
{
float previousY = m_Rigidbody->getWorldTransform().getOrigin().getY();
m_Rigidbody->getWorldTransform().getOrigin().setY(previousY + (m_bottomYOffset + m_stepHeight) * (1.0f - rayCallBack_bottom.m_closestHitFraction));
float t = rayCallBack_bottom.m_closestHitFraction ;
float clamped = (1.0 - rayCallBack_bottom.m_closestHitFraction);
btVector3 vel(m_Rigidbody->getLinearVelocity());
if(vel.getY() < 0) // -magic number is to fix bouncing down a slope.
m_Rigidbody->getWorldTransform().getOrigin().setY(previousY - 0.14f + (m_bottomYOffset + m_stepHeight) * (clamped));
vel.setY(0.0f);
m_Rigidbody->setLinearVelocity(vel);
m_onGround = true;
IsOnGround = true;
}
float testOffset = 0.07f;
@@ -189,8 +180,8 @@ namespace Physics
void CharacterController::UpdateVelocity()
{
m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY();
//m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY();
btVector3 grav = m_Rigidbody->getGravity();
btVector3 finalVel = btVector3(m_manualVelocity.x, m_manualVelocity.y, m_manualVelocity.z);
m_Rigidbody->setLinearVelocity(finalVel);

View File

@@ -5,6 +5,7 @@
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <vector>
#include "../Core/Maths.h"
namespace Physics
{
class CharacterController
@@ -12,14 +13,15 @@ namespace Physics
public:
bool IsOnGround = false;
bool m_hittingWall;
float m_stepHeight = 0.05f;
float m_stepHeight = 0.35f;
float m_MaxSlopeAngle = 45.0f;
btTransform* m_Transform;
btCollisionShape* m_CollisionShape;
btRigidBody* m_Rigidbody;
btPairCachingGhostObject* m_GhostObject;
btMotionState* m_MotionState;
bool m_onGround;
//bool m_onJumpableGround; // A bit lower contact than just onGround
float m_bottomYOffset;
@@ -33,7 +35,7 @@ namespace Physics
btVector3 m_previousPosition;
float m_jumpRechargeTimer;
CharacterController(float height, float radius, float mass);
CharacterController(float height, float radius, float mass, Vector3 position);
void MoveAndSlide(glm::vec3 velocity);
private:

View File

@@ -2,8 +2,12 @@
#include "Rigibody.h"
#include "../Core/Core.h"
#include "BulletDebugDrawer.h"
#include <src/Vendors/glm/ext/quaternion_common.hpp>
#include <src/Core/Logger.h>
namespace Physics
{
DynamicWorld::DynamicWorld() {
///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
@@ -21,6 +25,8 @@ namespace Physics
dynamicsWorld->setDebugDrawer(new BulletDebugDrawer());
m_Bodies = std::map<btRigidBody*, Ref<RigidBody>>();
SetGravity(Vector3(0, -10000, 0));
}
@@ -50,20 +56,32 @@ namespace Physics
// Specify filters manually, otherwise ghost doesn't collide with statics for some reason
dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter );
}
RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to)
{
btVector3 btFrom(from.x, from.y, from.z);
btVector3 btTo(to.x, to.y, to.z);
btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo);
ClosestRayResultCallback res(btFrom, btTo);
dynamicsWorld->rayTest(btFrom, btTo, res);
btVector3 localNormal;
if(res.m_collisionObject)
{
// TODO: Fix the godammn fucked up normal
localNormal = res.m_hitNormalWorld;
}
Vector3 localNorm = glm::vec3(localNormal.x(), localNormal.y(), localNormal.z());
//Logger::Log("normal: x:" + std::to_string(localNorm.x) + " y:" + std::to_string(localNorm.y )+ "z: " + std::to_string(localNorm.z));
res.m_closestHitFraction;
// Map bullet result to dto.
RaycastResult result{
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
glm::vec3(res.m_hitNormalWorld.x(), res.m_hitNormalWorld.y(), res.m_hitNormalWorld.z())
localNorm
};
return result;

View File

@@ -1,5 +1,64 @@
#pragma once
#include <glm/ext/vector_float3.hpp>
#include "CharacterController.h"
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
namespace Physics
{
struct ClosestRayResultCallback : public btCollisionWorld::RayResultCallback
{
ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld)
: m_rayFromWorld(rayFromWorld),
m_rayToWorld(rayToWorld)
{
}
btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction
btVector3 m_rayToWorld;
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
{
//caller already does the filter on the m_closestHitFraction
btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
m_closestHitFraction = rayResult.m_hitFraction;
m_collisionObject = rayResult.m_collisionObject;
m_hitNormalWorld = rayResult.m_hitNormalLocal;
m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction);
return rayResult.m_hitFraction;
}
};
class IgnoreBodyAndGhostCast :
public Physics::ClosestRayResultCallback
{
private:
btRigidBody* m_pBody;
btPairCachingGhostObject* m_pGhostObject;
public:
IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject)
: ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)),
m_pBody(pBody), m_pGhostObject(pGhostObject)
{
}
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
{
if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject)
return 1.0f;
return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
}
};
}
// result object from raycast.
struct RaycastResult {

View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -77,6 +77,7 @@ void FrameBuffer::QueueResize(Vector2 size)
void FrameBuffer::UpdateSize(Vector2 size)
{
m_Size = size;
ResizeQueued = false;
// Delete frame buffer and render buffer.
glDeleteFramebuffers(1, &m_FramebufferID);

View File

@@ -0,0 +1,120 @@
#include "MSAAFramebuffer.h"
#include <GL\glew.h>
MSAAFrameBuffer::MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size)
{
m_Textures = std::map<int, Ref<MultiSampledTexture>>();
m_Size = size;
glGenFramebuffers(1, &m_FramebufferID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
// Create render buffer and attach to frame buffer.
if (hasRenderBuffer)
{
glGenRenderbuffers(1, &m_RenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
}
else
{
m_RenderBuffer = -1;
}
// Unbind
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
void MSAAFrameBuffer::SetTexture(Ref<MultiSampledTexture> texture, GLenum attachment)
{
m_Textures[attachment] = texture;
// Attach texture to the framebuffer.
Bind();
texture->AttachToFramebuffer(attachment);
// Set draw buffer with dynamic amount of render target.
// Surely, this can be optimized.
int size = 0;
std::vector<unsigned int> keys = std::vector<unsigned int>();
for (auto s : m_Textures)
{
if (s.first != GL_DEPTH_ATTACHMENT)
{
keys.push_back(s.first);
size += 1;
}
}
if (size > 0)
glDrawBuffers(size, &keys[0]);
Unbind();
}
void MSAAFrameBuffer::Bind()
{
if (ResizeQueued)
UpdateSize(m_Size);
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FramebufferID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, m_Size.x, m_Size.y, 0, 0, m_Size.x, m_Size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, m_Size.x, m_Size.y);
}
void MSAAFrameBuffer::Unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void MSAAFrameBuffer::QueueResize(Vector2 size)
{
ResizeQueued = true;
m_Size = size;
}
void MSAAFrameBuffer::UpdateSize(Vector2 size)
{
m_Size = size;
// Delete frame buffer and render buffer.
glDeleteFramebuffers(1, &m_FramebufferID);
glDeleteRenderbuffers(1, &m_RenderBuffer);
// Recreate resized texture.
for (auto t : m_Textures)
t.second->Resize(size);
// New FBO and RBO.
glGenFramebuffers(1, &m_FramebufferID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
// Recreate resized texture.
for (auto t : m_Textures)
t.second->AttachToFramebuffer(t.first);
// Recreate render buffer
glGenRenderbuffers(1, &m_RenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
// Unbind.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
void MSAAFrameBuffer::SetDrawBuffer(GLenum draw)
{
Bind();
//glReadBuffer(draw);
Unbind();
}
void MSAAFrameBuffer::SetReadBuffer(GLenum read)
{
Bind();
//glReadBuffer(read);
Unbind();
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include "../Core/Maths.h"
#include <vector>
#include "../Core/Core.h"
#include <src/Rendering/Textures/MultiSampledTexture.h>
#include <map>
class MSAAFrameBuffer
{
private:
unsigned int m_FramebufferID;
unsigned int m_RenderBuffer;
Vector2 m_Size;
bool ResizeQueued = false;
std::map<int, Ref<MultiSampledTexture>> m_Textures;
Ref<MultiSampledTexture> m_Texture;
public:
MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size);
~MSAAFrameBuffer() { }
// 0x8CE0 = color attachment 0.
// TODO: Remove blackbox crap
Ref<MultiSampledTexture> GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; }
void SetTexture(Ref<MultiSampledTexture> texture, GLenum attachment = 0x8CE0);
void Bind();
void Unbind();
void QueueResize(Vector2 size);
Vector2 GetSize() const { return m_Size; }
void UpdateSize(Vector2 size);
void SetDrawBuffer(GLenum draw);
void SetReadBuffer(GLenum read);
};

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Shaders/Shader.h"
#include "../Scene/Entities/Components.h"
#include "../Scene/Components/Components.h"
#include "../Core/Core.h"
// DTO for light data.
struct Light {

View File

@@ -119,7 +119,7 @@ unsigned int Shader::Compile(unsigned int type)
// Retrieve uniform address and registers it if not already registered.
int Shader::FindUniformLocation(std::string uniform) {
if (UniformCache.find(uniform) == UniformCache.end()) {
if (UniformCache.count(uniform) == 0) {
int addr = glGetUniformLocation(ProgramId, uniform.c_str());
if (addr == -1)

View File

@@ -0,0 +1,101 @@
#include "MultiSampledTexture.h"
#include <GL\glew.h>
#include <iostream>
MultiSampledTexture::MultiSampledTexture(const std::string& path) {
m_RendererId = 0;
m_FilePath = path;
m_LocalBuffer = nullptr;
m_Width = 0;
m_Height = 0;
m_BPP = 0;
stbi_set_flip_vertically_on_load(1);
m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4);
glGenTextures(1, &m_RendererId);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId);
glGenerateMipmap(GL_TEXTURE_2D);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f);
//glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE);
glGenerateMipmap(GL_TEXTURE_2D);
if (m_LocalBuffer)
stbi_image_free(m_LocalBuffer);
else
std::cout << "Error: failed to load texture: " << path << std::endl;
}
// Empty texture not from file.
MultiSampledTexture::MultiSampledTexture(glm::vec2 size, GLenum format)
{
m_Format = format;
m_Width = size.x;
m_Height = size.y;
glGenTextures(1, &m_RendererId);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId);
glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
}
MultiSampledTexture::MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t)
{
m_Width = size.x;
m_Height = size.y;
glGenTextures(1, &m_RendererId);
glBindTexture(GL_TEXTURE_2D, m_RendererId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
auto pixel = bitmap(0, bitmap.height - 0 - 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels);
}
void MultiSampledTexture::Resize(glm::vec2 size)
{
glDeleteTextures(1, &m_RendererId);
m_Width = size.x;
m_Height = size.y;
glGenTextures(1, &m_RendererId);
glBindTexture(GL_TEXTURE_2D, m_RendererId);
glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
MultiSampledTexture::~MultiSampledTexture() {
glDeleteTextures(1, &m_RendererId);
}
void MultiSampledTexture::AttachToFramebuffer(GLenum attachment)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, m_RendererId, 0);
//glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0);
}
void MultiSampledTexture::Bind(unsigned int slot) const {
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, m_RendererId);
}
void MultiSampledTexture::Unbind() const {
glBindTexture(GL_TEXTURE_2D, 0);
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include "stb_image/stb_image.h"
#include <string>
#include "glm/vec2.hpp"
#include "msdfgen/core/BitmapRef.hpp"
typedef unsigned int GLenum;
class MultiSampledTexture
{
private:
unsigned int m_RendererId;
std::string m_FilePath;
unsigned char* m_LocalBuffer;
GLenum m_Format;
int m_Width;
int m_Height;
int m_BPP; // byte per pixel.
public:
MultiSampledTexture(const std::string& path);
MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t);
MultiSampledTexture(glm::vec2 size, GLenum format);
~MultiSampledTexture();
void Resize(glm::vec2 size);
void AttachToFramebuffer(GLenum attachment);
void Bind(unsigned int slot = 0) const;
void Unbind() const;
unsigned int GetID() const { return m_RendererId; }
inline int GetWidth() const { return m_Width; }
inline int GetHeight() const { return m_Height; }
};

View File

@@ -19,7 +19,7 @@ Texture::Texture(const std::string& path) {
glGenerateMipmap(GL_TEXTURE_2D);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@@ -45,7 +45,7 @@ Texture::Texture(glm::vec2 size, GLenum format)
glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
}

View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -1,7 +1,7 @@
#pragma once
#include "CameraComponent.h"
#include "../ImGuiHelper.h"
#include <src/Rendering/Camera.h>
#include "src/Scene/Entities/ImGuiHelper.h"
CameraComponent::CameraComponent()
{

View File

@@ -15,13 +15,26 @@ public:
}
json Serialize() {
BEGIN_SERIALIZE();
SERIALIZE_VAL(Height);
SERIALIZE_VAL(Radius);
SERIALIZE_VAL(Mass);
END_SERIALIZE();
}
bool Deserialize(const std::string str) {
BEGIN_DESERIALIZE();
Height = j["Height"];
Radius = j["Radius"];
Mass = j["Mass"];
return true;
}
void SyncWithTransform(TransformComponent& tc)
{
btVector3 pos = CharacterController->m_motionTransform.getOrigin();
glm::vec3 finalPos = glm::vec3(pos.x(), pos.y(), pos.z());
std::string msg = "moved to: " + std::to_string(finalPos.x) + " " + std::to_string(finalPos.y) + "\n";
printf(msg.c_str());
tc.Translation = finalPos;
}
};

View File

@@ -0,0 +1,24 @@
#pragma once
#include <glm\ext\matrix_float4x4.hpp>
#include <string>
#include "BaseComponent.h"
#include "TransformComponent.h"
#include "LightComponent.h"
#include "CameraComponent.h"
#include "MeshComponent.h"
#include "ModelComponent.h"
#include "QuakeMap.h"
#include "RigidbodyComponent.h"
#include "SphereCollider.h"
#include "MeshCollider.h"
#include "NativeScriptComponent.h"
#include "CharacterControllerComponent.h"
#include "ParentComponent.h"
#include "NameComponent.h"
#include <imgui/imgui.h>
#include "../Entities/Entity.h"
// TODO: include components here.

View File

@@ -2,9 +2,10 @@
//#include <imgui\imgui.h>
#include "LightComponent.h"
#include "../../../Rendering/Renderer.h"
#include "../ImGuiHelper.h"
#include <GL\glew.h>
#include "../Core/Core.h"
#include <src/Scene/Entities/ImGuiHelper.h>
LightComponent::LightComponent()
{
Color = glm::vec3(1, 1, 1);

View File

@@ -0,0 +1,196 @@
#pragma once
#include <glm\ext\vector_float3.hpp>
#include <glm\ext\vector_float2.hpp>
#include "TransformComponent.h"
#include "../Rendering/Camera.h"
#include "../Rendering/Framebuffer.h"
#include "BaseComponent.h"
#include "../Resource/Serializable.h"
enum LightType {
Directional, Point, Spot
};
class LightComponent {
public:
glm::vec2 yes = glm::vec2(2, 2);
LightType Type = Point;
glm::vec3 Direction = glm::vec3(0, -1, 0);
glm::vec3 Color;
bool IsVolumetric = false;
float Strength;
bool SyncDirectionWithSky = false;
Ref<FrameBuffer> m_Framebuffer;
bool CastShadows = true;
float Attenuation = 0.0f;
float LinearAttenuation = 0.0f;
float QuadraticAttenuation = 0.0f;
LightComponent();
glm::mat4 GetProjection();
glm::mat4 GetLightTransform();
void SetDirection(glm::vec3 dir);
glm::vec3 GetDirection();
void BeginDrawShadow();
void EndDrawShadow();
void DrawShadow();
void Draw(TransformComponent transformComponent, Ref<Camera> cam);
void DrawDeferred(TransformComponent transformComponent, Camera* cam);
void DrawEditor();
void SetType(LightType type);
std::vector<int> mCascadeSplits;
void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection, const glm::vec3& normalizedDirection)
{
glm::mat4 viewProjection = projection * view;
glm::mat4 inverseViewProjection = glm::inverse(viewProjection);
// TODO: Automate this
const float nearClip = 0.1f;
const float farClip = 1000.0f;
const float clipRange = farClip - nearClip;
// Calculate the optimal cascade distances
const float minZ = nearClip;
const float maxZ = nearClip + clipRange;
const float range = maxZ - minZ;
const float ratio = maxZ / minZ;
for (int i = 0; i < 4; i++)
{
const float p = (i + 1) / static_cast<float>(4);
const float log = minZ * glm::pow(ratio, p);
const float uniform = minZ + range * p;
//const float d = 0.91f * (log - uniform) + uniform;
//mCascadeSplits[i] = (d - nearClip) / clipRange;
}
//mCascadeSplits[0] = 0.2f;
//mCascadeSplits[1] = 0.45f;
//mCascadeSplits[2] = 1.0f;
float lastSplitDist = 0.0f;
// Calculate Orthographic Projection matrix for each cascade
for (int cascade = 0; cascade < 4; cascade++)
{
float splitDist = mCascadeSplits[cascade];
glm::vec4 frustumCorners[8] =
{
//Near face
{ 1.0f, 1.0f, -1.0f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f },
//Far face
{ 1.0f, 1.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f },
};
// Project frustum corners into world space from clip space
for (int i = 0; i < 8; i++)
{
glm::vec4 invCorner = inverseViewProjection * frustumCorners[i];
frustumCorners[i] = invCorner / invCorner.w;
}
for (int i = 0; i < 4; i++)
{
glm::vec4 dist = frustumCorners[i + 4] - frustumCorners[i];
frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist);
frustumCorners[i] = frustumCorners[i] + (dist * lastSplitDist);
}
// Get frustum center
glm::vec3 frustumCenter = glm::vec3(0.0f);
for (int i = 0; i < 8; i++)
frustumCenter += glm::vec3(frustumCorners[i]);
frustumCenter /= 8.0f;
// Get the minimum and maximum extents
float radius = 0.0f;
for (int i = 0; i < 8; i++)
{
float distance = glm::length(glm::vec3(frustumCorners[i]) - frustumCenter);
radius = glm::max(radius, distance);
}
radius = std::ceil(radius * 16.0f) / 16.0f;
glm::vec3 maxExtents = glm::vec3(radius);
glm::vec3 minExtents = -maxExtents;
// Calculate the view and projection matrix
glm::vec3 lightDir = -normalizedDirection;
glm::mat4 lightViewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, glm::vec3(0.0f, 0.0f, 1.0f));
//glm::mat4 lightProjectionMatrix = glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f + mCascadeNearPlaneOffset, maxExtents.z - minExtents.z + mCascadeFarPlaneOffset);
// Offset to texel space to avoid shimmering ->(https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering)
//glm::mat4 shadowMatrix = lightProjectionMatrix * lightViewMatrix;
const float ShadowMapResolution = 4096;
//glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f;
//glm::vec4 roundedOrigin = glm::round(shadowOrigin);
//glm::vec4 roundOffset = roundedOrigin - shadowOrigin;
//roundOffset = roundOffset * 2.0f / ShadowMapResolution;
//roundOffset.z = 0.0f;
//roundOffset.w = 0.0f;
//lightProjectionMatrix[3] += roundOffset;
// Store SplitDistance and ViewProjection-Matrix
//mCascadeSplitDepth[cascade] = (nearClip + splitDist * clipRange) * 1.0f;
//mViewProjections[cascade] = lightProjectionMatrix * lightViewMatrix;
lastSplitDist = mCascadeSplits[cascade];
// -----------------------Debug only-----------------------
// RendererDebug::BeginScene(viewProjection);
// RendererDebug::SubmitCameraFrustum(frustumCorners, glm::mat4(1.0f), GetColor(cascade)); // Draws the divided camera frustums
// RendererDebug::SubmitLine(glm::vec3(0.0f, 0.0f, 0.0f), frustumCenter, GetColor(cascade)); // Draws the center of the frustum (A line pointing from origin to the center)
// RendererDebug::EndScene();
}
}
json Serialize()
{
BEGIN_SERIALIZE();
SERIALIZE_VAL(Type);
SERIALIZE_VEC3(Direction);
SERIALIZE_VEC3(Color);
SERIALIZE_VAL(IsVolumetric);
SERIALIZE_VAL(Strength);
SERIALIZE_VAL(SyncDirectionWithSky);
SERIALIZE_VAL(CastShadows);
END_SERIALIZE();
}
bool Deserialize(std::string str)
{
BEGIN_DESERIALIZE();
if (j.contains("Type"))
Type = (LightType)j["Type"];
if (j.contains("IsVolumetric"))
IsVolumetric = j["IsVolumetric"];
if (j.contains("Strength"))
Strength = j["Strength"];
if (j.contains("SyncDirectionWithSky"))
SyncDirectionWithSky = j["SyncDirectionWithSky"];
if (j.contains("CastShadows"))
SyncDirectionWithSky = j["CastShadows"];
if (j.contains("Direction"))
{
float x = j["Direction"]["x"];
float y = j["Direction"]["y"];
float z = j["Direction"]["z"];
this->Direction = Vector3(x, y, z);
}
return true;
}
};

View File

@@ -1,5 +1,5 @@
#pragma once
#include "../../../Rendering/Textures/Material.h"
#include "../Rendering/Textures/Material.h"
#include <glm\ext\matrix_float4x4.hpp>
#include "BaseComponent.h"

View File

@@ -1,7 +1,7 @@
#pragma once
#include <glm\ext\matrix_float4x4.hpp>
#include <vector>
#include "../../../Rendering/Mesh/Mesh.h"
#include "../Rendering/Mesh/Mesh.h"
#include "assimp/Importer.hpp"
#include <assimp/scene.h>

View File

@@ -4,7 +4,7 @@
class NameComponent {
public:
std::string Name = "Entity";
int Id;
json Serialize()
{
BEGIN_SERIALIZE();

View File

@@ -1,7 +1,7 @@
#pragma once
#include <functional>
#include "../Core/Timestep.h"
#include "../ScriptableEntity.h"
#include "../Entities/ScriptableEntity.h"
struct NativeScriptComponent
{
ScriptableEntity* Instance = nullptr;

View File

@@ -1,6 +1,6 @@
#pragma once
#include "../Entity.h"
#include "../Entities/Entity.h"
struct ParentComponent
{
@@ -19,6 +19,7 @@ struct ParentComponent
bool Deserialize(std::string str)
{
return true;
}

View File

@@ -78,9 +78,9 @@ void QuakeMapComponent::Build()
vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height);
vertices.push_back(Vertex{
glm::vec3(vertex.vertex.y * (1.0f / 64), vertex.vertex.z * (1.0f / 64), vertex.vertex.x * (1.0f / 64)),
glm::vec2(vertex_uv.u, vertex_uv.v),
glm::vec3(vertex.normal.x, vertex.normal.z, vertex.normal.y),
glm::vec3(vertex.tangent.x, vertex.tangent.z, vertex.tangent.y), glm::vec3(0.0, 1.0, 0.0), 0.0f
glm::vec2(vertex_uv.u, 1.0 -vertex_uv.v),
glm::vec3(vertex.normal.y, vertex.normal.z, vertex.normal.x),
glm::vec3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x), glm::vec3(0.0, 1.0, 0.0), 0.0f
});
//printf("vertex: (%f %f %f), normal: (%f %f %f)\n",

View File

@@ -32,6 +32,7 @@ public:
{
BEGIN_DESERIALIZE();
this->Path = j["Path"];
this->HasCollisions = j["HasCollisions"];
Build(); // Maybe have some kind of loading bar or something.
return true;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "../Scripting/WrenScript.h"
#include <src/Resource/Serializable.h>
class WrenScriptComponent
{

View File

@@ -1,24 +0,0 @@
#pragma once
#include <glm\ext\matrix_float4x4.hpp>
#include <string>
#include "Components/BaseComponent.h"
#include "Components/TransformComponent.h"
#include "Components/LightComponent.h"
#include "Components/CameraComponent.h"
#include "Components/MeshComponent.h"
#include "Components/ModelComponent.h"
#include "Components/QuakeMap.h"
#include "Components/RigidbodyComponent.h"
#include "Components/SphereCollider.h"
#include "Components/MeshCollider.h"
#include "Components/NativeScriptComponent.h"
#include "Components/CharacterControllerComponent.h"
#include "Components/ParentComponent.h"
#include "Components/NameComponent.h"
#include <imgui/imgui.h>
#include "Entity.h"
// TODO: include components here.

View File

@@ -1,2 +0,0 @@
#pragma once
#include "../Entity.h"

View File

@@ -1,88 +0,0 @@
#pragma once
#include <glm\ext\vector_float3.hpp>
#include <glm\ext\vector_float2.hpp>
#include "TransformComponent.h"
#include "../Rendering/Camera.h"
#include "../../../Rendering/Framebuffer.h"
#include "BaseComponent.h"
#include "../Resource/Serializable.h"
enum LightType {
Directional, Point, Spot
};
class LightComponent {
public:
glm::vec2 yes = glm::vec2(2, 2);
LightType Type = Point;
glm::vec3 Direction = glm::vec3(0, -1, 0);
glm::vec3 Color;
bool IsVolumetric = false;
float Strength;
bool SyncDirectionWithSky = false;
Ref<FrameBuffer> m_Framebuffer;
bool CastShadows = true;
float Attenuation = 0.0f;
float LinearAttenuation = 0.0f;
float QuadraticAttenuation = 0.0f;
LightComponent();
glm::mat4 GetProjection();
glm::mat4 GetLightTransform();
void SetDirection(glm::vec3 dir);
glm::vec3 GetDirection();
void BeginDrawShadow();
void EndDrawShadow();
void DrawShadow();
void Draw(TransformComponent transformComponent, Ref<Camera> cam);
void DrawDeferred(TransformComponent transformComponent, Camera* cam);
void DrawEditor();
void SetType(LightType type);
json Serialize()
{
BEGIN_SERIALIZE();
SERIALIZE_VAL(Type);
SERIALIZE_VEC3(Direction);
SERIALIZE_VEC3(Color);
SERIALIZE_VAL(IsVolumetric);
SERIALIZE_VAL(Strength);
SERIALIZE_VAL(SyncDirectionWithSky);
SERIALIZE_VAL(CastShadows);
END_SERIALIZE();
}
bool Deserialize(std::string str)
{
BEGIN_DESERIALIZE();
if (j.contains("Type"))
Type = (LightType)j["Type"];
if (j.contains("IsVolumetric"))
IsVolumetric = j["IsVolumetric"];
if (j.contains("Strength"))
Strength = j["Strength"];
if (j.contains("SyncDirectionWithSky"))
SyncDirectionWithSky = j["SyncDirectionWithSky"];
if (j.contains("CastShadows"))
SyncDirectionWithSky = j["CastShadows"];
if (j.contains("Direction"))
{
float x = j["Direction"]["x"];
float y = j["Direction"]["y"];
float z = j["Direction"]["z"];
this->Direction = Vector3(x, y, z);
}
return true;
}
};

View File

@@ -1,14 +1,15 @@
#include "Components/ParentComponent.h"
#include "../Components/ParentComponent.h"
#include "Entity.h"
#include "Components/NameComponent.h"
#include "Components/TransformComponent.h"
#include "Components/CameraComponent.h"
#include "Components/QuakeMap.h"
#include "Components/LightComponent.h"
#include "Components/QuakeMap.h"
#include <src/Scene/Entities/Components/WrenScriptComponent.h>
#include "../Components/NameComponent.h"
#include "../Components/TransformComponent.h"
#include "../Components/CameraComponent.h"
#include "../Components/QuakeMap.h"
#include "../Components/LightComponent.h"
#include "../Components/QuakeMap.h"
#include "../Components/WrenScriptComponent.h"
#include "../Components/CharacterControllerComponent.h"
void Entity::AddChild(Entity ent)
{
if ((int)m_EntityHandle != ent.GetHandle())
@@ -34,6 +35,8 @@ json Entity::Serialize()
SERIALIZE_OBJECT_REF_LBL("LightComponent", GetComponent<LightComponent>());
if (HasComponent<WrenScriptComponent>())
SERIALIZE_OBJECT_REF_LBL("WrenScriptComponent", GetComponent<WrenScriptComponent>());
if (HasComponent<CharacterControllerComponent>())
SERIALIZE_OBJECT_REF_LBL("CharacterControllerComponent", GetComponent<CharacterControllerComponent>());
END_SERIALIZE();
}
@@ -47,6 +50,7 @@ bool Entity::Deserialize(const std::string& str)
DESERIALIZE_COMPONENT(QuakeMapComponent);
DESERIALIZE_COMPONENT(LightComponent);
DESERIALIZE_COMPONENT(WrenScriptComponent);
DESERIALIZE_COMPONENT(CharacterControllerComponent);
return true;
}

View File

@@ -2,7 +2,7 @@
#include <string>
#include <glm\ext\matrix_float4x4.hpp>
#include "../Scene.h"
#include "Components/BaseComponent.h"
#include "../Components/BaseComponent.h"
#include "../Resource/Serializable.h"
class Entity : public ISerializable

View File

@@ -1,8 +1,8 @@
#pragma once
#include "Entity.h"
#include "../Scene/Entities/Components/ParentComponent.h"
#include "../Scene/Entities/Components/NameComponent.h"
#include "../Components/ParentComponent.h"
#include "../Components/NameComponent.h"
class ScriptableEntity
{

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);
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,37 +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());
@@ -377,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();
}
}
@@ -390,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>();
@@ -411,100 +312,100 @@ 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)
{
Renderer::m_Shader->SetUniform1f("u_Exposure", m_EditorCamera->Exposure);
Renderer::m_Shader->SetUniform3f("u_EyePosition", m_EditorCamera->GetTranslation().x, m_EditorCamera->GetTranslation().y, m_EditorCamera->GetTranslation().z);
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());
@@ -513,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));
@@ -563,7 +464,7 @@ glm::vec3 Scene::GetGlobalPosition(Entity ent)
globalPos += currentParent.GetComponent<TransformComponent>().Translation;
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
}
return globalPos;
}
@@ -592,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;
}
@@ -621,7 +522,7 @@ Ref<Camera> Scene::GetCurrentCamera()
cam = m_EditorCamera;
return cam;
}
return m_EditorCamera;
}
@@ -633,7 +534,7 @@ bool Scene::Save()
{
if (Path == "")
Path = FileSystem::AbsoluteToRelative(FileDialog::SaveFile("*.scene") + ".scene");
return SaveAs(Path);
}
@@ -643,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;
}
@@ -665,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();
}
@@ -679,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"))
{
@@ -693,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"))
@@ -706,6 +607,6 @@ bool Scene::Deserialize(const std::string& str)
}
}
}
return true;
}

View File

@@ -11,7 +11,9 @@
#include "../Resource/Serializable.h"
#include "src/UI/UserInterface.h"
#include "../Core/Maths.h"
#include <src/Scene/Systems/System.h>
class Entity;
class Scene : public ISerializable
{
friend Entity;
@@ -20,12 +22,13 @@ private:
std::string Name;
bool has_changed = true;
std::vector<Ref<System>> m_Systems;
entt::registry m_Registry;
Ref<Environment> m_Environement;
Ref<EditorCamera> m_EditorCamera;
public:
entt::registry m_Registry;
std::vector<Ref<UI::UserInterface>> m_Interfaces;
std::string Path = "";
static Ref<Scene> New();
@@ -40,6 +43,7 @@ public:
void OnInit();
void OnExit();
void Update(Timestep ts);
void FixedUpdate(Timestep ts);
void EditorUpdate(Timestep ts);
// TODO: Maybe move this to Renderer::DrawScene() ?

View File

@@ -0,0 +1,98 @@
#include "PhysicsSystem.h"
#include "src/Scene/Scene.h"
#include "src/Scene/Components/BoxCollider.h"
#include <src/Scene/Components/RigidbodyComponent.h>
#include "src/Scene/Entities/Entity.h"
#include <src/Core/Physics/PhysicsManager.h>
#include <src/Scene/Components/CharacterControllerComponent.h>
#include <src/Scene/Components/QuakeMap.h>
PhysicsSystem::PhysicsSystem(Scene* scene)
{
m_Scene = scene;
}
void PhysicsSystem::Init()
{
// Create physic world.
auto view = m_Scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
for (auto e : view)
{
auto [transform, rigidbody] = view.get<TransformComponent, RigidBodyComponent>(e);
Entity ent = Entity({ e, m_Scene });
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_Scene->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, m_Scene });
PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController);
}
auto quakeMapview = m_Scene->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);
}
}
}
}
void PhysicsSystem::Update(Timestep ts)
{
// Update rigidbodies
PhysicsManager::Get()->Step(ts);
auto physicGroup = m_Scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
for (auto e : physicGroup) {
auto [transform, rb] = physicGroup.get<TransformComponent, RigidBodyComponent>(e);
rb.SyncTransformComponent(&m_Scene->m_Registry.get<TransformComponent>(e));
}
auto ccGroup = m_Scene->m_Registry.view<TransformComponent, CharacterControllerComponent>();
for (auto e : ccGroup) {
auto [transform, rb] = ccGroup.get<TransformComponent, CharacterControllerComponent>(e);
rb.SyncWithTransform(m_Scene->m_Registry.get<TransformComponent>(e));
}
}
void PhysicsSystem::FixedUpdate(Timestep ts)
{
}
void PhysicsSystem::Exit()
{
PhysicsManager::Get()->Reset();
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <src/Scene/Systems/System.h>
class PhysicsSystem : public System {
public:
PhysicsSystem(Scene* scene);
void Init() override;
void Update(Timestep ts) override;
void Draw() override {}
void FixedUpdate(Timestep ts) override;
void Exit() override;
};

View File

@@ -0,0 +1,69 @@
#include "ScriptingSystem.h"
#include <src/Scene/Components/WrenScriptComponent.h>
#include "src/Scene/Scene.h"
ScriptingSystem::ScriptingSystem(Scene* scene)
{
m_Scene = scene;
}
void ScriptingSystem::Init()
{
ScriptingEngine::Init();
auto entities = m_Scene->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();
}
}
}
void ScriptingSystem::Update(Timestep ts)
{
auto entities = m_Scene->m_Registry.view<WrenScriptComponent>();
for (auto& e : entities)
{
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
if (wren.WrenScript != nullptr)
wren.WrenScript->CallUpdate(ts);
}
}
void ScriptingSystem::FixedUpdate(Timestep ts)
{
auto entities = m_Scene->m_Registry.view<WrenScriptComponent>();
for (auto& e : entities)
{
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
if (wren.WrenScript != nullptr)
wren.WrenScript->CallFixedUpdate(ts);
}
}
void ScriptingSystem::Exit()
{
auto entities = m_Scene->m_Registry.view<WrenScriptComponent>();
for (auto& e : entities)
{
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
if (wren.WrenScript != nullptr)
wren.WrenScript->CallExit();
}
ScriptingEngine::Close();
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include "System.h"
class Scene;
class ScriptingSystem : public System {
public:
ScriptingSystem(Scene* scene);
void Init() override;
void Update(Timestep ts) override;
void Draw() override {}
void FixedUpdate(Timestep ts) override;
void Exit() override;
};

View File

@@ -0,0 +1,2 @@
#include "System.h"

View File

@@ -0,0 +1,19 @@
#pragma once
#include <src/Core/Timestep.h>
#include "src/Core/Core.h"
class Scene;
class System {
public:
Scene* m_Scene;
virtual void Init() = 0;
virtual void Draw() = 0;
virtual void Update(Timestep ts) = 0;
virtual void FixedUpdate(Timestep ts) = 0;
virtual void Exit() = 0;
};

View File

@@ -22,7 +22,11 @@ namespace ScriptAPI
void RegisterModule(WrenVM* vm) override
{
RegisterMethod("Sqrt_(_,_,_)", (void*)Sqrt);
RegisterMethod("Sin(_)", (void*)Sin);
RegisterMethod("Cos(_)", (void*)Cos);
RegisterMethod("Radians(_)", (void*)Radians);
RegisterMethod("Degrees(_)", (void*)Degrees);
RegisterMethod("Cross_(_,_,_,_,_,_)", (void*)Cross);
}
static void Sqrt(WrenVM* vm)
@@ -33,6 +37,55 @@ namespace ScriptAPI
float result = glm::sqrt((x * x) + (y * y) + (z * z));
wrenSetSlotDouble(vm, 0, result);
}
static void Cos(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::cos(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Sin(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::sin(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Radians(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::radians(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Degrees(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::degrees(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Cross(WrenVM* vm)
{
Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1),
wrenGetSlotDouble(vm, 2),
wrenGetSlotDouble(vm, 3));
Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4),
wrenGetSlotDouble(vm, 5),
wrenGetSlotDouble(vm, 6));
Vector3 cross = glm::cross(v1, v2);
wrenSetSlotNewList(vm, 0);
wrenSetSlotDouble(vm, 1, cross.x);
wrenSetSlotDouble(vm, 2, cross.y);
wrenSetSlotDouble(vm, 3, cross.z);
wrenInsertInList(vm, 0, -1, 1);
wrenInsertInList(vm, 0, -1, 2);
wrenInsertInList(vm, 0, -1, 3);
}
};

View File

@@ -0,0 +1,63 @@
#pragma once
#include "wren.h"
#include <string>
#include <src/Core/Logger.h>
#include "../Core/Maths.h"
#include "ScriptModule.h"
#include <iostream>
#include <wren.h>
#include "../Core/Physics/PhysicsManager.h"
namespace ScriptAPI
{
class PhysicsModule : public ScriptModule
{
std::string ModuleName = "Engine";
std::string GetModuleName() override
{
return "Physics";
}
void RegisterModule(WrenVM* vm) override
{
RegisterMethod("Raycast_(_,_,_,_,_,_)", (void*)Raycast);
}
static void Raycast(WrenVM* vm)
{
Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1),
wrenGetSlotDouble(vm, 2),
wrenGetSlotDouble(vm, 3));
Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4),
wrenGetSlotDouble(vm, 5),
wrenGetSlotDouble(vm, 6));
RaycastResult result = PhysicsManager::Get()->Raycast(v1, v2);
wrenSetSlotNewList(vm, 0);
// Returns a list with 3 vectors placed sequentially
// should be reconstructed in the wren side.
wrenSetSlotDouble(vm, 1, result.LocalPoint.x);
wrenSetSlotDouble(vm, 2, result.LocalPoint.y);
wrenSetSlotDouble(vm, 3, result.LocalPoint.z);
wrenSetSlotDouble(vm, 4, result.WorldPoint.x);
wrenSetSlotDouble(vm, 5, result.WorldPoint.y);
wrenSetSlotDouble(vm, 6, result.WorldPoint.z);
wrenSetSlotDouble(vm, 7, result.Normal.x);
wrenSetSlotDouble(vm, 8, result.Normal.y);
wrenSetSlotDouble(vm, 9, result.Normal.z);
wrenInsertInList(vm, 0, -1, 1);
wrenInsertInList(vm, 0, -1, 2);
wrenInsertInList(vm, 0, -1, 3);
wrenInsertInList(vm, 0, -1, 4);
wrenInsertInList(vm, 0, -1, 5);
wrenInsertInList(vm, 0, -1, 6);
wrenInsertInList(vm, 0, -1, 7);
wrenInsertInList(vm, 0, -1, 8);
wrenInsertInList(vm, 0, -1, 9);
}
};
}

View File

@@ -7,12 +7,13 @@
#include <wren.h>
#include "Engine.h"
#include "../Scene/Entities/Entity.h"
#include <src/Scene/Entities/Components/TransformComponent.h>
#include <src/Scene/Entities/Components/LightComponent.h>
#include <src/Scene/Entities/Components/QuakeMap.h>
#include <src/Scene/Entities/Components/CameraComponent.h>
#include <src/Scene/Entities/Components/RigidbodyComponent.h>
#include <src/Scene/Entities/Components/CharacterControllerComponent.h>
#include <src/Scene/Components/TransformComponent.h>
#include <src/Scene/Components/LightComponent.h>
#include <src/Scene/Components/QuakeMap.h>
#include <src/Scene/Components/CameraComponent.h>
#include <src/Scene/Components/RigidbodyComponent.h>
#include <src/Scene/Components/CharacterControllerComponent.h>
#include <src/Scene/Components/WrenScriptComponent.h>
namespace ScriptAPI
{
@@ -29,12 +30,16 @@ namespace ScriptAPI
{
RegisterMethod("GetEntityID(_)", (void*)GetEntity);
RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent);
RegisterMethod("GetTranslation_(_)", (void*)GetTranslation);
RegisterMethod("SetTranslation_(_,_,_,_)", (void*)SetTranslation);
RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity);
RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity);
RegisterMethod("GetScript_(_)", (void*)GetScript);
RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection);
RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection);
RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight);
RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide);
RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround);
}
static void GetEntity(WrenVM* vm)
@@ -80,6 +85,20 @@ namespace ScriptAPI
bool result = ent.HasComponent<RigidBodyComponent>();
wrenSetSlotBool(vm, 0, result);
}
if (name == "Script") {
bool result = ent.HasComponent<WrenScriptComponent>();
wrenSetSlotBool(vm, 0, result);
}
}
static void GetScript(WrenVM* vm) {
int handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
if (ent.HasComponent<WrenScriptComponent>())
{
wrenSetSlotHandle(vm, 0, ent.GetComponent<WrenScriptComponent>().WrenScript->m_Instance);
}
}
static void SetLightIntensity(WrenVM* vm)
@@ -158,7 +177,14 @@ namespace ScriptAPI
wrenInsertInList(vm, 0, 2, 3);
}
static void IsCharacterControllerOnGround(WrenVM* vm)
{
int handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& characterController = ent.GetComponent<CharacterControllerComponent>();
bool result = characterController.CharacterController->IsOnGround;
wrenSetSlotBool(vm, 0, result);
}
static void MoveAndSlide(WrenVM* vm)
{
@@ -172,5 +198,34 @@ namespace ScriptAPI
characterController.CharacterController->MoveAndSlide(Vector3(x, y, z));
}
static void GetTranslation(WrenVM* vm)
{
int handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
wrenSetSlotDouble(vm, 1, transform.Translation.x);
wrenSetSlotDouble(vm, 2, transform.Translation.y);
wrenSetSlotDouble(vm, 3, transform.Translation.z);
// Fill the list
wrenSetSlotNewList(vm, 0);
wrenInsertInList(vm, 0, 0, 1);
wrenInsertInList(vm, 0, 1, 2);
wrenInsertInList(vm, 0, 2, 3);
}
static void SetTranslation(WrenVM* vm)
{
int handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
float x = wrenGetSlotDouble(vm, 2);
float y = wrenGetSlotDouble(vm, 3);
float z = wrenGetSlotDouble(vm, 4);
transform.Translation = Vector3(x, y, z);
}
};
}

View File

@@ -6,6 +6,7 @@
#include <src/Scripting/Modules/SceneModule.h>
#include <src/Scripting/Modules/MathModule.h>
#include <src/Scripting/Modules/InputModule.h>
#include <src/Scripting/Modules/PhysicsModule.h>
WrenVM* ScriptingEngine::m_WrenVM;
@@ -112,6 +113,8 @@ void ScriptingEngine::Init()
RegisterModule(mathModule);
Ref<ScriptAPI::InputModule> inputModule = CreateRef<ScriptAPI::InputModule> ();
RegisterModule(inputModule);
Ref<ScriptAPI::PhysicsModule> physicsModule = CreateRef<ScriptAPI::PhysicsModule>();
RegisterModule(physicsModule);
}

View File

@@ -27,6 +27,7 @@ WrenScript::WrenScript(const std::string& path, const std::string& mod, bool isE
// Create handles to the instance methods.
this->m_OnInitHandle = wrenMakeCallHandle(vm, "init()");
this->m_OnUpdateHandle = wrenMakeCallHandle(vm, "update(_)");
this->m_OnFixedUpdateHandle = wrenMakeCallHandle(vm, "fixedUpdate(_)");
this->m_OnExitHandle = wrenMakeCallHandle(vm, "exit()");
if (isEntity)
@@ -49,6 +50,15 @@ void WrenScript::CallUpdate(float timestep)
WrenInterpretResult result = wrenCall(vm, this->m_OnUpdateHandle);
}
void WrenScript::CallFixedUpdate(float timestep)
{
WrenVM* vm = ScriptingEngine::GetWrenVM();
wrenEnsureSlots(vm, 2);
wrenSetSlotHandle(vm, 0, this->m_Instance);
wrenSetSlotDouble(vm, 1, timestep);
WrenInterpretResult result = wrenCall(vm, this->m_OnFixedUpdateHandle);
}
void WrenScript::CallExit()
{
WrenVM* vm = ScriptingEngine::GetWrenVM();

View File

@@ -11,6 +11,7 @@ public:
WrenHandle* m_Instance;
WrenHandle* m_OnInitHandle;
WrenHandle* m_OnUpdateHandle;
WrenHandle* m_OnFixedUpdateHandle;
WrenHandle* m_OnExitHandle;
WrenHandle* m_SetEntityIDHandle;
@@ -18,6 +19,7 @@ public:
void CallInit();
void CallUpdate(float timestep);
void CallFixedUpdate(float timestep);
void CallExit();
void RegisterMethod(const std::string& signature);

View File

@@ -153,7 +153,8 @@ int Window::Init()
// TODO: Style should move to editor
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.Fonts->AddFontDefault();
//io.Fonts->AddFontDefault();
io.Fonts->AddFontFromFileTTF("resources/Fonts/OpenSans-Regular.ttf", 16.0);
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
ImGui::StyleColorsDark();
@@ -222,6 +223,11 @@ void Window::Update(Timestep ts)
m_Scene->Update(ts);
}
void Window::FixedUpdate(Timestep ts)
{
m_Scene->FixedUpdate(ts);
}
void Window::Draw()
{
// Dont render if no scene is loaded.

View File

@@ -3,7 +3,6 @@
#include "Rendering/Framebuffer.h"
#include "Scene/Scene.h"
#include "Core/Core.h"
struct GLFWwindow;
class Window
{
@@ -31,7 +30,7 @@ public:
int Init();
void Update(Timestep ts);
void FixedUpdate(Timestep ts);
void Draw();
void EndDraw();

View File

@@ -1,4 +1,9 @@
# Nuake
Feel free to join the discord server for updates:
[![Support Server](https://img.shields.io/discord/852625335236558868.svg?label=Discord&logo=Discord&colorB=7289da&style=for-the-badge)](https://discord.gg/kuF4efPK7Y)
# What is it
@@ -15,7 +20,7 @@ Nuake is a game engine written from scratch by myself. It is not meant to be a e
Feel free to make pull requests and I will look over them myself.
# Documentation
No documentation is currently available, I will try my best to work on this asap.
You can access the current documentation at [here](https://nuake.readthedocs.io/en/latest/index.html)
# Features
- Trenchbroom integration with live reload

15
docs/General/building.rst Normal file
View File

@@ -0,0 +1,15 @@
How to build
==================
Building Nuake is currently the only supported way to get Nuake.
This means that you will need to build the projects file, build, then launch the project.
The following step should help you get Nuake running on your computer:
#. Clone the git repo and the submodules recursivly.
This can be done using the following command::
git clone --recurse-submodules https://github.com/antopilo/Nuake.git
#. Launch the cmd file called `generate.bat`.
This should generate a visual studio solution for you.
#. Build the project, everything should build in the right order and launch the editor.

View File

@@ -0,0 +1,4 @@
How do I contribute?
============
You can simply fork the current github `repository <https://github.com/antopilo/Nuake>`_ and create pull requests,
I will look over them personally.

30
docs/General/index.rst Normal file
View File

@@ -0,0 +1,30 @@
Introduction
============
.. toctree::
:maxdepth: 1
:name: toc-intro
introduction
Building
========
.. toctree::
:maxdepth: 1
:name: toc-building
building
Contribution
============
.. toctree::
:maxdepth: 1
:name: toc-contribution
contribution

View File

@@ -0,0 +1,20 @@
.. note:: Nuake is a work-in-progress project and is not suited for profesionnal game development.
Use at your own risk.
Welcome to the offical documentation of Nuake, an open-source 3D game engine!
Nuake is a 3D game engine aimed to create games similar to quake with modern technologies.
The recent resurgence of quake-like games gave me the initial ideas to create an engine designed
to make those types of games. This means that integration of tools like trenchbroom and quake-based tools
will be a priority during the development of Nuake.
What is Nuake?
============
Nuake is a work-in-progress game engine aimed to give a simple but flexible tool to create quake-type games.
What type of game is it for?
============
You can create any type of game using Nuake, but it is mostly designed to create 3D games.
You should be able to create FPS or TPS games without problems, although it was originally designed to create first person games.

View File

@@ -0,0 +1,3 @@
Engine module API
==============

View File

@@ -0,0 +1,33 @@
Entity scripts
==============
Entity scripts are Wren scripts that are attached to an entity using the WrenScript component.
After attaching the WrenScript component on an entity, you can select the script file directly.
In addition to pointing to the script file, you need to specify which class in the script is considered as the
entity script.
The class chosen must inherit from ScriptableEntity.
Here is an example of a barebone entity scripts::
import "Scripts/ScriptableEntity" for ScriptableEntity
class TestScript is ScriptableEntity {
construct new() {
}
init() {
}
update(ts) {
}
exit() {
}
}

14
docs/Scripting/index.rst Normal file
View File

@@ -0,0 +1,14 @@
Scripting
========
.. toctree::
:maxdepth: 1
:name: toc-scripting
entity_scripts
interface_scripts
engine
math
scene

View File

@@ -0,0 +1,2 @@
Interface scripts
=================

2
docs/Scripting/math.rst Normal file
View File

@@ -0,0 +1,2 @@
Math module API
==============

2
docs/Scripting/scene.rst Normal file
View File

@@ -0,0 +1,2 @@
Scene module API
==============

9
docs/Tutorial/index.rst Normal file
View File

@@ -0,0 +1,9 @@
Tutorials
=====
.. toctree::
:maxdepth: 1
:name: toc-tutorial
project
scene

View File

@@ -0,0 +1,2 @@
Project tutorial
================

2
docs/Tutorial/scene.rst Normal file
View File

@@ -0,0 +1,2 @@
Scene tutorial
==============

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More