#ifndef OPENCS_VIEW_OBJECT_H #define OPENCS_VIEW_OBJECT_H #include #include #include #include #include #include #include #include "tagbase.hpp" class QModelIndex; namespace osg { class PositionAttitudeTransform; class Geometry; class Group; class Node; } namespace osgFX { class Scribe; } namespace Resource { class ResourceSystem; } namespace CSMWorld { class Data; struct CellRef; class CommandMacro; } namespace CSVRender { class Actor; class Object; struct WorldspaceHitResult; // An object to attach as user data to the osg::Node, allows us to get an Object back from a Node when we are doing // a ray query class ObjectTag : public TagBase { public: ObjectTag(Object* object); Object* mObject; QString getToolTip(bool hideBasics, const WorldspaceHitResult& hit) const override; }; class ObjectMarkerTag : public ObjectTag { public: ObjectMarkerTag(Object* object, int axis); int mAxis; }; class Object { public: enum OverrideFlags { Override_Position = 1, Override_Rotation = 2, Override_Scale = 4 }; private: static const float MarkerShaftWidth; static const float MarkerShaftBaseLength; static const float MarkerHeadWidth; static const float MarkerHeadLength; CSMWorld::Data& mData; ESM::RefId mReferenceId; ESM::RefId mReferenceableId; osg::ref_ptr mRootNode; osg::ref_ptr mBaseNode; osg::ref_ptr mOutline; bool mSelected; bool mSnapTarget; osg::Group* mParentNode; Resource::ResourceSystem* mResourceSystem; bool mForceBaseToZero; ESM::Position mPositionOverride; float mScaleOverride; int mOverrideFlags; osg::ref_ptr mMarker[3]; int mSubMode; float mMarkerTransparency; std::unique_ptr mActor; /// Not implemented Object(const Object&); /// Not implemented Object& operator=(const Object&); /// Remove object from node (includes deleting) void clear(); /// Update model /// @note Make sure adjustTransform() was called first so world space particles get positioned correctly void update(); /// Adjust position, orientation and scale void adjustTransform(); /// Throws an exception if *this was constructed with referenceable const CSMWorld::CellRef& getReference() const; void updateMarker(); 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: Object(CSMWorld::Data& data, osg::Group* cellNode, const std::string& id, bool referenceable, bool forceBaseToZero = false); /// \param forceBaseToZero If this is a reference ignore the coordinates and place /// it at 0, 0, 0 instead. ~Object(); /// Mark the object as selected, selected objects show an outline effect void setSelected(bool selected, const osg::Vec4f& color = osg::Vec4f(1, 1, 1, 1)); bool getSelected() const; /// Mark Object as "snap target" void setSnapTarget(bool isSnapTarget); bool getSnapTarget() const; /// Get object node with GUI graphics osg::ref_ptr getRootNode(); /// Get object node without GUI graphics osg::ref_ptr getBaseNode(); /// \return Did this call result in a modification of the visual representation of /// this object? bool referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); /// \return Did this call result in a modification of the visual representation of /// this object? bool referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end); /// \return Did this call result in a modification of the visual representation of /// this object? bool referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); /// Reloads the underlying asset void reloadAssets(); /// Returns an empty string if this is a refereceable-type object. std::string getReferenceId() const; std::string getReferenceableId() const; osg::ref_ptr getTag() const; /// Is there currently an editing operation running on this object? bool isEdited() const; void setEdited(int flags); ESM::Position getPosition() const; float getScale() const; /// Set override position. void setPosition(const float position[3]); /// Set override rotation void setRotation(const float rotation[3]); /// 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); void setSubMode(int subMode); /// Erase all overrides and restore the visual representation of the object to its /// true state. void reset(); }; } #endif