diff options
Diffstat (limited to 'src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.h')
-rw-r--r-- | src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.h | 732 |
1 files changed, 732 insertions, 0 deletions
diff --git a/src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.h b/src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.h new file mode 100644 index 00000000..ed7ea70d --- /dev/null +++ b/src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.h @@ -0,0 +1,732 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +#ifndef QT3DS_STUDIO_RENDERER_TRANSLATION_H +#define QT3DS_STUDIO_RENDERER_TRANSLATION_H +#pragma once +#include "StudioRendererImpl.h" +#include "Qt3DSRenderLayer.h" +#include "Qt3DSRenderer.h" +#include "StudioWidget.h" +#include "render/Qt3DSRenderTexture2D.h" +#include "foundation/AutoDeallocatorAllocator.h" +#include "foundation/FastAllocator.h" +#include "StudioPickValues.h" +#include "Qt3DSDMGuides.h" +#include "PathWidget.h" +#include "StudioPreferences.h" +#include "StudioGradientWidget.h" +#include "StudioVisualAidWidget.h" +#include "StudioHelperGridWidget.h" + +namespace qt3ds { +namespace studio { + struct SGraphObjectTranslator; + extern QT3DSU32 g_GraphObjectTranslatorTag; + inline void InitializePointerTags(IStringTable &) { g_GraphObjectTranslatorTag = 0x0088BEEF; } +} +} +namespace qt3ds { +namespace render { + template <> + struct SPointerTag<qt3ds::studio::SGraphObjectTranslator> + { + static QT3DSU32 GetTag() { return qt3ds::studio::g_GraphObjectTranslatorTag; } + }; +} +} + +namespace qt3ds { +namespace studio { + + typedef std::shared_ptr<qt3dsdm::ISignalConnection> TSignalConnection; + + struct STranslation; + + struct SGraphObjectTranslator + { + protected: + qt3dsdm::Qt3DSDMInstanceHandle m_InstanceHandle; + + public: + // This will never be null. The reason it is a pointer is because + // alias translators need to switch which graph object they point to + qt3dsdm::Qt3DSDMInstanceHandle m_AliasInstanceHandle; + SGraphObject *m_GraphObject; + QT3DSU32 m_DirtyIndex; + SGraphObjectTranslator(qt3dsdm::Qt3DSDMInstanceHandle inInstance, SGraphObject &inObj) + : m_InstanceHandle(inInstance) + , m_GraphObject(&inObj) + , m_DirtyIndex(QT3DS_MAX_U32) + { + m_GraphObject->m_UserData = qt3ds::render::STaggedPointer(this); + } + // The destructors will not be called at this time for most of the objects + // but they will be released. + virtual ~SGraphObjectTranslator() {} + // Push new data into the UIC render graph. + virtual void PushTranslation(STranslation &inTranslatorContext); + virtual void AfterRenderGraphIsBuilt(STranslation &) {} + virtual void SetActive(bool inActive) = 0; + virtual void ClearChildren() = 0; + virtual void AppendChild(SGraphObject &inChild) = 0; + virtual void ResetEffect() {} + virtual const QString GetError() { return {}; } + virtual void SetError(const QString &error) { Q_UNUSED(error); } + virtual SGraphObject &GetGraphObject() { return *m_GraphObject; } + virtual SGraphObject &GetNonAliasedGraphObject() { return *m_GraphObject; } + virtual qt3dsdm::Qt3DSDMInstanceHandle GetInstanceHandle() { return m_InstanceHandle; } + virtual qt3dsdm::Qt3DSDMInstanceHandle GetSceneGraphInstanceHandle() + { + return m_InstanceHandle; + } + virtual qt3dsdm::Qt3DSDMInstanceHandle GetPossiblyAliasedInstanceHandle() + { + if (m_AliasInstanceHandle.Valid()) + return m_AliasInstanceHandle; + return GetInstanceHandle(); + } + }; + + struct STranslatorGetDirty + { + QT3DSU32 operator()(const SGraphObjectTranslator &inTrans) const + { + return inTrans.m_DirtyIndex; + } + }; + struct STranslatorSetDirty + { + void operator()(SGraphObjectTranslator &inTrans, QT3DSU32 idx) const + { + inTrans.m_DirtyIndex = idx; + } + }; + + typedef InvasiveSet<SGraphObjectTranslator, STranslatorGetDirty, STranslatorSetDirty> + TTranslatorDirtySet; + + struct TranslationSelectMode + { + enum Enum { + Group = 0, + Single = 1, + NestedComponentSingle, + }; + }; + + struct EditCameraTypes + { + enum Enum { + SceneCamera = 0, + Perspective, + Orthographic, + Directional, + }; + }; + + const QT3DSF32 g_EditCameraFOV = 45.0f; + const QT3DSF32 g_RotationScaleFactor = 2.0f * QT3DSF32(M_PI) / 180.0f; + + struct SEditorCameraInformation + { + QT3DSVec3 m_Position; + QT3DSVec3 m_Direction; + QT3DSF32 m_ViewRadius; + EditCameraTypes::Enum m_CameraType; + NVReal m_xRotation = 0.0f; + NVReal m_yRotation = 0.0f; + SEditorCameraInformation() + : m_Position(0, 0, 0) + , m_Direction(0, 0, 0) + , m_ViewRadius(600) + , m_CameraType(EditCameraTypes::Perspective) + { + } + + void ApplyToCamera(SCamera &inCamera, QT3DSVec2 inViewport, bool noScale = false) + { + // Setup shared default values. + inCamera.m_ClipFar = 2000000.0f; + inCamera.m_ClipNear = 1.0f; + + // In orthographic view adjust near clipping based on zoom level + if (m_CameraType == EditCameraTypes::Orthographic) { + // This seems like a suitable math + inCamera.m_ClipNear = (100000 / m_ViewRadius) - (50 * m_ViewRadius); + } + + if (m_CameraType == EditCameraTypes::Perspective) { + inCamera.m_FOV = g_EditCameraFOV; + TORAD(inCamera.m_FOV); + inCamera.m_Flags.SetOrthographic(false); + } else { + inCamera.m_Flags.SetOrthographic(true); + } + + // The goal is to setup a global transform that + QT3DSMat44 thePivotMatrix = QT3DSMat44::createIdentity(); + thePivotMatrix.column3.x = m_Position.x; + thePivotMatrix.column3.y = m_Position.y; + thePivotMatrix.column3.z = m_Position.z; + QT3DSMat44 theGlobalTransform = thePivotMatrix; + + QT3DSVec3 theUpDir(0, 1, 0); + if (m_CameraType == EditCameraTypes::Directional) { + QT3DSF32 theTestLen = m_Direction.cross(theUpDir).magnitudeSquared(); + if (theTestLen < .01f) + theUpDir = QT3DSVec3(0, 0, 1) * m_Direction.dot(QT3DSVec3(0, 1, 0)); + theUpDir.normalize(); + } + + QT3DSMat33 theLookAtMatrix = inCamera.GetLookAtMatrix(theUpDir, m_Direction); + QT3DSMat44 theRotationTransform = + QT3DSMat44(theLookAtMatrix.column0, theLookAtMatrix.column1, + theLookAtMatrix.column2, QT3DSVec3(0, 0, 0)); + + if (m_CameraType != EditCameraTypes::Directional) { + theRotationTransform.rotate(-m_xRotation, QT3DSVec3(0.0f, 1.0f, 0.0f)); + theRotationTransform.rotate(m_yRotation, QT3DSVec3(1.0f, 0.0f, 0.0f)); + inCamera.m_Rotation = inCamera.GetRotationVectorFromRotationMatrix(theRotationTransform.getUpper3x3()); + } + + // The view radius dictates the zoom. + QT3DSF32 theZoom = 1.0f; + if (inCamera.m_Flags.IsOrthographic()) { + QT3DSF32 theViewport = qMin(inViewport.x, inViewport.y); + theZoom = (m_ViewRadius * 2.0f) / theViewport; + } else { + // We know the hypotenuse is 600. + // So if we want to zoom the scene, we do this. + theZoom = m_ViewRadius / (sinf(inCamera.m_FOV / 2.0f) * 600.f); + } + QT3DSMat44 theScaleMatrix = QT3DSMat44(QT3DSVec4(theZoom, theZoom, theZoom, 1)); + QT3DSMat44 thePositionMatrix = QT3DSMat44::createIdentity(); + thePositionMatrix.column3.x = m_Position.x; + thePositionMatrix.column3.y = m_Position.y; + thePositionMatrix.column3.z = m_Position.z + 600; + theGlobalTransform = theGlobalTransform * theRotationTransform; + if (!noScale) + theGlobalTransform = theGlobalTransform * theScaleMatrix; + theGlobalTransform = theGlobalTransform * thePivotMatrix.getInverse(); + theGlobalTransform = theGlobalTransform * thePositionMatrix; + // This works because the camera has no hierarchy. + inCamera.m_LocalTransform = theGlobalTransform; + inCamera.m_Flags.SetTransformDirty(false); + inCamera.MarkDirty(qt3ds::render::NodeTransformDirtyFlag::TransformNotDirty); + } + + bool IsOrthographic() const { return m_CameraType != EditCameraTypes::Perspective; } + + bool SupportsRotation() const { return m_CameraType != EditCameraTypes::Directional; } + }; + struct MovementTypes + { + enum Enum { + Unknown = 0, + Translate, + TranslateAlongCameraDirection, + Scale, + ScaleZ, + Rotation, + RotationAboutCameraDirection, + }; + }; + + struct SEditorLayerTranslator; + struct SZoomRender + { + CPt m_Point; + qt3ds::render::SLayer *m_Layer; + SZoomRender(CPt inPoint, qt3ds::render::SLayer *inLayer) + : m_Point(inPoint) + , m_Layer(inLayer) + { + } + SZoomRender() + : m_Layer(nullptr) + { + } + }; + + struct PickTargetAreas + { + enum Enum { + Presentation, + Matte, + }; + }; + + struct SRulerRect + { + QT3DSI32 m_Left; + QT3DSI32 m_Top; + QT3DSI32 m_Right; + QT3DSI32 m_Bottom; + SRulerRect() + : m_Left(0) + , m_Top(0) + , m_Right(0) + , m_Bottom(0) + { + } + SRulerRect(QT3DSI32 l, QT3DSI32 t, QT3DSI32 r, QT3DSI32 b) + : m_Left(l) + , m_Top(t) + , m_Right(r) + , m_Bottom(b) + { + } + + bool Contains(QT3DSI32 x, QT3DSI32 y) const + { + return x >= m_Left && x <= m_Right && y >= m_Bottom && y <= m_Top; + } + + bool isNull() const + { + return m_Left == 0 && m_Top == 0 && m_Right == 0 && m_Bottom == 0; + } + }; + + struct SDragPreparationResult + { + qt3ds::render::IQt3DSRenderer *m_Renderer; + SNode *m_Node; + SLayer *m_Layer; + SCamera *m_Camera; + qt3ds::render::NVPlane m_Plane; + QT3DSVec3 m_GlobalPos; + QT3DSVec3 m_CameraGlobalPos; + QT3DSVec3 m_CameraDirection; + QT3DSVec3 m_Axis; + QT3DSMat44 m_GlobalTransform; + QT3DSMat33 m_NormalMatrix; + QT3DSU32 m_AxisIndex; + qt3ds::widgets::StudioWidgetComponentIds::Enum m_ComponentId; + qt3ds::widgets::StudioWidgetTypes::Enum m_WidgetType; + qt3ds::render::RenderWidgetModes::Enum m_WidgetMode; + SRay m_OriginalRay; + SRay m_CurrentRay; + SRay m_PreviousRay; + Option<QT3DSVec3> m_OriginalPlaneCoords; + Option<QT3DSVec3> m_CurrentPlaneCoords; + Option<QT3DSVec3> m_PreviousPlaneCoords; + bool m_IsPlane; + bool m_isBehindCamera; + SDragPreparationResult() {} + }; + + struct SPathAnchorDragInitialValue + { + QT3DSVec2 m_Position; + float m_IncomingAngle; + float m_IncomingDistance; + float m_OutgoingDistance; + SPathAnchorDragInitialValue() {} + }; + + struct STranslation : public qt3ds::render::IQt3DSRenderNodeFilter + { + typedef eastl::pair<qt3dsdm::Qt3DSDMInstanceHandle, SGraphObjectTranslator *> + THandleTranslatorPair; + typedef eastl::vector<THandleTranslatorPair> THandleTranslatorPairList; + // Now that we have aliases, one instance handle can map to several translators. One + // translator, however, only + // maps to one instance handle. + typedef nvhash_map<qt3dsdm::Qt3DSDMInstanceHandle, THandleTranslatorPairList, eastl::hash<int>> + TInstanceToTranslatorMap; + IStudioRenderer &m_Renderer; + IQt3DSRenderContext &m_Context; + CDoc &m_Doc; + IDocumentReader &m_Reader; + SComposerObjectDefinitions &m_ObjectDefinitions; + qt3dsdm::CStudioSystem &m_StudioSystem; + qt3dsdm::CStudioFullSystem &m_FullSystem; + Q3DStudio::CGraph &m_AssetGraph; + + // allocator for scene graph and translators + qt3ds::foundation::SSAutoDeallocatorAllocator m_Allocator; + // All translator related containers must come after the allocator + TInstanceToTranslatorMap m_TranslatorMap; + TTranslatorDirtySet m_DirtySet; + qt3ds::render::SPresentation m_Presentation; + qt3ds::render::SScene *m_Scene; + Q3DStudio::CGraphIterator m_GraphIterator; + nvvector<TSignalConnection> m_SignalConnections; + QT3DSI32 m_ComponentTimeDepth; + SNode m_MouseDownNode; + SCamera m_MouseDownCamera; + Option<QT3DSMat44> m_MouseDownParentGlobalTransformInverse; + Option<QT3DSMat33> m_MouseDownParentRotationInverse; + Option<QT3DSMat33> m_MouseDownGlobalRotation; + QT3DSI32 m_KeyRepeat; + bool m_EditCameraEnabled; + bool m_EditLightEnabled; + bool m_helperGridEnabled = true; + bool m_axisHelperEnabled = true; + SEditorCameraInformation m_EditCameraInfo; + SCamera m_EditCamera; + SCamera m_AxisCamera; + SLight m_EditLight; + QT3DSVec2 m_Viewport; + SEditorLayerTranslator *m_EditCameraLayerTranslator; + SEditorLayerTranslator *m_AxisHelperLayerTranslator; + Option<SZoomRender> m_ZoomRender; + NVScopedRefCounted<qt3ds::widgets::IStudioWidget> m_TranslationWidget; + NVScopedRefCounted<qt3ds::widgets::IStudioWidget> m_AxisHelperWidget; + NVScopedRefCounted<qt3ds::widgets::IStudioWidget> m_RotationWidget; + NVScopedRefCounted<qt3ds::widgets::IStudioWidget> m_ScaleWidget; + NVScopedRefCounted<qt3ds::widgets::IStudioWidget> m_LastRenderedWidget; + NVScopedRefCounted<qt3ds::widgets::SGradientWidget> m_GradientWidget; + NVScopedRefCounted<qt3ds::widgets::SVisualAidWidget> m_VisualAidWidget; + NVScopedRefCounted<qt3ds::widgets::SHelperGridWidget> m_helperGridWidget; + + NVScopedRefCounted<qt3ds::widgets::IPathWidget> m_PathWidget; + NVScopedRefCounted<qt3ds::render::NVRenderTexture2D> m_PickBuffer; + Option<SPathAnchorDragInitialValue> m_LastPathDragValue; + nvvector<qt3ds::QT3DSU8> m_PixelBuffer; + nvvector<SGraphObjectTranslator *> m_editModeCamerasAndLights; + QT3DSF32 m_CumulativeRotation; + eastl::vector<qt3ds::render::SPGGraphObject *> m_GuideContainer; + qt3ds::foundation::SFastAllocator<> m_GuideAllocator; + // The rects are maintained from last render because the render context + // doesn't guarantee the rects it returns are valid outside of begin/end render calls. + SRulerRect m_OuterRect; + SRulerRect m_InnerRect; // presentation rect. + + QT3DSVec4 m_rectColor; + QT3DSVec4 m_lineColor; + QT3DSVec4 m_guideColor; + QT3DSVec4 m_selectedGuideColor; + QT3DSVec4 m_guideFillColor; + QT3DSVec4 m_selectedGuideFillColor; + + NVScopedRefCounted<qt3ds::render::NVRenderTexture2D> m_previewTexture; + NVScopedRefCounted<qt3ds::render::NVRenderFrameBuffer> m_previewFbo; + NVScopedRefCounted<qt3ds::render::NVRenderRenderBuffer> m_previewRenderBuffer; + QT3DSVec2 m_previewFboDimensions; + + STranslation(IStudioRenderer &inRenderer, IQt3DSRenderContext &inContext); + void MarkBeginComponentTime(qt3dsdm::Qt3DSDMSlideHandle) { ++m_ComponentTimeDepth; } + + void MarkComponentTime(qt3dsdm::Qt3DSDMSlideHandle) + { + m_ComponentTimeDepth = qMax(0, m_ComponentTimeDepth - 1); + if (m_ComponentTimeDepth == 0) + RequestRender(); + } + + void ReleaseTranslation(Q3DStudio::TIdentifier inInstance); + + void MarkGraphInstanceDirty(Q3DStudio::TIdentifier inInstance, + Q3DStudio::TIdentifier /*inParent*/) + { + MarkDirty(inInstance); + } + + void MarkDirty(qt3dsdm::Qt3DSDMInstanceHandle inInstance); + + void DoMarkDirty(qt3dsdm::Qt3DSDMInstanceHandle inInstance) {MarkDirty(inInstance);} + + void MarkDirty(qt3dsdm::Qt3DSDMInstanceHandle *inInstance, long inInstanceCount) + { + for (long idx = 0; idx < inInstanceCount; ++idx) + MarkDirty(inInstance[idx]); + } + + void DrawBoundingBox(SNode &inNode, QT3DSVec3 inColor); + + void DrawChildBoundingBoxes(SNode &inNode) + { + ::CColor color = CStudioPreferences::groupBoundingBoxColor(); + QT3DSVec3 colorVec(color.GetRed() / 255.f, + color.GetGreen() / 255.f, + color.GetBlue() / 255.f); + for (SNode *theChild = inNode.m_FirstChild; theChild; + theChild = theChild->m_NextSibling) { + if (IncludeNode(*theChild)) + DrawBoundingBox(*theChild, colorVec); + } + } + + void DrawGroupBoundingBoxes(SGraphObjectTranslator &inTranslator) + { + SNode &theNode = static_cast<SNode &>(inTranslator.GetGraphObject()); + if (theNode.m_FirstChild) { + ::CColor color = CStudioPreferences::groupBoundingBoxColor(); + QT3DSVec3 colorVec(color.GetRed() / 255.f, + color.GetGreen() / 255.f, + color.GetBlue() / 255.f); + DrawBoundingBox(theNode, colorVec); + if (inTranslator.GetGraphObject().m_Type != GraphObjectTypes::Layer) + DrawChildBoundingBoxes(theNode); + } + } + + void DrawNonGroupBoundingBoxes(SGraphObjectTranslator &inTranslator) + { + SNode &theNode = static_cast<SNode &>(inTranslator.GetGraphObject()); + if (inTranslator.GetGraphObject().m_Type != GraphObjectTypes::Layer) { + ::CColor color = CStudioPreferences::singleBoundingBoxColor(); + QT3DSVec3 colorVec(color.GetRed() / 255.f, + color.GetGreen() / 255.f, + color.GetBlue() / 255.f); + DrawBoundingBox(theNode, colorVec); + DrawChildBoundingBoxes(theNode); + } else { + ::CColor color = CStudioPreferences::singleBoundingBoxColor(); + QT3DSVec3 colorVec(color.GetRed() / 255.f, + color.GetGreen() / 255.f, + color.GetBlue() / 255.f); + m_Context.GetRenderer().RenderLayerRect( + static_cast<SLayer &>(inTranslator.GetGraphObject()), colorVec); + } + } + + void drawPivot(SGraphObjectTranslator &inTranslator); + + void SetViewport(QT3DSF32 inWidth, QT3DSF32 inHeight); + + QT3DSVec2 GetViewportDimensions() const { return m_Viewport; } + QT3DSVec2 GetPreviewViewportDimensions() const; + qt3ds::render::NVRenderRect GetPreviewViewport() const; + + void ClearDirtySet() + { + // The dirty set may be modified while this operation is taking place in the case of + // alias nodes. + for (qt3ds::QT3DSU32 idx = 0; idx < (qt3ds::QT3DSU32)m_DirtySet.size(); ++idx) { + if (m_Reader.IsInstance(m_DirtySet[idx]->GetInstanceHandle())) + m_DirtySet[idx]->PushTranslation(*this); + } + m_DirtySet.clear(); + } + // We build the render graph every time we render. This may seem wasteful + void BuildRenderGraph(qt3dsdm::Qt3DSDMInstanceHandle inParent, bool scenePreviewPass, + Qt3DSDMInstanceHandle inAliasHandle + = qt3dsdm::Qt3DSDMInstanceHandle()); + void BuildRenderGraph(SGraphObjectTranslator &inParent, bool scenePreviewPass, + qt3dsdm::Qt3DSDMInstanceHandle inAliasHandle + = qt3dsdm::Qt3DSDMInstanceHandle()); + void + DeactivateScan(SGraphObjectTranslator &inParent, + qt3dsdm::Qt3DSDMInstanceHandle inAliasHandle = qt3dsdm::Qt3DSDMInstanceHandle()); + void PreRender(bool scenePreviewPass); + void Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPass); + void EndRender(); + void DoPrepareForDrag(SNode *inSelectedNode); + void ResetWidgets(); + void EndDrag(); + bool IsPathWidgetActive(); + + void PrepareForDrag() { DoPrepareForDrag(GetSelectedNode()); } + + SStudioPickValue Pick(CPt inMouseCoords, TranslationSelectMode::Enum inSelectMode, + bool ignoreWidgets = false); + Option<QT3DSU32> PickWidget(CPt inMouseCoords, TranslationSelectMode::Enum inSelectMode, + qt3ds::widgets::IStudioWidgetBase &inWidget); + + qt3ds::foundation::Option<qt3dsdm::SGuideInfo> PickRulers(CPt inMouseCoords); + + SNode *GetSelectedNode() + { + qt3dsdm::Qt3DSDMInstanceHandle theHandle = m_Doc.GetSelectedInstance(); + SGraphObjectTranslator *theTranslator = GetOrCreateTranslator(theHandle); + if (theTranslator + && GraphObjectTypes::IsNodeType(theTranslator->GetGraphObject().m_Type)) + return static_cast<SNode *>(&theTranslator->GetGraphObject()); + return nullptr; + } + static inline SFloat3 ToDataModel(const QT3DSVec3 &inValue) + { + return SFloat3(inValue.x, inValue.y, inValue.z); + } + + static inline SFloat3 ToDataModelRotation(const QT3DSVec3 &inValue) + { + SFloat3 retval = ToDataModel(inValue); + TODEG(retval.m_Floats[0]); + TODEG(retval.m_Floats[1]); + TODEG(retval.m_Floats[2]); + return retval; + } + + void SetPosition(const QT3DSVec3 &inPosition, CUpdateableDocumentEditor &inEditor) + { + inEditor.EnsureEditor(QObject::tr("Set Position"), __FILE__, __LINE__) + .SetInstancePropertyValue(m_Doc.GetSelectedInstance(), + m_ObjectDefinitions.m_Node.m_Position, + ToDataModel(inPosition)); + inEditor.FireImmediateRefresh(m_Doc.GetSelectedInstance()); + } + void SetRotation(const QT3DSVec3 &inRotation, CUpdateableDocumentEditor &inEditor) + { + inEditor.EnsureEditor(QObject::tr("Set Rotation"), __FILE__, __LINE__) + .SetInstancePropertyValue(m_Doc.GetSelectedInstance(), + m_ObjectDefinitions.m_Node.m_Rotation, + ToDataModelRotation(inRotation)); + inEditor.FireImmediateRefresh(m_Doc.GetSelectedInstance()); + } + void SetScale(const QT3DSVec3 &inScale, CUpdateableDocumentEditor &inEditor) + { + inEditor.EnsureEditor(QObject::tr("Set Scale"), __FILE__, __LINE__) + .SetInstancePropertyValue(m_Doc.GetSelectedInstance(), + m_ObjectDefinitions.m_Node.m_Scale, ToDataModel(inScale)); + inEditor.FireImmediateRefresh(m_Doc.GetSelectedInstance()); + } + + QT3DSVec3 GetIntendedPosition(qt3dsdm::Qt3DSDMInstanceHandle inInstance, CPt inPos); + + void ApplyPositionalChange(QT3DSVec3 inDiff, SNode &inNode, + CUpdateableDocumentEditor &inEditor); + + void TranslateSelectedInstanceAlongCameraDirection(CPt inOriginalCoords, CPt inMouseCoords, + CUpdateableDocumentEditor &inEditor); + + void TranslateSelectedInstance(CPt inOriginalCoords, CPt inMouseCoords, + CUpdateableDocumentEditor &inEditor, bool inLockToAxis); + + void ScaleSelectedInstanceZ(CPt inOriginalCoords, CPt inMouseCoords, + CUpdateableDocumentEditor &inEditor); + + void ScaleSelectedInstance(CPt inOriginalCoords, CPt inMouseCoords, + CUpdateableDocumentEditor &inEditor); + + void CalculateNodeGlobalRotation(SNode &inNode); + + void ApplyRotationToSelectedInstance(const QT3DSQuat &inFinalRotation, SNode &inNode, + CUpdateableDocumentEditor &inEditor, + bool inIsMouseRelative = true); + + void RotateSelectedInstanceAboutCameraDirectionVector(CPt inPreviousMouseCoords, + CPt inMouseCoords, + CUpdateableDocumentEditor &inEditor); + + // This method never feels right to me. It is difficult to apply it to a single axis (of + // course for that + // you can use the inspector palette). + void RotateSelectedInstance(CPt inOriginalCoords, CPt inPreviousMouseCoords, + CPt inMouseCoords, CUpdateableDocumentEditor &inEditor, + bool inLockToAxis); + + Option<SDragPreparationResult> + PrepareWidgetDrag(qt3ds::widgets::StudioWidgetComponentIds::Enum inComponentId, + qt3ds::widgets::StudioWidgetTypes::Enum inWidgetId, + qt3ds::render::RenderWidgetModes::Enum inWidgetMode, SNode &inNode, + CPt inOriginalCoords, CPt inPreviousMouseCoords, CPt inMouseCoords); + + void PerformWidgetDrag(int inWidgetSubComponent, CPt inOriginalCoords, + CPt inPreviousMouseCoords, CPt inMouseCoords, + CUpdateableDocumentEditor &inEditor); + + void PerformGuideDrag(Qt3DSDMGuideHandle inGuide, CPt inPoint, + CUpdateableDocumentEditor &inEditor); + bool CheckGuideInPresentationRect(Qt3DSDMGuideHandle inGuide, + CUpdateableDocumentEditor &inEditor); + + void PerformPathDrag(qt3ds::studio::SPathPick &inPathPick, CPt inOriginalCoords, + CPt inPreviousMouseCoords, CPt inMouseCoords, + CUpdateableDocumentEditor &inEditor); + + void RequestRender() + { + if (m_ComponentTimeDepth == 0) + m_Renderer.RequestRender(); + } + + void RenderZoomRender(SZoomRender &inRender); + + // IQt3DSRenderNodeFilter + bool IncludeNode(const SNode &inNode) override; + + PickTargetAreas::Enum GetPickArea(CPt inPoint); + + SNode *GetEditCameraLayer(); + SNode *GetAxisHelperLayer(); + + void ReleaseEffect(qt3dsdm::Qt3DSDMInstanceHandle inInstance); + void releaseMaterial(qt3dsdm::Qt3DSDMInstanceHandle inInstance); + // Create a new translator for this type. Do not add to any maps or anything else. + SGraphObjectTranslator *CreateTranslator(qt3dsdm::Qt3DSDMInstanceHandle inInstance); + // Returns the canonical translator for a given instance or creates a new translator if none + // exist. + SGraphObjectTranslator *GetOrCreateTranslator(qt3dsdm::Qt3DSDMInstanceHandle inInstance); + // Create a new aliased translator for this type. + SGraphObjectTranslator *GetOrCreateTranslator(qt3dsdm::Qt3DSDMInstanceHandle inInstance, + qt3dsdm::Qt3DSDMInstanceHandle inAliasInstance); + THandleTranslatorPairList & + GetTranslatorsForInstance(qt3dsdm::Qt3DSDMInstanceHandle inInstance); + qt3dsdm::Qt3DSDMInstanceHandle GetAnchorPoint(SPathPick &inPick); + qt3dsdm::Qt3DSDMInstanceHandle GetAnchorPoint(QT3DSU32 inAnchorIndex); + + void updateHelperGridFromSettings(); + void updateAxisHelperFromSettings(); + }; + + struct SDisableUseClearColor + { + SGraphObjectTranslator *m_SceneTranslator; + bool m_PreviousUseClearColor; + bool m_DisableUseClearColor; + + SDisableUseClearColor(STranslation &inTranslation, bool disableUseClearColor) + : m_SceneTranslator(nullptr) + , m_PreviousUseClearColor(false) + , m_DisableUseClearColor(disableUseClearColor) + { + if (m_DisableUseClearColor) { + TIdentifier theRoot = inTranslation.m_AssetGraph.GetRoot(0); + m_SceneTranslator = inTranslation.GetOrCreateTranslator(theRoot); + if (m_SceneTranslator) { + SScene &theScene = static_cast<SScene &>(m_SceneTranslator->GetGraphObject()); + m_PreviousUseClearColor = theScene.m_UseClearColor; + SetUseClearColor(false); + } + } + } + + ~SDisableUseClearColor() + { + if (m_DisableUseClearColor) { + SetUseClearColor(m_PreviousUseClearColor); + } + } + + void SetUseClearColor(bool inUseClearColor) + { + if (m_SceneTranslator) { + SScene &theScene = static_cast<SScene &>(m_SceneTranslator->GetGraphObject()); + theScene.m_UseClearColor = inUseClearColor; + } + } + }; +} +} + +#endif |