#include "entities/PathComponent.h" #include #include #include #include "common/SpdLogger.h" #include "common/RecourceHelper.h" #include "utils/TransformPath.h" #include "utils/OsgUtils.h" #include "utils/FileUtils.h" #include "entities/Entity.h" #include "workspace/WorkSpace.h" #include "workspace/Timestep.h" PathComponent::PathComponent(SceneComponent* parent) : SceneComponent(parent) { animationPath_ = new osg::AnimationPath(); animationPath_->setLoopMode(osg::AnimationPath::SWING); } PathComponent::~PathComponent() { } std::string PathComponent::GetTypeName() { return "PathComponent"; } bool PathComponent::SetAttribute(const char* name, const char* value) { if (0 == strcmp(name, "path")) { SetPath(value); return nullptr != transformPath_; } return SceneComponent::SetAttribute(name, value); } bool PathComponent::SaveAttribute(tinyxml2::XMLElement* element) { element->SetAttribute("path", path_.toStdString().c_str()); return SceneComponent::SaveAttribute(element); } void PathComponent::Begin() { WorkSpace* workspace = GetEntity()->GetWorkspace(); if (nullptr == workspace) { LOG_WARN("workspace is nullptr"); return; } timeStep_ = workspace->GetTimestep(); if (nullptr == timeStep_) { LOG_WARN("timeStep is nullptr"); return; } if (nullptr == transformPath_) { LOG_WARN("transformPath_ is nullptr"); return; } animationPath_->clear(); const std::vector& steps = timeStep_->GetSteps(); const std::vector& transforms = transformPath_->GetTransforms(); int num = std::min(steps.size(), transforms.size()); for (int index = 0; index < num; ++index) { const Transform& transform = transforms[index]; osg::AnimationPath::ControlPoint controlPoint(transform.GetLocation() /*+ osg::Vec3(index * 10, 0, 0)*/, OsgUtils::HPRToQuat(transform.GetRotation() + osg::Vec3(0, 0, -90.0)), transform.GetScale()); animationPath_->insert(steps[index], controlPoint); } /* osg::ref_ptr apcb = new osg::AnimationPathCallback; apcb->setAnimationPath(animationPath_); osg::MatrixTransform* mt = GetRootComponent()->GetMatrixTransform(); if (nullptr == mt) { LOG_WARN("mt is nullptr"); return; } mt->setUpdateCallback(apcb); */ deltaTime_ = 0; } void PathComponent::Update(double dt) { deltaTime_ += dt; if (nullptr == timeStep_) { return; } double st = timeStep_->GetCurrent(); osg::AnimationPath::ControlPoint cp; if (!animationPath_->getInterpolatedControlPoint(st, cp)) { return; } Transform* transform = owner_->GetTransform(); transform->SetLocation(cp.getPosition()); osg::Vec3 angle; OsgUtils::QuatToHPR(cp.getRotation(), &angle); transform->SetRotation(angle); // transform->SetScale(cp.getScale()); } void PathComponent::SetPath(const QString& path) { if (path == path_ || path.isEmpty()) { LOG_INFO("path is the same, file:{}", path.toLocal8Bit().constData()); return; } if (nullptr != transformPath_) { transformPath_->deleteLater(); } const QString workPath = GetEntity()->GetWorkspace()->GetDir(); const QString filePath = QString("%1/%2").arg(workPath).arg(path); transformPath_ = TransformPath::LoadFromFile(filePath, this); path_ = path; } const QString& PathComponent::GetPath() const { return path_; }