diff options
Diffstat (limited to 'src/Authoring/Studio/Render/PathWidget.cpp')
-rw-r--r-- | src/Authoring/Studio/Render/PathWidget.cpp | 512 |
1 files changed, 512 insertions, 0 deletions
diff --git a/src/Authoring/Studio/Render/PathWidget.cpp b/src/Authoring/Studio/Render/PathWidget.cpp new file mode 100644 index 00000000..49fea1ef --- /dev/null +++ b/src/Authoring/Studio/Render/PathWidget.cpp @@ -0,0 +1,512 @@ +/**************************************************************************** +** +** Copyright (C) 2006 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "stdafx.h" +#include "PathWidget.h" +#include "UICRenderWidgets.h" +#include "render/Qt3DSRenderContext.h" +#include "render/Qt3DSRenderVertexBuffer.h" +#include "render/Qt3DSRenderShaderProgram.h" +#include "render/Qt3DSRenderInputAssembler.h" +#include "UICRenderPath.h" +#include "UICRenderPathSubPath.h" +#include "UICRenderPathManager.h" +#include "UICRenderContext.h" +#include "UICRenderShaderCodeGeneratorV2.h" + +using namespace uic::widgets; + +namespace { + +QT3DSVec3 toVec3(QT3DSVec2 inPoint) +{ + return QT3DSVec3(inPoint.x, inPoint.y, 0.0f); +} +QT3DSVec3 toVec3(QT3DSVec2 inPoint, float z) +{ + return QT3DSVec3(inPoint.x, inPoint.y, z); +} + +struct SPointEntry +{ + QT3DSVec2 m_Position; + QT3DSVec3 m_Color; + QT3DSF32 m_ObjectId; + SPointEntry(QT3DSVec2 pos, QT3DSVec3 color, size_t objId) + : m_Position(pos) + , m_Color(color) + , m_ObjectId((QT3DSF32)objId) + { + } + SPointEntry() {} +}; + +struct SPathWidget : public IPathWidget +{ + typedef nvvector<eastl::pair<QT3DSU32, uic::studio::SPathPick::EAnchorProperty>> + TReverseAnchorBuffer; + + NVAllocatorCallback &m_Allocator; + IUICRenderContext &m_UICContext; + + NVScopedRefCounted<NVRenderVertexBuffer> m_PointVertexBuffer; + NVScopedRefCounted<NVRenderInputAssembler> m_PointAssembler; + NVScopedRefCounted<NVRenderShaderProgram> m_PointShader; + NVScopedRefCounted<NVRenderShaderProgram> m_PointPickShader; + + NVScopedRefCounted<NVRenderVertexBuffer> m_LineVertexBuffer; + NVScopedRefCounted<NVRenderInputAssembler> m_LineAssembler; + NVScopedRefCounted<NVRenderShaderProgram> m_LineShader; + + nvvector<eastl::pair<QT3DSVec2, QT3DSVec2>> m_LineBuffer; + nvvector<SPointEntry> m_PointBuffer; + TReverseAnchorBuffer m_AnchorIndexBuffer; + SWidgetRenderSetupResult m_RenderSetup; + QT3DSVec2 m_PointViewportDimensions; + QT3DSMat44 m_PointMVP; + + QT3DSI32 m_RefCount; + SPathWidget(NVAllocatorCallback &inAlloc, IUICRenderContext &inRc) + : m_Allocator(inAlloc) + , m_UICContext(inRc) + , m_LineBuffer(inAlloc, "m_LineBuffer") + , m_PointBuffer(inAlloc, "m_PointBuffer") + , m_AnchorIndexBuffer(inAlloc, "m_AnchorIndexBuffer") + , m_LineShader(nullptr) + , m_RefCount(0) + { + } + + void addRef() override { ++m_RefCount; } + void release() override + { + --m_RefCount; + if (m_RefCount <= 0) { + NVAllocatorCallback &alloc(m_Allocator); + NVDelete(alloc, this); + } + } + + void SetNode(SNode &inNode) override { m_Node = &inNode; } + + QT3DSVec3 ToGlobalSpace(QT3DSVec3 inPoint) { return m_Node->m_GlobalTransform.transform(inPoint); } + + QT3DSVec3 ToCameraSpace(QT3DSVec3 inPoint) + { + QT3DSVec3 theGlobalPos = m_Node->m_GlobalTransform.transform(inPoint); + return m_RenderSetup.m_WidgetInfo.m_CameraGlobalInverse.transform(theGlobalPos); + } + + QT3DSVec3 ToCameraSpace(QT3DSVec2 inPoint) + { + return ToCameraSpace(QT3DSVec3(inPoint.x, inPoint.y, 0.0f)); + } + + void GeneratePointVertexGeometrySections(IShaderProgramGenerator &inProgramGenerator) + { + IShaderStageGenerator &vertex(*inProgramGenerator.GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &geometry( + *inProgramGenerator.GetStage(ShaderGeneratorStages::Geometry)); + vertex.AddIncoming("attr_pos", "vec2"); + vertex.AddIncoming("attr_color", "vec3"); + vertex.AddIncoming("attr_objid", "float"); + vertex.AddOutgoing("point_color", "vec3"); + vertex.AddOutgoing("object_id", "float"); + vertex.AddUniform("model_view_projection", "mat4"); + vertex << "void main()" << Endl << "{" << Endl + << "\tgl_Position = model_view_projection * vec4( attr_pos.xy, 0.0, 1.0 );" << Endl + << "\tpoint_color = attr_color;" << Endl << "\tobject_id = uint(attr_objid);" << Endl + << "}" << Endl; + + geometry.AddUniform("viewport_dimensions", "vec2"); + geometry.AddUniform("pointsize", "float"); + geometry.AddIncoming("point_color", "vec3"); + geometry.AddIncoming("object_id", "float"); + geometry.AddOutgoing("point_colorGE", "vec3"); + geometry.AddOutgoing("object_idGE", "float"); + geometry.AddOutgoing("uv_coords", "vec2"); + geometry.Append("layout (points) in;"); + geometry.Append("layout (triangle_strip, max_vertices = 4) out;"); + geometry.Append( + "void main() {" + "// project points to screen space\n" + "\tvec2 p0 = vec2(gl_in[0].gl_Position.xy) / gl_in[0].gl_Position.w;\n" + "\tvec2 increments = (pointsize / viewport_dimensions) / 2.0;\n" + "\tgl_Position = vec4( p0.x - increments.x, p0.y + increments.y, 0.0, 1.0 );\n" + "\tpoint_colorGE = point_color[0];\n" + "\tuv_coords = vec2(0.0, 0.0);\n" + "\tobject_idGE = object_id[0];\n" + "\tEmitVertex();\n" + "\tgl_Position = vec4( p0.x + increments.x, p0.y + increments.y, 0.0, 1.0 );\n" + "\tpoint_colorGE = point_color[0];\n" + "\tuv_coords = vec2(1.0, 0.0);\n" + "\tobject_idGE = object_id[0];\n" + "\tEmitVertex();\n" + "\tgl_Position = vec4( p0.x - increments.x, p0.y - increments.y, 0.0, 1.0 );\n" + "\tpoint_colorGE = point_color[0];\n" + "\tuv_coords = vec2(0.0, 1.0);\n" + "\tobject_idGE = object_id[0];\n" + "\tEmitVertex();\n" + "\tgl_Position = vec4( p0.x + increments.x, p0.y - increments.y, 0.0, 1.0 );\n" + "\tpoint_colorGE = point_color[0];\n" + "\tuv_coords = vec2(1.0, 1.0);\n" + "\tobject_idGE = object_id[0];\n" + "\tEmitVertex();\n" + "\tEndPrimitive();\n" + "}\n"); + } + + NVRenderShaderProgram *GetPointShader(IShaderProgramGenerator &inProgramGenerator) + { + if (m_PointShader) + return m_PointShader.mPtr; + inProgramGenerator.BeginProgram(IShaderProgramGenerator::DefaultFlags() + | ShaderGeneratorStages::Geometry); + GeneratePointVertexGeometrySections(inProgramGenerator); + + IShaderStageGenerator &fragment( + *inProgramGenerator.GetStage(ShaderGeneratorStages::Fragment)); + fragment.AddIncoming("point_colorGE", "vec3"); + fragment.AddIncoming("uv_coords", "vec2"); + fragment.Append("void main()\n" + "{\n" + "\tvec2 coords = uv_coords - vec2(.5, .5);\n" + "\tfloat coordLen = length( coords );\n" + "\tfloat margin = .4;\n" + "\tfloat leftover = min( 1.0, (coordLen - margin)/.1 );\n" + "\tfloat alpha = coordLen < margin ? 1.0 : mix( 1.0, 0.0, leftover );\n" + "\tfragOutput = vec4(point_colorGE, alpha);\n" + "}\n"); + + m_PointShader = inProgramGenerator.CompileGeneratedShader("path widget point shader"); + return m_PointShader.mPtr; + } + + NVRenderShaderProgram *GetPointPickShader(IShaderProgramGenerator &inProgramGenerator) + { + if (m_PointPickShader) + return m_PointPickShader.mPtr; + inProgramGenerator.BeginProgram(IShaderProgramGenerator::DefaultFlags() + | ShaderGeneratorStages::Geometry); + GeneratePointVertexGeometrySections(inProgramGenerator); + + IShaderStageGenerator &fragment( + *inProgramGenerator.GetStage(ShaderGeneratorStages::Fragment)); + fragment.AddIncoming("object_idGE", "float"); + fragment.AddIncoming("uv_coords", "vec2"); + fragment.Append("void main()\n" + "{\n" + "\tvec2 coords = uv_coords - vec2(.5, .5);\n" + "\tfloat coordLen = length( coords );\n" + "\tfloat margin = .4;\n" + "\tuint object_id = coordLen < margin ? uint(object_idGE + 1) : uint(0);\n" + "\tfragOutput.r = float(object_id % 256)/255.0;\n" + "\tfragOutput.g = float(object_id / 256)/255.0;\n" + //"\tfragOutput.g = float(object_id) / 10.0;\n" + "\tfragOutput.b = 0.0;\n" + "\tfragOutput.a = 1.0;\n" + "}\n"); + m_PointPickShader = + inProgramGenerator.CompileGeneratedShader("path widget point pick shader"); + return m_PointPickShader.mPtr; + } + + NVRenderShaderProgram *GetLineShader(IShaderProgramGenerator &inProgramGenerator) + { + if (m_LineShader) + return m_LineShader.mPtr; + + inProgramGenerator.BeginProgram(IShaderProgramGenerator::DefaultFlags() + | ShaderGeneratorStages::Geometry); + + IShaderStageGenerator &vertex(*inProgramGenerator.GetStage(ShaderGeneratorStages::Vertex)); + IShaderStageGenerator &geometry( + *inProgramGenerator.GetStage(ShaderGeneratorStages::Geometry)); + IShaderStageGenerator &fragment( + *inProgramGenerator.GetStage(ShaderGeneratorStages::Fragment)); + + vertex.AddIncoming("attr_pos", "vec2"); + vertex.AddUniform("model_view_projection", "mat4"); + vertex << "void main()" << Endl << "{" << Endl + << "\tgl_Position = model_view_projection * vec4( attr_pos.xy, 0.0, 1.0 );" << Endl + << "}" << Endl; + + geometry.AddUniform("viewport_dimensions", "vec2"); + geometry.AddUniform("linewidth", "float"); + geometry.AddOutgoing("uv_coords", "vec2"); + geometry.Append( + "layout (lines) in;\n" + "layout (triangle_strip, max_vertices = 4) out;\n" + "void main()\n" + "{\n" + "\tvec2 p0 = vec2(gl_in[0].gl_Position.xy) / gl_in[0].gl_Position.w;\n" + "\tvec2 p1 = vec2(gl_in[1].gl_Position.xy) / gl_in[1].gl_Position.w;\n" + "\tvec2 slope = normalize( p1 - p0 );\n" + "\tvec2 tangent = vec2(slope.y, -slope.x);\n" + "\tvec2 increments = (linewidth / viewport_dimensions) / 2.0;\n" + "\tvec2 tangentVec = vec2( tangent.x * increments.x, tangent.y * increments.y );\n" + "\tgl_Position = vec4( p0 - tangentVec, 0.0, 1.0);\n" + "\tuv_coords = vec2(0.0, 0.0);\n" + "\tEmitVertex();\n" + "\tgl_Position = vec4( p0 + tangentVec, 0.0, 1.0);\n" + "\tuv_coords = vec2(1.0, 0.0);\n" + "\tEmitVertex();\n" + "\tgl_Position = vec4( p1 - tangentVec, 0.0, 1.0);\n" + "\tuv_coords = vec2(0.0, 1.0);\n" + "\tEmitVertex();\n" + "\tgl_Position = vec4( p1 + tangentVec, 0.0, 1.0);\n" + "\tuv_coords = vec2(1.0, 1.0);\n" + "\tEmitVertex();\n" + "\tEndPrimitive();\n" + "}\n"); + + fragment.AddUniform("line_color", "vec3"); + fragment.AddIncoming("uv_coords", "vec2"); + fragment.Append("void main()\n" + "{\n" + "\tvec2 coords = uv_coords - vec2(.5, .5);\n" + "\tfloat coordLen = abs(coords.x);\n" + "\tfloat margin = .1;\n" + "\tfloat leftover = min( 1.0, (coordLen - margin)/.3 );\n" + "\tleftover = leftover * leftover;\n" + "\tfloat alpha = coordLen < margin ? 1.0 : mix( 1.0, 0.0, leftover );\n" + "\tfragOutput = vec4(line_color, alpha);\n" + "}\n"); + + m_LineShader = inProgramGenerator.CompileGeneratedShader("path widget line shader"); + return m_LineShader.mPtr; + } + + void RenderPointBuffer(NVRenderShaderProgram &inProgram, const QT3DSMat44 &inMVP, + NVRenderContext &inRenderContext) + { + inRenderContext.SetCullingEnabled(false); + inRenderContext.SetDepthTestEnabled(false); + inRenderContext.SetDepthWriteEnabled(false); + inRenderContext.SetStencilTestEnabled(false); + inRenderContext.SetBlendingEnabled(true); + inRenderContext.SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( + qt3ds::render::NVRenderSrcBlendFunc::SrcAlpha, + qt3ds::render::NVRenderDstBlendFunc::OneMinusSrcAlpha, + qt3ds::render::NVRenderSrcBlendFunc::One, + qt3ds::render::NVRenderDstBlendFunc::OneMinusSrcAlpha)); + inRenderContext.SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); + inRenderContext.SetActiveShader(&inProgram); + inProgram.SetPropertyValue("model_view_projection", inMVP); + inProgram.SetPropertyValue("pointsize", (QT3DSF32)15.0f); + inProgram.SetPropertyValue("viewport_dimensions", m_PointViewportDimensions); + inRenderContext.SetInputAssembler(m_PointAssembler); + inRenderContext.Draw(NVRenderDrawMode::Points, m_PointBuffer.size(), 0); + } + + void PushPoint(const SPointEntry &inEntry, QT3DSU32 inAnchorIndex, + uic::studio::SPathPick::EAnchorProperty inProperty) + { + QT3DSU32 anchorIndex = (QT3DSU32)m_PointBuffer.size(); + m_PointBuffer.push_back(inEntry); + m_AnchorIndexBuffer.push_back(eastl::make_pair(inAnchorIndex, inProperty)); + } + + void Render(IRenderWidgetContext &inWidgetContext, NVRenderContext &inRenderContext) override + { + if (!m_Node) + return; + SPath &thePath = static_cast<SPath &>(*m_Node); + IPathManager &theManager = m_UICContext.GetPathManager(); + + QT3DSVec3 anchorColor(0, 1, 0); + QT3DSVec3 controlColor(0, 0, 1); + m_LineBuffer.clear(); + m_PointBuffer.clear(); + // point index -> anchor index + m_AnchorIndexBuffer.clear(); + QT3DSU32 anchorIndex = 0; + + for (SPathSubPath *theSubPath = thePath.m_FirstSubPath; theSubPath; + theSubPath = theSubPath->m_NextSubPath) { + NVDataRef<uic::render::SPathAnchorPoint> thePathBuffer( + theManager.GetPathSubPathBuffer(*theSubPath)); + if (thePathBuffer.size() == 0) + return; + + QT3DSU32 numAnchors = thePathBuffer.size(); + for (QT3DSU32 idx = 0, end = numAnchors; idx < end; ++idx) { + const uic::render::SPathAnchorPoint &theAnchorPoint(thePathBuffer[idx]); + if (idx > 0) { + QT3DSVec2 incoming(uic::render::IPathManagerCore::GetControlPointFromAngleDistance( + theAnchorPoint.m_Position, theAnchorPoint.m_IncomingAngle, + theAnchorPoint.m_IncomingDistance)); + PushPoint(SPointEntry(incoming, controlColor, m_PointBuffer.size()), + anchorIndex, uic::studio::SPathPick::IncomingControl); + m_LineBuffer.push_back(eastl::make_pair(theAnchorPoint.m_Position, incoming)); + } + PushPoint(SPointEntry(theAnchorPoint.m_Position, anchorColor, m_PointBuffer.size()), + anchorIndex, uic::studio::SPathPick::Anchor); + if (idx < (numAnchors - 1)) { + QT3DSVec2 outgoing(uic::render::IPathManagerCore::GetControlPointFromAngleDistance( + theAnchorPoint.m_Position, theAnchorPoint.m_OutgoingAngle, + theAnchorPoint.m_OutgoingDistance)); + PushPoint(SPointEntry(outgoing, controlColor, m_PointBuffer.size()), + anchorIndex, uic::studio::SPathPick::OutgoingControl); + m_LineBuffer.push_back(eastl::make_pair(theAnchorPoint.m_Position, outgoing)); + } + ++anchorIndex; + } + } + + m_RenderSetup = SWidgetRenderSetupResult(inWidgetContext, *m_Node, + uic::render::RenderWidgetModes::Local); + + m_PointMVP = m_RenderSetup.m_WidgetInfo.m_LayerProjection + * m_RenderSetup.m_WidgetInfo.m_CameraGlobalInverse * m_Node->m_GlobalTransform; + + NVRenderRect theViewport = inRenderContext.GetViewport(); + m_PointViewportDimensions = QT3DSVec2((QT3DSF32)theViewport.m_Width, (QT3DSF32)theViewport.m_Height); + + if (!m_LineBuffer.empty()) { + QT3DSU32 vertItemSize = sizeof(QT3DSVec2); + QT3DSU32 vertBufSize = m_LineBuffer.size() * vertItemSize * 2; + if ((!m_LineVertexBuffer) || m_LineVertexBuffer->Size() < vertBufSize) { + m_LineVertexBuffer = inRenderContext.CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Dynamic, vertBufSize, vertItemSize, + qt3ds::foundation::toU8DataRef(m_LineBuffer.data(), (QT3DSU32)m_LineBuffer.size())); + m_LineAssembler = nullptr; + } else + m_LineVertexBuffer->UpdateBuffer( + qt3ds::foundation::toU8DataRef(m_LineBuffer.data(), (QT3DSU32)m_LineBuffer.size())); + + if (m_LineAssembler == nullptr) { + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry( + "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 0), + }; + NVRenderAttribLayout *theAttribLayout = + &inWidgetContext.CreateAttributeLayout(toConstDataRef(theEntries, 1)); + m_LineAssembler = inRenderContext.CreateInputAssembler( + theAttribLayout, toConstDataRef(&m_LineVertexBuffer.mPtr, 1), nullptr, + toConstDataRef(vertItemSize), toConstDataRef((QT3DSU32)0)); + } + inRenderContext.SetInputAssembler(m_LineAssembler); + NVRenderShaderProgram *lineShader = + GetLineShader(inWidgetContext.GetProgramGenerator()); + if (lineShader) { + inRenderContext.SetCullingEnabled(false); + inRenderContext.SetDepthTestEnabled(false); + inRenderContext.SetDepthWriteEnabled(false); + inRenderContext.SetStencilTestEnabled(false); + inRenderContext.SetBlendingEnabled(true); + inRenderContext.SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( + qt3ds::render::NVRenderSrcBlendFunc::SrcAlpha, + qt3ds::render::NVRenderDstBlendFunc::OneMinusSrcAlpha, + qt3ds::render::NVRenderSrcBlendFunc::One, + qt3ds::render::NVRenderDstBlendFunc::OneMinusSrcAlpha)); + inRenderContext.SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( + NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); + inRenderContext.SetActiveShader(lineShader); + lineShader->SetPropertyValue("model_view_projection", m_PointMVP); + lineShader->SetPropertyValue("line_color", QT3DSVec3(1.0, 1.0, 0.0)); + // Note the line needs to be wide enough to account for anti-aliasing. + lineShader->SetPropertyValue("linewidth", 3.0f); + lineShader->SetPropertyValue("viewport_dimensions", m_PointViewportDimensions); + inRenderContext.Draw(NVRenderDrawMode::Lines, m_LineBuffer.size() * 2, 0); + } + } + { + QT3DSU32 vertItemSize = (sizeof(SPointEntry)); + QT3DSU32 vertBufSize = m_PointBuffer.size() * vertItemSize; + if ((!m_PointVertexBuffer) || m_PointVertexBuffer->Size() < vertBufSize) { + m_PointVertexBuffer = inRenderContext.CreateVertexBuffer( + qt3ds::render::NVRenderBufferUsageType::Dynamic, vertBufSize, vertItemSize, + qt3ds::foundation::toU8DataRef(m_PointBuffer.data(), (QT3DSU32)m_PointBuffer.size())); + m_PointAssembler = nullptr; + } else + m_PointVertexBuffer->UpdateBuffer( + qt3ds::foundation::toU8DataRef(m_PointBuffer.data(), (QT3DSU32)m_PointBuffer.size())); + if (m_PointAssembler == nullptr) { + qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { + qt3ds::render::NVRenderVertexBufferEntry( + "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 0), + qt3ds::render::NVRenderVertexBufferEntry( + "attr_color", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3, 8), + qt3ds::render::NVRenderVertexBufferEntry( + "attr_objid", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 1, 20), + }; + NVRenderAttribLayout *theAttribLayout = + &inWidgetContext.CreateAttributeLayout(toConstDataRef(theEntries, 3)); + m_PointAssembler = inRenderContext.CreateInputAssembler( + theAttribLayout, toConstDataRef(&m_PointVertexBuffer.mPtr, 1), nullptr, + toConstDataRef(vertItemSize), toConstDataRef((QT3DSU32)0)); + } + NVRenderShaderProgram *thePointShader = + GetPointShader(inWidgetContext.GetProgramGenerator()); + GetPointPickShader(inWidgetContext.GetProgramGenerator()); + + if (thePointShader) { + m_PointMVP = m_RenderSetup.m_WidgetInfo.m_LayerProjection + * m_RenderSetup.m_WidgetInfo.m_CameraGlobalInverse * m_Node->m_GlobalTransform; + + RenderPointBuffer(*m_PointShader, m_PointMVP, inRenderContext); + } + } + } + + void RenderPick(const QT3DSMat44 &inProjPreMult, NVRenderContext &inRenderContext, + uic::render::SWindowDimensions inWinDimensions) override + { + if (m_PointAssembler == nullptr || m_PointPickShader == nullptr) + return; + // The projection premultiplication step moves the viewport around till + // it is centered over the mouse and scales everything *post* rendering (to keep appropriate + // aspect). + QT3DSMat44 theMVP = inProjPreMult * m_PointMVP; + m_PointViewportDimensions = + QT3DSVec2((QT3DSF32)inWinDimensions.m_Width, (QT3DSF32)inWinDimensions.m_Height); + + RenderPointBuffer(*m_PointPickShader, theMVP, inRenderContext); + } + + uic::studio::SStudioPickValue PickIndexToPickValue(QT3DSU32 inPickIndex) override + { + inPickIndex -= 1; + + if (inPickIndex < m_AnchorIndexBuffer.size()) + return uic::studio::SPathPick(m_AnchorIndexBuffer[inPickIndex].first, + m_AnchorIndexBuffer[inPickIndex].second); + else { + QT3DS_ASSERT(false); + return uic::studio::SPathPick(); + } + } +}; +} + +IPathWidget &IPathWidget::CreatePathWidget(NVAllocatorCallback &inCallback, IUICRenderContext &inRc) +{ + return *QT3DS_NEW(inCallback, SPathWidget)(inCallback, inRc); +} |