Gizmo working

This commit is contained in:
Chewico 2026-02-11 01:49:59 +01:00
parent 946c9e0027
commit 041853a4a0
18 changed files with 187 additions and 93 deletions

View File

@ -67,6 +67,11 @@ namespace Deer {
getContextEntity(handle).destroy();
}
glm::mat4 Scripting::entity_getWorldMatrix(EntityHandle& handle) {
Entity& entity = getContextEntity(handle);
return entity.getWorldMatrix();
}
int Scripting::entity_getNetworkBehaviour(EntityHandle& handle) {
return (int)getContextEntityComponent<TagComponent>(handle).networkBehaviour;
}

View File

@ -32,6 +32,8 @@ namespace Deer {
void entity_destroy(EntityHandle&);
CScriptArray* entity_getChildrens(EntityHandle&);
glm::mat4 entity_getWorldMatrix(EntityHandle&);
int entity_getNetworkBehaviour(EntityHandle&);
void entity_setNetworkBehaviour(int, EntityHandle&);
int entity_getForcedNetworkBehaviour(EntityHandle&);

View File

@ -7,6 +7,18 @@ namespace Deer {
new (mem) glm::vec3();
}
void mat4_constructor(void* mem) {
new (mem) glm::mat4(1.0f);
}
glm::mat4 mat4_getRelativeMatrix(glm::mat4& other, glm::mat4& self) {
return glm::inverse(other) * self;
}
glm::vec3 mat4_getPosition(glm::mat4& matrix) {
return glm::vec3(matrix[3][0], matrix[3][1], matrix[3][2]);
}
void vec3_constructor_params(float x, float y, float z, void* mem) {
new (mem) glm::vec3(x, y, z);
}

View File

@ -10,6 +10,10 @@ namespace Deer {
void vec3_constructor(void*);
void vec3_constructor_params(float, float, float, void*);
void mat4_constructor(void*);
glm::mat4 mat4_getRelativeMatrix(glm::mat4&, glm::mat4&);
glm::vec3 mat4_getPosition(glm::mat4&);
glm::vec3 vec3_add(glm::vec3&, glm::vec3&);
glm::vec3 vec3_sub(const glm::vec3&, glm::vec3&);
glm::vec3 vec3_neg(glm::vec3&);

View File

@ -31,6 +31,8 @@ namespace Deer {
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "bool opEquals(const Entity &in) const", entity_opEquals);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "array<Entity>@ getChildrens()", entity_getChildrens);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "mat4 getWorldMatrix()", entity_getWorldMatrix);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "EntityNetworkBehaviour get_networkBehaviour() const property", entity_getNetworkBehaviour);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "void set_networkBehaviour(EntityNetworkBehaviour) property", entity_setNetworkBehaviour);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "EntityNetworkBehaviour getForcedNetworkBehaviour()", entity_getForcedNetworkBehaviour);

View File

@ -20,6 +20,9 @@ namespace Deer {
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "vec3", "void f()", vec3_constructor);
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "vec3", "void f(float, float = 0, float = 0)", vec3_constructor_params);
scriptEngine->RegisterObjectType("mat4", sizeof(glm::mat4), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::mat4>() | asOBJ_APP_CLASS_ALLFLOATS | asOBJ_APP_CLASS_MORE_CONSTRUCTORS);
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "mat4", "void f()", mat4_constructor);
scriptEngine->RegisterObjectType("quat", sizeof(glm::quat), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::quat>() | asOBJ_APP_CLASS_ALLFLOATS | asOBJ_APP_CLASS_MORE_CONSTRUCTORS);
scriptEngine->RegisterObjectProperty("quat", "float x", asOFFSET(glm::quat, x));
scriptEngine->RegisterObjectProperty("quat", "float y", asOFFSET(glm::quat, y));
@ -58,6 +61,9 @@ namespace Deer {
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "quat", "void setEuler(vec3)", quat_setEuler);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "quat", "vec3 getEuler() const", quat_getEuler);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "mat4", "mat4 getRelativeMatrix(mat4&in) const", mat4_getRelativeMatrix);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "mat4", "vec3 getPosition() const", mat4_getPosition);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Transform", "vec3 relative(vec3)", transform_relative);
}

View File

@ -7,6 +7,7 @@
#include "DeerRender/Universe.h"
#include "DeerRender/Window.h"
#include "DeerRender/World.h"
#include "imgui.h"
#include "DeerRender/Render/RenderCommand.h"

View File

@ -3,9 +3,8 @@
namespace Deer {
Scope<FrameBuffer> ResourceBuilder<FrameBuffer>::buildResource(const FrameBufferData& baseData) {
TextureBufferType tbt;
switch (baseData.frameBufferType)
{
case FrameBufferData::FrameBufferType::RGBA8 :
switch (baseData.frameBufferType) {
case FrameBufferData::FrameBufferType::RGBA8:
tbt = TextureBufferType::RGBA8;
break;
@ -15,9 +14,7 @@ namespace Deer {
FrameBufferSpecification spec(baseData.sizeX, baseData.sizeY, {tbt}, baseData.samples);
Scope<FrameBuffer> frameBuffer = Scope<FrameBuffer>(FrameBuffer::create(spec));
return frameBuffer;
}
}
} // namespace Deer

View File

@ -127,7 +127,6 @@ namespace Deer {
ImGuiIO& io = ImGui::GetIO();
io.AddKeyEvent((ImGuiKey)e.getKeyCode(),
ImGui::IsKeyPressed(ImGuiKey_LeftSuper) || ImGui::IsKeyPressed(ImGuiKey_RightSuper));
return false;
}

View File

@ -75,6 +75,10 @@ namespace Deer {
REGISTER_GLOBAL_FUNC(scriptEngine, "void drawFrameBuffer(FrameBuffer texture, int, int)", Scripting::drawFrameBuffer);
REGISTER_GLOBAL_FUNC(scriptEngine, "void drawFrameBufferCentered(FrameBuffer texture, int, int)", Scripting::drawFrameBufferCentered);
REGISTER_GLOBAL_FUNC(scriptEngine, "bool manipulationTransform(WorldCamera&in, mat4&in, mat4&out, bool local)", Scripting::manipulationTransform);
REGISTER_GLOBAL_FUNC(scriptEngine, "bool manipulationRotation(WorldCamera&in, mat4&in, mat4&out, bool local)", Scripting::manipulationRotation);
REGISTER_GLOBAL_FUNC(scriptEngine, "bool manipulationScale(WorldCamera&in, mat4&in, mat4&out, bool local)", Scripting::manipulationScale);
// Input state
REGISTER_GLOBAL_FUNC(scriptEngine, "bool isKeyDown(key)", Scripting::isKeyDown);
REGISTER_GLOBAL_FUNC(scriptEngine, "bool isKeyPressed(key)", Scripting::isKeyPressed);

View File

@ -3,14 +3,18 @@
#include "DeerCore/Scripting/Helpers.h"
#include "DeerRender/Texture.h"
#include "glm/glm.hpp"
#include "DeerRender/ImGuiLayer.h"
#include "DeerRender/Scripting/InternalAPI/ImGUI.h"
#include "DeerRender/World.h"
#include "angelscript.h"
#include "glm/glm.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "imgui.h"
#include "scriptany.h"
#include "ImGuizmo.h"
#include <string>
namespace Deer {
@ -299,6 +303,69 @@ namespace Deer {
ImVec2(0, 1), ImVec2(1, 0));
}
bool manipulationTransform(WorldCamera& camera, glm::mat4& objMatrix, glm::mat4& outMatrix, bool local) {
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
ImVec2 window_pos = ImGui::GetItemRectMin();
ImVec2 window_size = ImGui::GetItemRectSize();
ImGuizmo::SetRect(window_pos.x, window_pos.y, window_size.x, window_size.y);
glm::mat4 cameraProjection = camera.camera.getMatrix();
cameraProjection[2][2] *= -1.0f;
cameraProjection[2][3] *= -1.0f;
glm::mat4 cameraView = glm::inverse(camera.transform.getMatrix());
outMatrix = objMatrix;
ImGuizmo::MODE mode = local ? ImGuizmo::MODE::LOCAL : ImGuizmo::MODE::WORLD;
ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection), ImGuizmo::OPERATION::TRANSLATE, mode, glm::value_ptr(outMatrix));
return ImGuizmo::IsUsing();
}
bool manipulationScale(WorldCamera& camera, glm::mat4& objMatrix, glm::mat4& outMatrix, bool local) {
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
ImVec2 window_pos = ImGui::GetItemRectMin();
ImVec2 window_size = ImGui::GetItemRectSize();
ImGuizmo::SetRect(window_pos.x, window_pos.y, window_size.x, window_size.y);
glm::mat4 cameraProjection = camera.camera.getMatrix();
cameraProjection[2][2] *= -1.0f;
cameraProjection[2][3] *= -1.0f;
glm::mat4 cameraView = glm::inverse(camera.transform.getMatrix());
outMatrix = objMatrix;
ImGuizmo::MODE mode = local ? ImGuizmo::MODE::LOCAL : ImGuizmo::MODE::WORLD;
ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection), ImGuizmo::OPERATION::SCALE, mode, glm::value_ptr(outMatrix));
return ImGuizmo::IsUsing();
}
bool manipulationRotation(WorldCamera& camera, glm::mat4& objMatrix, glm::mat4& outMatrix, bool local) {
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
ImVec2 window_pos = ImGui::GetItemRectMin();
ImVec2 window_size = ImGui::GetItemRectSize();
ImGuizmo::SetRect(window_pos.x, window_pos.y, window_size.x, window_size.y);
glm::mat4 cameraProjection = camera.camera.getMatrix();
cameraProjection[2][2] *= -1.0f;
cameraProjection[2][3] *= -1.0f;
glm::mat4 cameraView = glm::inverse(camera.transform.getMatrix());
outMatrix = objMatrix;
ImGuizmo::MODE mode = local ? ImGuizmo::MODE::LOCAL : ImGuizmo::MODE::WORLD;
ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection), ImGuizmo::OPERATION::ROTATE, mode, glm::value_ptr(outMatrix));
return ImGuizmo::IsUsing();
}
void drawIconCentered(Resource<Texture> texture, int size) {
if (!texture.isValid()) {
ImGui::TextColored(ImVec4(0.5, 0, 0, 1), "Invalid texture");

View File

@ -9,6 +9,7 @@ class asIScriptFunction;
class CScriptAny;
namespace Deer {
struct WorldCamera;
namespace Scripting {
namespace DragDropPayload {
@ -42,6 +43,10 @@ namespace Deer {
void drawFrameBuffer(Resource<FrameBuffer> frameBuffer, int sizeX, int sizeY);
void drawFrameBufferCentered(Resource<FrameBuffer> frameBuffer, int sizeX, int sizeY);
bool manipulationTransform(WorldCamera&, glm::mat4&, glm::mat4&, bool local);
bool manipulationScale(WorldCamera&, glm::mat4&, glm::mat4&, bool local);
bool manipulationRotation(WorldCamera&, glm::mat4&, glm::mat4&, bool local);
int getIconId(const std::string& name);
// Layout & panel
@ -117,5 +122,6 @@ namespace Deer {
void openPopup(std::string&, CScriptAny*);
void closePopup();
} // namespace Scripting
} // namespace Deer

View File

@ -9,11 +9,11 @@
#include "scriptarray.h"
#include "scriptstdstring.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Components.h"
#include "DeerRender/Mesh.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Components.h"
#include "DeerRender/Shader.h"
#include "glm/glm.hpp"
#include "glm/matrix.hpp"
@ -97,8 +97,8 @@ namespace Deer {
return frameBuffer.getData().getSpecification().height;
}
void frameBuffer_clearRGBA(int r, int g, int b, int a, Resource<FrameBuffer>& frameBuffer) {
int data[] = {r, g, b, a};
frameBuffer.getData().clear();
uint8_t data[] = {(uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a};
frameBuffer.getData().clearBuffer(0, data);
}
bool frameBuffer_isValid(Resource<FrameBuffer>& frameBuffer) {

View File

@ -11,42 +11,40 @@ class MeshComponentRender {
if (!entity.hasComponent<MeshComponent>())
return;
ImGui::title("Mesh Component");
ImGui::space(10, 10);
ImGui::text("Mesh : ");
ImGui::sameline();
if (meshComponent.hasMesh) {
ImGui::text(meshComponent.meshResource.name);
} else {
ImGui::text("Empty");
}
// Mesh icon
if (meshComponent.hasMesh) {
ImGui::drawIcon(StudioAPI::loadIcon("object3d.png"), 32);
FrameBuffer frameBuffer = Previewer::getMeshPreview(meshComponent.meshResource);
ImGui::drawFrameBufferCentered(frameBuffer, 128, 128);
} else {
ImGui::drawIcon(StudioAPI::loadIcon("empty.png"), 32);
ImGui::drawIconCentered(StudioAPI::loadIcon("empty.png"), 128);
}
ImGui::dragDropTarget("MESH", ReciverFunction(this.setMesh));
if (meshComponent.hasMesh) {
ImGui::sameline();
ImGui::space();
ImGui::sameline();
GPUMesh mesh = meshComponent.get_meshResource();
ImGui::titleCenterY(mesh.name, 32);
ImGui::dragDropTarget("MESH", ReciverFunction(this.setMesh));
}
ImGui::space(0, 20);
if (ImGui::button("Clear")) {
meshComponent.clear();
}
ImGui::sameline();
ImGui::space(0, 20);
ImGui::sameline();
bool active = meshComponent.get_isActive();
ImGui::space(10, 10);
bool active = meshComponent.isActive;
if (meshComponent.get_hasMesh()) {
active = ImGui::checkbox("Active", active);
meshComponent.set_isActive(active);
} else {
ImGui::checkboxDisabled("Active", active);
}
ImGui::sameline();
if (ImGui::buttonEnd("Clear")) {
meshComponent.clear();
}
}
void setMesh(any@ meshData) {

View File

@ -25,51 +25,30 @@ class ShaderComponentRender {
if (!entity.hasComponent<ShaderComponent>())
return;
// Shader icon
ImGui::title("Shader Component");
ImGui::space(10, 10);
ImGui::text("Shader : ");
ImGui::sameline();
if (shaderComponent.hasShader) {
ImGui::drawIcon(StudioAPI::loadIcon("shader.png"), 32);
ImGui::text(shaderComponent.shader.name);
} else {
ImGui::drawIcon(StudioAPI::loadIcon("empty.png"), 32);
ImGui::text("Empty");
}
// Mesh icon
if (shaderComponent.hasShader) {
FrameBuffer frameBuffer = Previewer::getShaderPreview(shaderComponent.shader);
ImGui::drawFrameBufferCentered(frameBuffer, 128, 128);
} else {
ImGui::drawIconCentered(StudioAPI::loadIcon("empty.png"), 128);
}
ImGui::dragDropTarget("SHADER", ReciverFunction(this.setShader));
if (shaderComponent.hasShader) {
ImGui::sameline();
ImGui::space();
ImGui::sameline();
Shader shader = shaderComponent.shader;
ImGui::titleCenterY(shader.name, 32);
ImGui::dragDropTarget("SHADER", ReciverFunction(this.setShader));
}
ImGui::space();
// Texture icon
Texture texture = shaderComponent.texture;
if (texture.isValid()) {
ImGui::drawIcon(texture, 32);
} else {
ImGui::drawIcon(StudioAPI::loadIcon("empty.png"), 32);
}
ImGui::dragDropTarget("TEXTURE", ReciverFunction(this.setTexture));
if (texture.isValid()) {
ImGui::sameline();
ImGui::space();
ImGui::sameline();
ImGui::titleCenterY(texture.name, 32);
ImGui::dragDropTarget("TEXTURE", ReciverFunction(this.setTexture));
}
ImGui::space(0, 20);
if (ImGui::button("Clear")) {
if (ImGui::buttonEnd("Clear")) {
shaderComponent.clear();
}
}
void remove() {

View File

@ -1,7 +1,7 @@
namespace Previewer {
FrameBuffer getMeshPreview(GPUMesh mesh) {
FrameBuffer frame = Resource::createFrameBuffer(mesh.path, 128, 128);
frame.clearRGBA(0, 0, 0, 255);
frame.clearRGBA(0, 0, 0, 0);
WorldCamera wcamera;
wcamera.transform.position = vec3(0, 1, -3.5);

View File

@ -21,23 +21,35 @@ class ViewportPanel : Panel {
return;
frameBuffer.resize(x, y);
frameBuffer.clearRGBA(0, 0, 0, 255);
frameBuffer.clearRGBA(20, 30, 45, 255);
sceneCamera.camera.aspect = float(x) / y;
World::render(frameBuffer, sceneCamera);
ImGui::drawFrameBufferCentered(frameBuffer, x, y);
if(ActiveEntity::entity != World::getRoot()) {
mat4 entityTransform = ActiveEntity::entity.getWorldMatrix();
if (ImGui::manipulationTransform(sceneCamera, entityTransform, entityTransform, false)) {
mat4 parentTransform = ActiveEntity::entity.parent.getWorldMatrix();
mat4 relativeMatrix = entityTransform.getRelativeMatrix(parentTransform);
ActiveEntity::entity.getComponent<TransformComponent>().position = relativeMatrix.getPosition();
}
}
if (!ImGui::isPanelActive())
return;
if (ImGui::isMouseDragging(key::MouseLeft) && !ImGui::isKeyDown(key::MouseMiddle)) {
if (ImGui::isMouseDragging(key::MouseRight) && !ImGui::isKeyDown(key::MouseMiddle)) {
pitch += ImGui::getMouseDeltaY() * 0.1;
yaw += ImGui::getMouseDeltaX() * 0.1;
sceneCamera.transform.rotation.setEuler(vec3(pitch, yaw, 0));
}
if (ImGui::isMouseDragging(key::MouseMiddle) && !ImGui::isKeyDown(key::MouseLeft)) {
if (ImGui::isMouseDragging(key::MouseMiddle) && !ImGui::isKeyDown(key::MouseRight)) {
vec3 panDir = vec3();
panDir.x -= ImGui::getMouseDeltaX();

View File

@ -10,13 +10,13 @@ Collapsed=0
[Window][ViewportPanel]
Pos=561,26
Size=1574,853
Size=1500,853
Collapsed=0
DockId=0x00000005,0
[Window][PropertiesPanel]
Pos=2137,26
Size=423,853
Pos=2063,26
Size=497,853
Collapsed=0
DockId=0x00000006,0
@ -37,7 +37,7 @@ DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,26 Size=2560,1345 Split=Y
DockNode ID=0x00000003 Parent=0x0AC2E849 SizeRef=1920,493 Split=X
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=559,985 Selected=0x16E3C1E7
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1359,985 Split=X
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=934,493 CentralNode=1 Selected=0x0F5FFC8C
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=423,493 Selected=0x9876A79B
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=1500,493 CentralNode=1 Selected=0x0F5FFC8C
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=497,493 Selected=0x9876A79B
DockNode ID=0x00000004 Parent=0x0AC2E849 SizeRef=1920,490 Selected=0x018A0F9B