mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-09 20:08:57 +03:00
Various improvements:
Framebuffer resize queued to next frame to fix flickering Wren VM init moved to on play event Added new Wren modules Added missing components to the editor Changed how the wren scripts gets initialized
This commit is contained in:
@@ -3,6 +3,52 @@ class Math {
|
||||
}
|
||||
|
||||
class Vector3 {
|
||||
|
||||
x {_x}
|
||||
y {_y}
|
||||
z {_z}
|
||||
x=(value) {
|
||||
_x = value
|
||||
}
|
||||
y=(value) {
|
||||
_y = value
|
||||
}
|
||||
z=(value) {
|
||||
_z = value
|
||||
}
|
||||
|
||||
mul(other) {
|
||||
if(other is Vector3) {
|
||||
return Vector3.new(_x * other.x,
|
||||
_y * other.y,
|
||||
_z * other.z)
|
||||
} else {
|
||||
return Vector3.new(_x * other, _y * other, _z * other)
|
||||
}
|
||||
}
|
||||
|
||||
*(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,
|
||||
_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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "Scripts/Engine" for Engine
|
||||
import "Scripts/Math" for Vector3
|
||||
|
||||
class Scene {
|
||||
foreign static GetEntityID(name)
|
||||
@@ -11,35 +12,50 @@ class Scene {
|
||||
}
|
||||
|
||||
foreign static EntityHasComponent(id, name)
|
||||
static EntityGetComponent(id, component) {
|
||||
if(this.EntityHasComponent(id, component) == false) {
|
||||
Engine.Log("Tried getting a non-existent component of type: %(component) on entity with id: %(id)")
|
||||
return
|
||||
}
|
||||
|
||||
// Component specific private setter and getter.
|
||||
foreign static GetLightIntensity_(e)
|
||||
foreign static SetLightIntensity_(e, intensity)
|
||||
if (component == "Light") {
|
||||
return Light.new(id)
|
||||
} else if (component == "CharacterController") {
|
||||
return CharacterController.new(id)
|
||||
} else if (component == "Camera") {
|
||||
return Camera.new(id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// Transform
|
||||
foreign static SetTranslation_(e, x, y, z)
|
||||
foreign static SetRotation_(e, x, y, z)
|
||||
foreign static SetScale_(e, x, y, z)
|
||||
|
||||
// Character controller
|
||||
foreign static SetVelocity(e, x, y, z)
|
||||
foreign static SetStepHeight(e, x, y, z)
|
||||
foreign static IsOnGround(e)
|
||||
*/
|
||||
// Light
|
||||
//
|
||||
// Components
|
||||
//
|
||||
/*
|
||||
foreign static SetLightIsVolumetric_(e, bool)
|
||||
foreign static SetLightSyncDirectionWithSky_(e, bool)
|
||||
foreign static SetLightColor_(e, r, g, b)
|
||||
// Transform
|
||||
//foreign static SetTranslation_(e, x, y, z)
|
||||
//foreign static SetRotation_(e, x, y, z)
|
||||
//foreign static SetScale_(e, x, y, z)
|
||||
|
||||
// Light
|
||||
foreign static GetLightIntensity_(e) // returns a float
|
||||
foreign static SetLightIntensity_(e, intensity)
|
||||
//foreign static SetLightIsVolumetric_(e, bool)
|
||||
//foreign static SetLightSyncDirectionWithSky_(e, bool)
|
||||
//foreign static SetLightColor_(e, r, g, b)
|
||||
//foreign static GetLightColor_(e)
|
||||
|
||||
// Camera
|
||||
foreign static SetCameraFov_(e, fov)
|
||||
foreign static SetCameraType(e, type)
|
||||
foreign static SetCameraDirection_(e, x, y, z)
|
||||
*/
|
||||
foreign static GetCameraDirection_(e) // returns a list x,y,z
|
||||
foreign static GetCameraRight_(e) // returns a list x,y,z
|
||||
//foreign static SetcameraFov(e, fov)
|
||||
//foreign static GetCameraFov(e) // returns a float
|
||||
|
||||
// Character controller
|
||||
foreign static MoveAndSlide_(e, x, y, z)
|
||||
//foreign static IsOnGround_(e)
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Entity {
|
||||
@@ -52,14 +68,7 @@ class Entity {
|
||||
}
|
||||
|
||||
GetComponent(component) {
|
||||
if(this.HasComponent(component) == false) {
|
||||
Engine.Log("Tried getting a non-existent component of type: %(component) on entity with id: %(_entityId)")
|
||||
return
|
||||
}
|
||||
|
||||
if (component == "Light") {
|
||||
return Light.new(_entityId)
|
||||
}
|
||||
return Scene.EntityGetComponent(_entityId, component)
|
||||
}
|
||||
|
||||
// Foreign engine functions
|
||||
@@ -110,17 +119,37 @@ class Light {
|
||||
|
||||
SetColor(color) {
|
||||
this.SetColor_(_entityId, color.r, color.g, color.b, color.a)
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
class CharacterController {
|
||||
construct new(id) {
|
||||
_entityId = id
|
||||
}
|
||||
|
||||
SetDirection(direction) {
|
||||
var normalized = direction.Normalize()
|
||||
this.SetDirection_(_entityId, normalized.x, normalized.y, normalized.z)
|
||||
MoveAndSlide(vel) {
|
||||
Scene.MoveAndSlide_(_entityId, vel.x, vel.y, vel.z)
|
||||
}
|
||||
|
||||
foreign static SetType_(id, type)
|
||||
foreign static SetColor_(id, r, g, b)
|
||||
|
||||
foreign static SetDirection_(id, x, y, z)
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Camera {
|
||||
construct new(id) {
|
||||
_entityId = id
|
||||
}
|
||||
|
||||
SetDirection(dir) {
|
||||
Scene.SetCameraDirection_(_entityId, dir.x, dir.y, dir.z)
|
||||
}
|
||||
|
||||
GetDirection() {
|
||||
var dir = Scene.GetCameraDirection_(_entityId)
|
||||
return Vector3.new(dir[0], dir[1], dir[2])
|
||||
}
|
||||
|
||||
GetRight() {
|
||||
var dir = Scene.GetCameraRight_(_entityId)
|
||||
return Vector3.new(dir[0], dir[1], dir[2])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
15
Editor/resources/Scripts/ScriptableEntity.wren
Normal file
15
Editor/resources/Scripts/ScriptableEntity.wren
Normal file
@@ -0,0 +1,15 @@
|
||||
import "Scripts/Scene" for Scene
|
||||
|
||||
class ScriptableEntity {
|
||||
SetEntityId(id) {
|
||||
_EntityID = id
|
||||
}
|
||||
|
||||
GetComponent(component) {
|
||||
return Scene.EntityGetComponent(_EntityID, component)
|
||||
}
|
||||
|
||||
HasComponent(component) {
|
||||
return Scene.EntityHasComponent(_EntityID, component)
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "src/Resource/Project.h"
|
||||
#include <src/Scene/Entities/Components/LuaScriptComponent.h>
|
||||
#include <src/Core/Logger.h>
|
||||
#include <src/Scene/Entities/Components/WrenScriptComponent.h>
|
||||
Ref<UI::UserInterface> userInterface;
|
||||
ImFont* normalFont;
|
||||
ImFont* EditorInterface::bigIconFont;
|
||||
@@ -80,7 +81,7 @@ void EditorInterface::DrawViewport()
|
||||
glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
|
||||
|
||||
if(Engine::GetCurrentWindow()->GetFrameBuffer()->GetSize() != viewportPanelSize)
|
||||
Engine::GetCurrentWindow()->GetFrameBuffer()->UpdateSize(viewportPanelSize);
|
||||
Engine::GetCurrentWindow()->GetFrameBuffer()->QueueResize(viewportPanelSize);
|
||||
|
||||
Ref<Texture> texture = Engine::GetCurrentWindow()->GetFrameBuffer()->GetTexture();
|
||||
ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
|
||||
@@ -321,16 +322,22 @@ void EditorInterface::DrawEntityPropreties()
|
||||
}
|
||||
if (ImGui::BeginPopup("add_component_popup"))
|
||||
{
|
||||
if (ImGui::MenuItem("Lua script") && !m_SelectedEntity.HasComponent<LuaScriptComponent>())
|
||||
m_SelectedEntity.AddComponent<LuaScriptComponent>();
|
||||
if (ImGui::MenuItem("Light Component") && !m_SelectedEntity.HasComponent<LightComponent>())
|
||||
m_SelectedEntity.AddComponent<LightComponent>();
|
||||
if (ImGui::MenuItem("Mesh Component") && !m_SelectedEntity.HasComponent<MeshComponent>())
|
||||
m_SelectedEntity.AddComponent<MeshComponent>();
|
||||
if (ImGui::MenuItem("Wren Script") && !m_SelectedEntity.HasComponent<WrenScriptComponent>())
|
||||
m_SelectedEntity.AddComponent<WrenScriptComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Camera Component") && !m_SelectedEntity.HasComponent<CameraComponent>())
|
||||
m_SelectedEntity.AddComponent<CameraComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Light Component") && !m_SelectedEntity.HasComponent<LightComponent>())
|
||||
m_SelectedEntity.AddComponent<LightComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Mesh Component") && !m_SelectedEntity.HasComponent<MeshComponent>())
|
||||
m_SelectedEntity.AddComponent<MeshComponent>();
|
||||
if (ImGui::MenuItem("Quake map Component") && !m_SelectedEntity.HasComponent<QuakeMapComponent>())
|
||||
m_SelectedEntity.AddComponent<QuakeMapComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Character controller") && !m_SelectedEntity.HasComponent<CharacterControllerComponent>())
|
||||
m_SelectedEntity.AddComponent<CharacterControllerComponent>();
|
||||
if (ImGui::MenuItem("Rigidbody Component") && !m_SelectedEntity.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
m_SelectedEntity.AddComponent<RigidBodyComponent>();
|
||||
@@ -377,32 +384,43 @@ void EditorInterface::DrawEntityPropreties()
|
||||
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<LuaScriptComponent>()) {
|
||||
if (m_SelectedEntity.HasComponent<WrenScriptComponent>()) {
|
||||
std::string icon = ICON_FA_FILE;
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Lua script").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Wren Script").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
auto& component = m_SelectedEntity.GetComponent<LuaScriptComponent>();
|
||||
auto& component = m_SelectedEntity.GetComponent<WrenScriptComponent>();
|
||||
|
||||
// Path
|
||||
std::string path = component.Script;
|
||||
|
||||
|
||||
char pathBuffer[256];
|
||||
|
||||
memset(pathBuffer, 0, sizeof(pathBuffer));
|
||||
std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer));
|
||||
|
||||
if (ImGui::InputText("##ScriptPath", pathBuffer, sizeof(pathBuffer)))
|
||||
{
|
||||
path = std::string(pathBuffer);
|
||||
}
|
||||
path = FileSystem::AbsoluteToRelative(std::string(pathBuffer));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Browse"))
|
||||
{
|
||||
path = FileDialog::OpenFile(".map");
|
||||
}
|
||||
path = FileSystem::AbsoluteToRelative(FileDialog::OpenFile(".wren"));
|
||||
|
||||
component.Script = path;
|
||||
|
||||
// Class
|
||||
std::string module = component.Class;
|
||||
|
||||
char classBuffer[256];
|
||||
|
||||
memset(classBuffer, 0, sizeof(classBuffer));
|
||||
std::strncpy(classBuffer, module.c_str(), sizeof(classBuffer));
|
||||
|
||||
if (ImGui::InputText("##ScriptModule", classBuffer, sizeof(classBuffer)))
|
||||
module = std::string(classBuffer);
|
||||
|
||||
component.Class = module;
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<CameraComponent>()) {
|
||||
@@ -416,6 +434,18 @@ void EditorInterface::DrawEntityPropreties()
|
||||
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<CharacterControllerComponent>())
|
||||
{
|
||||
if (ImGui::CollapsingHeader("Character controller", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
auto& c = m_SelectedEntity.GetComponent<CharacterControllerComponent>();
|
||||
ImGui::InputFloat("Height", &c.Height);
|
||||
ImGui::InputFloat("Radius", &c.Radius);
|
||||
ImGui::InputFloat("Mass", &c.Mass);
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<MeshComponent>()) {
|
||||
|
||||
std::string icon = ICON_FA_TREE;
|
||||
@@ -907,17 +937,26 @@ void OpenProject()
|
||||
Engine::LoadProject(project);
|
||||
|
||||
// Create new interface named test.
|
||||
userInterface = UI::UserInterface::New("test");
|
||||
//userInterface = UI::UserInterface::New("test");
|
||||
|
||||
|
||||
// Set current interface running.
|
||||
Engine::GetCurrentScene()->AddInterface(userInterface);
|
||||
|
||||
//Engine::GetCurrentScene()->AddInterface(userInterface);
|
||||
}
|
||||
|
||||
void OpenScene()
|
||||
{
|
||||
// Parse the project and load it.
|
||||
std::string projectPath = FileDialog::OpenFile(".scene");
|
||||
|
||||
Ref<Scene> scene = Scene::New();
|
||||
if (!scene->Deserialize(FileSystem::ReadFile(projectPath, true))) {
|
||||
Logger::Log("Error failed loading scene: " + projectPath);
|
||||
return;
|
||||
}
|
||||
|
||||
scene->Path = FileSystem::AbsoluteToRelative(projectPath);
|
||||
Engine::LoadScene(scene);
|
||||
}
|
||||
|
||||
void EditorInterface::DrawInit()
|
||||
@@ -981,6 +1020,10 @@ void EditorInterface::Draw()
|
||||
m_IsEntitySelected = false;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Set current scene as default")) {
|
||||
Engine::GetProject()->DefaultScene = Engine::GetCurrentScene();
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Open scene...", "CTRL+O"))
|
||||
{
|
||||
OpenScene();
|
||||
|
||||
@@ -24,8 +24,6 @@ void Engine::Init()
|
||||
PhysicsManager::Get()->Init();
|
||||
Logger::Log("Physics initialized");
|
||||
|
||||
ScriptingEngine::Init();
|
||||
Logger::Log("Scripting engine initialized");
|
||||
|
||||
CurrentWindow = Window::Get();
|
||||
Logger::Log("Window initialized");
|
||||
|
||||
@@ -16,12 +16,13 @@ class Camera : public ISerializable
|
||||
private:
|
||||
CAMERA_TYPE m_Type;
|
||||
|
||||
float AspectRatio = 16.0f / 9.0f;
|
||||
|
||||
Vector3 Rotation = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 Scale = { 1.0f, 1.0f, 1.0f };
|
||||
Matrix4 m_Perspective;
|
||||
|
||||
public:
|
||||
float AspectRatio = 16.0f / 9.0f;
|
||||
// TODO: remove duplicate direction and have a proper api.
|
||||
Vector3 up = Vector3(0.0f, 1.0f, 0.0f);
|
||||
Vector3 cameraFront = Vector3(0.0f, 0.0f, 1.0f);
|
||||
|
||||
@@ -55,6 +55,9 @@ void FrameBuffer::SetTexture(Ref<Texture> texture, GLenum attachment)
|
||||
|
||||
void FrameBuffer::Bind()
|
||||
{
|
||||
if (ResizeQueued)
|
||||
UpdateSize(m_Size);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferID);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glViewport(0, 0, m_Size.x, m_Size.y);
|
||||
@@ -65,6 +68,12 @@ void FrameBuffer::Unbind()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::QueueResize(Vector2 size)
|
||||
{
|
||||
ResizeQueued = true;
|
||||
m_Size = size;
|
||||
}
|
||||
|
||||
void FrameBuffer::UpdateSize(Vector2 size)
|
||||
{
|
||||
m_Size = size;
|
||||
|
||||
@@ -11,7 +11,8 @@ private:
|
||||
unsigned int m_RenderBuffer;
|
||||
|
||||
Vector2 m_Size;
|
||||
|
||||
bool ResizeQueued = false;
|
||||
|
||||
std::map<int, Ref<Texture>> m_Textures;
|
||||
Ref<Texture> m_Texture;
|
||||
|
||||
@@ -27,6 +28,7 @@ public:
|
||||
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void QueueResize(Vector2 size);
|
||||
Vector2 GetSize() const { return m_Size; }
|
||||
void UpdateSize(Vector2 size);
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ int Shader::FindUniformLocation(std::string uniform) {
|
||||
if (addr == -1)
|
||||
std::cout << "Warning: uniform '" << uniform << "' doesn't exists!" << std::endl;
|
||||
else {
|
||||
std::cout << "Info: uniform '" << uniform << "' registered." << std::endl;
|
||||
//std::cout << "Info: uniform '" << uniform << "' registered." << std::endl;
|
||||
UniformCache[uniform] = addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,11 +33,8 @@ void Project::Save()
|
||||
|
||||
void Project::SaveAs(const std::string FullPath)
|
||||
{
|
||||
// Serialize the scene.
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Name);
|
||||
SERIALIZE_VAL(Description);
|
||||
|
||||
json j = Serialize();
|
||||
// Dump.
|
||||
std::string serialized_string = j.dump();
|
||||
|
||||
|
||||
8
Nuake/src/Scene/Entities/Components/InterfaceComponent.h
Normal file
8
Nuake/src/Scene/Entities/Components/InterfaceComponent.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "../Core/Core.h"
|
||||
#include <src/UI/UserInterface.h>
|
||||
|
||||
class InterfaceComponent
|
||||
{
|
||||
Ref<UI::UserInterface> Interface;
|
||||
};
|
||||
31
Nuake/src/Scene/Entities/Components/WrenScriptComponent.h
Normal file
31
Nuake/src/Scene/Entities/Components/WrenScriptComponent.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "../Scripting/WrenScript.h"
|
||||
|
||||
class WrenScriptComponent
|
||||
{
|
||||
public:
|
||||
std::string Script;
|
||||
std::string Class;
|
||||
|
||||
Ref<WrenScript> WrenScript;
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Script);
|
||||
SERIALIZE_VAL(Class);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(std::string str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
if (j.contains("Script"))
|
||||
Script = j["Script"];
|
||||
if (j.contains("Class"))
|
||||
Class = j["Class"];
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Components/QuakeMap.h"
|
||||
#include "Components/LightComponent.h"
|
||||
#include "Components/QuakeMap.h"
|
||||
#include <src/Scene/Entities/Components/WrenScriptComponent.h>
|
||||
void Entity::AddChild(Entity ent)
|
||||
{
|
||||
if ((int)m_EntityHandle != ent.GetHandle())
|
||||
@@ -31,6 +32,8 @@ json Entity::Serialize()
|
||||
SERIALIZE_OBJECT_REF_LBL("QuakeMapComponent", GetComponent<QuakeMapComponent>());
|
||||
if (HasComponent<LightComponent>())
|
||||
SERIALIZE_OBJECT_REF_LBL("LightComponent", GetComponent<LightComponent>());
|
||||
if (HasComponent<WrenScriptComponent>())
|
||||
SERIALIZE_OBJECT_REF_LBL("WrenScriptComponent", GetComponent<WrenScriptComponent>());
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
@@ -43,6 +46,7 @@ bool Entity::Deserialize(const std::string& str)
|
||||
DESERIALIZE_COMPONENT(CameraComponent);
|
||||
DESERIALIZE_COMPONENT(QuakeMapComponent);
|
||||
DESERIALIZE_COMPONENT(LightComponent);
|
||||
DESERIALIZE_COMPONENT(WrenScriptComponent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "../Scene/Entities/Components/LuaScriptComponent.h"
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
|
||||
#include "../Scene/Entities/Components/WrenScriptComponent.h"
|
||||
Ref<Scene> Scene::New()
|
||||
{
|
||||
return CreateRef<Scene>();
|
||||
@@ -44,6 +44,8 @@ bool Scene::SetName(std::string& newName)
|
||||
|
||||
void Scene::OnInit()
|
||||
{
|
||||
ScriptingEngine::Init();
|
||||
|
||||
// Create physic world.
|
||||
auto view = m_Registry.view<TransformComponent, RigidBodyComponent>();
|
||||
for (auto e : view)
|
||||
@@ -98,10 +100,19 @@ void Scene::OnInit()
|
||||
|
||||
// Instanciate scripts.
|
||||
{
|
||||
m_Registry.view<LuaScriptComponent>().each([=](auto entity, auto& nsc)
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,12 +121,21 @@ void Scene::OnExit()
|
||||
PhysicsManager::Get()->Reset();
|
||||
|
||||
// destroy scripts.
|
||||
auto entities = m_Registry.view<WrenScriptComponent>();
|
||||
for (auto& e : entities)
|
||||
{
|
||||
m_Registry.view<NativeScriptComponent>().each([=](auto entity, auto& nsc)
|
||||
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
|
||||
|
||||
if (wren.WrenScript != nullptr)
|
||||
{
|
||||
nsc.Instance->OnDestroy();
|
||||
});
|
||||
wren.WrenScript->CallExit();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ScriptingEngine::Close();
|
||||
}
|
||||
|
||||
// update entities and some components.
|
||||
@@ -129,6 +149,16 @@ void Scene::Update(Timestep 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);
|
||||
|
||||
@@ -618,12 +648,14 @@ bool Scene::SaveAs(const std::string& path)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Scene::ReloadInterfaces()
|
||||
{
|
||||
for (auto& i : m_Interfaces)
|
||||
i->Reload();
|
||||
}
|
||||
|
||||
|
||||
void Scene::AddInterface(Ref<UI::UserInterface> interface)
|
||||
{
|
||||
this->m_Interfaces.push_back(interface);
|
||||
@@ -643,7 +675,6 @@ json Scene::Serialize()
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Scene::Deserialize(const std::string& str)
|
||||
{
|
||||
if (str == "")
|
||||
@@ -675,5 +706,6 @@ bool Scene::Deserialize(const std::string& str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ namespace ScriptAPI
|
||||
|
||||
static void Sqrt(WrenVM* vm)
|
||||
{
|
||||
float x = wrenGetSlotDouble(vm, 0);
|
||||
float y = wrenGetSlotDouble(vm, 0);
|
||||
float z = wrenGetSlotDouble(vm, 0);
|
||||
float x = wrenGetSlotDouble(vm, 1);
|
||||
float y = wrenGetSlotDouble(vm, 2);
|
||||
float z = wrenGetSlotDouble(vm, 3);
|
||||
float result = glm::sqrt((x * x) + (y * y) + (z * z));
|
||||
wrenSetSlotDouble(vm, 0, result);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#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>
|
||||
|
||||
namespace ScriptAPI
|
||||
{
|
||||
@@ -30,6 +31,10 @@ namespace ScriptAPI
|
||||
RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent);
|
||||
RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity);
|
||||
RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity);
|
||||
RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection);
|
||||
RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection);
|
||||
RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight);
|
||||
RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide);
|
||||
}
|
||||
|
||||
static void GetEntity(WrenVM* vm)
|
||||
@@ -99,7 +104,73 @@ namespace ScriptAPI
|
||||
|
||||
static void SetCameraDirection(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
float x = wrenGetSlotDouble(vm, 2);
|
||||
float y = wrenGetSlotDouble(vm, 3);
|
||||
float z = wrenGetSlotDouble(vm, 4);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& cam = ent.GetComponent<CameraComponent>();
|
||||
cam.CameraInstance->SetDirection(Vector3(x, y, z));
|
||||
}
|
||||
|
||||
static void GetCameraDirection(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& cam = ent.GetComponent<CameraComponent>();
|
||||
|
||||
Vector3 dir = cam.CameraInstance->GetDirection();
|
||||
|
||||
wrenEnsureSlots(vm, 4);
|
||||
|
||||
// set the slots
|
||||
// Fill the list
|
||||
wrenSetSlotNewList(vm, 0);
|
||||
wrenSetSlotDouble(vm, 1, dir.x);
|
||||
wrenSetSlotDouble(vm, 2, dir.y);
|
||||
wrenSetSlotDouble(vm, 3, dir.z);
|
||||
|
||||
wrenInsertInList(vm, 0, -1, 1);
|
||||
wrenInsertInList(vm, 0, -1, 2);
|
||||
wrenInsertInList(vm, 0, -1, 3);
|
||||
}
|
||||
|
||||
static void GetCameraRight(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& cam = ent.GetComponent<CameraComponent>();
|
||||
|
||||
Vector3 right = cam.CameraInstance->cameraRight;
|
||||
|
||||
// set the slots
|
||||
wrenSetSlotDouble(vm, 1, right.x);
|
||||
wrenSetSlotDouble(vm, 2, right.y);
|
||||
wrenSetSlotDouble(vm, 3, right.z);
|
||||
|
||||
// Fill the list
|
||||
wrenSetSlotNewList(vm, 0);
|
||||
wrenInsertInList(vm, 0, 0, 1);
|
||||
wrenInsertInList(vm, 0, 1, 2);
|
||||
wrenInsertInList(vm, 0, 2, 3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void MoveAndSlide(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
float x = wrenGetSlotDouble(vm, 2);
|
||||
float y = wrenGetSlotDouble(vm, 3);
|
||||
float z = wrenGetSlotDouble(vm, 4);
|
||||
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
auto& characterController = ent.GetComponent<CharacterControllerComponent>();
|
||||
characterController.CharacterController->MoveAndSlide(Vector3(x, y, z));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
@@ -40,11 +40,25 @@ void writeFn(WrenVM* vm, const char* text) {
|
||||
printf("%s", text);
|
||||
}
|
||||
|
||||
bool hasEnding(std::string const& fullString, std::string const& ending) {
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
|
||||
WrenLoadModuleResult result = { 0 };
|
||||
std::string str = FileSystem::ReadFile("resources/" + std::string(name) + ".wren", true);
|
||||
|
||||
std::string path = "resources/" + std::string(name);
|
||||
if(!hasEnding(path, ".wren"))
|
||||
path += ".wren";
|
||||
|
||||
std::string str = FileSystem::ReadFile(path, true);
|
||||
char* c = strcpy(new char[str.length() + 1], str.c_str());
|
||||
|
||||
result.source = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
#include "WrenScript.h"
|
||||
#include "../Core/FileSystem.h"
|
||||
#include <src/Vendors/wren/src/include/wren.h>
|
||||
WrenScript::WrenScript(const std::string& path, const std::string& mod)
|
||||
{
|
||||
|
||||
WrenScript::WrenScript(const std::string& path, const std::string& mod, bool isEntity)
|
||||
{
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
|
||||
|
||||
// Import statement
|
||||
std::string source = "import \"" + path + "\" for " + mod;
|
||||
|
||||
// Import file as module
|
||||
wrenInterpret(vm, "main", source.c_str());
|
||||
|
||||
// Get handle to class
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenGetVariable(vm, "main", mod.c_str(), 0);
|
||||
WrenHandle* classHandle = wrenGetSlotHandle(vm, 0);
|
||||
|
||||
// Call the constructor
|
||||
WrenHandle* constructHandle = wrenMakeCallHandle(vm, "new()");
|
||||
wrenCall(vm, constructHandle);
|
||||
|
||||
// Retreive value of constructor
|
||||
this->m_Instance = wrenGetSlotHandle(vm, 0);
|
||||
|
||||
// Create handles to the instance methods.
|
||||
this->m_OnInitHandle = wrenMakeCallHandle(vm, "init()");
|
||||
this->m_OnUpdateHandle = wrenMakeCallHandle(vm, "update(_)");
|
||||
this->m_OnExitHandle = wrenMakeCallHandle(vm, "exit()");
|
||||
|
||||
if (isEntity)
|
||||
this->m_SetEntityIDHandle = wrenMakeCallHandle(vm, "SetEntityId(_)");
|
||||
}
|
||||
|
||||
void WrenScript::CallInit()
|
||||
@@ -26,7 +42,6 @@ void WrenScript::CallInit()
|
||||
|
||||
void WrenScript::CallUpdate(float timestep)
|
||||
{
|
||||
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
wrenEnsureSlots(vm, 2);
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
@@ -37,6 +52,7 @@ void WrenScript::CallUpdate(float timestep)
|
||||
void WrenScript::CallExit()
|
||||
{
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
WrenInterpretResult result = wrenCall(vm, this->m_OnExitHandle);
|
||||
}
|
||||
@@ -56,7 +72,16 @@ void WrenScript::CallMethod(const std::string& signature)
|
||||
// Not found. maybe try to register it?
|
||||
if (methods.find(signature) == methods.end())
|
||||
return;
|
||||
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
WrenHandle* handle = methods[signature];
|
||||
WrenInterpretResult result = wrenCall(vm, handle);
|
||||
}
|
||||
|
||||
void WrenScript::SetScriptableEntityID(int id)
|
||||
{
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
wrenSetSlotDouble(vm, 1, id);
|
||||
WrenInterpretResult result = wrenCall(vm, this->m_SetEntityIDHandle);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,9 @@ public:
|
||||
WrenHandle* m_OnInitHandle;
|
||||
WrenHandle* m_OnUpdateHandle;
|
||||
WrenHandle* m_OnExitHandle;
|
||||
WrenHandle* m_SetEntityIDHandle;
|
||||
|
||||
WrenScript(const std::string& path, const std::string& mod);
|
||||
WrenScript(const std::string& path, const std::string& mod, bool isEntity = false);
|
||||
|
||||
void CallInit();
|
||||
void CallUpdate(float timestep);
|
||||
@@ -21,4 +22,6 @@ public:
|
||||
|
||||
void RegisterMethod(const std::string& signature);
|
||||
void CallMethod(const std::string& signature);
|
||||
|
||||
void SetScriptableEntityID(int id);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "InterfaceParser.h"
|
||||
|
||||
#include "Styling/Stylesheet.h"
|
||||
Ref<Canvas> InterfaceParser::Root = CreateRef<Canvas>();
|
||||
|
||||
void InterfaceParser::Iterate(const pugi::xml_node& xml_node, Ref<Node> node, int depth)
|
||||
@@ -271,6 +271,11 @@ Ref<Canvas> InterfaceParser::CreateCanvas(const pugi::xml_node& xml_node)
|
||||
std::string module = s[1];
|
||||
node->Script = ScriptingEngine::RegisterScript(path, module);
|
||||
}
|
||||
if (name == "stylesheet")
|
||||
{
|
||||
std::string path = a.value();
|
||||
node->StyleSheet = UI::StyleSheet::New(path);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "../Core/Core.h"
|
||||
#include "../Scripting/WrenScript.h"
|
||||
#include <map>
|
||||
#include "../Styling/Stylesheet.h"
|
||||
|
||||
// Base container for UI.
|
||||
class Canvas : public Node
|
||||
{
|
||||
@@ -11,5 +13,7 @@ private:
|
||||
|
||||
public:
|
||||
Ref<WrenScript> Script;
|
||||
Ref<UI::StyleSheet> StyleSheet;
|
||||
|
||||
Canvas();
|
||||
};
|
||||
@@ -1,18 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "katana-parser/katana.h"
|
||||
#include "../Core/FileSystem.h"
|
||||
#include "../Core/Logger.h"
|
||||
#include "../Core/Core.h"
|
||||
#include "Style.h"
|
||||
|
||||
#include "katana-parser/katana.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "../Nodes/Node.h"
|
||||
#include <src/UI/Styling/StyleSheetParser.h>
|
||||
#include <regex>
|
||||
#include <regex>
|
||||
#include <src/UI/InterfaceParser.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
namespace UI
|
||||
{
|
||||
class StyleSheet
|
||||
@@ -24,7 +20,20 @@ namespace UI
|
||||
public:
|
||||
std::string Path;
|
||||
static Ref<StyleSheet> New(const std::string& path);
|
||||
std::vector<std::string> Split(std::string const& str, const char delim)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
size_t start;
|
||||
size_t end = 0;
|
||||
|
||||
while ((start = str.find_first_not_of(delim, end)) != std::string::npos)
|
||||
{
|
||||
end = str.find(delim, start);
|
||||
result.push_back(str.substr(start, end - start));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
void AddStyleGroup(std::string selector, Ref<StyleGroup> group)
|
||||
{
|
||||
Styles[selector] = group;
|
||||
@@ -90,7 +99,7 @@ namespace UI
|
||||
std::smatch match_value;
|
||||
Layout::LayoutVec4 result;
|
||||
|
||||
std::vector<std::string> splits = InterfaceParser::split(value, ' ');
|
||||
std::vector<std::string> splits = Split(value, ' ');
|
||||
int idx = 0;
|
||||
for (auto& s : splits)
|
||||
{
|
||||
|
||||
@@ -14,11 +14,8 @@ namespace UI
|
||||
m_Name = name;
|
||||
|
||||
font = FontLoader::LoadFont("resources/Fonts/RobotoMono-Regular.ttf");
|
||||
|
||||
m_Stylesheet = StyleSheet::New("/Interface\\Testing.css");
|
||||
|
||||
Root = InterfaceParser::Parse("resources/Interface/Testing.interface");
|
||||
|
||||
|
||||
if (!Root)
|
||||
{
|
||||
Logger::Log("Failed to generate interface structure");
|
||||
@@ -38,7 +35,6 @@ namespace UI
|
||||
|
||||
void UserInterface::Reload()
|
||||
{
|
||||
m_Stylesheet = StyleSheet::New("/Interface\\Testing.css");
|
||||
Root = InterfaceParser::Parse("resources/Interface/Testing.interface");
|
||||
if (!Root)
|
||||
{
|
||||
@@ -67,8 +63,8 @@ namespace UI
|
||||
Root->YogaNode = yoga_root;
|
||||
|
||||
for (auto& g : Root->GetGroups())
|
||||
if (m_Stylesheet->HasStyleGroup(g))
|
||||
Root->ApplyStyle(m_Stylesheet->GetStyleGroup(g));
|
||||
if (Root->StyleSheet->HasStyleGroup(g))
|
||||
Root->ApplyStyle(Root->StyleSheet->GetStyleGroup(g));
|
||||
Root->SetYogaLayout();
|
||||
CreateYogaLayoutRecursive(Root, yoga_root);
|
||||
}
|
||||
@@ -85,8 +81,8 @@ namespace UI
|
||||
n->YogaNode = newYogaNode;
|
||||
|
||||
for (auto& g : n->GetGroups())
|
||||
if (m_Stylesheet->HasStyleGroup(g))
|
||||
n->ApplyStyle(m_Stylesheet->GetStyleGroup(g));
|
||||
if (Root->StyleSheet->HasStyleGroup(g))
|
||||
n->ApplyStyle(Root->StyleSheet->GetStyleGroup(g));
|
||||
|
||||
n->SetYogaLayout();
|
||||
YGNodeInsertChild(yoga_node, newYogaNode, index);
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace UI
|
||||
Ref<FrameBuffer> m_Framebuffer; // Texture of the interface.
|
||||
std::string m_Name;
|
||||
Ref<Canvas> Root;
|
||||
Ref<StyleSheet> m_Stylesheet;
|
||||
YGConfigRef yoga_config;
|
||||
YGNodeRef yoga_root;
|
||||
public:
|
||||
|
||||
@@ -232,6 +232,8 @@ void Window::Draw()
|
||||
Ref<Camera> cam = m_Scene->GetCurrentCamera();
|
||||
if (!cam) return;
|
||||
|
||||
Vector2 size = m_Framebuffer->GetSize();
|
||||
cam->AspectRatio = size.x / size.y;
|
||||
Renderer::BeginDraw(cam);
|
||||
{
|
||||
|
||||
|
||||
Reference in New Issue
Block a user