class Viewport : Panel { FrameBuffer frameBuffer; WorldCamera sceneCamera; float pitch = 0; float yaw = 0; int frameCounter = 0; float deltaAcomulated = 0; float latestFrameRate; int editMode = 0; void onImGui() { if (!frameBuffer.isValid()) return; frameCounter++; deltaAcomulated += World::getRenderDeltaTime(); if (frameCounter == 50) { latestFrameRate = 50 / deltaAcomulated; frameCounter = 0; deltaAcomulated = 0; } float vel = World::getRenderDeltaTime() * 3; if (ImGui::isKeyDown(key::LeftShift)) vel *= 3; int x = ImGui::getAvailableSizeX(); int y = ImGui::getAvailableSizeY(); if (x < 10 || y < 10) return; frameBuffer.resize(x, y); frameBuffer.clearRGBA(20, 23, 25, 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 (editMode == 0 && ImGui::manipulationTransform(sceneCamera, entityTransform, entityTransform, false)) { mat4 parentTransform = ActiveEntity::entity.parent.getWorldMatrix(); mat4 relativeMatrix = entityTransform.getRelativeMatrix(parentTransform); ActiveEntity::entity.getComponent().position = relativeMatrix.getPosition(); } if (editMode == 1 && ImGui::manipulationRotation(sceneCamera, entityTransform, entityTransform, false)) { mat4 parentTransform = ActiveEntity::entity.parent.getWorldMatrix(); mat4 relativeMatrix = entityTransform.getRelativeMatrix(parentTransform); ActiveEntity::entity.getComponent().rotation = relativeMatrix.getRotation(); } if (editMode == 2 && ImGui::manipulationScale(sceneCamera, entityTransform, entityTransform, false)) { mat4 parentTransform = ActiveEntity::entity.parent.getWorldMatrix(); mat4 relativeMatrix = entityTransform.getRelativeMatrix(parentTransform); ActiveEntity::entity.getComponent().scale = relativeMatrix.getScale(); } } if (!ImGui::isPanelActive()) return; 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::MouseRight)) { vec3 panDir = vec3(); panDir.x -= ImGui::getMouseDeltaX(); panDir.y += ImGui::getMouseDeltaY(); panDir = panDir * 0.01f; sceneCamera.transform.position = sceneCamera.transform.relative(panDir); } vec3 relDir = vec3(); if (ImGui::isKeyDown(key::W)) relDir.z++; if (ImGui::isKeyDown(key::S)) relDir.z--; relDir.z += ImGui::getMouseWheel() * 100; if (ImGui::isKeyDown(key::D)) relDir.x++; if (ImGui::isKeyDown(key::A)) relDir.x--; relDir = relDir * vel; sceneCamera.transform.position = sceneCamera.transform.relative(relDir); float vertically = 0; if (ImGui::isKeyDown(key::Space)) vertically++; if (ImGui::isKeyDown(key::LeftCtrl)) vertically--; sceneCamera.transform.position = sceneCamera.transform.position + vec3(0, vertically * vel, 0); } void onInit() { frameBuffer = Resource::createFrameBuffer("MainFrameBuffer", 1000, 1000); sceneCamera.transform.position = vec3(0, 1, -2); sceneCamera.camera.nearZ = 0.1; sceneCamera.camera.farZ = 100; ImGui::disablePanelPadding(true); } void onMenuBar() { /* if (ImGui::menuItem("Viewport")) { ImGui::openPopup("ViewportCameraProps", any()); }*/ ImGui::simplePopup("ViewportCameraProps", SimpleFunction(this.viewportCameraProps)); ImGui::textColor(0, 0.5f, 0,"" + int(latestFrameRate)); ImGui::drawComboEnd("##EditMode", "Translate", SimpleFunction(this.transformCombo)); } void transformCombo () { if (ImGui::drawComboItem("Translate", editMode == 0)) { editMode = 0; } if (ImGui::drawComboItem("Rotate", editMode == 1)) { editMode = 1; } if (ImGui::drawComboItem("Scale", editMode == 2)) { editMode = 2; } } void viewportCameraProps() { sceneCamera.camera.fov = ImGui::slider("Fov", sceneCamera.camera.fov / 3.14f * 180, 10, 160) / 180 * 3.14f; World::setRenderFrequency(ImGui::sliderInt("Render frequency", World::getRenderFrequency(), 10, 300)); } }