From 1a748e531041368d74de766d94d85a68f66c8d3d Mon Sep 17 00:00:00 2001 From: ducphamhong Date: Sat, 15 May 2021 16:54:27 +0700 Subject: [PATCH] #123 Draw handle translate, fill polygon and arrow on gizmos --- .../EditorComponents/Handles/CHandlesData.h | 5 +- .../Handles/CHandlesRenderer.cpp | 80 ++++++++++++++++-- .../Source/LineDraw/CLineDrawData.cpp | 13 +-- .../Source/PolygonDraw/CPolygonDrawData.cpp | 84 +++++++++++++++++++ .../Source/PolygonDraw/CPolygonDrawData.h | 49 +++++++++++ 5 files changed, 220 insertions(+), 11 deletions(-) create mode 100644 Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.cpp create mode 100644 Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.h diff --git a/Projects/Editor/Source/EditorComponents/Handles/CHandlesData.h b/Projects/Editor/Source/EditorComponents/Handles/CHandlesData.h index 9c001adb5..f6514a3ac 100644 --- a/Projects/Editor/Source/EditorComponents/Handles/CHandlesData.h +++ b/Projects/Editor/Source/EditorComponents/Handles/CHandlesData.h @@ -26,12 +26,15 @@ This file is part of the "Skylicht Engine". #include "Entity/IEntityData.h" #include "LineDraw/CLineDrawData.h" +#include "PolygonDraw/CPolygonDrawData.h" namespace Skylicht { namespace Editor { - class CHandlesData : public CLineDrawData + class CHandlesData : + public CLineDrawData, + public CPolygonDrawData { public: CHandlesData(); diff --git a/Projects/Editor/Source/EditorComponents/Handles/CHandlesRenderer.cpp b/Projects/Editor/Source/EditorComponents/Handles/CHandlesRenderer.cpp index cd4dea2d7..7a04a22f9 100644 --- a/Projects/Editor/Source/EditorComponents/Handles/CHandlesRenderer.cpp +++ b/Projects/Editor/Source/EditorComponents/Handles/CHandlesRenderer.cpp @@ -39,6 +39,9 @@ namespace Skylicht m_data->LineBuffer->getMaterial().ZBuffer = ECFN_DISABLED; m_data->LineBuffer->getMaterial().ZWriteEnable = false; + m_data->PolygonBuffer->getMaterial().ZBuffer = ECFN_DISABLED; + m_data->PolygonBuffer->getMaterial().ZWriteEnable = false; + m_directionUnary[0] = core::vector3df(1.f, 0.f, 0.f); m_directionUnary[1] = core::vector3df(0.f, 1.f, 0.f); m_directionUnary[2] = core::vector3df(0.f, 0.f, 1.f); @@ -80,7 +83,8 @@ namespace Skylicht if (m_enable == false) return; - m_data->clearBuffer(); + ((CLineDrawData*)m_data)->clearBuffer(); + ((CPolygonDrawData*)m_data)->clearBuffer(); // Caculate the screen scale factor irr::core::matrix4 invView; @@ -88,8 +92,15 @@ namespace Skylicht irr::core::matrix4 view(getVideoDriver()->getTransform(video::ETS_VIEW)); view.getInversePrimitive(invView); } + core::vector3df cameraRight(invView[0], invView[1], invView[2]); + core::vector3df cameraLook(invView[8], invView[9], invView[10]); + core::vector3df cameraUp(invView[4], invView[5], invView[6]); + cameraRight.normalize(); + cameraLook.normalize(); + cameraUp.normalize(); + m_screenFactor = 0.2f / getSegmentLengthClipSpace(core::vector3df(), cameraRight, entityManager->getCamera()); // Draw position axis @@ -98,8 +109,8 @@ namespace Skylicht { const core::vector3df& pos = handles->getHandlePosition(); - float quadMin = 0.2f; - float quadMax = 0.6f; + float quadMin = 0.1f; + float quadMax = 0.4f; core::vector3df quad[4] = { core::vector3df(quadMin, quadMin, 0.0f), @@ -119,6 +130,54 @@ namespace Skylicht { // draw axis m_data->addLineVertexBatch(pos, pos + dirAxis * m_screenFactor, m_directionColor[i]); + + // draw arrow + float arrowSize1 = m_screenFactor * 0.1f; + float arrowSize2 = m_screenFactor * 0.05f; + + core::vector3df side = dirAxis.crossProduct(cameraLook); + side.normalize(); + + core::vector3df a = pos + dirAxis * m_screenFactor; + core::vector3df m = a - dirAxis * arrowSize1; + core::vector3df b = m + side * arrowSize2; + core::vector3df c = m - side * arrowSize2; + m_data->addTriangleFill(a, b, c, m_directionColor[i]); + + // draw quad + /* + float arrowSize1 = m_screenFactor * 0.1f; + float arrowSize2 = m_screenFactor * 0.05f; + + core::vector3df a = pos + dirAxis * m_screenFactor; + + core::vector3df sideQuad = side * arrowSize2; + core::vector3df upQuad = cameraUp * arrowSize2; + + core::vector3df v1, v2, v3, v4; + v1.set( + a.X - sideQuad.X + upQuad.X, + a.Y - sideQuad.Y + upQuad.Y, + a.Z - sideQuad.Z + upQuad.Z + ); + v2.set( + a.X + sideQuad.X + upQuad.X, + a.Y + sideQuad.Y + upQuad.Y, + a.Z + sideQuad.Z + upQuad.Z + ); + v3.set( + a.X + sideQuad.X - upQuad.X, + a.Y + sideQuad.Y - upQuad.Y, + a.Z + sideQuad.Z - upQuad.Z + ); + v4.set( + a.X - sideQuad.X - upQuad.X, + a.Y - sideQuad.Y - upQuad.Y, + a.Z - sideQuad.Z - upQuad.Z + ); + core::vector3df arrow[] = { v1, v2, v3, v4 }; + m_data->addPolygonFill(arrow, 4, m_directionColor[i]); + */ } if (belowPlaneLimit) @@ -132,11 +191,16 @@ namespace Skylicht m_data->addLineVertexBatch(planeLine[1], planeLine[2], m_directionColor[i]); m_data->addLineVertexBatch(planeLine[2], planeLine[3], m_directionColor[i]); m_data->addLineVertexBatch(planeLine[3], planeLine[0], m_directionColor[i]); + + SColor fillColor = m_directionColor[i]; + fillColor.setAlpha(50); + m_data->addPolygonFill(planeLine, 4, fillColor); } } } - m_data->LineBuffer->setDirty(); + ((CLineDrawData*)m_data)->updateBuffer(); + ((CPolygonDrawData*)m_data)->updateBuffer(); } // References: https://github.com/CedricGuillemet/ImGuizmo/blob/master/ImGuizmo.cpp @@ -248,7 +312,13 @@ namespace Skylicht IVideoDriver* driver = getVideoDriver(); driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - IMeshBuffer* buffer = m_data->LineBuffer; + IMeshBuffer* buffer = NULL; + + buffer = m_data->PolygonBuffer; + driver->setMaterial(buffer->getMaterial()); + driver->drawMeshBuffer(buffer); + + buffer = m_data->LineBuffer; driver->setMaterial(buffer->getMaterial()); driver->drawMeshBuffer(buffer); } diff --git a/Projects/Skylicht/Components/Source/LineDraw/CLineDrawData.cpp b/Projects/Skylicht/Components/Source/LineDraw/CLineDrawData.cpp index b5965e6dd..b521f4898 100644 --- a/Projects/Skylicht/Components/Source/LineDraw/CLineDrawData.cpp +++ b/Projects/Skylicht/Components/Source/LineDraw/CLineDrawData.cpp @@ -62,18 +62,21 @@ namespace Skylicht void CLineDrawData::addLineVertexBatch(const core::vector3df& v1, const core::vector3df& v2, const SColor& color) { - int idxCount = LineBuffer->getVertexBuffer()->getVertexCount(); + IVertexBuffer* vtxBuffer = LineBuffer->getVertexBuffer(); + IIndexBuffer* idxBuffer = LineBuffer->getIndexBuffer(); + + u32 idxCount = vtxBuffer->getVertexCount(); video::S3DVertex vert; vert.Color = color; vert.Pos = v1; - LineBuffer->getVertexBuffer()->addVertex(&vert); + vtxBuffer->addVertex(&vert); vert.Pos = v2; - LineBuffer->getVertexBuffer()->addVertex(&vert); + vtxBuffer->addVertex(&vert); - LineBuffer->getIndexBuffer()->addIndex(idxCount++); - LineBuffer->getIndexBuffer()->addIndex(idxCount); + idxBuffer->addIndex(idxCount++); + idxBuffer->addIndex(idxCount); } void CLineDrawData::clearBuffer() diff --git a/Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.cpp b/Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.cpp new file mode 100644 index 000000000..c220649c8 --- /dev/null +++ b/Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.cpp @@ -0,0 +1,84 @@ +/* +!@ +MIT License + +Copyright (c) 2019 Skylicht Technology CO., LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +This file is part of the "Skylicht Engine". +https://github.com/skylicht-lab/skylicht-engine +!# +*/ + +#include "pch.h" +#include "Material/Shader/CShaderManager.h" +#include "CPolygonDrawData.h" + +namespace Skylicht +{ + CPolygonDrawData::CPolygonDrawData() + { + PolygonBuffer = new CMeshBuffer(getVideoDriver()->getVertexDescriptor(EVT_STANDARD)); + PolygonBuffer->getMaterial().MaterialType = CShaderManager::getInstance()->getShaderIDByName("VertexColorAlpha"); + PolygonBuffer->getMaterial().BackfaceCulling = false; + PolygonBuffer->setHardwareMappingHint(EHM_STREAM); + } + + CPolygonDrawData::~CPolygonDrawData() + { + PolygonBuffer->drop(); + } + + void CPolygonDrawData::clearBuffer() + { + PolygonBuffer->getVertexBuffer()->set_used(0); + PolygonBuffer->getIndexBuffer()->set_used(0); + } + + void CPolygonDrawData::updateBuffer() + { + PolygonBuffer->setDirty(); + } + + void CPolygonDrawData::addPolygonFill(core::vector3df* points, u32 count, const SColor& color) + { + IVertexBuffer* vtxBuffer = PolygonBuffer->getVertexBuffer(); + IIndexBuffer* idxBuffer = PolygonBuffer->getIndexBuffer(); + + u32 idxCount = vtxBuffer->getVertexCount(); + + video::S3DVertex vert; + vert.Color = color; + + for (u32 i = 0; i < count; i++) + { + vert.Pos = points[i]; + vtxBuffer->addVertex(&vert); + } + + for (u32 i = 2; i < count; i++) + { + idxBuffer->addIndex(idxCount); + idxBuffer->addIndex(idxCount + i - 1); + idxBuffer->addIndex(idxCount + i); + } + } + + void CPolygonDrawData::addTriangleFill(const core::vector3df& a, const core::vector3df& b, const core::vector3df& c, const SColor& color) + { + core::vector3df points[] = { a, b, c }; + addPolygonFill(points, 3, color); + } +} \ No newline at end of file diff --git a/Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.h b/Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.h new file mode 100644 index 000000000..f4800ca82 --- /dev/null +++ b/Projects/Skylicht/Components/Source/PolygonDraw/CPolygonDrawData.h @@ -0,0 +1,49 @@ +/* +!@ +MIT License + +Copyright (c) 2019 Skylicht Technology CO., LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +This file is part of the "Skylicht Engine". +https://github.com/skylicht-lab/skylicht-engine +!# +*/ + +#pragma once + +#include "Entity/IEntityData.h" + +namespace Skylicht +{ + class CPolygonDrawData + { + public: + IMeshBuffer* PolygonBuffer; + + public: + CPolygonDrawData(); + + virtual ~CPolygonDrawData(); + + void clearBuffer(); + + void updateBuffer(); + + void addPolygonFill(core::vector3df* points, u32 count, const SColor& color); + + void addTriangleFill(const core::vector3df& a, const core::vector3df& b, const core::vector3df& c, const SColor& color); + }; +} \ No newline at end of file