diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index c0ac864f..fcac85b3 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -67,7 +67,7 @@ namespace Nuake { ImGuizmo::SetOrthographic(false); ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + Vector2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); if (Engine::GetCurrentWindow()->GetFrameBuffer()->GetSize() != viewportPanelSize) Engine::GetCurrentWindow()->GetFrameBuffer()->QueueResize(viewportPanelSize); @@ -89,7 +89,7 @@ namespace Nuake { { TransformComponent& tc = m_SelectedEntity.GetComponent(); ParentComponent& parent = m_SelectedEntity.GetComponent(); - glm::mat4 oldTransform = tc.GetTransform(); + Matrix4 oldTransform = tc.GetTransform(); ImGuizmo::Manipulate( glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetTransform()), glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetPerspective()), @@ -97,17 +97,17 @@ namespace Nuake { ); if (ImGuizmo::IsUsing()) { - glm::vec3 scale; + Vector3 scale; glm::quat rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; + Vector3 translation; + Vector3 skew; + Vector4 perspective; glm::decompose(oldTransform, scale, rotation, translation, skew, perspective); //rotation = glm::conjugate(rotation); if (scale.x < 0 && scale.y < 0 && scale.z < 0) scale = glm::vec3(0, 0, 0); rotation = glm::conjugate(rotation); - glm::vec3 euler = glm::eulerAngles(rotation); + Vector3 euler = glm::eulerAngles(rotation); Vector3 globalPos = Vector3(); Entity currentParent = m_SelectedEntity; @@ -131,29 +131,29 @@ namespace Nuake { if (m_IsEntitySelected) { - if (ImGui::Begin("CSM")) - { - if (m_SelectedEntity.HasComponent()) - { - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); - Ref texture = m_SelectedEntity.GetComponent().m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT); - ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - } - } - ImGui::End(); - - if (ImGui::Begin("CSM 2")) - { - if (m_SelectedEntity.HasComponent()) - { - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); - Ref texture = m_SelectedEntity.GetComponent().m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT); - ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - } - } - ImGui::End(); + //if (ImGui::Begin("CSM")) + //{ + // if (m_SelectedEntity.HasComponent()) + // { + // ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + // glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + // Ref texture = m_SelectedEntity.GetComponent().m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT); + // ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + // } + //} + //ImGui::End(); + // + //if (ImGui::Begin("CSM 2")) + //{ + // if (m_SelectedEntity.HasComponent()) + // { + // ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + // glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + // Ref texture = m_SelectedEntity.GetComponent().m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT); + // ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + // } + //} + //ImGui::End(); } } @@ -179,6 +179,7 @@ namespace Nuake { if(nameComponent.IsPrefab && e.HasComponent()) ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0,255,0,255)); + bool open = ImGui::TreeNodeEx(name.c_str(), base_flags); if(nameComponent.IsPrefab && e.HasComponent()) ImGui::PopStyleColor(); @@ -214,7 +215,6 @@ namespace Nuake { } } - // Click. if (ImGui::IsItemClicked()) { m_SelectedEntity = e; @@ -223,15 +223,16 @@ namespace Nuake { if (ImGui::BeginPopupContextItem()) { - if (ImGui::Selectable("Remove")) { - + if (ImGui::Selectable("Remove")) + { QueueDeletion = e; } if (ImGui::Selectable("Move to root")) { auto& p = m_SelectedEntity.GetComponent(); - if (p.HasParent) { + if (p.HasParent) + { auto& pp = p.Parent.GetComponent(); pp.RemoveChildren(m_SelectedEntity); p.HasParent = false; @@ -254,7 +255,6 @@ namespace Nuake { DrawEntityTree(c); ImGui::TreePop(); - } ImGui::PopFont(); } @@ -271,23 +271,23 @@ namespace Nuake { if (ImGui::Begin("Environnement")) { - auto env = Engine::GetCurrentScene()->GetEnvironment(); + Ref env = Engine::GetCurrentScene()->GetEnvironment(); if (ImGui::CollapsingHeader("Procedural Sky")) { ImGui::DragFloat("Sun Intensity", &env->ProceduralSkybox->SunIntensity, 0.1f, 0.0f); - glm::vec3 currentDirection = env->ProceduralSkybox->SunDirection; + Vector3 currentDirection = env->ProceduralSkybox->SunDirection; ImGuiHelper::DrawVec3("Sun Direction", ¤tDirection); env->ProceduralSkybox->SunDirection = glm::normalize(currentDirection); - glm::vec3 mieScattering = env->ProceduralSkybox->MieScattering * 10000.0f; + Vector3 mieScattering = env->ProceduralSkybox->MieScattering * 10000.0f; ImGuiHelper::DrawVec3("Mie Scattering", &mieScattering); env->ProceduralSkybox->MieScattering = mieScattering / 10000.0f; } if (ImGui::CollapsingHeader("Fog")) { - ImGui::DragFloat("Volumetric scattering", &env->VolumetricFog, .01f, 0.0f, 1.0f); - ImGui::DragFloat("Volumetric step count", &env->VolumetricStepCount, 1.f, 0.0f); + ImGui::DragFloat("Volumetric Scattering", &env->VolumetricFog, .01f, 0.0f, 1.0f); + ImGui::DragFloat("Volumetric Step Count", &env->VolumetricStepCount, 1.f, 0.0f); } } @@ -297,7 +297,7 @@ namespace Nuake { if (ImGui::Begin(title.c_str())) { // Buttons to add and remove entity. - ImGui::BeginChild("Buttons", ImVec2(300, 20), false); + if(ImGui::BeginChild("Buttons", ImVec2(300, 20), false)) { // Add entity. if (ImGui::Button("Add")) @@ -671,6 +671,7 @@ namespace Nuake { } ImGui::End(); } + void EditorInterface::DrawGizmos() { Ref scene = Engine::GetCurrentScene(); @@ -714,9 +715,6 @@ namespace Nuake { Ref rootDirectory = FileSystem::GetFileTree(); if (!rootDirectory) return; - - - } void EditorInterface::DrawDirectory(Ref directory) @@ -806,7 +804,8 @@ namespace Nuake { } // Exit if no current directory. - if (!m_CurrentDirectory) { + if (!m_CurrentDirectory) + { ImGui::EndTable(); ImGui::End(); return; @@ -836,8 +835,6 @@ namespace Nuake { i++; } } - - } ImGui::EndTable(); @@ -1096,16 +1093,13 @@ namespace Nuake { if (Engine::GetProject()) Engine::GetProject()->Save(); - // Parse the project and load it. - std::string selectedProject = FileDialog::SaveFile(".project") + ".project"; + std::string selectedProject = FileDialog::SaveFile("Project file\0*.project"); + if (selectedProject == "") // Hit cancel + return; - - Ref project = Project::New("Unnamed project", "no description", selectedProject); - project->FullPath = selectedProject; + Ref project = Project::New("Unnamed project", "no description", selectedProject + ".project"); Engine::LoadProject(project); - - Ref scene = Scene::New(); - Engine::LoadScene(scene); + Engine::LoadScene(Scene::New()); } @@ -1115,6 +1109,9 @@ namespace Nuake { // Parse the project and load it. std::string projectPath = FileDialog::OpenFile("Project file\0*.project"); + if (projectPath == "") // Hit cancel. + return; + FileSystem::SetRootDirectory(projectPath + "/../"); Ref project = Project::New(); if (!project->Deserialize(FileSystem::ReadFile(projectPath, true))) @@ -1160,7 +1157,7 @@ namespace Nuake { ImGui::Text("Welcome to Nuake Engine"); ImGui::Text("Developement build"); - ImGui::Text("This project is still very early in developement and is not stable!"); + ImGui::Text("This project is still very early in developement!"); if (ImGui::Button("New Project")) NewProject(); @@ -1269,14 +1266,17 @@ namespace Nuake { { if (ImGui::BeginMenu("Create new")) { - if (ImGui::MenuItem("Empty")) { + if (ImGui::MenuItem("Empty")) + { auto ent = Engine::GetCurrentScene()->CreateEntity("Empty entity"); } - if (ImGui::MenuItem("Light")) { + if (ImGui::MenuItem("Light")) + { auto ent = Engine::GetCurrentScene()->CreateEntity("Light"); ent.AddComponent(); } - if (ImGui::MenuItem("Camera")) { + if (ImGui::MenuItem("Camera")) + { auto ent = Engine::GetCurrentScene()->CreateEntity("Camera"); ent.AddComponent(); } @@ -1290,7 +1290,8 @@ namespace Nuake { auto ent = Engine::GetCurrentScene()->CreateEntity("Trenchbroom map"); ent.AddComponent(); } - if (ImGui::MenuItem("Mesh")) { + if (ImGui::MenuItem("Mesh")) + { auto ent = Engine::GetCurrentScene()->CreateEntity("Mesh"); ent.AddComponent(); } @@ -1303,15 +1304,10 @@ namespace Nuake { } if (ImGui::BeginMenu("Debug")) { - if (ImGui::MenuItem("Show ImGui demo", NULL, m_ShowImGuiDemo)) { - m_ShowImGuiDemo = !m_ShowImGuiDemo; - } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Quit")) - { + if (ImGui::MenuItem("Show ImGui demo", NULL, m_ShowImGuiDemo)) m_ShowImGuiDemo = !m_ShowImGuiDemo; ImGui::EndMenu(); } + if (ImGui::BeginMenu("Quit")) ImGui::EndMenu(); ImGui::EndMainMenuBar(); } @@ -1330,35 +1326,22 @@ namespace Nuake { filesystem.Draw(); filesystem.DrawDirectoryExplorer(); - if (m_ShowImGuiDemo) ImGui::ShowDemoWindow(); if (ImGui::Begin("Toolbar")) { - if (ImGui::Button(ICON_FA_HAND_POINTER)) - CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; + if (ImGui::Button(ICON_FA_HAND_POINTER)) CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; ImGui::SameLine(); - if (ImGui::Button(ICON_FA_ARROWS_ALT)) - CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; + if (ImGui::Button(ICON_FA_ARROWS_ALT)) CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; ImGui::SameLine(); - if (ImGui::Button(ICON_FA_SYNC_ALT)) - CurrentOperation = ImGuizmo::OPERATION::ROTATE; + if (ImGui::Button(ICON_FA_SYNC_ALT)) CurrentOperation = ImGuizmo::OPERATION::ROTATE; ImGui::SameLine(); - if (ImGui::Button(ICON_FA_EXPAND_ALT)) - CurrentOperation = ImGuizmo::OPERATION::SCALE; + if (ImGui::Button(ICON_FA_EXPAND_ALT)) CurrentOperation = ImGuizmo::OPERATION::SCALE; ImGui::SameLine(); - if (ImGui::Button(ICON_FA_PLAY)) - { - Engine::EnterPlayMode(); - } + if (ImGui::Button(ICON_FA_PLAY)) Engine::EnterPlayMode(); ImGui::SameLine(); - if (ImGui::Button(ICON_FA_STOP)) - { - Engine::ExitPlayMode(); - } - - + if (ImGui::Button(ICON_FA_STOP)) Engine::ExitPlayMode(); } ImGui::End(); } diff --git a/Editor/src/FileSystemUI.cpp b/Editor/src/FileSystemUI.cpp index b718adb3..ebf6b954 100644 --- a/Editor/src/FileSystemUI.cpp +++ b/Editor/src/FileSystemUI.cpp @@ -27,48 +27,37 @@ namespace Nuake { void FileSystemUI::EditorInterfaceDrawFiletree(Ref dir) { - for (auto d : dir->Directories) + ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; + //if (is_selected) + + std::string icon = ICON_FA_FOLDER; + if (m_CurrentDirectory == dir) + base_flags |= ImGuiTreeNodeFlags_Selected; + if (dir->Directories.size() <= 0) + base_flags = ImGuiTreeNodeFlags_Leaf; + + bool open = ImGui::TreeNodeEx(dir->name.c_str(), base_flags); + + if (ImGui::IsItemClicked()) + m_CurrentDirectory = dir; + + if (open) { - ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; - bool is_selected = m_CurrentDirectory == d; - if (is_selected) - base_flags |= ImGuiTreeNodeFlags_Selected; - - if (d->Directories.size() == 0) - { - base_flags = ImGuiTreeNodeFlags_Leaf; - } - std::string icon = ICON_FA_FOLDER; - if (is_selected) - icon = ICON_FA_FOLDER_OPEN; - bool open = ImGui::TreeNodeEx((icon + " " + d->name).c_str(), base_flags); - - if (ImGui::IsItemClicked()) - m_CurrentDirectory = d; - if (open) - { - if (d->Directories.size() > 0) + if (dir->Directories.size() > 0) + for (auto& d : dir->Directories) EditorInterfaceDrawFiletree(d); - ImGui::TreePop(); - } - + ImGui::TreePop(); } } - - void FileSystemUI::DrawDirectory(Ref directory) { ImGui::PushFont(EditorInterface::bigIconFont); std::string id = ICON_FA_FOLDER + std::string("##") + directory->name; + if (ImGui::Button(id.c_str(), ImVec2(100, 100))) m_CurrentDirectory = directory; - if (ImGui::BeginPopupContextWindow()) - { - if (ImGui::MenuItem("Htest")); - ImGui::EndPopup(); - } ImGui::Text(directory->name.c_str()); ImGui::PopFont(); } @@ -170,28 +159,22 @@ namespace Nuake { if (ImGui::BeginChild("Tree browser", ImVec2(sz1, avail.y))) { - if (ImGui::BeginPopupContextItem("item context menu")) - { - if (ImGui::Selectable("Set to zero")); - if (ImGui::Selectable("Set to PI")); - ImGui::SetNextItemWidth(-1); - ImGui::EndPopup(); - } - ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; + ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_SpanAvailWidth; bool is_selected = m_CurrentDirectory == FileSystem::RootDirectory; if (is_selected) - base_flags |= ImGuiTreeNodeFlags_Selected | ImGuiTreeNodeFlags_DefaultOpen; + base_flags |= ImGuiTreeNodeFlags_Selected; std::string icon = ICON_FA_FOLDER; - bool open = ImGui::TreeNodeEx((icon + " " + rootDirectory->name).c_str(), base_flags); + bool open = ImGui::TreeNodeEx((icon + " " + "Project files").c_str(), base_flags); if (ImGui::IsItemClicked()) { m_CurrentDirectory = FileSystem::RootDirectory; } if (open) { - EditorInterfaceDrawFiletree(rootDirectory); + for(auto& d : rootDirectory->Directories) + EditorInterfaceDrawFiletree(d); ImGui::TreePop(); } @@ -205,7 +188,8 @@ namespace Nuake { Ref currentParent = m_CurrentDirectory; paths.push_back(m_CurrentDirectory); - while (currentParent != nullptr) { + while (currentParent != nullptr) + { paths.push_back(currentParent); currentParent = currentParent->Parent; } @@ -215,7 +199,7 @@ namespace Nuake { if (ImGui::BeginChild("Wrapper", avail)) { avail.y = 30; - if (ImGui::BeginChild("ariane", avail)) + if (ImGui::BeginChild("Path", avail)) { if (ImGui::Button("Refresh")) FileSystem::Scan(); @@ -238,31 +222,24 @@ namespace Nuake { if (ImGui::BeginChild("Content", avail)) { - // Wrapping. int width = ImGui::GetWindowWidth() * 0.8f; ImVec2 buttonSize = ImVec2(80, 80); - int amount = (width / 100); // -2 because button overflow width + ... button. + int amount = (int)(width / 100); + if (amount <= 0) amount = 1; + int i = 1; // current amount of item per row. if (ImGui::BeginTable("ssss", amount)) { // Button to go up a level. - if (m_CurrentDirectory != FileSystem::RootDirectory) + if (m_CurrentDirectory && m_CurrentDirectory != FileSystem::RootDirectory && m_CurrentDirectory->Parent) { ImGui::TableNextColumn(); if (ImGui::Button("..", ImVec2(100, 100))) m_CurrentDirectory = m_CurrentDirectory->Parent; ImGui::TableNextColumn(); - // Increment item per row tracker. i++; } - // Exit if no current directory. - if (!m_CurrentDirectory) { - ImGui::EndTable(); - ImGui::End(); - return; - } - if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0) { for (auto d : m_CurrentDirectory->Directories) @@ -275,6 +252,7 @@ namespace Nuake { i++; } } + if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0) { for (auto f : m_CurrentDirectory->Files) @@ -298,7 +276,7 @@ namespace Nuake { } if (ImGui::BeginPopupContextWindow()) { - if (ImGui::Button("New Wren script")) + if (ImGui::MenuItem("New Wren script")) { ImGui::OpenPopup("CreateNewFile"); diff --git a/Nuake/src/Resource/Project.cpp b/Nuake/src/Resource/Project.cpp index 89d23b63..fc5f019a 100644 --- a/Nuake/src/Resource/Project.cpp +++ b/Nuake/src/Resource/Project.cpp @@ -7,7 +7,7 @@ namespace Nuake { - Project::Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath) + Project::Project(const std::string& Name, const std::string& Description, const std::string& FullPath, const std::string& defaultScenePath) { this->Name = Name; this->Description = Description; @@ -40,7 +40,7 @@ namespace Nuake SaveAs(this->FullPath); } - void Project::SaveAs(const std::string FullPath) + void Project::SaveAs(const std::string& FullPath) { json j = Serialize(); std::string serialized_string = j.dump(); @@ -53,11 +53,8 @@ namespace Nuake projectFile.close(); } - Ref Project::New(const std::string Name, const std::string Description, const std::string FullPath) + Ref Project::New(const std::string& Name, const std::string& Description, const std::string& FullPath) { - if (Name == "") - return nullptr; - return CreateRef(Name, Description, FullPath); } @@ -66,7 +63,7 @@ namespace Nuake return CreateRef(); } - Ref Project::Load(std::string path) + Ref Project::Load(std::string& path) { std::ifstream i(path); json j; @@ -91,8 +88,12 @@ namespace Nuake BEGIN_SERIALIZE(); SERIALIZE_VAL(Name); SERIALIZE_VAL(Description); - SERIALIZE_VAL_LBL("DefaultScene", DefaultScene->Path); - SERIALIZE_VAL_LBL("EntityDefinition", EntityDefinitionsFile->Path); + + if(DefaultScene) + SERIALIZE_VAL_LBL("DefaultScene", DefaultScene->Path); + + if(EntityDefinitionsFile) + SERIALIZE_VAL_LBL("EntityDefinition", EntityDefinitionsFile->Path); SERIALIZE_VAL(TrenchbroomPath); END_SERIALIZE(); } @@ -107,7 +108,7 @@ namespace Nuake Name = j["Name"]; Description = j["Description"]; - if (j.contains("EntityDefinition")) + if (j.contains("EntityDefinition") && j["EntityDefinition"] != "") { std::string path = j["EntityDefinition"]; EntityDefinitionsFile = CreateRef(path); @@ -123,7 +124,7 @@ namespace Nuake DefaultScene = Scene::New(); // Load default scene, a project can have no default scene set. - if (!j.contains("DefaultScene")) + if (!j.contains("DefaultScene") ) return true; std::string scenePath = j["DefaultScene"]; diff --git a/Nuake/src/Resource/Project.h b/Nuake/src/Resource/Project.h index f42bba55..da025243 100644 --- a/Nuake/src/Resource/Project.h +++ b/Nuake/src/Resource/Project.h @@ -21,15 +21,15 @@ namespace Nuake Ref DefaultScene; Ref EntityDefinitionsFile; - Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath = ""); + Project(const std::string& Name, const std::string& Description, const std::string& FullPath, const std::string& defaultScenePath = ""); Project(); void Save(); - void SaveAs(const std::string FullPath); + void SaveAs(const std::string& FullPath); - static Ref New(const std::string Name, const std::string Description, const std::string FullPath); + static Ref New(const std::string& Name, const std::string& Description, const std::string& FullPath); static Ref New(); - static Ref Load(std::string path); + static Ref Load(std::string& path); json Serialize() override; bool Deserialize(const std::string& str) override; diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index fd771dfe..5c65f87c 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -278,8 +278,9 @@ namespace Nuake { pbrShader->SetUniform1i("u_ShowNormal", 0); - if (cam) + if (!cam) { + return; pbrShader->SetUniform1f("u_Exposure", cam->Exposure); pbrShader->SetUniformMat4f("u_View", cam->GetTransform()); pbrShader->SetUniformMat4f("u_Projection", cam->GetPerspective()); diff --git a/Nuake/src/Window.cpp b/Nuake/src/Window.cpp index 7017125c..c6e789e9 100644 --- a/Nuake/src/Window.cpp +++ b/Nuake/src/Window.cpp @@ -64,9 +64,6 @@ namespace Nuake { bool Window::SetScene(Ref scene) { - if (scene == nullptr) - return false; - m_Scene = scene; return true; } @@ -161,8 +158,8 @@ namespace Nuake { io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; ImGui::StyleColorsDark(); - ImGui::GetStyle().FrameRounding = 4.0f; - ImGui::GetStyle().GrabRounding = 4.0f; + ImGui::GetStyle().FrameRounding = 2.0f; + ImGui::GetStyle().GrabRounding = 2.0f; ImVec4* colors = ImGui::GetStyle().Colors; colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);