Skip to content

Commit

Permalink
Refactor SceneEl from meshimporter into their own hpp+cpp files (#802)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkewley committed Nov 16, 2023
1 parent a6ed1fc commit 1af36f8
Show file tree
Hide file tree
Showing 8 changed files with 301 additions and 235 deletions.
5 changes: 4 additions & 1 deletion src/OpenSimCreator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@ add_library(OpenSimCreator STATIC

ModelGraph/CrossrefDescriptor.hpp
ModelGraph/CrossrefDirection.hpp
ModelGraph/ISceneElLookup.hpp
ModelGraph/ModelGraphIDs.cpp
ModelGraph/ModelGraphIDs.hpp
ModelGraph/ModelGraphStrings.hpp
ModelGraph/SceneEl.cpp
ModelGraph/SceneEl.hpp
ModelGraph/SceneElClass.hpp
ModelGraph/SceneElFlags.hpp
ModelGraph/SceneElVariant.hpp
Expand Down Expand Up @@ -234,7 +237,7 @@ add_library(OpenSimCreator STATIC
Utils/TPS3D.hpp
Utils/UndoableModelActions.cpp
Utils/UndoableModelActions.hpp
"ModelGraph/ModelGraphIDs.cpp")
"ModelGraph/ModelGraphIDs.cpp" "ModelGraph/SceneEl.cpp")

# OpenSimCreatorConfig.hpp
#
Expand Down
2 changes: 1 addition & 1 deletion src/OpenSimCreator/ModelGraph/CrossrefDescriptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ namespace osc
CStringView m_Label;
CrossrefDirection m_Direction;
};
}
}
2 changes: 1 addition & 1 deletion src/OpenSimCreator/ModelGraph/CrossrefDirection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ namespace osc
{
return (osc::to_underlying(lhs) & osc::to_underlying(rhs)) != 0;
}
}
}
27 changes: 27 additions & 0 deletions src/OpenSimCreator/ModelGraph/ISceneElLookup.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <oscar/Utils/UID.hpp>

namespace osc
{
// virtual interface to something that can be used to lookup scene elements in
// some larger document
class SceneEl;
class ISceneElLookup {
protected:
ISceneElLookup() = default;
ISceneElLookup(ISceneElLookup const&) = default;
ISceneElLookup(ISceneElLookup&&) noexcept = default;
ISceneElLookup& operator=(ISceneElLookup const&) = default;
ISceneElLookup& operator=(ISceneElLookup&&) noexcept = default;
public:
virtual ~ISceneElLookup() noexcept = default;

SceneEl const* find(UID id) const
{
return implFind(id);
}
private:
virtual SceneEl const* implFind(UID) const = 0;
};
}
30 changes: 30 additions & 0 deletions src/OpenSimCreator/ModelGraph/SceneEl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "SceneEl.hpp"

#include <oscar/Maths/MathHelpers.hpp>

#include <algorithm>

void osc::SceneEl::applyRotation(
ISceneElLookup const& lookup,
Vec3 const& eulerAngles,
Vec3 const& rotationCenter)
{
Transform t = getXForm(lookup);
ApplyWorldspaceRotation(t, eulerAngles, rotationCenter);
setXform(lookup, t);
}

bool osc::SceneEl::isCrossReferencing(
UID id,
CrossrefDirection direction) const
{
auto const crossRefs = implGetCrossReferences();
return std::any_of(
crossRefs.begin(),
crossRefs.end(),
[id, direction](CrossrefDescriptor const& desc)
{
return desc.getConnecteeID() == id && (desc.getDirection() & direction);
}
);
}
230 changes: 230 additions & 0 deletions src/OpenSimCreator/ModelGraph/SceneEl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
#pragma once

#include <OpenSimCreator/ModelGraph/CrossrefDescriptor.hpp>
#include <OpenSimCreator/ModelGraph/CrossrefDirection.hpp>
#include <OpenSimCreator/ModelGraph/SceneElFlags.hpp>
#include <OpenSimCreator/ModelGraph/SceneElVariant.hpp>

#include <oscar/Maths/AABB.hpp>
#include <oscar/Maths/Transform.hpp>
#include <oscar/Maths/Quat.hpp>
#include <oscar/Maths/Vec3.hpp>
#include <oscar/Utils/CStringView.hpp>
#include <oscar/Utils/UID.hpp>

#include <iosfwd>
#include <memory>
#include <string_view>
#include <vector>

namespace osc { class ISceneElLookup; }
namespace osc { class SceneElClass; }

namespace osc
{
// virtual scene element support
//
// the editor UI uses custom scene elements, rather than OpenSim types, because they have to
// support:
//
// - visitor patterns (custom UI elements tailored to each known type)
// - value semantics (undo/redo, rollbacks, etc.)
// - groundspace manipulation (3D gizmos, drag and drop)
// - easy UI integration (GLM datatypes, designed to be easy to dump into OpenGL, etc.)
class SceneEl {
protected:
SceneEl() = default;
SceneEl(SceneEl const&) = default;
SceneEl(SceneEl&&) noexcept = default;
SceneEl& operator=(SceneEl const&) = default;
SceneEl& operator=(SceneEl&&) noexcept = default;
public:
virtual ~SceneEl() noexcept = default;

SceneElClass const& getClass() const
{
return implGetClass();
}

std::unique_ptr<SceneEl> clone() const
{
return implClone();
}

ConstSceneElVariant toVariant() const
{
return implToVariant();
}

SceneElVariant toVariant()
{
return implToVariant();
}

int getNumCrossReferences() const
{
return static_cast<int>(implGetCrossReferences().size());
}

UID getCrossReferenceConnecteeID(int i) const
{
return implGetCrossReferences().at(i).getConnecteeID();
}

void setCrossReferenceConnecteeID(int i, UID newID)
{
implSetCrossReferenceConnecteeID(i, newID);
}

CStringView getCrossReferenceLabel(int i) const
{
return implGetCrossReferences().at(i).getLabel();
}

CrossrefDirection getCrossReferenceDirection(int i) const
{
return implGetCrossReferences().at(i).getDirection();
}

UID getID() const
{
return implGetID();
}

std::ostream& operator<<(std::ostream& o) const
{
return implWriteToStream(o);
}

CStringView getLabel() const
{
return implGetLabel();
}

void setLabel(std::string_view newLabel)
{
implSetLabel(newLabel);
}

Transform getXForm(ISceneElLookup const& lookup) const
{
return implGetXform(lookup);
}
void setXform(ISceneElLookup const& lookup, Transform const& newTransform)
{
implSetXform(lookup, newTransform);
}

Vec3 getPos(ISceneElLookup const& lookup) const
{
return getXForm(lookup).position;
}
void setPos(ISceneElLookup const& lookup, Vec3 const& newPos)
{
setXform(lookup, getXForm(lookup).withPosition(newPos));
}

Vec3 getScale(ISceneElLookup const& lookup) const
{
return getXForm(lookup).scale;
}

void setScale(ISceneElLookup const& lookup, Vec3 const& newScale)
{
setXform(lookup, getXForm(lookup).withScale(newScale));
}

Quat getRotation(ISceneElLookup const& lookup) const
{
return getXForm(lookup).rotation;
}

void setRotation(ISceneElLookup const& lookup, Quat const& newRotation)
{
setXform(lookup, getXForm(lookup).withRotation(newRotation));
}

AABB calcBounds(ISceneElLookup const& lookup) const
{
return implCalcBounds(lookup);
}

void applyTranslation(ISceneElLookup const& lookup, Vec3 const& translation)
{
setPos(lookup, getPos(lookup) + translation);
}

void applyRotation(
ISceneElLookup const& lookup,
Vec3 const& eulerAngles,
Vec3 const& rotationCenter
);

void applyScale(ISceneElLookup const& lookup, Vec3 const& scaleFactors)
{
setScale(lookup, getScale(lookup) * scaleFactors);
}

bool canChangeLabel() const
{
return implGetFlags() & SceneElFlags::CanChangeLabel;
}

bool canChangePosition() const
{
return implGetFlags() & SceneElFlags::CanChangePosition;
}

bool canChangeRotation() const
{
return implGetFlags() & SceneElFlags::CanChangeRotation;
}

bool canChangeScale() const
{
return implGetFlags() & SceneElFlags::CanChangeScale;
}

bool canDelete() const
{
return implGetFlags() & SceneElFlags::CanDelete;
}

bool canSelect() const
{
return implGetFlags() & SceneElFlags::CanSelect;
}

bool hasPhysicalSize() const
{
return implGetFlags() & SceneElFlags::HasPhysicalSize;
}

bool isCrossReferencing(
UID id,
CrossrefDirection direction = CrossrefDirection::Both
) const;

private:
virtual SceneElClass const& implGetClass() const = 0;
virtual std::unique_ptr<SceneEl> implClone() const = 0;
virtual ConstSceneElVariant implToVariant() const = 0;
virtual SceneElVariant implToVariant() = 0;
virtual SceneElFlags implGetFlags() const = 0;

virtual std::vector<CrossrefDescriptor> implGetCrossReferences() const { return {}; }
virtual void implSetCrossReferenceConnecteeID(int, UID) {}

virtual std::ostream& implWriteToStream(std::ostream&) const = 0;

virtual UID implGetID() const = 0;

virtual CStringView implGetLabel() const = 0;
virtual void implSetLabel(std::string_view) {}

virtual Transform implGetXform(ISceneElLookup const&) const = 0;
virtual void implSetXform(ISceneElLookup const&, Transform const&) {}

virtual AABB implCalcBounds(ISceneElLookup const&) const = 0;
};
}
2 changes: 1 addition & 1 deletion src/OpenSimCreator/ModelGraph/SceneElFlags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ namespace osc
{
return static_cast<SceneElFlags>(osc::to_underlying(lhs) | osc::to_underlying(rhs));
}
}
}
Loading

0 comments on commit 1af36f8

Please sign in to comment.