From 492b99b008e677cee28181f88e756f3fb7481b24 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Tue, 7 Nov 2017 00:41:27 -0500 Subject: [PATCH 1/7] Transparent object markers --- apps/opencs/model/prefs/state.cpp | 1 + apps/opencs/view/render/object.cpp | 38 +++++++++++++++++++++++++----- apps/opencs/view/render/object.hpp | 7 ++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 1f84c5a87..2a40c4e18 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -191,6 +191,7 @@ void CSMPrefs::State::declare() setTooltip ("Acceleration factor during drag operations while holding down shift"). setRange (0.001, 100.0); declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); + declareDouble ("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0,1); declareCategory ("Tooltips"); declareBool ("scene", "Show Tooltips in 3D scenes", true); diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 522057097..d725f5dc9 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -285,15 +286,15 @@ osg::ref_ptr CSVRender::Object::makeMoveOrScaleMarker (int axis) for (int i=0; i<8; ++i) colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f, - axis==2 ? 1.0f : 0.2f, 1.0f)); + axis==2 ? 1.0f : 0.2f, mMarkerTransparency)); for (int i=8; i<8+4+1; ++i) colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.0f, axis==1 ? 1.0f : 0.0f, - axis==2 ? 1.0f : 0.0f, 1.0f)); + axis==2 ? 1.0f : 0.0f, mMarkerTransparency)); geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); - geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF); + setupCommonMarkerState(geometry); osg::ref_ptr geode (new osg::Geode); geode->addDrawable (geometry); @@ -350,7 +351,11 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) vertices->at(index++) = getMarkerPosition(outerX, outerY, -MarkerShaftWidth / 2, axis); } - colors->at(0) = osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f, axis==2 ? 1.0f : 0.2f, 1.0f); + colors->at(0) = osg::Vec4f ( + axis==0 ? 1.0f : 0.2f, + axis==1 ? 1.0f : 0.2f, + axis==2 ? 1.0f : 0.2f, + mMarkerTransparency); for (size_t i = 0; i < SegmentCount; ++i) { @@ -374,7 +379,7 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) geometry->setColorArray(colors, osg::Array::BIND_OVERALL); geometry->addPrimitiveSet(primitives); - geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF); + setupCommonMarkerState(geometry); osg::ref_ptr geode = new osg::Geode(); geode->addDrawable (geometry); @@ -382,6 +387,21 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) return geode; } +void CSVRender::Object::setupCommonMarkerState(osg::ref_ptr geometry) +{ + const int RenderBin = osg::StateSet::TRANSPARENT_BIN - 1; + + osg::ref_ptr state = geometry->getOrCreateStateSet(); + state->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + state->setMode(GL_BLEND, osg::StateAttribute::ON); + + osg::ref_ptr depth(new osg::Depth); + depth->setWriteMask(false); + state->setAttributeAndModes(depth, osg::StateAttribute::ON); + + state->setRenderBinDetails(RenderBin, "RenderBin"); +} + osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int axis) { switch (axis) @@ -399,7 +419,7 @@ osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode, const std::string& id, bool referenceable, bool forceBaseToZero) : mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero), - mScaleOverride (1), mOverrideFlags (0), mSubMode (-1) + mScaleOverride (1), mOverrideFlags (0), mSubMode (-1), mMarkerTransparency(0.5f) { mRootNode = new osg::PositionAttitudeTransform; @@ -629,6 +649,12 @@ void CSVRender::Object::setScale (float scale) adjustTransform(); } +void CSVRender::Object::setMarkerTransparency(float value) +{ + mMarkerTransparency = value; + updateMarker(); +} + void CSVRender::Object::apply (CSMWorld::CommandMacro& commands) { const CSMWorld::RefCollection& collection = mData.getReferences(); diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index e14697e62..3e54093d3 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -96,6 +97,7 @@ namespace CSVRender int mOverrideFlags; osg::ref_ptr mMarker[3]; int mSubMode; + float mMarkerTransparency; /// Not implemented Object (const Object&); @@ -121,6 +123,9 @@ namespace CSVRender osg::ref_ptr makeMoveOrScaleMarker (int axis); osg::ref_ptr makeRotateMarker (int axis); + /// Sets up a stateset with properties common to all marker types. + void setupCommonMarkerState(osg::ref_ptr geometry); + osg::Vec3f getMarkerPosition (float x, float y, float z, int axis); public: @@ -179,6 +184,8 @@ namespace CSVRender /// Set override scale void setScale (float scale); + void setMarkerTransparency(float value); + /// Apply override changes via command and end edit mode void apply (CSMWorld::CommandMacro& commands); From 197ea9564663006100606b74f9c87a499a7a6ba4 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Thu, 9 Nov 2017 13:04:46 -0500 Subject: [PATCH 2/7] Prevent arrows for move/scale markers from intersecting. --- apps/opencs/view/render/object.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index d725f5dc9..0ed7830f3 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -221,7 +221,7 @@ osg::ref_ptr CSVRender::Object::makeMoveOrScaleMarker (int axis) for (int i=0; i<2; ++i) { - float length = i ? shaftLength : 0; + float length = i ? shaftLength : MarkerShaftWidth; vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis)); vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis)); From de214db8d46c97349fa81d01bd3489ac04d5ae51 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Thu, 9 Nov 2017 13:45:32 -0500 Subject: [PATCH 3/7] Use configured transparency. --- apps/opencs/view/render/object.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 0ed7830f3..a3ecbadeb 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -22,6 +22,7 @@ #include "../../model/world/universalid.hpp" #include "../../model/world/commandmacro.hpp" #include "../../model/world/cellcoordinates.hpp" +#include "../../model/prefs/state.hpp" #include #include @@ -473,6 +474,7 @@ void CSVRender::Object::setSelected(bool selected) else mRootNode->addChild(mBaseNode); + mMarkerTransparency = CSMPrefs::get()["3D Scene Input"]["object-marker-alpha"].toDouble(); updateMarker(); } From 556117f6e6b6e51d89cc0681abcb45bbaed3497b Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Fri, 10 Nov 2017 01:56:06 -0500 Subject: [PATCH 4/7] Update marker transparency when changed. --- apps/opencs/view/render/worldspacewidget.cpp | 14 ++++++++++++++ apps/opencs/view/render/worldspacewidget.hpp | 1 + 2 files changed, 15 insertions(+) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 325fa5f6d..a80a61a79 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -51,6 +51,7 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg , mToolTipPos (-1, -1) , mShowToolTips(false) , mToolTipDelay(0) + , mInConstructor(true) { setAcceptDrops(true); @@ -114,6 +115,8 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg CSMPrefs::Shortcut* abortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this); connect(abortShortcut, SIGNAL(activated()), this, SLOT(abortDrag())); + + mInConstructor = false; } CSVRender::WorldspaceWidget::~WorldspaceWidget () @@ -128,6 +131,17 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti mDragWheelFactor = setting->toDouble(); else if (*setting=="3D Scene Input/drag-shift-factor") mDragShiftFactor = setting->toDouble(); + else if (*setting=="3D Scene Input/object-marker-alpha" && !mInConstructor) + { + float alpha = setting->toDouble(); + // getSelection is virtual, thus this can not be called from the constructor + auto selection = getSelection(Mask_Reference); + for (osg::ref_ptr tag : selection) + { + if (auto objTag = dynamic_cast(tag.get())) + objTag->mObject->setMarkerTransparency(alpha); + } + } else if (*setting=="Tooltips/scene-delay") mToolTipDelay = setting->toInt(); else if (*setting=="Tooltips/scene") diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 08b97e1be..9160ca47e 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -65,6 +65,7 @@ namespace CSVRender QPoint mToolTipPos; bool mShowToolTips; int mToolTipDelay; + bool mInConstructor; public: From 1cd539bad2724df2815ad6df0ed37e3fa29c1ee2 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Fri, 10 Nov 2017 02:06:06 -0500 Subject: [PATCH 5/7] Fix render order for markers --- apps/opencs/view/render/object.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index a3ecbadeb..c5da094e6 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -390,7 +390,7 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) void CSVRender::Object::setupCommonMarkerState(osg::ref_ptr geometry) { - const int RenderBin = osg::StateSet::TRANSPARENT_BIN - 1; + const int RenderBin = osg::StateSet::TRANSPARENT_BIN; osg::ref_ptr state = geometry->getOrCreateStateSet(); state->setMode(GL_LIGHTING, osg::StateAttribute::OFF); From c8f79ea8382797ef47b8eb3989a1afaeb58f884a Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sat, 25 Nov 2017 20:46:14 -0500 Subject: [PATCH 6/7] Adjust rotation markers --- apps/opencs/view/render/object.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index c5da094e6..2e9f03719 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -307,11 +307,11 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) { const float Pi = 3.14159265f; - const float InnerRadius = mBaseNode->getBound().radius(); + const float InnerRadius = std::max(MarkerShaftBaseLength, mBaseNode->getBound().radius()); const float OuterRadius = InnerRadius + MarkerShaftWidth; const float SegmentDistance = 100.f; - const size_t SegmentCount = std::min(64, std::max(8, (int)(OuterRadius * 2 * Pi / SegmentDistance))); + const size_t SegmentCount = std::min(64, std::max(24, (int)(OuterRadius * 2 * Pi / SegmentDistance))); const size_t VerticesPerSegment = 4; const size_t IndicesPerSegment = 24; From eb23367175b28cb07fe5f9449d54b05aed4f5533 Mon Sep 17 00:00:00 2001 From: Kyle Cooley Date: Sun, 26 Nov 2017 17:39:57 -0500 Subject: [PATCH 7/7] Fix rendering depth/order issues --- apps/opencs/view/render/object.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 2e9f03719..df7283b1a 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -336,6 +336,9 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) osg::ref_ptr primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, IndexCount); + // prevent some depth collision issues from overlaps + osg::Vec3f offset = getMarkerPosition(0, MarkerShaftWidth/4, 0, axis); + for (size_t i = 0; i < SegmentCount; ++i) { size_t index = i * VerticesPerSegment; @@ -346,10 +349,10 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) float outerX = OuterRadius * std::cos(i * Angle); float outerY = OuterRadius * std::sin(i * Angle); - vertices->at(index++) = getMarkerPosition(innerX, innerY, MarkerShaftWidth / 2, axis); - vertices->at(index++) = getMarkerPosition(innerX, innerY, -MarkerShaftWidth / 2, axis); - vertices->at(index++) = getMarkerPosition(outerX, outerY, MarkerShaftWidth / 2, axis); - vertices->at(index++) = getMarkerPosition(outerX, outerY, -MarkerShaftWidth / 2, axis); + vertices->at(index++) = getMarkerPosition(innerX, innerY, MarkerShaftWidth / 2, axis) + offset; + vertices->at(index++) = getMarkerPosition(innerX, innerY, -MarkerShaftWidth / 2, axis) + offset; + vertices->at(index++) = getMarkerPosition(outerX, outerY, MarkerShaftWidth / 2, axis) + offset; + vertices->at(index++) = getMarkerPosition(outerX, outerY, -MarkerShaftWidth / 2, axis) + offset; } colors->at(0) = osg::Vec4f ( @@ -390,17 +393,11 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) void CSVRender::Object::setupCommonMarkerState(osg::ref_ptr geometry) { - const int RenderBin = osg::StateSet::TRANSPARENT_BIN; - osg::ref_ptr state = geometry->getOrCreateStateSet(); state->setMode(GL_LIGHTING, osg::StateAttribute::OFF); state->setMode(GL_BLEND, osg::StateAttribute::ON); - osg::ref_ptr depth(new osg::Depth); - depth->setWriteMask(false); - state->setAttributeAndModes(depth, osg::StateAttribute::ON); - - state->setRenderBinDetails(RenderBin, "RenderBin"); + state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int axis)