Clean up use of transforms in scene graph.

This commit is contained in:
jmsgrogan 2023-01-19 17:37:26 +00:00
parent 3915a40c96
commit f26ee2ebc4
37 changed files with 238 additions and 242 deletions

View file

@ -7,6 +7,14 @@ class Transform
public: public:
Transform(const Point& location = {}, double scaleX = 1.0, double scaleY = 1.0, double scaleZ = 1.0); Transform(const Point& location = {}, double scaleX = 1.0, double scaleY = 1.0, double scaleZ = 1.0);
void applyPre(const Transform& transform)
{
mLocation.move(transform.getLocation().getX(), transform.getLocation().getY(), transform.getLocation().getZ());
mScaleX *= transform.getScaleX();
mScaleY *= transform.getScaleY();
mScaleZ *= transform.getScaleZ();
}
void setLocation(const Point& loc); void setLocation(const Point& loc);
void setScale(double scaleX, double scaleY = 1.0, double scaleZ = 1.0); void setScale(double scaleX, double scaleY = 1.0, double scaleZ = 1.0);

View file

@ -4,10 +4,11 @@
#include "AbstractMesh.h" #include "AbstractMesh.h"
#include "MeshPrimitives.h" #include "MeshPrimitives.h"
#include "SceneInfo.h" #include "SceneInfo.h"
#include "Circle.h" #include "Circle.h"
CircleNode::CircleNode(const Point& location, double radius) CircleNode::CircleNode(const Transform& transform, double radius)
: GeometryNode(location), : GeometryNode(transform),
mRadius(radius) mRadius(radius)
{ {
mMinorRadius = mRadius; mMinorRadius = mRadius;
@ -28,7 +29,7 @@ void CircleNode::setRadius(double radius)
if (mRadius != radius) if (mRadius != radius)
{ {
mRadius = radius; mRadius = radius;
mTransformIsDirty = true; mGeometryIsDirty = true;
} }
} }
@ -37,28 +38,47 @@ void CircleNode::setMinorRadius(double radius)
if (mMinorRadius != radius) if (mMinorRadius != radius)
{ {
mMinorRadius = radius; mMinorRadius = radius;
mTransformIsDirty = true; mGeometryIsDirty = true;
} }
} }
std::unique_ptr<AbstractGeometricItem> CircleNode::createGeometryPrimitive() const
{
auto circle = std::make_unique<Circle>(Point{ 0, 0 }, mRadius);
circle->setMinorRadius(mMinorRadius);
return circle;
}
std::unique_ptr<AbstractMesh> CircleNode::createMeshPrimitive() const
{
return MeshPrimitives::buildCircleAsTriMesh();
}
void CircleNode::createOrUpdateGeometry(SceneInfo* sceneInfo) void CircleNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
{ {
if (!mBackgroundItem)
{
if (sceneInfo->mSupportsGeometryPrimitives) if (sceneInfo->mSupportsGeometryPrimitives)
{ {
double unit_circle_radius = 0.5; mBackgroundItem = std::make_unique<SceneModel>(createGeometryPrimitive());
auto circle = std::make_unique<Circle>(Point{ 0, 0 }, unit_circle_radius);
circle->setMinorRadius(unit_circle_radius*mMinorRadius/mRadius);
mBackgroundItem = std::make_unique<SceneModel>(std::move(circle));
} }
else else
{ {
auto mesh = MeshPrimitives::buildCircleAsTriMesh(); mBackgroundItem = std::make_unique<SceneModel>(createMeshPrimitive());
mBackgroundItem = std::make_unique<SceneModel>(std::move(mesh)); mBackgroundItem->setMeshTransform(Transform({}, mRadius, mRadius));
} }
mBackgroundItem->setName(mName + "_Model"); mBackgroundItem->setName(mName + "_Model");
} }
else
void CircleNode::updateTransform() {
{ if (sceneInfo->mSupportsGeometryPrimitives)
mBackgroundItem->updateTransform({ mLocation, 2 * mRadius, 2 * mRadius }); {
mBackgroundItem->updateGeometry(createGeometryPrimitive());
}
else
{
mBackgroundItem->updateMesh(createMeshPrimitive());
mBackgroundItem->setMeshTransform(Transform({}, mRadius, mRadius));
}
}
} }

View file

@ -2,10 +2,13 @@
#include "GeometryNode.h" #include "GeometryNode.h"
class AbstractGeometricItem;
class AbstractMesh;
class CircleNode : public GeometryNode class CircleNode : public GeometryNode
{ {
public: public:
CircleNode(const Point& location, double radius); CircleNode(const Transform& transform, double radius);
Type getType() override; Type getType() override;
double getRadius() const; double getRadius() const;
@ -14,7 +17,9 @@ public:
void setRadius(double radius); void setRadius(double radius);
private: private:
void createOrUpdateGeometry(SceneInfo* sceneInfo) override; void createOrUpdateGeometry(SceneInfo* sceneInfo) override;
void updateTransform() override;
std::unique_ptr<AbstractGeometricItem> createGeometryPrimitive() const;
std::unique_ptr<AbstractMesh> createMeshPrimitive() const;
double mRadius{1.0}; double mRadius{1.0};
double mMinorRadius{ 1.0 }; double mMinorRadius{ 1.0 };

View file

@ -1,7 +1,9 @@
#include "LineNode.h" #include "LineNode.h"
LineNode::LineNode(const Point& location, const std::vector<Point>& points) #include "SceneModel.h"
: GeometryNode(location),
LineNode::LineNode(const Transform& transform, const std::vector<Point>& points)
: GeometryNode(transform),
mPoints(points) mPoints(points)
{ {
@ -21,8 +23,3 @@ void LineNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
} }
mBackgroundItem->setName(mName + "_Model"); mBackgroundItem->setName(mName + "_Model");
} }
void LineNode::updateTransform()
{
mBackgroundItem->updateTransform({ mLocation });
}

View file

@ -10,14 +10,12 @@
class LineNode : public GeometryNode class LineNode : public GeometryNode
{ {
public: public:
LineNode(const Point& location, const std::vector<Point>& points); LineNode(const Transform& transform, const std::vector<Point>& points);
Type getType(); Type getType();
private: private:
void createOrUpdateGeometry(SceneInfo* sceneInfo) override; void createOrUpdateGeometry(SceneInfo* sceneInfo) override;
void updateTransform() override;
std::vector<Point> mPoints; std::vector<Point> mPoints;
}; };

View file

@ -3,19 +3,21 @@
#include "Rectangle.h" #include "Rectangle.h"
#include "MeshPrimitives.h" #include "MeshPrimitives.h"
#include "SceneInfo.h"
RectangleNode::RectangleNode(const Point& loc, double width, double height) #include "SceneInfo.h"
: GeometryNode(loc), #include "SceneModel.h"
RectangleNode::RectangleNode(const Transform& transform, double width, double height)
: GeometryNode(transform),
mWidth(width), mWidth(width),
mHeight(height) mHeight(height)
{ {
} }
std::unique_ptr<RectangleNode> RectangleNode::Create(const Point& loc, double width, double height) std::unique_ptr<RectangleNode> RectangleNode::Create(const Transform& transform, double width, double height)
{ {
return std::make_unique<RectangleNode>(loc, width, height); return std::make_unique<RectangleNode>(transform, width, height);
} }
GeometryNode::Type RectangleNode::getType() GeometryNode::Type RectangleNode::getType()
@ -93,8 +95,3 @@ void RectangleNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
} }
} }
} }
void RectangleNode::updateTransform()
{
mBackgroundItem->updateTransform({ mLocation });
}

View file

@ -7,8 +7,8 @@
class RectangleNode : public GeometryNode class RectangleNode : public GeometryNode
{ {
public: public:
RectangleNode(const Point& loc, double width, double height); RectangleNode(const Transform& transform, double width, double height);
static std::unique_ptr<RectangleNode> Create(const Point& loc, double width, double height); static std::unique_ptr<RectangleNode> Create(const Transform& transform, double width, double height);
GeometryNode::Type getType() override; GeometryNode::Type getType() override;
@ -22,7 +22,6 @@ public:
private: private:
void createOrUpdateGeometry(SceneInfo* sceneInfo) override; void createOrUpdateGeometry(SceneInfo* sceneInfo) override;
void updateTransform() override;
double mWidth{1}; double mWidth{1};
double mHeight{1}; double mHeight{1};

View file

@ -1,15 +1,27 @@
#include "AbstractVisualNode.h" #include "AbstractVisualNode.h"
AbstractVisualNode::AbstractVisualNode(const Point& location, const std::string& name) AbstractVisualNode::AbstractVisualNode(const Transform& transform, const std::string& name)
: mLocation(location), : mTransform(transform),
mName(name) mName(name)
{ {
} }
AbstractVisualNode::~AbstractVisualNode()
{
}
SceneItem* AbstractVisualNode::getSceneItem(std::size_t idx) const SceneItem* AbstractVisualNode::getSceneItem(std::size_t idx) const
{ {
if (idx < mSceneItems.size())
{
return mSceneItems[idx].get(); return mSceneItems[idx].get();
}
else
{
return nullptr;
}
} }
std::size_t AbstractVisualNode::getNumSceneItems() const std::size_t AbstractVisualNode::getNumSceneItems() const
@ -22,11 +34,6 @@ void AbstractVisualNode::update(SceneInfo* sceneInfo)
} }
Image* AbstractVisualNode::getImage() const
{
return mImage.get();
}
void AbstractVisualNode::syncChildren(const std::vector<AbstractVisualNode*>& children) void AbstractVisualNode::syncChildren(const std::vector<AbstractVisualNode*>& children)
{ {
mChildren = children; mChildren = children;
@ -47,11 +54,6 @@ void AbstractVisualNode::setIsVisible(bool isVisible)
mIsVisible = isVisible; mIsVisible = isVisible;
} }
std::size_t AbstractVisualNode::getNumChildren() const
{
return mChildren.size();
}
void AbstractVisualNode::setName(const std::string& name) void AbstractVisualNode::setName(const std::string& name)
{ {
mName = name; mName = name;
@ -67,11 +69,16 @@ bool AbstractVisualNode::getIsVisible() const
return mIsVisible; return mIsVisible;
} }
void AbstractVisualNode::setLocation(const Point& loc) const Transform& AbstractVisualNode::getTransform() const
{ {
if (mLocation != loc) return mTransform;
}
void AbstractVisualNode::setTransform(const Transform& transform)
{
if (mTransform != transform)
{ {
mTransformIsDirty = true; mTransformIsDirty = true;
mLocation = loc; mTransform = transform;
} }
} }

View file

@ -1,23 +1,20 @@
#pragma once #pragma once
#include "SceneModel.h" #include "SceneItem.h"
#include "AbstractMesh.h" #include "Transform.h"
#include "Image.h"
#include "Point.h"
#include <memory> #include <memory>
#include <string>
#include <iostream> #include <vector>
struct SceneInfo; struct SceneInfo;
class AbstractVisualNode class AbstractVisualNode
{ {
public: public:
AbstractVisualNode(const Point& location, const std::string& name = {}); AbstractVisualNode(const Transform& transform = {}, const std::string& name = {});
virtual ~AbstractVisualNode() = default; virtual ~AbstractVisualNode();
void addChild(AbstractVisualNode* child); void addChild(AbstractVisualNode* child);
@ -25,30 +22,27 @@ public:
virtual std::size_t getNumSceneItems() const; virtual std::size_t getNumSceneItems() const;
std::size_t getNumChildren() const;
const std::vector<AbstractVisualNode*>& getChildren() const; const std::vector<AbstractVisualNode*>& getChildren() const;
const std::string& getName() const; const std::string& getName() const;
Image* getImage() const;
bool getIsVisible() const; bool getIsVisible() const;
const Transform& getTransform() const;
void syncChildren(const std::vector<AbstractVisualNode*>& children); void syncChildren(const std::vector<AbstractVisualNode*>& children);
void setIsVisible(bool isVisible); void setIsVisible(bool isVisible);
void setName(const std::string& name); void setName(const std::string& name);
virtual void setLocation(const Point& loc); virtual void setTransform(const Transform& transform);
virtual void update(SceneInfo* sceneInfo); virtual void update(SceneInfo* sceneInfo);
protected: protected:
Point mLocation; Transform mTransform;
std::vector<std::unique_ptr<SceneItem> > mSceneItems; std::vector<std::unique_ptr<SceneItem> > mSceneItems;
std::unique_ptr<Image> mImage;
std::vector<AbstractVisualNode*> mChildren; std::vector<AbstractVisualNode*> mChildren;

View file

@ -3,8 +3,8 @@
#include "SceneInfo.h" #include "SceneInfo.h"
#include "SceneModel.h" #include "SceneModel.h"
GeometryNode::GeometryNode(const Point& location) GeometryNode::GeometryNode(const Transform& transform)
: MaterialNode(location), : MaterialNode(transform),
mStrokeThickness(1.0), mStrokeThickness(1.0),
mType(Type::Path) mType(Type::Path)
{ {
@ -75,12 +75,6 @@ void GeometryNode::update(SceneInfo* sceneInfo)
mGeometryIsDirty = false; mGeometryIsDirty = false;
} }
if (mTransformIsDirty)
{
updateTransform();
mTransformIsDirty = false;
}
if (mMaterialIsDirty) if (mMaterialIsDirty)
{ {
updateMaterial(); updateMaterial();

View file

@ -18,7 +18,7 @@ public:
}; };
public: public:
GeometryNode(const Point& location); GeometryNode(const Transform& transform);
virtual ~GeometryNode(); virtual ~GeometryNode();
virtual Type getType() = 0; virtual Type getType() = 0;
@ -34,7 +34,6 @@ public:
protected: protected:
virtual void createOrUpdateGeometry(SceneInfo* sceneInfo) = 0; virtual void createOrUpdateGeometry(SceneInfo* sceneInfo) = 0;
virtual void updateMaterial(); virtual void updateMaterial();
virtual void updateTransform() = 0;
double mStrokeThickness{0}; double mStrokeThickness{0};
Type mType; Type mType;

View file

@ -1,9 +1,10 @@
#include "GridNode.h" #include "GridNode.h"
#include "MeshPrimitives.h" #include "MeshPrimitives.h"
#include "SceneModel.h"
GridNode::GridNode(const Point& location) GridNode::GridNode(const Transform& transform)
: MaterialNode(location) : MaterialNode(transform)
{ {
} }
@ -30,7 +31,7 @@ void GridNode::setWidth(double width)
{ {
if (mWidth != width) if (mWidth != width)
{ {
mTransformIsDirty = true; mGeometryIsDirty = true;
mWidth = width; mWidth = width;
} }
} }
@ -39,7 +40,7 @@ void GridNode::setHeight(double height)
{ {
if (mHeight != height) if (mHeight != height)
{ {
mTransformIsDirty = true; mGeometryIsDirty = true;
mHeight = height; mHeight = height;
} }
} }
@ -124,8 +125,8 @@ void GridNode::update(SceneInfo* sceneInfo)
{ {
auto size = mHeight > mWidth ? mWidth : mHeight; auto size = mHeight > mWidth ? mWidth : mHeight;
mBackgroundModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)}); //mBackgroundModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)});
mOutlineModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)}); //mOutlineModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)});
mTransformIsDirty = false; mTransformIsDirty = false;
} }

View file

@ -3,11 +3,12 @@
#include "MaterialNode.h" #include "MaterialNode.h"
#include "Color.h" #include "Color.h"
class SceneModel;
class GridNode : public MaterialNode class GridNode : public MaterialNode
{ {
public: public:
GridNode(const Point& location); GridNode(const Transform& transform);
void setNumX(std::size_t numX); void setNumX(std::size_t numX);
@ -28,7 +29,10 @@ private:
std::size_t mNumberY{5}; std::size_t mNumberY{5};
double mWidth{1}; double mWidth{1};
double mHeight{1}; double mHeight{1};
bool mDataDirty = true; bool mDataDirty = true;
bool mGeometryIsDirty = true;
std::vector<Color> mData; std::vector<Color> mData;
std::unique_ptr<SceneModel> mBackgroundModel; std::unique_ptr<SceneModel> mBackgroundModel;

View file

@ -1,9 +1,7 @@
#include "MaterialNode.h" #include "MaterialNode.h"
#include <iostream> MaterialNode::MaterialNode(const Transform& transform)
: AbstractVisualNode(transform),
MaterialNode::MaterialNode(const Point& location)
: AbstractVisualNode(location),
mFillColor(Color(255, 255, 255)), mFillColor(Color(255, 255, 255)),
mStrokeColor(Color(0, 0, 0)) mStrokeColor(Color(0, 0, 0))
{ {

View file

@ -7,7 +7,7 @@
class MaterialNode : public AbstractVisualNode class MaterialNode : public AbstractVisualNode
{ {
public: public:
MaterialNode(const Point& location); MaterialNode(const Transform& transform);
const Color& getFillColor() const; const Color& getFillColor() const;
const Color& getStrokeColor() const; const Color& getStrokeColor() const;

View file

@ -1,9 +1,10 @@
#include "MeshNode.h" #include "MeshNode.h"
#include <iostream> #include "SceneModel.h"
#include "AbstractMesh.h"
MeshNode::MeshNode(const Point& location) MeshNode::MeshNode(const Transform& transform)
: MaterialNode(location) : MaterialNode(transform)
{ {
} }
@ -69,7 +70,6 @@ void MeshNode::update(SceneInfo* sceneInfo)
if (mWorkingMesh && mMeshIsDirty) if (mWorkingMesh && mMeshIsDirty)
{ {
std::cout << "Updating mesh with " << mWorkingMesh->getNumNodes() << std::endl;
mModel->updateMesh(mWorkingMesh); mModel->updateMesh(mWorkingMesh);
mMeshIsDirty = false; mMeshIsDirty = false;
} }
@ -77,7 +77,7 @@ void MeshNode::update(SceneInfo* sceneInfo)
if (mTransformIsDirty) if (mTransformIsDirty)
{ {
auto size = mHeight > mWidth ? mWidth : mHeight; auto size = mHeight > mWidth ? mWidth : mHeight;
mModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)}); //mModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)});
mTransformIsDirty = false; mTransformIsDirty = false;
} }

View file

@ -2,12 +2,13 @@
#include "MaterialNode.h" #include "MaterialNode.h"
class SceneModel;
class AbstractMesh; class AbstractMesh;
class MeshNode : public MaterialNode class MeshNode : public MaterialNode
{ {
public: public:
MeshNode(const Point& location); MeshNode(const Transform& transform);
void setMesh(AbstractMesh* mesh); void setMesh(AbstractMesh* mesh);
SceneItem* getSceneItem(std::size_t idx) const override; SceneItem* getSceneItem(std::size_t idx) const override;

View file

@ -3,16 +3,18 @@
#include "Path.h" #include "Path.h"
#include "SceneInfo.h" #include "SceneInfo.h"
PathNode::PathNode(const Point& loc, const std::string& psPath) #include "SceneModel.h"
: GeometryNode(loc),
PathNode::PathNode(const Transform& transform, const std::string& psPath)
: GeometryNode(transform),
mPathString(psPath) mPathString(psPath)
{ {
} }
std::unique_ptr<PathNode> PathNode::Create(const Point& loc, const std::string& psPath) std::unique_ptr<PathNode> PathNode::Create(const Transform& transform, const std::string& psPath)
{ {
return std::make_unique<PathNode>(loc, psPath); return std::make_unique<PathNode>(transform, psPath);
} }
GeometryNode::Type PathNode::getType() GeometryNode::Type PathNode::getType()
@ -52,8 +54,3 @@ void PathNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
} }
} }
} }
void PathNode::updateTransform()
{
mBackgroundItem->updateTransform({ mLocation });
}

View file

@ -7,8 +7,8 @@
class PathNode : public GeometryNode class PathNode : public GeometryNode
{ {
public: public:
PathNode(const Point& loc, const std::string& psPath); PathNode(const Transform& transform, const std::string& psPath);
static std::unique_ptr<PathNode> Create(const Point& loc, const std::string& psPath); static std::unique_ptr<PathNode> Create(const Transform& transform, const std::string& psPath);
GeometryNode::Type getType() override; GeometryNode::Type getType() override;
@ -18,7 +18,6 @@ public:
private: private:
void createOrUpdateGeometry(SceneInfo* sceneInfo) override; void createOrUpdateGeometry(SceneInfo* sceneInfo) override;
void updateTransform() override;
std::string mPathString; std::string mPathString;
}; };

View file

@ -6,7 +6,7 @@ class RootNode : public AbstractVisualNode
{ {
public: public:
RootNode() RootNode()
: AbstractVisualNode(DiscretePoint(0, 0)) : AbstractVisualNode(Transform())
{ {
} }

View file

@ -14,10 +14,8 @@
#include "StringUtils.h" #include "StringUtils.h"
#include <iostream> TextNode::TextNode(const std::string& content, const Transform& transform)
: MaterialNode(transform)
TextNode::TextNode(const std::string& content, const Point& loc)
: MaterialNode(loc)
{ {
mTextData.mContent= content; mTextData.mContent= content;
} }
@ -27,9 +25,9 @@ TextNode::~TextNode()
} }
std::unique_ptr<TextNode> TextNode::Create(const std::string& content, const Point& loc) std::unique_ptr<TextNode> TextNode::Create(const std::string& content, const Transform& transform)
{ {
return std::make_unique<TextNode>(content, loc); return std::make_unique<TextNode>(content, transform);
} }
std::string TextNode::getFontLabel() const std::string TextNode::getFontLabel() const
@ -168,10 +166,10 @@ void TextNode::update(SceneInfo* sceneInfo)
if (mTransformIsDirty) if (mTransformIsDirty)
{ {
mTextItem->updateTransform({mLocation}); //mTextItem->updateTransform({mLocation});
mTextItem->setTextWidth(mWidth); //mTextItem->setTextWidth(mWidth);
mTextItem->setTextHeight(mHeight); //mTextItem->setTextHeight(mHeight);
mTransformIsDirty = false; //mTransformIsDirty = false;
} }
if (mMaterialIsDirty) if (mMaterialIsDirty)

View file

@ -15,11 +15,11 @@ class FontsManager;
class TextNode : public MaterialNode class TextNode : public MaterialNode
{ {
public: public:
TextNode(const std::string& content, const Point& loc); TextNode(const std::string& content, const Transform& transform);
~TextNode(); ~TextNode();
static std::unique_ptr<TextNode> Create(const std::string& content, const Point& loc); static std::unique_ptr<TextNode> Create(const std::string& content, const Transform& transform);
std::string getContent() const; std::string getContent() const;
std::string getFontLabel() const; std::string getFontLabel() const;

View file

@ -7,7 +7,7 @@ class TransformNode : public AbstractVisualNode
public: public:
TransformNode() TransformNode()
: AbstractVisualNode(DiscretePoint(0, 0)) : AbstractVisualNode(Transform())
{ {
} }

View file

@ -19,12 +19,6 @@ Scene::~Scene()
} }
void Scene::update()
{
mSceneItems.clear();
updateNode(mRootNode.get());
}
void Scene::addNode(AbstractVisualNode* node) void Scene::addNode(AbstractVisualNode* node)
{ {
mRootNode->addChild(node); mRootNode->addChild(node);
@ -32,7 +26,7 @@ void Scene::addNode(AbstractVisualNode* node)
bool Scene::isEmpty() const bool Scene::isEmpty() const
{ {
return mRootNode->getNumChildren() == 0; return mRootNode->getChildren().empty();
} }
const Color& Scene::getBackgroundColor() const const Color& Scene::getBackgroundColor() const
@ -45,15 +39,24 @@ void Scene::setBackgroundColor(const Color& color)
mBackGroundColor = color; mBackGroundColor = color;
} }
void Scene::updateNode(AbstractVisualNode* node) void Scene::update()
{
mSceneItems.clear();
updateNode(mRootNode.get(), Transform());
}
void Scene::updateNode(AbstractVisualNode* node, const Transform& transform)
{ {
node->update(mSceneInfo.get()); node->update(mSceneInfo.get());
auto node_transform = node->getTransform();
node_transform.applyPre(transform);
for (auto child : node->getChildren()) for (auto child : node->getChildren())
{ {
if (child->getIsVisible()) if (child->getIsVisible())
{ {
updateNode(child); updateNode(child, node_transform);
} }
} }
@ -61,6 +64,7 @@ void Scene::updateNode(AbstractVisualNode* node)
{ {
if (auto item = node->getSceneItem(idx)) if (auto item = node->getSceneItem(idx))
{ {
item->updateTransform(node_transform);
mSceneItems.push_back(item); mSceneItems.push_back(item);
} }
} }

View file

@ -3,6 +3,7 @@
#include "TextData.h" #include "TextData.h"
#include "SceneInfo.h" #include "SceneInfo.h"
#include "Color.h" #include "Color.h"
#include "Transform.h"
#include <vector> #include <vector>
#include <memory> #include <memory>
@ -38,7 +39,7 @@ public:
void update(); void update();
private: private:
void updateNode(AbstractVisualNode* node); void updateNode(AbstractVisualNode* node, const Transform& transform);
Color mBackGroundColor; Color mBackGroundColor;
std::unique_ptr<RootNode> mRootNode; std::unique_ptr<RootNode> mRootNode;

View file

@ -55,6 +55,15 @@ void SceneModel::updateMesh(std::unique_ptr<AbstractMesh> mesh)
mGeometryIsDirty = true; mGeometryIsDirty = true;
} }
void SceneModel::setMeshTransform(const Transform& transform)
{
if (mMeshTransform != transform)
{
mMeshTransform = transform;
mGeometryIsDirty = true;
}
}
void SceneModel::updateGeometry(std::unique_ptr<AbstractGeometricItem> geometry) void SceneModel::updateGeometry(std::unique_ptr<AbstractGeometricItem> geometry)
{ {
mGeometry = std::move(geometry); mGeometry = std::move(geometry);

View file

@ -23,6 +23,7 @@ public:
bool getShowOutline() const; bool getShowOutline() const;
Type getType() const override; Type getType() const override;
void setMeshTransform(const Transform& transform);
void setShowOutline(bool showOutline); void setShowOutline(bool showOutline);
void updateGeometry(std::unique_ptr<AbstractGeometricItem> geometry); void updateGeometry(std::unique_ptr<AbstractGeometricItem> geometry);
@ -32,6 +33,8 @@ public:
private: private:
AbstractMesh* mRawMesh{nullptr}; AbstractMesh* mRawMesh{nullptr};
std::unique_ptr<AbstractMesh> mMesh; std::unique_ptr<AbstractMesh> mMesh;
Transform mMeshTransform;
std::unique_ptr<Texture> mColorMap; std::unique_ptr<Texture> mColorMap;
std::unique_ptr<AbstractGeometricItem> mGeometry; std::unique_ptr<AbstractGeometricItem> mGeometry;

View file

@ -6,8 +6,8 @@
#include "SvgElement.h" #include "SvgElement.h"
#include "SvgShapeElements.h" #include "SvgShapeElements.h"
SvgNode::SvgNode(const Point& location) SvgNode::SvgNode(const Transform& transform)
: MaterialNode(location) : MaterialNode(transform)
{ {
} }
@ -21,27 +21,14 @@ void SvgNode::setContent(std::unique_ptr<SvgDocument> doc)
mGeometryNodes.clear(); mGeometryNodes.clear();
} }
void SvgNode::setWidth(unsigned width) unsigned SvgNode::getContentWidth() const
{ {
if (mWidth != width) return mContentWidth;
{
mWidth = width;
mTransformIsDirty = true;
}
} }
void SvgNode::setHeight(unsigned height) unsigned SvgNode::getContentHeight() const
{ {
if (mHeight != height) return mContentHeight;
{
mHeight = height;
mTransformIsDirty = true;
}
}
void SvgNode::updateTransform()
{
} }
void SvgNode::createOrUpdateGeometry(SceneInfo* sceneInfo) void SvgNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
@ -72,8 +59,12 @@ void SvgNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
raw_node = geom_node.get(); raw_node = geom_node.get();
mGeometryNodes.push_back(std::move(geom_node)); mGeometryNodes.push_back(std::move(geom_node));
} }
if (raw_node)
{
addChild(raw_node); addChild(raw_node);
} }
}
} }
void SvgNode::update(SceneInfo* sceneInfo) void SvgNode::update(SceneInfo* sceneInfo)
@ -84,12 +75,6 @@ void SvgNode::update(SceneInfo* sceneInfo)
mContentDirty = false; mContentDirty = false;
} }
if (mTransformIsDirty)
{
updateTransform();
mTransformIsDirty = false;
}
if (mMaterialIsDirty) if (mMaterialIsDirty)
{ {
if (mHasFillColor) if (mHasFillColor)

View file

@ -10,26 +10,25 @@
class SvgNode : public MaterialNode class SvgNode : public MaterialNode
{ {
public: public:
SvgNode(const Point& location); SvgNode(const Transform& transform);
unsigned getContentWidth() const;
unsigned getContentHeight() const;
void setContent(std::unique_ptr<SvgDocument> doc); void setContent(std::unique_ptr<SvgDocument> doc);
void setWidth(unsigned width);
void setHeight(unsigned height);
void update(SceneInfo* sceneInfo); void update(SceneInfo* sceneInfo);
private: private:
void createOrUpdateGeometry(SceneInfo* sceneInfo); void createOrUpdateGeometry(SceneInfo* sceneInfo);
void updateTransform();
void onCircle(XmlElement* element, std::unique_ptr<GeometryNode>& node); void onCircle(XmlElement* element, std::unique_ptr<GeometryNode>& node);
void onPath(XmlElement* element, std::unique_ptr<GeometryNode>& node); void onPath(XmlElement* element, std::unique_ptr<GeometryNode>& node);
unsigned mWidth{ 0 };
unsigned mHeight{ 0 };
bool mContentDirty{ true }; bool mContentDirty{ true };
unsigned mContentWidth{ 1 };
unsigned mContentHeight{ 1 };
std::vector<std::unique_ptr<GeometryNode> > mGeometryNodes; std::vector<std::unique_ptr<GeometryNode> > mGeometryNodes;
std::unique_ptr<SvgDocument> mContent; std::unique_ptr<SvgDocument> mContent;
}; };

View file

@ -203,9 +203,14 @@ bool Button::isDirty() const
void Button::doPaint(const PaintEvent* event) void Button::doPaint(const PaintEvent* event)
{ {
if (mTransformDirty)
{
mRootNode->setTransform(Transform(mLocation));
mTransformDirty = false;
}
updateBackground(event); updateBackground(event);
updateLabel(event); updateLabel(event);
updateIcon(event); updateIcon(event);
mContentDirty = false; mContentDirty = false;
@ -215,17 +220,12 @@ void Button::updateLabel(const PaintEvent* event)
{ {
if (!mTextNode) if (!mTextNode)
{ {
mTextNode = TextNode::Create(mLabel, mLocation); mTextNode = TextNode::Create(mLabel, Transform({ mSize.mWidth /2.0, mSize.mHeight / 2.0 }));
mTextNode->setName(mName + "_TextNode"); mTextNode->setName(mName + "_TextNode");
mTextNode->setContent(mLabel); mTextNode->setContent(mLabel);
mRootNode->addChild(mTextNode.get());
}
if (mTransformDirty)
{
mTextNode->setLocation(mLocation);
mTextNode->setWidth(mSize.mWidth); mTextNode->setWidth(mSize.mWidth);
mTextNode->setHeight(mSize.mHeight); mTextNode->setHeight(mSize.mHeight);
mRootNode->addChild(mTextNode.get());
} }
if (mMaterialDirty) if (mMaterialDirty)
@ -255,14 +255,14 @@ void Button::updateIcon(const PaintEvent* event)
{ {
if (!mIconNode && mIcon != Resource::Icon::Svg::NONE) if (!mIconNode && mIcon != Resource::Icon::Svg::NONE)
{ {
mIconNode = std::make_unique<IconNode>(mLocation); mIconNode = std::make_unique<IconNode>(Transform());
mIconNode->setName(mName + "_IconNode"); mIconNode->setName(mName + "_IconNode");
mIconNode->setContent(IconNode::IconType::Svg, MediaResourceManager::getSvgIconNode(mIcon)); mIconNode->setSvgContent(MediaResourceManager::getSvgIconNode(mIcon));
mRootNode->addChild(mIconNode.get()); mRootNode->addChild(mIconNode.get());
} }
else if (mContentDirty && mIcon != Resource::Icon::Svg::NONE) else if (mContentDirty && mIcon != Resource::Icon::Svg::NONE)
{ {
mIconNode->setContent(IconNode::IconType::Svg, MediaResourceManager::getSvgIconNode(mIcon)); mIconNode->setSvgContent(MediaResourceManager::getSvgIconNode(mIcon));
} }
if (!mIconNode) if (!mIconNode)
@ -270,11 +270,6 @@ void Button::updateIcon(const PaintEvent* event)
return; return;
} }
if (mTransformDirty)
{
mIconNode->setLocation(mLocation);
}
if (mMaterialDirty) if (mMaterialDirty)
{ {
auto icon_fill = event->getThemesManager()->getColor(mIconColor); auto icon_fill = event->getThemesManager()->getColor(mIconColor);

View file

@ -46,7 +46,7 @@ void Label::updateLabel(const PaintEvent* event)
if (!mTextNode) if (!mTextNode)
{ {
mTextNode = TextNode::Create(mLabel, middle); mTextNode = TextNode::Create(mLabel, Transform());
mTextNode->setWidth(mSize.mWidth); mTextNode->setWidth(mSize.mWidth);
mTextNode->setHeight(mSize.mHeight); mTextNode->setHeight(mSize.mHeight);
mRootNode->addChild(mTextNode.get()); mRootNode->addChild(mTextNode.get());
@ -57,13 +57,6 @@ void Label::updateLabel(const PaintEvent* event)
mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground)); mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground));
} }
if (mTransformDirty)
{
mTextNode->setLocation(middle);
mTextNode->setWidth(mSize.mWidth);
mTextNode->setHeight(mSize.mHeight);
}
if (mContentDirty) if (mContentDirty)
{ {
mTextNode->setContent(mLabel); mTextNode->setContent(mLabel);

View file

@ -86,11 +86,9 @@ void TextBox::doPaint(const PaintEvent* event)
void TextBox::updateLabel(const PaintEvent* event) void TextBox::updateLabel(const PaintEvent* event)
{ {
auto loc = DiscretePoint(mLocation.getX() + mPadding.mLeft, mLocation.getY() + mPadding.mTop + unsigned(0));
if (!mTextNode) if (!mTextNode)
{ {
mTextNode = TextNode::Create(mContent, loc); mTextNode = TextNode::Create(mContent, Transform());
mTextNode->setWidth(mSize.mWidth); mTextNode->setWidth(mSize.mWidth);
mTextNode->setHeight(mSize.mHeight); mTextNode->setHeight(mSize.mHeight);
mRootNode->addChild(mTextNode.get()); mRootNode->addChild(mTextNode.get());
@ -103,7 +101,6 @@ void TextBox::updateLabel(const PaintEvent* event)
if (mTransformDirty) if (mTransformDirty)
{ {
mTextNode->setLocation(loc);
mTextNode->setWidth(mSize.mWidth); mTextNode->setWidth(mSize.mWidth);
mTextNode->setHeight(mSize.mHeight); mTextNode->setHeight(mSize.mHeight);
} }

View file

@ -2,12 +2,22 @@
#include "SvgNode.h" #include "SvgNode.h"
IconNode::IconNode(const Point& loc) IconNode::IconNode(const Transform& transform)
: AbstractVisualNode(loc) : AbstractVisualNode(transform)
{ {
} }
unsigned IconNode::getContentWidth() const
{
return mSvgContent->getContentWidth();
}
unsigned IconNode::getContentHeight() const
{
return mSvgContent->getContentHeight();
}
void IconNode::setSvgContent(std::unique_ptr<SvgNode> svg_node) void IconNode::setSvgContent(std::unique_ptr<SvgNode> svg_node)
{ {
mChildren.clear(); mChildren.clear();
@ -29,27 +39,10 @@ void IconNode::setFillColor(const Color& color)
} }
} }
void IconNode::setWidth(unsigned width)
{
if (mType == IconType::Svg)
{
mSvgContent->setWidth(width);
}
}
void IconNode::setHeight(unsigned height)
{
if (mType == IconType::Svg)
{
mSvgContent->setFillColor(height);
mSvgContent->setHasStrokeColor(false);
}
}
void IconNode::setOutlineColor(const Color& color) void IconNode::setOutlineColor(const Color& color)
{ {
if (mType == IconType::Svg) if (mType == IconType::Svg)
{ {
dynamic_cast<SvgNode*>(mContent.get())->setStrokeColor(color); mSvgContent->setStrokeColor(color);
} }
} }

View file

@ -14,13 +14,11 @@ public:
Svg Svg
}; };
IconNode(const Point& loc); IconNode(const Transform& transform = {});
void setLocation(const Point& loc) override; unsigned getContentWidth() const;
void setWidth(unsigned width); unsigned getContentHeight() const;
void setHeight(unsigned height);
void setFillColor(const Color& color); void setFillColor(const Color& color);

View file

@ -11,7 +11,7 @@ Path MediaResourceManager::getSvgIconPath(Resource::Icon::Svg icon)
return mResourceLocation / MediaResources::getPath(icon); return mResourceLocation / MediaResources::getPath(icon);
} }
std::unique_ptr<AbstractVisualNode> MediaResourceManager::getSvgIconNode(Resource::Icon::Svg icon) std::unique_ptr<SvgNode> MediaResourceManager::getSvgIconNode(Resource::Icon::Svg icon)
{ {
const auto path = getSvgIconPath(icon); const auto path = getSvgIconPath(icon);

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "MediaResources.h" #include "MediaResources.h"
#include "AbstractVisualNode.h" #include "SvgNode.h"
#include <filesystem> #include <filesystem>
@ -10,7 +10,7 @@ using Path = std::filesystem::path;
class MediaResourceManager class MediaResourceManager
{ {
public: public:
static std::unique_ptr<AbstractVisualNode> getSvgIconNode(Resource::Icon::Svg icon); static std::unique_ptr<SvgNode> getSvgIconNode(Resource::Icon::Svg icon);
static Path getSvgIconPath(Resource::Icon::Svg icon); static Path getSvgIconPath(Resource::Icon::Svg icon);

View file

@ -317,9 +317,9 @@ void Widget::createOrUpdateGeometry()
const auto deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom; const auto deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
if (!mBackgroundNode) if (!mBackgroundNode)
{ {
const auto locX = mLocation.getX() + mMargin.mLeft; Point margin_offset(mMargin.mLeft, mMargin.mTop);
const auto locY = mLocation.getY() + mMargin.mTop;
mBackgroundNode = std::make_unique<RectangleNode>(DiscretePoint(locX, locY), deltaX, deltaY); mBackgroundNode = std::make_unique<RectangleNode>(Transform(margin_offset), deltaX, deltaY);
mBackgroundNode->setRadius(mRadius); mBackgroundNode->setRadius(mRadius);
mBackgroundNode->setName(mName + "_BackgroundNode"); mBackgroundNode->setName(mName + "_BackgroundNode");
@ -335,9 +335,7 @@ void Widget::createOrUpdateGeometry()
void Widget::updateTransform() void Widget::updateTransform()
{ {
const auto locX = mLocation.getX() + mMargin.mLeft; mRootNode->setTransform({ mLocation });
const auto locY = mLocation.getY() + mMargin.mTop;
mBackgroundNode->setLocation(DiscretePoint(locX, locY));
} }
void Widget::updateMaterial(const PaintEvent* event) void Widget::updateMaterial(const PaintEvent* event)
@ -401,25 +399,30 @@ mt::Window* Widget::getTopLevelWindow() const
return mWindow; return mWindow;
} }
std::cout << "I am " << getName() << std::endl;
auto lastParent = mParent; auto lastParent = mParent;
auto nextParent = mParent; auto nextParent = mParent;
while(nextParent) while(nextParent)
{ {
auto temp = lastParent;
lastParent = nextParent; lastParent = nextParent;
nextParent = lastParent->getParent(); nextParent = temp->getParent();
std::cout << "Checking if " << lastParent->getName() << std::endl;
if (nextParent) if (nextParent)
{ {
std::cout << "Next is " << nextParent->getName() << std::endl; //std::cout << "Next is " << nextParent->getName() << std::endl;
} }
else else
{ {
std::cout << "no next" << std::endl; //std::cout << "no next" << std::endl;
} }
} }
if (lastParent)
{
return lastParent->getTopLevelWindow(); return lastParent->getTopLevelWindow();
}
else
{
return nullptr;
}
} }
Widget* Widget::getParent() const Widget* Widget::getParent() const