2023-07-02 22:21:26 +02:00
|
|
|
//
|
|
|
|
|
// Created by tv on 21.05.23.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "MainViewport.h"
|
|
|
|
|
#include "MainWindow.h"
|
|
|
|
|
#include <glm/ext.hpp>
|
|
|
|
|
#include<imgui.h>
|
|
|
|
|
#include "IconsFontAwesome6.h"
|
|
|
|
|
#include "glm/gtx/string_cast.hpp"
|
2023-07-22 00:15:53 +02:00
|
|
|
#include<algorithm>
|
2023-07-02 22:21:26 +02:00
|
|
|
#include<cmath>
|
2023-07-22 00:15:53 +02:00
|
|
|
#include"Config/Configs.h"
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
MainViewport *MainVP;
|
|
|
|
|
|
|
|
|
|
glm::mat4 TransformToMatrix(Transform tf) {
|
|
|
|
|
auto Pos = glm::vec3(tf.Position.X, tf.Position.Y, tf.Position.Z);
|
|
|
|
|
auto Rot = glm::vec3(tf.Rotation.X, tf.Rotation.Y, tf.Rotation.Z);
|
|
|
|
|
auto Scale = glm::vec3(tf.Scale.X, tf.Scale.Y, tf.Scale.Z);
|
|
|
|
|
|
|
|
|
|
glm::mat4 translationMatrix = glm::translate(glm::mat4(1), Pos);
|
|
|
|
|
glm::mat4 rotationMatrixZ = glm::rotate(glm::mat4(1), glm::radians(Rot.z), glm::vec3(0, 0, 1));
|
|
|
|
|
glm::mat4 rotationMatrixY = glm::rotate(rotationMatrixZ, glm::radians(Rot.y), glm::vec3(0, 1, 0));
|
|
|
|
|
glm::mat4 rotationMatrix = glm::rotate(rotationMatrixY, glm::radians(Rot.x), glm::vec3(1, 0, 0));
|
|
|
|
|
glm::mat4 scaleMatrix = glm::scale(glm::mat4(1), Scale);
|
|
|
|
|
|
|
|
|
|
return translationMatrix * rotationMatrix * scaleMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glm::vec3 ToGlmVec3(Vector3 Vec3) {
|
2023-07-19 14:50:43 +02:00
|
|
|
return {Vec3.X, Vec3.Y, Vec3.Z};
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
bool IsArea(const std::string& Type) {
|
2023-07-22 00:15:53 +02:00
|
|
|
return std::any_of(Configs::g_areas.begin(), Configs::g_areas.end(),[&](const std::string &areatype){
|
|
|
|
|
return Type == areatype;
|
|
|
|
|
});
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-20 03:54:54 +02:00
|
|
|
MainViewport::MainViewport() : Graphics::ViewportWidget("Main Viewport", true), VP(1.0f), defaultShader("ForwardPass"), flatShader("FlatForwardPass") {
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
MainVP = this;
|
2023-07-19 14:50:43 +02:00
|
|
|
|
|
|
|
|
m_internalFramebuf = std::make_unique<Graphics::Framebuffer>(
|
|
|
|
|
std::vector<Graphics::FramebufferTextureInfo>{
|
|
|
|
|
{GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT0},
|
|
|
|
|
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_COLOR_ATTACHMENT1},
|
|
|
|
|
{GL_RGBA16F, GL_RGBA, GL_FLOAT, GL_COLOR_ATTACHMENT2},
|
|
|
|
|
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL_ATTACHMENT}
|
|
|
|
|
},
|
2023-07-20 03:54:54 +02:00
|
|
|
defaultShader);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
|
|
|
|
SunCam = std::make_unique<Graphics::Framebuffer>(
|
|
|
|
|
std::vector<Graphics::FramebufferTextureInfo>{
|
|
|
|
|
{GL_DEPTH_COMPONENT16,GL_DEPTH_COMPONENT,GL_FLOAT,GL_DEPTH_ATTACHMENT}
|
|
|
|
|
},
|
|
|
|
|
Graphics::Shader("ShadowPass"),
|
2023-07-20 03:54:54 +02:00
|
|
|
Math::Vector2i(8192,8192));
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-07-22 00:15:53 +02:00
|
|
|
auto& tex = SunCam->getFbTexByAttachment(GL_DEPTH_ATTACHMENT);
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex.m_texture->getId());
|
2023-07-19 14:50:43 +02:00
|
|
|
|
|
|
|
|
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_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D,0);
|
|
|
|
|
|
|
|
|
|
|
2023-07-02 22:21:26 +02:00
|
|
|
//ObjMesh = Graphics::Mesh();
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
ObjIdPos = m_internalFramebuf->m_shader.getUniformLocation("ObjIdIn");
|
|
|
|
|
ObjColPos = m_internalFramebuf->m_shader.getUniformLocation("ObjColor");
|
|
|
|
|
TeamId = m_internalFramebuf->m_shader.getUniformLocation("TeamId");
|
|
|
|
|
CamPosLoc = m_internalFramebuf->m_shader.getUniformLocation("CameraPosition");
|
|
|
|
|
LightDirId = m_internalFramebuf->m_shader.getUniformLocation("LightDirection");
|
|
|
|
|
SunVpLoc = m_internalFramebuf->m_shader.getUniformLocation("SunVP");
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
void MainViewport::RenderRail(Rail *rail) {
|
|
|
|
|
static Model RailPointMdl = Model("St_RailPoint");
|
|
|
|
|
|
|
|
|
|
if (rail->Points.size() > 1) {
|
|
|
|
|
auto lastRailPoint = rail->Points.front();
|
|
|
|
|
|
|
|
|
|
for (RailPoint &railPoint: rail->Points) {
|
|
|
|
|
RailPointMdl.Draw(railPoint.TF, m_internalFramebuf->m_shader, VP);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-02 22:21:26 +02:00
|
|
|
void MainViewport::Draw() {
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-07-20 03:54:54 +02:00
|
|
|
|
|
|
|
|
if(greenScreen) {
|
|
|
|
|
glClearColor(0, 1, 0, 1);
|
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
}
|
2023-07-19 14:50:43 +02:00
|
|
|
|
|
|
|
|
m_internalFramebuf->m_shader.use();
|
|
|
|
|
|
|
|
|
|
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
static auto lasttime = boost::chrono::high_resolution_clock::now();
|
|
|
|
|
|
|
|
|
|
auto timenow = boost::chrono::high_resolution_clock::now();
|
|
|
|
|
|
|
|
|
|
boost::chrono::duration<float> TimeDiff = (timenow - lasttime);
|
|
|
|
|
|
|
|
|
|
lasttime = timenow;
|
|
|
|
|
|
|
|
|
|
float DeltaTime = TimeDiff.count();
|
|
|
|
|
|
|
|
|
|
glm::vec3 cameraDirection = glm::vec3(
|
|
|
|
|
glm::sin(glm::radians(camrot.x)) * glm::cos(glm::radians(camrot.y)),
|
|
|
|
|
glm::sin(glm::radians(camrot.y)),
|
|
|
|
|
glm::cos(glm::radians(camrot.x)) * glm::cos(glm::radians(camrot.y))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
glm::vec3 cameraLeft = glm::vec3(
|
|
|
|
|
glm::sin(glm::radians(camrot.x + 90)),
|
|
|
|
|
0,
|
|
|
|
|
glm::cos(glm::radians(camrot.x + 90))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (ImGui::IsWindowFocused()) {
|
|
|
|
|
if (ImGui::IsKeyPressed(ImGuiKey_N))
|
|
|
|
|
ImGui::OpenPopup("Main VP Debug");
|
|
|
|
|
|
|
|
|
|
float speedmod = 1.0f;
|
|
|
|
|
|
|
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_LeftShift))
|
|
|
|
|
speedmod = 2;
|
|
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
|
|
|
|
speedmod = 0.5;
|
|
|
|
|
|
|
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_W)) {
|
|
|
|
|
camPos += cameraDirection * speed * speedmod * DeltaTime;
|
|
|
|
|
}
|
|
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_A)) {
|
|
|
|
|
camPos += cameraLeft * speed * speedmod * DeltaTime;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_S)) {
|
|
|
|
|
camPos -= cameraDirection * speed * speedmod * DeltaTime;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_D)) {
|
|
|
|
|
camPos -= cameraLeft * speed * speedmod * DeltaTime;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//glm::mat4 VP = Projection * View;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glm::mat4 projectionMatrix = glm::perspective(
|
|
|
|
|
glm::radians(
|
|
|
|
|
fov), // The vertical Field of View, in radians: the amount of "zoom". Think "camera lens". Usually between 90° (extra wide) and 30° (quite zoomed in)
|
2023-07-19 14:50:43 +02:00
|
|
|
(float) m_internalFramebuf->getSize().x /
|
|
|
|
|
(float) m_internalFramebuf->getSize().y, // Aspect Ratio. Depends on the size of your window. Notice that 4/3 == 800/600 == 1280/960, sounds familiar ?
|
|
|
|
|
NearClippingPlane, // Near clipping plane. Keep as big as possible, or you'll get precision issues.
|
|
|
|
|
FarClippingPlane // Far clipping plane. Keep as little as possible.
|
2023-07-02 22:21:26 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
//glm::mat4 ViewMatrix = glm::translate(glm::mat4(1.0f), -camPos);
|
|
|
|
|
glm::mat4 ViewMatrix = glm::lookAt(camPos, camPos + cameraDirection, glm::vec3(0, 1, 0));
|
|
|
|
|
|
|
|
|
|
VP = projectionMatrix * ViewMatrix;// * ViewMatrix * ModelMat;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glUniform3f(CamPosLoc, camPos.x,camPos.y,camPos.z);
|
|
|
|
|
|
2023-07-02 22:21:26 +02:00
|
|
|
if (ImGui::BeginPopup("Main VP Debug")) {
|
|
|
|
|
ImGui::DragFloat3("Camera Postion", &camPos.x, 0.01);
|
|
|
|
|
ImGui::DragFloat2("Camera Rotation", &camrot.x, 0.01);
|
|
|
|
|
ImGui::SliderFloat("FOV", &fov, 0, 180);
|
|
|
|
|
ImGui::DragFloat("Speed", &speed, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
ImGui::DragFloat("Near Clipping Plane", &NearClippingPlane, 1);
|
|
|
|
|
ImGui::DragFloat("Far Clipping Plane", &FarClippingPlane, 1);
|
|
|
|
|
ImGui::DragFloat("Shadow Area", &shadowArea, 0.01);
|
|
|
|
|
//ImGui::SliderFloat("Shading Effectiveness", &ShadingEffectiveness, 0, 1);
|
|
|
|
|
ImGui::DragFloat3("Light Direction", &LightDir.x, 0.01);
|
2023-07-02 22:21:26 +02:00
|
|
|
ImGui::Checkbox("Draw All Areas", &drawAllAreas);
|
2023-07-20 03:54:54 +02:00
|
|
|
ImGui::Checkbox("Green Screen", &greenScreen);
|
|
|
|
|
if(ImGui::Button("Switch Shading Modes")){
|
|
|
|
|
if(flatShading)
|
|
|
|
|
m_internalFramebuf->m_shader = defaultShader;
|
|
|
|
|
else
|
|
|
|
|
m_internalFramebuf->m_shader = flatShader;
|
|
|
|
|
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
ObjIdPos = m_internalFramebuf->m_shader.getUniformLocation("ObjIdIn");
|
|
|
|
|
ObjColPos = m_internalFramebuf->m_shader.getUniformLocation("ObjColor");
|
|
|
|
|
TeamId = m_internalFramebuf->m_shader.getUniformLocation("TeamId");
|
|
|
|
|
CamPosLoc = m_internalFramebuf->m_shader.getUniformLocation("CameraPosition");
|
|
|
|
|
LightDirId = m_internalFramebuf->m_shader.getUniformLocation("LightDirection");
|
|
|
|
|
SunVpLoc = m_internalFramebuf->m_shader.getUniformLocation("SunVP");
|
|
|
|
|
|
2023-07-20 03:54:54 +02:00
|
|
|
flatShading = !flatShading;
|
|
|
|
|
}
|
2023-07-02 22:21:26 +02:00
|
|
|
ImGui::EndPopup();
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
m_internalFramebuf->m_shader.use();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
if(!flatShading)
|
|
|
|
|
glUniform3f(LightDirId, LightDir.x , LightDir.y,LightDir.z);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glUniform4f(ObjColPos, 1, 1, 1, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
auto &map = GetMainWindow()->loadedMap;
|
|
|
|
|
|
|
|
|
|
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
|
|
|
|
GLuint ClearID[] = {0};
|
|
|
|
|
glClearBufferuiv(GL_COLOR, 0, ClearID);
|
|
|
|
|
|
|
|
|
|
glDrawBuffer(GL_COLOR_ATTACHMENT2);
|
2023-07-19 14:50:43 +02:00
|
|
|
GLfloat ClearPos[] = {0, 0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
glClearBufferfv(GL_COLOR, 0, ClearPos);
|
|
|
|
|
|
|
|
|
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
|
|
|
|
|
|
|
|
|
unsigned int ObjID = 16;
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
if(!flatShading) {
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glm::vec3 SunPos = (glm::normalize(LightDir) * 1500.0f) + camPos;
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glm::mat4 SunProj = glm::ortho(-shadowArea, shadowArea, -shadowArea, shadowArea, 1.0f, 4000.0f);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glm::mat4 SunView = glm::lookAt(SunPos, camPos, {0, 1, 0});
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glm::mat4 SunVP = SunProj * SunView;
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
SunCam->bind();
|
|
|
|
|
SunCam->m_shader.use();
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glDepthFunc(GL_LESS);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
|
glCullFace(GL_BACK);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glDisable(GL_BLEND);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
for (auto &obj: map.Objects) {
|
|
|
|
|
if (IsArea(obj.Type)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-07-19 14:50:43 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
if (!MdlFromObj.contains(obj.Type)) {
|
|
|
|
|
if (boost::filesystem::exists(
|
|
|
|
|
boost::filesystem::current_path() / "Models" / obj.Type / (obj.Type + ".dae")))
|
|
|
|
|
MdlFromObj.insert({obj.Type, Model(obj.Type)});
|
|
|
|
|
else {
|
|
|
|
|
MdlFromObj.insert({obj.Type, Model("St_Default")});
|
|
|
|
|
std::cout << "Model missing: \n\t" << obj.Type << std::endl;
|
|
|
|
|
}
|
2023-07-19 14:50:43 +02:00
|
|
|
}
|
2023-08-28 21:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
auto &mdl = MdlFromObj.find(obj.Type)->second;
|
|
|
|
|
|
|
|
|
|
mdl.Draw(obj.TF, SunCam->m_shader, SunVP);
|
2023-07-19 14:50:43 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
m_internalFramebuf->bind();
|
|
|
|
|
m_internalFramebuf->m_shader.use();
|
|
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glDepthFunc(GL_LESS);
|
|
|
|
|
|
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
|
glCullFace(GL_FRONT);
|
|
|
|
|
|
|
|
|
|
auto &tex = SunCam->getFbTexByAttachment(GL_DEPTH_ATTACHMENT);
|
|
|
|
|
tex.m_texture->setActive(5);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glUniformMatrix4fv(SunVpLoc,1,GL_FALSE,&SunVP[0][0]);
|
2023-07-19 14:50:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
|
glCullFace(GL_FRONT);
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto &obj: map.Objects) {
|
2023-08-28 21:23:47 +02:00
|
|
|
if(!flatShading)
|
|
|
|
|
glUniform1i(TeamId,(GLint)obj.Team);
|
2023-07-19 14:50:43 +02:00
|
|
|
|
|
|
|
|
if (IsArea(obj.Type) && !drawAllAreas) {
|
2023-07-02 22:21:26 +02:00
|
|
|
ObjID++;
|
|
|
|
|
continue;
|
2023-07-19 14:50:43 +02:00
|
|
|
} else if (IsArea(obj.Type) && drawAllAreas) {
|
2023-07-02 22:21:26 +02:00
|
|
|
static auto AreaMdl = Model("St_Area");
|
|
|
|
|
glUniform1ui(ObjIdPos, ObjID);
|
2023-07-19 14:50:43 +02:00
|
|
|
AreaMdl.Draw(obj.TF, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
ObjID++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!MdlFromObj.contains(obj.Type)) {
|
|
|
|
|
if (boost::filesystem::exists(
|
|
|
|
|
boost::filesystem::current_path() / "Models" / obj.Type / (obj.Type + ".dae")))
|
|
|
|
|
MdlFromObj.insert({obj.Type, Model(obj.Type)});
|
|
|
|
|
else {
|
|
|
|
|
MdlFromObj.insert({obj.Type, Model("St_Default")});
|
|
|
|
|
std::cout << "Model missing: \n\t" << obj.Type << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
auto &mdl = MdlFromObj.find(obj.Type)->second;
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform1ui(ObjIdPos, ObjID);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
if (&obj == GetMainWindow()->selectedElem)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 1, .7, .7, 1);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
mdl.Draw(obj.TF, m_internalFramebuf->m_shader, VP);
|
2023-08-28 21:23:47 +02:00
|
|
|
if (&obj == GetMainWindow()->selectedElem)
|
|
|
|
|
glUniform4f(ObjColPos, 1, 1, 1, 1);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
ObjID++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GetMainWindow()->selectedElem != nullptr) {
|
|
|
|
|
auto selobj = GetMainWindow()->selectedElem;
|
2023-08-28 21:23:47 +02:00
|
|
|
glUniform1ui(ObjIdPos, 0);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
if (IsArea(selobj->Type)) {
|
2023-07-02 22:21:26 +02:00
|
|
|
static auto AreaMdl = Model("St_Area");
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
AreaMdl.Draw(selobj->TF, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
for (Link &link: GetMainWindow()->selectedElem->Links) {
|
|
|
|
|
Element *elem = GetMainWindow()->loadedMap.GetElementById(link.Destination);
|
|
|
|
|
if (elem == nullptr)
|
|
|
|
|
continue;
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
if (Rail *rail = dynamic_cast<Rail *>(elem)) {
|
|
|
|
|
RenderRail(rail);
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
if (Rail *rail = dynamic_cast<Rail *>(GetMainWindow()->selectedElem)) {
|
|
|
|
|
RenderRail(rail);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-02 22:21:26 +02:00
|
|
|
//mdl.DrawSelection(selobj->TF);
|
|
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
//glClear(GL_DEPTH_BUFFER_BIT);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-08-28 21:23:47 +02:00
|
|
|
/*if (CurrentGizmoType == Move) {
|
2023-07-02 22:21:26 +02:00
|
|
|
static Model Arrow = Model("St_Arrow");
|
|
|
|
|
|
|
|
|
|
auto tf = Transform();
|
|
|
|
|
tf.Position = selobj->TF.Position;
|
2023-07-19 14:50:43 +02:00
|
|
|
// float size = glm::distance(glm::vec3(tf.Position.X, tf.Position.Y, tf.Position.Z), camPos);
|
2023-07-02 22:21:26 +02:00
|
|
|
//tf.Scale = {size/ 50, size/ 50, size/ 50};
|
2023-07-19 14:50:43 +02:00
|
|
|
tf.Scale = {1, 1, 1};
|
2023-07-02 22:21:26 +02:00
|
|
|
tf.Rotation = {0, 0, 90};
|
|
|
|
|
|
|
|
|
|
glUniform4f(ObjColPos, 0.5, 0, 0, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 1)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 1, 0, 0, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
Arrow.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
tf.Rotation = {0, 0, 0};
|
|
|
|
|
glUniform4f(ObjColPos, 0, 0.5, 0, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 2)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 0, 1, 0, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 2);
|
2023-07-19 14:50:43 +02:00
|
|
|
Arrow.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
tf.Rotation = {90, 0, 0};
|
|
|
|
|
glUniform4f(ObjColPos, 0, 0, 0.5, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 3)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 0, 0, 1, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 3);
|
2023-07-19 14:50:43 +02:00
|
|
|
Arrow.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glUniform4f(ObjColPos, 1, 1, 1, 1);
|
|
|
|
|
} else if (CurrentGizmoType == Scale) {
|
|
|
|
|
static Model Scalar = Model("St_Scalar");
|
|
|
|
|
|
|
|
|
|
auto tf = Transform();
|
|
|
|
|
tf.Position = selobj->TF.Position;
|
2023-07-19 14:50:43 +02:00
|
|
|
// float size = glm::distance(glm::vec3(tf.Position.X, tf.Position.Y, tf.Position.Z), camPos);
|
2023-07-02 22:21:26 +02:00
|
|
|
//tf.Scale = {size/ 50, size/ 50, size/ 50};
|
2023-07-19 14:50:43 +02:00
|
|
|
tf.Scale = {1, 1, 1};
|
2023-07-02 22:21:26 +02:00
|
|
|
tf.Rotation = {selobj->TF.Rotation.X + 90, selobj->TF.Rotation.Y + 90, selobj->TF.Rotation.Z};
|
|
|
|
|
|
|
|
|
|
glUniform4f(ObjColPos, 0.5, 0, 0, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 1)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 1, 0, 0, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
Scalar.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
tf.Rotation = {selobj->TF.Rotation.X, selobj->TF.Rotation.Y, selobj->TF.Rotation.Z};
|
|
|
|
|
glUniform4f(ObjColPos, 0, 0.5, 0, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 2)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 0, 1, 0, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 2);
|
2023-07-19 14:50:43 +02:00
|
|
|
Scalar.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
tf.Rotation = {selobj->TF.Rotation.X + 90, selobj->TF.Rotation.Y, selobj->TF.Rotation.Z};
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 0, 0, 0.5, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 3)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 0, 0, 1, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 3);
|
2023-07-19 14:50:43 +02:00
|
|
|
Scalar.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glUniform4f(ObjColPos, 1, 1, 1, 1);
|
|
|
|
|
} else if (CurrentGizmoType == Rotate) {
|
|
|
|
|
static Model Rotator = Model("St_Rotate");
|
|
|
|
|
|
|
|
|
|
auto tf = Transform();
|
|
|
|
|
tf.Position = selobj->TF.Position;
|
2023-07-19 14:50:43 +02:00
|
|
|
// float size = glm::distance(glm::vec3(tf.Position.X, tf.Position.Y, tf.Position.Z), camPos);
|
2023-07-02 22:21:26 +02:00
|
|
|
//tf.Scale = {size/ 50, size/ 50, size/ 50};
|
2023-07-19 14:50:43 +02:00
|
|
|
tf.Scale = {1, 1, 1};
|
2023-07-02 22:21:26 +02:00
|
|
|
tf.Rotation = {0, 0, 90};
|
|
|
|
|
|
|
|
|
|
glUniform4f(ObjColPos, 0.5, 0, 0, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 1)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 1, 0, 0, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
Rotator.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
tf.Rotation = {0, 0, 0};
|
|
|
|
|
glUniform4f(ObjColPos, 0, 0.5, 0, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 2)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 0, 1, 0, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 2);
|
2023-07-19 14:50:43 +02:00
|
|
|
Rotator.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
tf.Rotation = {90, 0, 0};
|
|
|
|
|
glUniform4f(ObjColPos, 0, 0, 0.5, 1);
|
2023-07-19 14:50:43 +02:00
|
|
|
if (HoveredObjId == 3)
|
2023-07-02 22:21:26 +02:00
|
|
|
glUniform4f(ObjColPos, 0, 0, 1, 1);
|
|
|
|
|
glUniform1ui(ObjIdPos, 3);
|
2023-07-19 14:50:43 +02:00
|
|
|
Rotator.Draw(tf, m_internalFramebuf->m_shader, VP);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glUniform4f(ObjColPos, 1, 1, 1, 1);
|
2023-08-28 21:23:47 +02:00
|
|
|
}*/
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
|
|
|
|
inline float GetVecComponent(const t &v1, const t &v2) {
|
|
|
|
|
auto NormComp = glm::normalize(v2);
|
|
|
|
|
return (glm::dot(v1, NormComp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
|
|
|
|
inline t ProjectToRayNormalized(const t &v1, const t &ray) {
|
2023-07-19 14:50:43 +02:00
|
|
|
return glm::dot(v1, ray) / glm::dot(ray, ray) * ray;
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
2023-07-19 14:50:43 +02:00
|
|
|
inline t ProjectToRay(const t &v1, const t &rayStart, const t &ray) {
|
|
|
|
|
return ProjectToRayNormalized(v1 - rayStart, ray - rayStart) + rayStart;
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
2023-07-19 14:50:43 +02:00
|
|
|
inline t ProjectToRayNormDir(const t &v1, const t &rayStart, const t &RayDir) {
|
|
|
|
|
return ProjectToRayNormalized(v1 - rayStart, RayDir) + rayStart;
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec3 MainViewport::ScreenSpaceToRay(glm::vec2 ScreenPos) {
|
2023-07-02 22:21:26 +02:00
|
|
|
auto InverseVP = glm::inverse(VP);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec4 worldPos = InverseVP * glm::vec4(ScreenPos, 1.0, 1.0);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glm::vec3 dir = glm::normalize(glm::vec3(worldPos));
|
|
|
|
|
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainViewport::HandleInput(InputEvent event) {
|
|
|
|
|
static glm::vec2 lastMpos = glm::vec2(0, 0);
|
|
|
|
|
|
|
|
|
|
glm::vec2 currentMpos = glm::vec2(event.x, event.y);
|
|
|
|
|
|
|
|
|
|
//static glm::vec3 GizmoDirPrePos = {0,0,0};
|
|
|
|
|
|
|
|
|
|
glm::vec2 DeltaMousePos = currentMpos - lastMpos;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
static glm::vec3 ObjBindingVec = {0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
static float ObjScalingDist = 0.0f;
|
|
|
|
|
|
|
|
|
|
static glm::vec3 GizmoDir = glm::vec3(1, 1, 1);
|
|
|
|
|
static unsigned int SpecialObjCur = 0;
|
|
|
|
|
|
|
|
|
|
auto SelObj = GetMainWindow()->selectedElem;
|
|
|
|
|
|
|
|
|
|
switch (event.EventType) {
|
2023-07-19 14:50:43 +02:00
|
|
|
case (InputType::MouseHover): {
|
|
|
|
|
GLint y = event.y * m_internalFramebuf->getSize().y;
|
|
|
|
|
GLint x = event.x * m_internalFramebuf->getSize().x;
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
2023-07-19 14:50:43 +02:00
|
|
|
glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &HoveredObjId);
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
2023-07-19 14:50:43 +02:00
|
|
|
break;
|
2023-07-02 22:21:26 +02:00
|
|
|
case (InputType::MouseDownL): {
|
2023-07-19 14:50:43 +02:00
|
|
|
GLint y = event.y * m_internalFramebuf->getSize().y;
|
|
|
|
|
GLint x = event.x * m_internalFramebuf->getSize().x;
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, m_internalFramebuf->getId());
|
2023-07-02 22:21:26 +02:00
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
|
|
|
|
unsigned int obj = 0;
|
|
|
|
|
|
|
|
|
|
glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &obj);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (obj < 16) {
|
|
|
|
|
SpecialObjCur = obj;
|
|
|
|
|
if (CurrentGizmoType == Move) {
|
2023-07-19 14:50:43 +02:00
|
|
|
if (0 < obj && obj <= 3) {
|
2023-07-02 22:21:26 +02:00
|
|
|
if (obj == 1) {
|
|
|
|
|
GizmoDir = {1, 0, 0};
|
|
|
|
|
} else if (obj == 2) {
|
|
|
|
|
GizmoDir = {0, 1, 0};
|
|
|
|
|
} else if (obj == 3) {
|
|
|
|
|
GizmoDir = {0, 0, 1};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec4 CurWDirPos = {0, 0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, glm::value_ptr(CurWDirPos));
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec3 GizmoDirPrePos = ProjectToRayNormalized({CurWDirPos.x, CurWDirPos.y, CurWDirPos.z},
|
|
|
|
|
GizmoDir);
|
|
|
|
|
glm::vec3 objpos = {SelObj->TF.Position.X, SelObj->TF.Position.Y, SelObj->TF.Position.Z};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
ObjBindingVec = objpos - GizmoDirPrePos;
|
|
|
|
|
|
|
|
|
|
std::cout << glm::to_string(ObjBindingVec) << std::endl;
|
|
|
|
|
}
|
2023-07-19 14:50:43 +02:00
|
|
|
} else if (CurrentGizmoType == Scale) {
|
|
|
|
|
if (0 < obj && obj <= 3) {
|
2023-07-02 22:21:26 +02:00
|
|
|
if (obj == 1) {
|
|
|
|
|
GizmoDir = {1, 0, 0};
|
|
|
|
|
} else if (obj == 2) {
|
|
|
|
|
GizmoDir = {0, 1, 0};
|
|
|
|
|
} else if (obj == 3) {
|
|
|
|
|
GizmoDir = {0, 0, 1};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto TF = SelObj->TF;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
TF.Scale = {1, 1, 1};
|
|
|
|
|
TF.Position = {0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
auto mat = TransformToMatrix(TF);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
GizmoDir = mat * glm::vec4(GizmoDir, 1);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec4 CurWDirPos = {0, 0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, glm::value_ptr(CurWDirPos));
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec3 GizmoDirPrePos = ProjectToRayNormalized({CurWDirPos.x, CurWDirPos.y, CurWDirPos.z},
|
|
|
|
|
GizmoDir);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glm::vec3 objpos = ToGlmVec3(SelObj->TF.Position);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
ObjScalingDist = glm::distance(ProjectToRayNormalized(objpos, GizmoDir), GizmoDirPrePos);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
ObjBindingVec = ToGlmVec3(SelObj->TF.Scale);
|
|
|
|
|
|
|
|
|
|
//std::cout << ObjScalingDist << std::endl;
|
|
|
|
|
} /*if (CurrentGizmoType == Rotate) {
|
|
|
|
|
if(0 < obj && obj <= 3 ) {
|
|
|
|
|
if (obj == 1) {
|
|
|
|
|
GizmoDir = {1, 0, 0};
|
|
|
|
|
} else if (obj == 2) {
|
|
|
|
|
GizmoDir = {0, 1, 0};
|
|
|
|
|
} else if (obj == 3) {
|
|
|
|
|
GizmoDir = {0, 0, 1};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
|
|
|
|
glm::vec4 CurWDirPos = {0,0,0,0};
|
|
|
|
|
|
|
|
|
|
glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, glm::value_ptr(CurWDirPos));
|
|
|
|
|
|
|
|
|
|
glm::vec3 GizmoDirPrePos = ProjectToRayNormalized({CurWDirPos.x,-CurWDirPos.y,CurWDirPos.z},GizmoDir);
|
|
|
|
|
glm::vec3 objpos = {SelObj->TF.Position.X,SelObj->TF.Position.Y,SelObj->TF.Position.Z};
|
|
|
|
|
|
|
|
|
|
ObjBindingVec = objpos - GizmoDirPrePos;
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
obj -= 16;
|
|
|
|
|
|
|
|
|
|
GetMainWindow()->selectedElem = &GetMainWindow()->loadedMap.Objects[obj];
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case (InputType::MouseHoldL): {
|
2023-07-19 14:50:43 +02:00
|
|
|
GLint y = event.y * m_internalFramebuf->getSize().y;
|
|
|
|
|
GLint x = event.x * m_internalFramebuf->getSize().x;
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, m_internalFramebuf->getId());
|
2023-07-02 22:21:26 +02:00
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
|
|
|
|
unsigned int obj = 0;
|
|
|
|
|
|
|
|
|
|
glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &obj);
|
|
|
|
|
|
|
|
|
|
if (CurrentGizmoType == Move) {
|
2023-07-19 14:50:43 +02:00
|
|
|
if (SpecialObjCur == 0) {
|
2023-07-02 22:21:26 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/*if(SpecialObjCur != obj){
|
|
|
|
|
SpecialObjCur = 0;
|
|
|
|
|
return;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
auto tf = SelObj->TF;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
tf.Rotation = {0, 0, 0};
|
|
|
|
|
tf.Scale = {1, 1, 1};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
auto Tf = TransformToMatrix(tf);
|
|
|
|
|
|
|
|
|
|
if (SpecialObjCur == 1) {
|
|
|
|
|
GizmoDir = {1, 0, 0};
|
|
|
|
|
} else if (SpecialObjCur == 2) {
|
|
|
|
|
GizmoDir = {0, 1, 0};
|
|
|
|
|
} else if (SpecialObjCur == 3) {
|
|
|
|
|
GizmoDir = {0, 0, 1};
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
auto ClipSpaceStart = (VP * Tf) * glm::vec4(0, 0, 0, 1);
|
|
|
|
|
auto ClipSpaceEnd = (VP * Tf) * glm::vec4(GizmoDir, 1);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec2 ScreenSpaceStart = {
|
|
|
|
|
((ClipSpaceStart.x / ClipSpaceStart.w + 1) / 2) * (float)m_internalFramebuf->getSize().x,
|
|
|
|
|
((ClipSpaceStart.y / ClipSpaceStart.w + 1) / 2) * (float)m_internalFramebuf->getSize().y};
|
|
|
|
|
glm::vec2 ScreenSpaceEnd = {
|
|
|
|
|
((ClipSpaceEnd.x / ClipSpaceEnd.w + 1) / 2) * (float)m_internalFramebuf->getSize().x,
|
|
|
|
|
((ClipSpaceEnd.y / ClipSpaceEnd.w + 1) / 2) * (float)m_internalFramebuf->getSize().y};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glm::vec2 ScrenSpaceDir = ScreenSpaceEnd - ScreenSpaceStart;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec2 MousePos = {x, y};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec2 FixedMousePos = ProjectToRayNormDir(MousePos, ScreenSpaceStart, ScrenSpaceDir);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
//SpecialObjCur = obj;
|
2023-07-19 14:50:43 +02:00
|
|
|
if (0 < SpecialObjCur && SpecialObjCur <= 3) {
|
2023-07-02 22:21:26 +02:00
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec4 CurWDirPos = {0, 0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glReadPixels((int)floorf(FixedMousePos.x), (int)floorf(FixedMousePos.y), 1, 1, GL_RGBA, GL_FLOAT,
|
|
|
|
|
glm::value_ptr(CurWDirPos));
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
//std::cout << glm::to_string(CurWDirPos) << std::endl;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
auto DirProjectedTranslationPos = ProjectToRayNormalized(
|
|
|
|
|
{CurWDirPos.x, CurWDirPos.y, CurWDirPos.z}, GizmoDir);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
if (SpecialObjCur == 1) {
|
|
|
|
|
SelObj->TF.Position.X = ObjBindingVec.x + DirProjectedTranslationPos.x;
|
|
|
|
|
} else if (SpecialObjCur == 2) {
|
|
|
|
|
SelObj->TF.Position.Y = ObjBindingVec.y + DirProjectedTranslationPos.y;
|
|
|
|
|
} else if (SpecialObjCur == 3) {
|
|
|
|
|
SelObj->TF.Position.Z = ObjBindingVec.z + DirProjectedTranslationPos.z;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec3 objpos = {SelObj->TF.Position.X, SelObj->TF.Position.Y, SelObj->TF.Position.Z};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
ObjBindingVec = objpos - DirProjectedTranslationPos;
|
|
|
|
|
lastMpos = currentMpos;
|
|
|
|
|
}
|
|
|
|
|
} else if (CurrentGizmoType == Scale) {
|
2023-07-19 14:50:43 +02:00
|
|
|
if (SpecialObjCur == 0)
|
2023-07-02 22:21:26 +02:00
|
|
|
return;
|
2023-07-19 14:50:43 +02:00
|
|
|
if (SpecialObjCur != obj) {
|
2023-07-02 22:21:26 +02:00
|
|
|
SpecialObjCur = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-07-19 14:50:43 +02:00
|
|
|
if (0 < SpecialObjCur && SpecialObjCur <= 3) {
|
2023-07-02 22:21:26 +02:00
|
|
|
SpecialObjCur = obj;
|
|
|
|
|
if (obj == 1) {
|
|
|
|
|
GizmoDir = {1, 0, 0};
|
|
|
|
|
} else if (obj == 2) {
|
|
|
|
|
GizmoDir = {0, 1, 0};
|
|
|
|
|
} else if (obj == 3) {
|
|
|
|
|
GizmoDir = {0, 0, 1};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto TF = SelObj->TF;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
TF.Scale = {1, 1, 1};
|
|
|
|
|
TF.Position = {0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
auto mat = TransformToMatrix(TF);
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
GizmoDir = mat * glm::vec4(GizmoDir, 1);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
2023-07-19 14:50:43 +02:00
|
|
|
glm::vec4 CurWDirPos = {0, 0, 0, 0};
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
//GizmoDir = glm::normalize( * GizmoDir)
|
|
|
|
|
glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, glm::value_ptr(CurWDirPos));
|
|
|
|
|
|
|
|
|
|
glm::vec3 ObjPos = ToGlmVec3(SelObj->TF.Position);
|
|
|
|
|
|
|
|
|
|
ObjPos.y = -ObjPos.y;
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
CurWDirPos -= glm::vec4(ObjPos, 1);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
auto DirProjectedTranslationPos = ProjectToRayNormalized(
|
|
|
|
|
{CurWDirPos.x, CurWDirPos.y, CurWDirPos.z}, GizmoDir);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
float VecComp = GetVecComponent(DirProjectedTranslationPos, GizmoDir);
|
2023-07-02 22:21:26 +02:00
|
|
|
|
|
|
|
|
float DeltaInDir = 0;
|
|
|
|
|
|
|
|
|
|
if (SpecialObjCur == 1) {
|
2023-07-19 14:50:43 +02:00
|
|
|
DeltaInDir = (ObjBindingVec.x + ((VecComp / ObjScalingDist) - 1) * ObjBindingVec.x) -
|
|
|
|
|
SelObj->TF.Scale.X;
|
2023-07-02 22:21:26 +02:00
|
|
|
SelObj->TF.Scale.X = ObjBindingVec.x + ((VecComp / ObjScalingDist) - 1) * ObjBindingVec.x;
|
|
|
|
|
} else if (SpecialObjCur == 2) {
|
2023-07-19 14:50:43 +02:00
|
|
|
DeltaInDir = (ObjBindingVec.y + ((VecComp / ObjScalingDist) - 1) * ObjBindingVec.y) -
|
|
|
|
|
SelObj->TF.Scale.Y;
|
2023-07-02 22:21:26 +02:00
|
|
|
SelObj->TF.Scale.Y = ObjBindingVec.y + ((VecComp / ObjScalingDist) - 1) * ObjBindingVec.y;
|
|
|
|
|
} else if (SpecialObjCur == 3) {
|
2023-07-19 14:50:43 +02:00
|
|
|
DeltaInDir = (ObjBindingVec.z + ((VecComp / ObjScalingDist) - 1) * ObjBindingVec.z) -
|
|
|
|
|
SelObj->TF.Scale.Z;
|
2023-07-02 22:21:26 +02:00
|
|
|
SelObj->TF.Scale.Z = ObjBindingVec.z + ((VecComp / ObjScalingDist) - 1) * ObjBindingVec.z;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-19 14:50:43 +02:00
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) {
|
|
|
|
|
if (SpecialObjCur != 1) SelObj->TF.Scale.X += DeltaInDir;
|
|
|
|
|
if (SpecialObjCur != 2) SelObj->TF.Scale.Y += DeltaInDir;
|
|
|
|
|
if (SpecialObjCur != 3) SelObj->TF.Scale.Z += DeltaInDir;
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastMpos = currentMpos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case (InputType::MouseUpL):
|
|
|
|
|
SpecialObjCur = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case (InputType::MouseDownR):
|
|
|
|
|
ImGui::SetWindowFocus();
|
|
|
|
|
lastMpos = currentMpos;
|
|
|
|
|
break;
|
|
|
|
|
case (InputType::MouseHoldR):
|
|
|
|
|
ImGui::SetWindowFocus();
|
2023-07-19 14:50:43 +02:00
|
|
|
camrot.x += (lastMpos.x - currentMpos.x) * (float) m_internalFramebuf->getSize().x * .1f;
|
|
|
|
|
camrot.y += (lastMpos.y - currentMpos.y) * (float) m_internalFramebuf->getSize().y * .1f;
|
2023-07-02 22:21:26 +02:00
|
|
|
lastMpos = currentMpos;
|
|
|
|
|
break;
|
2023-07-19 14:50:43 +02:00
|
|
|
default:
|
|
|
|
|
break;
|
2023-07-02 22:21:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainViewport::DrawOver() {
|
|
|
|
|
|
|
|
|
|
auto textsz = ImGui::CalcTextSize(ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT " "
|
|
|
|
|
ICON_FA_ARROWS_LEFT_RIGHT_TO_LINE " "
|
|
|
|
|
ICON_FA_ROTATE);
|
|
|
|
|
ImGui::SetCursorPos(ImVec2(ImGui::GetWindowWidth() - textsz.x - 70, textsz.y + 20));
|
|
|
|
|
ImGui::BeginGroupPanel("Tools");
|
|
|
|
|
if (CurrentGizmoType == Move) {
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, 0xFF008000);
|
|
|
|
|
if (ImGui::Button(ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT "##MainVpMoveGadget"))
|
|
|
|
|
CurrentGizmoType = Move;
|
|
|
|
|
ImGui::PopStyleColor();
|
|
|
|
|
} else {
|
|
|
|
|
if (ImGui::Button(ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT "##MainVpMoveGadget"))
|
|
|
|
|
CurrentGizmoType = Move;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
|
|
if (CurrentGizmoType == Scale) {
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, 0xFF008000);
|
|
|
|
|
if (ImGui::Button(ICON_FA_ARROWS_LEFT_RIGHT_TO_LINE "##MainVpScaleGadget"))
|
|
|
|
|
CurrentGizmoType = Scale;
|
|
|
|
|
ImGui::PopStyleColor();
|
|
|
|
|
} else {
|
|
|
|
|
if (ImGui::Button(ICON_FA_ARROWS_LEFT_RIGHT_TO_LINE "##MainVpScaleGadget"))
|
|
|
|
|
CurrentGizmoType = Scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
|
|
if (CurrentGizmoType == Rotate) {
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, 0xFF008000);
|
|
|
|
|
if (ImGui::Button(ICON_FA_ROTATE "##MainVpRotateGadget"))
|
|
|
|
|
CurrentGizmoType = Rotate;
|
|
|
|
|
ImGui::PopStyleColor();
|
|
|
|
|
} else {
|
|
|
|
|
if (ImGui::Button(ICON_FA_ROTATE "##MainVpRotateGadget"))
|
|
|
|
|
CurrentGizmoType = Rotate;
|
|
|
|
|
}
|
|
|
|
|
ImGui::EndGroupPanel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glm::vec2 MainViewport::CalcGizmoDir(glm::vec3 dir) {
|
|
|
|
|
|
|
|
|
|
auto SelObj = GetMainWindow()->selectedElem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto DirPos = glm::vec4(dir, 1);
|
|
|
|
|
auto ObjPos = glm::vec4(0, 0, 0, 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto tf = SelObj->TF;
|
|
|
|
|
|
|
|
|
|
tf.Rotation = {0, 0, 0};
|
|
|
|
|
tf.Scale = {1, 1, 1};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto ModelMat = TransformToMatrix(tf);
|
|
|
|
|
|
|
|
|
|
auto ObjPosClipSpace = (VP * ModelMat) * ObjPos;
|
|
|
|
|
auto DirPosClipSpace = (VP * ModelMat) * DirPos;
|
|
|
|
|
|
|
|
|
|
auto ObjPosVPSpace = glm::vec2(ObjPosClipSpace.x / ObjPosClipSpace.w,
|
|
|
|
|
ObjPosClipSpace.y / ObjPosClipSpace.w);
|
|
|
|
|
auto DirPosVPSpace = glm::vec2(DirPosClipSpace.x / DirPosClipSpace.w,
|
|
|
|
|
DirPosClipSpace.y / DirPosClipSpace.w);
|
|
|
|
|
|
|
|
|
|
return DirPosVPSpace - ObjPosVPSpace;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-22 00:15:53 +02:00
|
|
|
void MainViewport::clearModels() {
|
|
|
|
|
MdlFromObj.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainViewport::cleanUnnescessary() {
|
|
|
|
|
auto &map = GetMainWindow()->loadedMap;
|
|
|
|
|
|
|
|
|
|
for(auto mdlPairIter = MdlFromObj.begin(); mdlPairIter != MdlFromObj.end(); ){
|
|
|
|
|
auto nextiter = mdlPairIter;
|
|
|
|
|
nextiter++;
|
|
|
|
|
|
|
|
|
|
if(nextiter == MdlFromObj.end())
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if(std::none_of(map.Objects.begin(), map.Objects.end(),[&](const LevelObject &obj){
|
|
|
|
|
return obj.Type == nextiter->first;
|
|
|
|
|
})){
|
|
|
|
|
MdlFromObj.erase(nextiter);
|
|
|
|
|
} else {
|
|
|
|
|
mdlPairIter = nextiter;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MainViewport *g_getMainViewport() {
|
2023-07-02 22:21:26 +02:00
|
|
|
return MainVP;
|
|
|
|
|
}
|