diff --git a/src/entities/LabelComponent.cpp b/src/entities/LabelComponent.cpp index 7bf431b8..97cbe010 100644 --- a/src/entities/LabelComponent.cpp +++ b/src/entities/LabelComponent.cpp @@ -9,7 +9,6 @@ #include "entities/Entity.h" #include "common/SpdLogger.h" -#include "scutcheon/osgScutcheon.h" LabelComponent::LabelComponent(SceneComponent* parent) : SceneComponent(parent) diff --git a/src/entities/TrajectoryTraceComponent.cpp b/src/entities/TrajectoryTraceComponent.cpp index f4b0296b..4b8195d0 100644 --- a/src/entities/TrajectoryTraceComponent.cpp +++ b/src/entities/TrajectoryTraceComponent.cpp @@ -1,6 +1,7 @@ #include "entities/TrajectoryTraceComponent.h" #include +#include #include #include @@ -210,11 +211,8 @@ double TrajectoryTraceComponent::GetMinMoveDistance() const { void TrajectoryTraceComponent::SetMaxPoints(int maxPoints) { maxPoints_ = std::max(2, maxPoints); if (vertices_.valid() && static_cast(vertices_->size()) > maxPoints_) { - const int overflow = static_cast(vertices_->size()) - maxPoints_; - vertices_->erase(vertices_->begin(), vertices_->begin() + overflow); - drawArrays_->setCount(static_cast(vertices_->size())); - vertices_->dirty(); - geometry_->dirtyBound(); + TrimOverflowPoints(); + DirtyGeometry(); } } @@ -271,6 +269,7 @@ double TrajectoryTraceComponent::GetGapLength() const { void TrajectoryTraceComponent::SetDashScrollSpeed(double speed) { dashScrollSpeed_ = speed; + DirtyGeometry(); } double TrajectoryTraceComponent::GetDashScrollSpeed() const { @@ -281,16 +280,9 @@ void TrajectoryTraceComponent::ClearTrace() { InitializeGeometry(); vertices_->clear(); + renderVertices_->clear(); sampleTimes_.clear(); - drawArrays_->setCount(0); - vertices_->dirty(); - geometry_->dirtyBound(); - if (geode_.valid()) { - geode_->dirtyBound(); - } - if (mt_.valid()) { - mt_->dirtyBound(); - } + DirtyGeometry(); } void TrajectoryTraceComponent::InitializeGeometry() { @@ -302,15 +294,15 @@ void TrajectoryTraceComponent::InitializeGeometry() { geode_ = new osg::Geode; geometry_ = new osg::Geometry; vertices_ = new osg::Vec3Array; + renderVertices_ = new osg::Vec3Array; colors_ = new osg::Vec4Array; drawArrays_ = new osg::DrawArrays(GL_LINE_STRIP, 0, 0); lineWidthState_ = new osg::LineWidth(lineWidth_); - lineStippleState_ = new osg::LineStipple(1, 0xFFFF); geometry_->setDataVariance(osg::Object::DYNAMIC); geometry_->setUseDisplayList(false); geometry_->setUseVertexBufferObjects(true); - geometry_->setVertexArray(vertices_.get()); + geometry_->setVertexArray(renderVertices_.get()); geometry_->addPrimitiveSet(drawArrays_.get()); colors_->push_back(color_); @@ -323,7 +315,6 @@ void TrajectoryTraceComponent::InitializeGeometry() { stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); stateSet->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 0.0, 1.0, false)); stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - stateSet->setAttributeAndModes(lineStippleState_.get(), osg::StateAttribute::OFF); geode_->addDrawable(geometry_.get()); mt_->addChild(geode_.get()); @@ -349,23 +340,8 @@ bool TrajectoryTraceComponent::AppendPoint(const osg::Vec3d& geoPoint) { vertices_->push_back(worldPoint); sampleTimes_.push_back(elapsedTime_); - if (static_cast(vertices_->size()) > maxPoints_) { - const int overflow = static_cast(vertices_->size()) - maxPoints_; - vertices_->erase(vertices_->begin(), vertices_->begin() + overflow); - for (int i = 0; i < overflow && !sampleTimes_.empty(); ++i) { - sampleTimes_.pop_front(); - } - } - - drawArrays_->setCount(static_cast(vertices_->size())); - vertices_->dirty(); - geometry_->dirtyBound(); - if (geode_.valid()) { - geode_->dirtyBound(); - } - if (mt_.valid()) { - mt_->dirtyBound(); - } + TrimOverflowPoints(); + DirtyGeometry(); if (attachedToScene_ && mt_->getNumParents() == 0) { AttachTraceToScene(); @@ -389,15 +365,7 @@ bool TrajectoryTraceComponent::UpdateTailPoint(const osg::Vec3d& geoPoint) { if (!sampleTimes_.empty()) { sampleTimes_.back() = elapsedTime_; } - drawArrays_->setCount(static_cast(vertices_->size())); - vertices_->dirty(); - geometry_->dirtyBound(); - if (geode_.valid()) { - geode_->dirtyBound(); - } - if (mt_.valid()) { - mt_->dirtyBound(); - } + DirtyGeometry(); if (attachedToScene_ && mt_->getNumParents() == 0) { AttachTraceToScene(); @@ -463,15 +431,7 @@ void TrajectoryTraceComponent::TrimExpiredPoints() { } if (removed) { - drawArrays_->setCount(static_cast(vertices_->size())); - vertices_->dirty(); - geometry_->dirtyBound(); - if (geode_.valid()) { - geode_->dirtyBound(); - } - if (mt_.valid()) { - mt_->dirtyBound(); - } + DirtyGeometry(); } } @@ -487,34 +447,100 @@ void TrajectoryTraceComponent::UpdateStyle() { lineWidthState_->setWidth(lineWidth_); } - if (lineStippleState_.valid() && geode_.valid()) { - const double cycle = std::max(1.0, dashLength_ + gapLength_); - double factorValue = cycle / std::max(1.0f, lineWidth_); - if (factorValue < 1.0) { - factorValue = 1.0; - } else if (factorValue > 255.0) { - factorValue = 255.0; - } - int factor = static_cast(factorValue); - int onBits = static_cast(std::round(16.0 * dashLength_ / cycle)); - if (onBits < 1) { - onBits = 1; - } else if (onBits > 15) { - onBits = 15; - } - unsigned short pattern = 0; - for (int i = 0; i < 16; ++i) { - if (i < onBits) { - pattern |= static_cast(1u << i); - } - } - if (!dashed_) { - pattern = 0xFFFF; - geode_->getOrCreateStateSet()->setAttributeAndModes(lineStippleState_.get(), osg::StateAttribute::OFF); - } else { - geode_->getOrCreateStateSet()->setAttributeAndModes(lineStippleState_.get(), osg::StateAttribute::ON); - } - lineStippleState_->setFactor(factor); - lineStippleState_->setPattern(pattern); + DirtyGeometry(); +} + +void TrajectoryTraceComponent::DirtyGeometry() { + if (!geometry_.valid() || !drawArrays_.valid() || !renderVertices_.valid()) { + return; + } + + RebuildRenderGeometry(); + renderVertices_->dirty(); + geometry_->dirtyBound(); + if (geode_.valid()) { + geode_->dirtyBound(); + } + if (mt_.valid()) { + mt_->dirtyBound(); } } + +void TrajectoryTraceComponent::TrimOverflowPoints() { + if (!vertices_.valid()) { + return; + } + + if (static_cast(vertices_->size()) <= maxPoints_) { + return; + } + + const int overflow = static_cast(vertices_->size()) - maxPoints_; + vertices_->erase(vertices_->begin(), vertices_->begin() + overflow); + for (int i = 0; i < overflow && !sampleTimes_.empty(); ++i) { + sampleTimes_.pop_front(); + } +} + +void TrajectoryTraceComponent::RebuildRenderGeometry() { + if (!renderVertices_.valid()) { + return; + } + + renderVertices_->clear(); + if (!vertices_.valid() || vertices_->empty()) { + drawArrays_->setMode(GL_LINE_STRIP); + drawArrays_->setCount(0); + return; + } + + if (!dashed_ || vertices_->size() < 2) { + drawArrays_->setMode(GL_LINE_STRIP); + renderVertices_->assign(vertices_->begin(), vertices_->end()); + drawArrays_->setCount(static_cast(renderVertices_->size())); + return; + } + + drawArrays_->setMode(GL_LINES); + + const double cycle = std::max(0.001, dashLength_ + gapLength_); + double dashOffset = std::fmod(elapsedTime_ * dashScrollSpeed_, cycle); + if (dashOffset < 0.0) { + dashOffset += cycle; + } + + double accumulatedDistance = 0.0; + for (std::size_t i = 1; i < vertices_->size(); ++i) { + const osg::Vec3d& start = (*vertices_)[i - 1]; + const osg::Vec3d& end = (*vertices_)[i]; + const osg::Vec3d segment = end - start; + const double segmentLength = segment.length(); + if (segmentLength <= 1e-6) { + continue; + } + + const osg::Vec3d direction = segment / segmentLength; + double localDistance = 0.0; + while (localDistance < segmentLength) { + double phase = std::fmod(accumulatedDistance + localDistance + dashOffset, cycle); + if (phase < 0.0) { + phase += cycle; + } + + if (phase < dashLength_) { + const double visibleLength = std::min(dashLength_ - phase, segmentLength - localDistance); + const osg::Vec3d visibleStart = start + direction * localDistance; + const osg::Vec3d visibleEnd = start + direction * (localDistance + visibleLength); + renderVertices_->push_back(visibleStart); + renderVertices_->push_back(visibleEnd); + localDistance += visibleLength; + } else { + localDistance += std::min(cycle - phase, segmentLength - localDistance); + } + } + + accumulatedDistance += segmentLength; + } + + drawArrays_->setCount(static_cast(renderVertices_->size())); +} diff --git a/src/entities/TrajectoryTraceComponent.h b/src/entities/TrajectoryTraceComponent.h index 58b22cc9..d7753acb 100644 --- a/src/entities/TrajectoryTraceComponent.h +++ b/src/entities/TrajectoryTraceComponent.h @@ -3,7 +3,6 @@ #include "entities/SceneComponent.h" #include -#include #include #include #include @@ -71,15 +70,18 @@ private: void AttachTraceToScene(); void TrimExpiredPoints(); void UpdateStyle(); + void DirtyGeometry(); + void TrimOverflowPoints(); + void RebuildRenderGeometry(); private: osg::ref_ptr geode_; osg::ref_ptr geometry_; osg::ref_ptr vertices_; + osg::ref_ptr renderVertices_; osg::ref_ptr colors_; osg::ref_ptr drawArrays_; osg::ref_ptr lineWidthState_; - osg::ref_ptr lineStippleState_; osg::Vec4 color_{1.0f, 0.8f, 0.1f, 1.0f}; float lineWidth_{2.0f}; diff --git a/src/ui/PropertyBrowser/qtworkspaceattribute.cpp b/src/ui/PropertyBrowser/qtworkspaceattribute.cpp index 6c5e6f79..b98713ff 100644 --- a/src/ui/PropertyBrowser/qtworkspaceattribute.cpp +++ b/src/ui/PropertyBrowser/qtworkspaceattribute.cpp @@ -483,7 +483,8 @@ void QTrajectoryTraceComponentAttribute::SetColor(const QColor& c) { } OsgUtils::QColorToVec4(c, &vColor); - object_->SetColor(vColor); + const std::string value = StringUtils::Vec4ToString(vColor); + object_->SetAttribute("color", value.c_str()); } QColor QTrajectoryTraceComponentAttribute::GetColor() const { @@ -502,7 +503,8 @@ void QTrajectoryTraceComponentAttribute::SetLineWidth(double width) { return; } - object_->SetLineWidth(static_cast(width)); + const std::string value = std::to_string(width); + object_->SetAttribute("lineWidth", value.c_str()); } double QTrajectoryTraceComponentAttribute::GetLineWidth() const { @@ -518,7 +520,8 @@ void QTrajectoryTraceComponentAttribute::SetSampleInterval(double interval) { return; } - object_->SetSampleInterval(interval); + const std::string value = std::to_string(interval); + object_->SetAttribute("sampleInterval", value.c_str()); } double QTrajectoryTraceComponentAttribute::GetSampleInterval() const { @@ -534,7 +537,8 @@ void QTrajectoryTraceComponentAttribute::SetMinMoveDistance(double distance) { return; } - object_->SetMinMoveDistance(distance); + const std::string value = std::to_string(distance); + object_->SetAttribute("minMoveDistance", value.c_str()); } double QTrajectoryTraceComponentAttribute::GetMinMoveDistance() const { @@ -550,7 +554,8 @@ void QTrajectoryTraceComponentAttribute::SetMaxPoints(int maxPoints) { return; } - object_->SetMaxPoints(maxPoints); + const std::string value = std::to_string(maxPoints); + object_->SetAttribute("maxPoints", value.c_str()); } int QTrajectoryTraceComponentAttribute::GetMaxPoints() const { @@ -566,7 +571,8 @@ void QTrajectoryTraceComponentAttribute::SetTailDuration(double duration) { return; } - object_->SetTailDuration(duration); + const std::string value = std::to_string(duration); + object_->SetAttribute("tailDuration", value.c_str()); } double QTrajectoryTraceComponentAttribute::GetTailDuration() const { @@ -582,7 +588,7 @@ void QTrajectoryTraceComponentAttribute::SetVisible(bool visible) { return; } - object_->SetTraceVisible(visible); + object_->SetAttribute("visible", visible ? "true" : "false"); } bool QTrajectoryTraceComponentAttribute::IsVisible() const { @@ -598,7 +604,7 @@ void QTrajectoryTraceComponentAttribute::SetDashed(bool dashed) { return; } - object_->SetDashed(dashed); + object_->SetAttribute("dashed", dashed ? "true" : "false"); } bool QTrajectoryTraceComponentAttribute::IsDashed() const { @@ -614,7 +620,8 @@ void QTrajectoryTraceComponentAttribute::SetDashLength(double length) { return; } - object_->SetDashLength(length); + const std::string value = std::to_string(length); + object_->SetAttribute("dashLength", value.c_str()); } double QTrajectoryTraceComponentAttribute::GetDashLength() const { @@ -630,7 +637,8 @@ void QTrajectoryTraceComponentAttribute::SetGapLength(double length) { return; } - object_->SetGapLength(length); + const std::string value = std::to_string(length); + object_->SetAttribute("gapLength", value.c_str()); } double QTrajectoryTraceComponentAttribute::GetGapLength() const { @@ -646,7 +654,8 @@ void QTrajectoryTraceComponentAttribute::SetDashScrollSpeed(double speed) { return; } - object_->SetDashScrollSpeed(speed); + const std::string value = std::to_string(speed); + object_->SetAttribute("dashScrollSpeed", value.c_str()); } double QTrajectoryTraceComponentAttribute::GetDashScrollSpeed() const { diff --git a/src/viewer/OsgWidget.cpp b/src/viewer/OsgWidget.cpp index 45983ea3..58fec6b2 100644 --- a/src/viewer/OsgWidget.cpp +++ b/src/viewer/OsgWidget.cpp @@ -23,7 +23,6 @@ #include "scene/OEScene.h" #include "workspace/WorkSpaceManager.h" #include "workspace/WorkSpace.h" -#include "scutcheon/osgScutcheon.h" #include "workspace/PresetModelConfigParser.h" #include "entities/EntitiesManager.h"