mirror of
https://github.com/leozide/leocad.git
synced 2026-07-27 19:56:49 +00:00
Saved undo data as structures.
This commit is contained in:
+34
-24
@@ -13,6 +13,11 @@
|
||||
|
||||
#define LC_CAMERA_SAVE_VERSION 7 // LeoCAD 0.80
|
||||
|
||||
lcCamera::lcCamera()
|
||||
: lcObject(lcObjectType::Camera)
|
||||
{
|
||||
}
|
||||
|
||||
lcCamera::lcCamera(bool Simple)
|
||||
: lcObject(lcObjectType::Camera), mSimple(Simple)
|
||||
{
|
||||
@@ -26,8 +31,8 @@ lcCamera::lcCamera(bool Simple)
|
||||
}
|
||||
}
|
||||
|
||||
lcCamera::lcCamera(const lcVector3& Position, const lcVector3& TargetPosition)
|
||||
: lcObject(lcObjectType::Camera)
|
||||
lcCamera::lcCamera(bool Simple, const lcVector3& Position, const lcVector3& TargetPosition)
|
||||
: lcObject(lcObjectType::Camera), mSimple(Simple)
|
||||
{
|
||||
// Fix the up vector
|
||||
lcVector3 UpVector(0, 0, 1), FrontVector(Position - TargetPosition), SideVector;
|
||||
@@ -893,33 +898,38 @@ void lcCamera::RemoveKeyFrames()
|
||||
mUpVector.RemoveAllKeys();
|
||||
}
|
||||
|
||||
bool lcCamera::SaveUndoData(QDataStream& Stream, const lcModel* Model) const
|
||||
lcCameraHistoryState lcCamera::GetHistoryState(const lcModel* Model) const
|
||||
{
|
||||
static_assert(sizeof(lcCamera) == 248);
|
||||
Q_UNUSED(Model);
|
||||
lcCameraHistoryState State;
|
||||
|
||||
Stream << m_fovy;
|
||||
Stream << m_zNear;
|
||||
Stream << m_zFar;
|
||||
Stream << mName;
|
||||
Stream << mProjection;
|
||||
Stream << mHidden;
|
||||
|
||||
return mPosition.SaveUndoData(Stream) && mTargetPosition.SaveUndoData(Stream) && mUpVector.SaveUndoData(Stream);
|
||||
State.Id = mId;
|
||||
State.Hidden = mHidden;
|
||||
State.Simple = mSimple;
|
||||
State.Fovy = m_fovy;
|
||||
State.NearPlane = m_zNear;
|
||||
State.FarPlane = m_zFar;
|
||||
State.Projection = mProjection;
|
||||
State.Position = mPosition;
|
||||
State.TargetPosition = mTargetPosition;
|
||||
State.UpVector = mUpVector;
|
||||
State.Name = mName;
|
||||
|
||||
return State;
|
||||
}
|
||||
|
||||
bool lcCamera::LoadUndoData(QDataStream& Stream, const lcModel* Model)
|
||||
void lcCamera::SetHistoryState(const lcCameraHistoryState& State, const lcModel* Model)
|
||||
{
|
||||
Q_UNUSED(Model);
|
||||
|
||||
Stream >> m_fovy;
|
||||
Stream >> m_zNear;
|
||||
Stream >> m_zFar;
|
||||
Stream >> mName;
|
||||
Stream >> mProjection;
|
||||
Stream >> mHidden;
|
||||
|
||||
return mPosition.LoadUndoData(Stream) && mTargetPosition.LoadUndoData(Stream) && mUpVector.LoadUndoData(Stream);
|
||||
mId = State.Id;
|
||||
mHidden = State.Hidden;
|
||||
mSimple = State.Simple;
|
||||
m_fovy = State.Fovy;
|
||||
m_zNear = State.NearPlane;
|
||||
m_zFar = State.FarPlane;
|
||||
mProjection = State.Projection;
|
||||
mPosition = State.Position;
|
||||
mTargetPosition = State.TargetPosition;
|
||||
mUpVector = State.UpVector;
|
||||
mName = State.Name;
|
||||
}
|
||||
|
||||
void lcCamera::RayTest(lcObjectRayTest& ObjectRayTest) const
|
||||
|
||||
+27
-4
@@ -30,11 +30,34 @@ enum lcCameraSection : quint32
|
||||
LC_CAMERA_SECTION_UPVECTOR
|
||||
};
|
||||
|
||||
struct lcCameraHistoryState
|
||||
{
|
||||
lcObjectId Id;
|
||||
bool Hidden;
|
||||
bool Simple;
|
||||
float Fovy;
|
||||
float NearPlane;
|
||||
float FarPlane;
|
||||
lcCameraProjection Projection;
|
||||
lcObjectProperty<lcVector3> Position;
|
||||
lcObjectProperty<lcVector3> TargetPosition;
|
||||
lcObjectProperty<lcVector3> UpVector;
|
||||
QString Name;
|
||||
|
||||
bool operator==(const lcCameraHistoryState& Other) const
|
||||
{
|
||||
return Id == Other.Id && Hidden == Other.Hidden && Simple == Other.Simple && Fovy == Other.Fovy &&
|
||||
NearPlane == Other.NearPlane && FarPlane == Other.FarPlane && Projection == Other.Projection &&
|
||||
Position == Other.Position && TargetPosition == Other.TargetPosition && UpVector == Other.UpVector && Name == Other.Name;
|
||||
}
|
||||
};
|
||||
|
||||
class lcCamera : public lcObject
|
||||
{
|
||||
public:
|
||||
lcCamera();
|
||||
lcCamera(bool Simple);
|
||||
lcCamera(const lcVector3& Position, const lcVector3& TargetPosition);
|
||||
lcCamera(bool Simple, const lcVector3& Position, const lcVector3& TargetPosition);
|
||||
virtual ~lcCamera();
|
||||
|
||||
lcCamera(const lcCamera&) = delete;
|
||||
@@ -167,8 +190,8 @@ public:
|
||||
bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override;
|
||||
bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) override;
|
||||
void RemoveKeyFrames() override;
|
||||
bool SaveUndoData(QDataStream& Stream, const lcModel* Model) const override;
|
||||
bool LoadUndoData(QDataStream& Stream, const lcModel* Model) override;
|
||||
lcCameraHistoryState GetHistoryState(const lcModel* Model) const;
|
||||
void SetHistoryState(const lcCameraHistoryState& State, const lcModel* Model);
|
||||
|
||||
void InsertTime(lcStep Start, lcStep Time);
|
||||
void RemoveTime(lcStep Start, lcStep Time);
|
||||
@@ -207,6 +230,6 @@ public:
|
||||
|
||||
protected:
|
||||
QString mName;
|
||||
bool mSimple = false;
|
||||
bool mSimple = true;
|
||||
lcCameraProjection mProjection = lcCameraProjection::Perspective;
|
||||
};
|
||||
|
||||
+39
-1
@@ -1,11 +1,15 @@
|
||||
#include "lc_global.h"
|
||||
#include <stdlib.h>
|
||||
#include "group.h"
|
||||
#include "lc_model.h"
|
||||
#include "lc_file.h"
|
||||
|
||||
lcGroupId lcGroup::mNextId;
|
||||
|
||||
lcGroup::lcGroup()
|
||||
: mId(mNextId)
|
||||
{
|
||||
mGroup = nullptr;
|
||||
mNextId = static_cast<lcGroupId>(static_cast<uint32_t>(mNextId) + 1);
|
||||
}
|
||||
|
||||
void lcGroup::FileLoad(lcFile* File)
|
||||
@@ -58,3 +62,37 @@ void lcGroup::CreateName(const std::vector<std::unique_ptr<lcGroup>>& Groups)
|
||||
|
||||
mName = Prefix + QString::number(Max + 1);
|
||||
}
|
||||
|
||||
lcGroupHistoryState lcGroup::GetHistoryState(const lcModel* Model) const
|
||||
{
|
||||
lcGroupHistoryState State;
|
||||
|
||||
State.Id = mId;
|
||||
State.ParentIndex = ~0;
|
||||
State.Name = mName;
|
||||
|
||||
if (mGroup)
|
||||
{
|
||||
const std::vector<std::unique_ptr<lcGroup>>& Groups = Model->GetGroups();
|
||||
|
||||
for (size_t GroupIndex = 0; GroupIndex < Groups.size(); GroupIndex++)
|
||||
{
|
||||
if (Groups[GroupIndex].get() == mGroup)
|
||||
{
|
||||
State.ParentIndex = GroupIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return State;
|
||||
}
|
||||
|
||||
void lcGroup::SetHistoryState(const lcGroupHistoryState& State, const lcModel* Model)
|
||||
{
|
||||
const std::vector<std::unique_ptr<lcGroup>>& Groups = Model->GetGroups();
|
||||
|
||||
mId = State.Id;
|
||||
mName = State.Name;
|
||||
mGroup = (State.ParentIndex < Groups.size()) ? Groups[State.ParentIndex].get() : nullptr;
|
||||
}
|
||||
|
||||
+30
-4
@@ -2,6 +2,20 @@
|
||||
|
||||
#define LC_MAX_GROUP_NAME 64
|
||||
|
||||
enum class lcGroupId : uint32_t;
|
||||
|
||||
struct lcGroupHistoryState
|
||||
{
|
||||
lcGroupId Id;
|
||||
uint32_t ParentIndex;
|
||||
QString Name;
|
||||
|
||||
bool operator==(const lcGroupHistoryState& Other) const
|
||||
{
|
||||
return Id == Other.Id && ParentIndex == Other.ParentIndex && Name == Other.Name;
|
||||
}
|
||||
};
|
||||
|
||||
class lcGroup
|
||||
{
|
||||
public:
|
||||
@@ -11,11 +25,23 @@ public:
|
||||
{
|
||||
return mGroup ? mGroup->GetTopGroup() : this;
|
||||
}
|
||||
|
||||
|
||||
lcGroupId GetId() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
void FileLoad(lcFile* File);
|
||||
void CreateName(const std::vector<std::unique_ptr<lcGroup>>& Groups);
|
||||
|
||||
lcGroup* mGroup;
|
||||
|
||||
lcGroupHistoryState GetHistoryState(const lcModel* Model) const;
|
||||
void SetHistoryState(const lcGroupHistoryState& State, const lcModel* Model);
|
||||
|
||||
lcGroup* mGroup = nullptr;
|
||||
QString mName;
|
||||
|
||||
protected:
|
||||
lcGroupId mId = static_cast<lcGroupId>(0);
|
||||
|
||||
static lcGroupId mNextId;
|
||||
};
|
||||
|
||||
|
||||
@@ -464,6 +464,11 @@ inline bool operator==(const lcMatrix33& a, const lcMatrix33& b)
|
||||
return a.r[0] == b.r[0] && a.r[1] == b.r[1] && a.r[2] == b.r[2];
|
||||
}
|
||||
|
||||
inline bool operator==(const lcMatrix44& a, const lcMatrix44& b)
|
||||
{
|
||||
return a.r[0] == b.r[0] && a.r[1] == b.r[1] && a.r[2] == b.r[2] && a.r[3] == b.r[3];
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
|
||||
inline QDebug operator<<(QDebug Debug, const lcVector2& v)
|
||||
|
||||
+48
-4
@@ -1809,6 +1809,49 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect
|
||||
ModelActionSelection->LoadStartState(this);
|
||||
}
|
||||
|
||||
template<typename StateType, typename ObjectType>
|
||||
void lcModel::LoadObjectHistoryState(const std::vector<StateType>& ObjectStates, std::vector<std::unique_ptr<ObjectType>>& Objects)
|
||||
{
|
||||
std::vector<std::unique_ptr<ObjectType>> NewObjects;
|
||||
|
||||
NewObjects.reserve(ObjectStates.size());
|
||||
|
||||
for (const StateType& ObjectState : ObjectStates)
|
||||
{
|
||||
auto ObjectId = ObjectState.Id;
|
||||
bool Found = false;
|
||||
|
||||
for (auto ObjectIt = Objects.begin(); ObjectIt != Objects.end(); ++ObjectIt)
|
||||
{
|
||||
ObjectType* Object = ObjectIt->get();
|
||||
|
||||
if (Object->GetId() == ObjectId)
|
||||
{
|
||||
NewObjects.emplace_back(std::move(*ObjectIt));
|
||||
Objects.erase(ObjectIt);
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Found)
|
||||
NewObjects.emplace_back(new ObjectType());
|
||||
}
|
||||
|
||||
Objects = std::move(NewObjects);
|
||||
|
||||
for (size_t ObjectIndex = 0; ObjectIndex < Objects.size(); ObjectIndex++)
|
||||
Objects[ObjectIndex]->SetHistoryState(ObjectStates[ObjectIndex], this);
|
||||
}
|
||||
|
||||
void lcModel::LoadHistoryState(const lcModelHistoryState& HistoryState)
|
||||
{
|
||||
LoadObjectHistoryState(HistoryState.Groups, mGroups);
|
||||
LoadObjectHistoryState(HistoryState.Pieces, mPieces);
|
||||
LoadObjectHistoryState(HistoryState.Cameras, mCameras);
|
||||
LoadObjectHistoryState(HistoryState.Lights, mLights);
|
||||
}
|
||||
|
||||
void lcModel::BeginObjectEditAction(lcModelActionObjectEditMode ModelActionObjectEditMode, const lcCamera* Camera)
|
||||
{
|
||||
std::unique_ptr<lcModelActionObjectEdit> ModelActionObjectEdit = std::make_unique<lcModelActionObjectEdit>(ModelActionObjectEditMode);
|
||||
@@ -1816,8 +1859,7 @@ void lcModel::BeginObjectEditAction(lcModelActionObjectEditMode ModelActionObjec
|
||||
if (!ModelActionObjectEdit)
|
||||
return;
|
||||
|
||||
if (!ModelActionObjectEdit->SaveStartState(this, Camera))
|
||||
return;
|
||||
ModelActionObjectEdit->SaveStartState(this, Camera);
|
||||
|
||||
mActionSequence.emplace_back(std::move(ModelActionObjectEdit));
|
||||
}
|
||||
@@ -1832,7 +1874,9 @@ void lcModel::EndObjectEditAction(std::vector<size_t>&& ObjectIndices, std::vect
|
||||
if (!ModelActionObjectEdit)
|
||||
return;
|
||||
|
||||
if (!ModelActionObjectEdit->SaveEndState(this, std::move(ObjectIndices), std::move(GroupIndices)))
|
||||
ModelActionObjectEdit->SaveEndState(this, std::move(ObjectIndices), std::move(GroupIndices));
|
||||
|
||||
if (ModelActionObjectEdit->StateChanged())
|
||||
mActionSequence.pop_back();
|
||||
}
|
||||
|
||||
@@ -4950,7 +4994,7 @@ void lcModel::InsertCameraToolClicked(const lcVector3& Position)
|
||||
BeginActionSequence();
|
||||
BeginObjectEditAction(lcModelActionObjectEditMode::CreateCamera, nullptr);
|
||||
|
||||
lcCamera* Camera = new lcCamera(Position, GetSelectionOrModelCenter());
|
||||
lcCamera* Camera = new lcCamera(false, Position, GetSelectionOrModelCenter());
|
||||
|
||||
Camera->CreateName(mCameras);
|
||||
mCameras.emplace_back(Camera);
|
||||
|
||||
+6
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
enum class lcObjectPropertyId;
|
||||
enum class lcCameraProjection;
|
||||
struct lcModelHistoryState;
|
||||
class lcModelAction;
|
||||
class lcModelActionSelection;
|
||||
class lcModelActionObjectEdit;
|
||||
@@ -229,7 +230,11 @@ public:
|
||||
void ShowNextStep();
|
||||
void InsertStep(lcStep Step);
|
||||
void RemoveStep(lcStep Step);
|
||||
|
||||
|
||||
template<typename StateType, typename ObjectType>
|
||||
void LoadObjectHistoryState(const std::vector<StateType>& ObjectStates, std::vector<std::unique_ptr<ObjectType>>& Objects);
|
||||
void LoadHistoryState(const lcModelHistoryState& HistoryState);
|
||||
|
||||
lcPiece* AddPiece(PieceInfo* Info, quint32 Section);
|
||||
void AddPiece(std::unique_ptr<lcPiece> Piece, size_t PieceIndex);
|
||||
void RemovePieces(const std::vector<size_t>& PieceIndices);
|
||||
|
||||
+28
-300
@@ -143,332 +143,60 @@ void lcModelActionSelection::LoadState(const lcModelActionSelectionState& State,
|
||||
}
|
||||
|
||||
lcModelActionObjectEdit::lcModelActionObjectEdit(lcModelActionObjectEditMode Mode)
|
||||
: mMode(Mode)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool lcModelActionObjectEdit::SaveHistoryBuffer(QByteArray& Buffer, const lcModel* Model)
|
||||
void lcModelActionObjectEdit::SaveState(lcModelHistoryState& State, const lcModel* Model)
|
||||
{
|
||||
QDataStream Stream(&Buffer, QIODevice::WriteOnly);
|
||||
|
||||
const std::vector<std::unique_ptr<lcGroup>>& Groups = Model->GetGroups();
|
||||
|
||||
for (const std::unique_ptr<lcGroup>& Group : Groups)
|
||||
State.Groups.emplace_back(Group->GetHistoryState(Model));
|
||||
|
||||
const std::vector<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
|
||||
|
||||
for (const std::unique_ptr<lcPiece>& Piece : Pieces)
|
||||
State.Pieces.emplace_back(Piece->GetHistoryState(Model));
|
||||
|
||||
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
|
||||
|
||||
for (const std::unique_ptr<lcCamera>& Camera : Cameras)
|
||||
State.Cameras.emplace_back(Camera->GetHistoryState(Model));
|
||||
|
||||
const std::vector<std::unique_ptr<lcLight>>& Lights = Model->GetLights();
|
||||
|
||||
uint64_t ObjectCount[4] = { Groups.size(), Pieces.size(), Cameras.size(), Lights.size() };
|
||||
|
||||
if (Stream.writeRawData(reinterpret_cast<const char*>(ObjectCount), sizeof(ObjectCount)) != sizeof(ObjectCount))
|
||||
return false;
|
||||
|
||||
for (size_t GroupIndex : mGroupIndices)
|
||||
{
|
||||
const lcGroup* Group = Groups[GroupIndex].get();
|
||||
uint64_t ParentIndex = UINT64_MAX;
|
||||
|
||||
if (Group->mGroup)
|
||||
for (ParentIndex = 0; ParentIndex < Groups.size(); ParentIndex++)
|
||||
if (Group->mGroup == Groups[ParentIndex].get())
|
||||
break;
|
||||
|
||||
Stream << Group->mName;
|
||||
Stream << ParentIndex;
|
||||
}
|
||||
|
||||
for (size_t PieceIndex : mPieceIndices)
|
||||
if (!Pieces[PieceIndex]->SaveUndoData(Stream, Model))
|
||||
return false;
|
||||
|
||||
for (size_t CameraIndex : mCameraIndices)
|
||||
if (!Cameras[CameraIndex]->SaveUndoData(Stream, Model))
|
||||
return false;
|
||||
|
||||
for (size_t LightIndex : mLightIndices)
|
||||
if (!Lights[LightIndex]->SaveUndoData(Stream, Model))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
for (const std::unique_ptr<lcLight>& Light : Lights)
|
||||
State.Lights.emplace_back(Light->GetHistoryState(Model));
|
||||
}
|
||||
|
||||
bool lcModelActionObjectEdit::LoadHistoryBuffer(const QByteArray& Buffer, lcModel* Model, bool CreateObjects) const
|
||||
void lcModelActionObjectEdit::LoadState(const lcModelHistoryState& State, lcModel* Model)
|
||||
{
|
||||
QDataStream Stream(const_cast<QByteArray*>(&Buffer), QIODevice::ReadOnly);
|
||||
|
||||
const std::vector<std::unique_ptr<lcGroup>>& Groups = Model->GetGroups();
|
||||
const std::vector<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
|
||||
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
|
||||
const std::vector<std::unique_ptr<lcLight>>& Lights = Model->GetLights();
|
||||
|
||||
uint64_t ObjectCount[4];
|
||||
|
||||
if (Stream.readRawData(reinterpret_cast<char*>(ObjectCount), sizeof(ObjectCount)) != sizeof(ObjectCount))
|
||||
return false;
|
||||
|
||||
if (CreateObjects)
|
||||
{
|
||||
ObjectCount[0] -= mGroupIndices.size();
|
||||
ObjectCount[1] -= mPieceIndices.size();
|
||||
ObjectCount[2] -= mCameraIndices.size();
|
||||
ObjectCount[3] -= mLightIndices.size();
|
||||
}
|
||||
|
||||
if (ObjectCount[0] != Groups.size() || ObjectCount[1] != Pieces.size() || ObjectCount[2] != Cameras.size() || ObjectCount[3] != Lights.size())
|
||||
return false;
|
||||
|
||||
if (CreateObjects)
|
||||
{
|
||||
for (size_t GroupIndex : mGroupIndices)
|
||||
{
|
||||
std::unique_ptr<lcGroup> Group(new lcGroup());
|
||||
QString Name;
|
||||
uint64_t ParentIndex;
|
||||
|
||||
Stream >> Name;
|
||||
Stream >> ParentIndex;
|
||||
|
||||
Group->mName = Name;
|
||||
Group->mGroup = ParentIndex < Groups.size() ? Groups[ParentIndex].get() : nullptr;
|
||||
|
||||
Model->AddGroup(std::move(Group), GroupIndex);
|
||||
}
|
||||
|
||||
for (size_t PieceIndex : mPieceIndices)
|
||||
{
|
||||
if (PieceIndex > Pieces.size())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<lcPiece> Piece(new lcPiece(nullptr));
|
||||
|
||||
if (!Piece->LoadUndoData(Stream, Model))
|
||||
return false;
|
||||
|
||||
Model->AddPiece(std::move(Piece), PieceIndex);
|
||||
}
|
||||
|
||||
for (size_t CameraIndex : mCameraIndices)
|
||||
{
|
||||
if (CameraIndex > Cameras.size())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<lcCamera> Camera(new lcCamera(false));
|
||||
|
||||
if (!Camera->LoadUndoData(Stream, Model))
|
||||
return false;
|
||||
|
||||
Model->AddCamera(std::move(Camera), CameraIndex);
|
||||
}
|
||||
|
||||
for (size_t LightIndex : mLightIndices)
|
||||
{
|
||||
if (LightIndex > Lights.size())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<lcLight> Light(new lcLight(lcVector3(0.0f, 0.0f, 0.0f), lcLightType::Point));
|
||||
|
||||
if (!Light->LoadUndoData(Stream, Model))
|
||||
return false;
|
||||
|
||||
Model->AddLight(std::move(Light), LightIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t GroupIndex : mGroupIndices)
|
||||
{
|
||||
lcGroup* Group = Groups[GroupIndex].get();
|
||||
QString Name;
|
||||
uint64_t ParentIndex;
|
||||
|
||||
Stream >> Name;
|
||||
Stream >> ParentIndex;
|
||||
|
||||
Group->mName = Name;
|
||||
Group->mGroup = ParentIndex < Groups.size() ? Groups[ParentIndex].get() : nullptr;
|
||||
}
|
||||
|
||||
for (size_t PieceIndex : mPieceIndices)
|
||||
{
|
||||
if (PieceIndex >= Pieces.size())
|
||||
return false;
|
||||
|
||||
const std::unique_ptr<lcPiece>& Piece = Pieces[PieceIndex];
|
||||
|
||||
if (!Piece->LoadUndoData(Stream, Model))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t CameraIndex : mCameraIndices)
|
||||
{
|
||||
if (CameraIndex >= Cameras.size())
|
||||
return false;
|
||||
|
||||
const std::unique_ptr<lcCamera>& Camera = Cameras[CameraIndex];
|
||||
|
||||
if (!Camera->LoadUndoData(Stream, Model))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t LightIndex : mLightIndices)
|
||||
{
|
||||
if (LightIndex >= Lights.size())
|
||||
return false;
|
||||
|
||||
const std::unique_ptr<lcLight>& Light = Lights[LightIndex];
|
||||
|
||||
if (!Light->LoadUndoData(Stream, Model))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
Model->LoadHistoryState(State);
|
||||
}
|
||||
|
||||
bool lcModelActionObjectEdit::SaveStartState(const lcModel* Model, const lcCamera* Camera)
|
||||
void lcModelActionObjectEdit::SaveStartState(const lcModel* Model, const lcCamera* Camera)
|
||||
{
|
||||
const std::vector<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
|
||||
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
|
||||
const std::vector<std::unique_ptr<lcLight>>& Lights = Model->GetLights();
|
||||
|
||||
switch (mMode)
|
||||
{
|
||||
case lcModelActionObjectEditMode::EditAllObjects:
|
||||
mPieceIndices.resize(Pieces.size());
|
||||
std::iota(mPieceIndices.begin(), mPieceIndices.end(), 0);
|
||||
|
||||
mCameraIndices.resize(Cameras.size());
|
||||
std::iota(mCameraIndices.begin(), mCameraIndices.end(), 0);
|
||||
|
||||
mLightIndices.resize(Lights.size());
|
||||
std::iota(mLightIndices.begin(), mLightIndices.end(), 0);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::EditAllPieces:
|
||||
mPieceIndices.resize(Pieces.size());
|
||||
std::iota(mPieceIndices.begin(), mPieceIndices.end(), 0);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::EditSelectedObjects:
|
||||
for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++)
|
||||
if (Pieces[PieceIndex]->IsSelected())
|
||||
mPieceIndices.push_back(PieceIndex);
|
||||
|
||||
for (size_t CameraIndex = 0; CameraIndex < Cameras.size(); CameraIndex++)
|
||||
if (Cameras[CameraIndex]->IsSelected())
|
||||
mCameraIndices.push_back(CameraIndex);
|
||||
|
||||
for (size_t LightIndex = 0; LightIndex < Lights.size(); LightIndex++)
|
||||
if (Lights[LightIndex]->IsSelected())
|
||||
mLightIndices.push_back(LightIndex);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::EditSelectedPieces:
|
||||
for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++)
|
||||
if (Pieces[PieceIndex]->IsSelected())
|
||||
mPieceIndices.push_back(PieceIndex);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::EditUnselectedPieces:
|
||||
for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++)
|
||||
if (!Pieces[PieceIndex]->IsSelected())
|
||||
mPieceIndices.push_back(PieceIndex);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::EditCamera:
|
||||
for (size_t CameraIndex = 0; CameraIndex < Cameras.size(); CameraIndex++)
|
||||
{
|
||||
if (Cameras[CameraIndex].get() == Camera)
|
||||
{
|
||||
mCameraIndices.push_back(CameraIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreatePieces:
|
||||
case lcModelActionObjectEditMode::CreateCamera:
|
||||
case lcModelActionObjectEditMode::CreateLight:
|
||||
break;
|
||||
};
|
||||
|
||||
return SaveHistoryBuffer(mStartBuffer, Model);
|
||||
SaveState(mStartState, Model);
|
||||
}
|
||||
|
||||
bool lcModelActionObjectEdit::SaveEndState(const lcModel* Model, std::vector<size_t>&& ObjectIndices, std::vector<size_t>&& GroupIndices)
|
||||
void lcModelActionObjectEdit::SaveEndState(const lcModel* Model, std::vector<size_t>&& ObjectIndices, std::vector<size_t>&& GroupIndices)
|
||||
{
|
||||
switch (mMode)
|
||||
{
|
||||
case lcModelActionObjectEditMode::EditAllObjects:
|
||||
case lcModelActionObjectEditMode::EditAllPieces:
|
||||
case lcModelActionObjectEditMode::EditSelectedObjects:
|
||||
case lcModelActionObjectEditMode::EditSelectedPieces:
|
||||
case lcModelActionObjectEditMode::EditUnselectedPieces:
|
||||
case lcModelActionObjectEditMode::EditCamera:
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreatePieces:
|
||||
mPieceIndices = std::move(ObjectIndices);
|
||||
mGroupIndices = std::move(GroupIndices);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreateCamera:
|
||||
mCameraIndices = std::move(ObjectIndices);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreateLight:
|
||||
mLightIndices = std::move(ObjectIndices);
|
||||
break;
|
||||
};
|
||||
|
||||
return SaveHistoryBuffer(mEndBuffer, Model);
|
||||
SaveState(mEndState, Model);
|
||||
}
|
||||
|
||||
void lcModelActionObjectEdit::LoadStartState(lcModel* Model) const
|
||||
{
|
||||
switch (mMode)
|
||||
{
|
||||
case lcModelActionObjectEditMode::EditAllObjects:
|
||||
case lcModelActionObjectEditMode::EditAllPieces:
|
||||
case lcModelActionObjectEditMode::EditSelectedObjects:
|
||||
case lcModelActionObjectEditMode::EditSelectedPieces:
|
||||
case lcModelActionObjectEditMode::EditUnselectedPieces:
|
||||
case lcModelActionObjectEditMode::EditCamera:
|
||||
LoadHistoryBuffer(mStartBuffer, Model, false);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreatePieces:
|
||||
Model->RemovePieces(mPieceIndices);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreateCamera:
|
||||
Model->RemoveCameras(mCameraIndices);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreateLight:
|
||||
Model->RemoveLights(mLightIndices);
|
||||
break;
|
||||
};
|
||||
LoadState(mStartState, Model);
|
||||
}
|
||||
|
||||
void lcModelActionObjectEdit::LoadEndState(lcModel* Model) const
|
||||
{
|
||||
switch (mMode)
|
||||
{
|
||||
case lcModelActionObjectEditMode::EditAllObjects:
|
||||
case lcModelActionObjectEditMode::EditAllPieces:
|
||||
case lcModelActionObjectEditMode::EditSelectedObjects:
|
||||
case lcModelActionObjectEditMode::EditSelectedPieces:
|
||||
case lcModelActionObjectEditMode::EditUnselectedPieces:
|
||||
case lcModelActionObjectEditMode::EditCamera:
|
||||
LoadHistoryBuffer(mEndBuffer, Model, false);
|
||||
break;
|
||||
|
||||
case lcModelActionObjectEditMode::CreatePieces:
|
||||
case lcModelActionObjectEditMode::CreateCamera:
|
||||
case lcModelActionObjectEditMode::CreateLight:
|
||||
LoadHistoryBuffer(mEndBuffer, Model, true);
|
||||
break;
|
||||
};
|
||||
LoadState(mEndState, Model);
|
||||
}
|
||||
|
||||
bool lcModelActionObjectEdit::StateChanged() const
|
||||
{
|
||||
return mStartState != mEndState;
|
||||
}
|
||||
|
||||
lcModelActionGroupPieces::lcModelActionGroupPieces(lcModelActionGroupPiecesMode Mode, const QString& GroupName)
|
||||
|
||||
+26
-17
@@ -60,34 +60,43 @@ enum class lcModelActionObjectEditMode
|
||||
CreateLight
|
||||
};
|
||||
|
||||
struct lcGroupHistoryState;
|
||||
struct lcPieceHistoryState;
|
||||
struct lcCameraHistoryState;
|
||||
struct lcLightHistoryState;
|
||||
|
||||
struct lcModelHistoryState
|
||||
{
|
||||
std::vector<lcGroupHistoryState> Groups;
|
||||
std::vector<lcPieceHistoryState> Pieces;
|
||||
std::vector<lcCameraHistoryState> Cameras;
|
||||
std::vector<lcLightHistoryState> Lights;
|
||||
|
||||
bool operator!=(const lcModelHistoryState& Other) const
|
||||
{
|
||||
return Groups != Other.Groups || Pieces != Other.Pieces || Cameras != Other.Cameras || Lights != Other.Lights;
|
||||
}
|
||||
};
|
||||
|
||||
class lcModelActionObjectEdit: public lcModelAction
|
||||
{
|
||||
public:
|
||||
lcModelActionObjectEdit(lcModelActionObjectEditMode Mode);
|
||||
virtual ~lcModelActionObjectEdit() = default;
|
||||
|
||||
bool SaveStartState(const lcModel* Model, const lcCamera* Camera);
|
||||
bool SaveEndState(const lcModel* Model, std::vector<size_t>&& ObjectIndices, std::vector<size_t>&& GroupIndices);
|
||||
void SaveStartState(const lcModel* Model, const lcCamera* Camera);
|
||||
void SaveEndState(const lcModel* Model, std::vector<size_t>&& ObjectIndices, std::vector<size_t>&& GroupIndices);
|
||||
void LoadStartState(lcModel* Model) const;
|
||||
void LoadEndState(lcModel* Model) const;
|
||||
|
||||
lcModelActionObjectEditMode GetMode() const
|
||||
{
|
||||
return mMode;
|
||||
}
|
||||
|
||||
bool StateChanged() const;
|
||||
|
||||
protected:
|
||||
bool SaveHistoryBuffer(QByteArray& Buffer, const lcModel* Model);
|
||||
bool LoadHistoryBuffer(const QByteArray& Buffer, lcModel* Model, bool CreateObjects) const;
|
||||
static void SaveState(lcModelHistoryState& State, const lcModel* Model);
|
||||
static void LoadState(const lcModelHistoryState& State, lcModel* Model);
|
||||
|
||||
std::vector<size_t> mGroupIndices;
|
||||
std::vector<size_t> mPieceIndices;
|
||||
std::vector<size_t> mCameraIndices;
|
||||
std::vector<size_t> mLightIndices;
|
||||
|
||||
lcModelActionObjectEditMode mMode;
|
||||
QByteArray mStartBuffer;
|
||||
QByteArray mEndBuffer;
|
||||
lcModelHistoryState mStartState;
|
||||
lcModelHistoryState mEndState;
|
||||
};
|
||||
|
||||
enum class lcModelActionGroupPiecesMode
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
template bool lcObjectProperty<T>::HasKeyFrame(lcStep Time) const; \
|
||||
template bool lcObjectProperty<T>::SetKeyFrame(lcStep Time, bool KeyFrame); \
|
||||
template void lcObjectProperty<T>::Save(QTextStream& Stream, const char* ObjectName, const char* VariableName, bool SaveEmpty) const; \
|
||||
template bool lcObjectProperty<T>::Load(QTextStream& Stream, const QString& Token, const char* VariableName); \
|
||||
template bool lcObjectProperty<T>::SaveUndoData(QDataStream& Stream) const; \
|
||||
template bool lcObjectProperty<T>::LoadUndoData(QDataStream& Stream);
|
||||
template bool lcObjectProperty<T>::Load(QTextStream& Stream, const QString& Token, const char* VariableName);
|
||||
|
||||
LC_OBJECT_PROPERTY(float)
|
||||
LC_OBJECT_PROPERTY(int)
|
||||
@@ -314,42 +312,3 @@ bool lcObjectProperty<T>::Load(QTextStream& Stream, const QString& Token, const
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool lcObjectProperty<T>::SaveUndoData(QDataStream& Stream) const
|
||||
{
|
||||
size_t KeyCount = mKeys.size();
|
||||
qint64 DataSize = KeyCount * sizeof(lcObjectPropertyKey<T>);
|
||||
|
||||
if (Stream.writeRawData(reinterpret_cast<const char*>(&mValue), sizeof(mValue)) != sizeof(mValue))
|
||||
return false;
|
||||
|
||||
if (Stream.writeRawData(reinterpret_cast<const char*>(&KeyCount), sizeof(KeyCount)) != sizeof(KeyCount))
|
||||
return false;
|
||||
|
||||
if (Stream.writeRawData(reinterpret_cast<const char*>(mKeys.data()), DataSize) != DataSize)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool lcObjectProperty<T>::LoadUndoData(QDataStream& Stream)
|
||||
{
|
||||
if (Stream.readRawData(reinterpret_cast<char*>(&mValue), sizeof(mValue)) != sizeof(mValue))
|
||||
return false;
|
||||
|
||||
size_t KeyCount;
|
||||
|
||||
if (Stream.readRawData(reinterpret_cast<char*>(&KeyCount), sizeof(KeyCount)) != sizeof(KeyCount))
|
||||
return false;
|
||||
|
||||
mKeys.resize(KeyCount);
|
||||
|
||||
qsizetype DataSize = KeyCount * sizeof(lcObjectPropertyKey<T>);
|
||||
|
||||
if (Stream.readRawData(reinterpret_cast<char*>(mKeys.data()), DataSize) != DataSize)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -67,11 +67,13 @@ template<typename T>
|
||||
class lcObjectProperty
|
||||
{
|
||||
public:
|
||||
lcObjectProperty() = default;
|
||||
|
||||
explicit lcObjectProperty(const T& DefaultValue)
|
||||
: mValue(DefaultValue)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
operator const T& () const
|
||||
{
|
||||
return mValue;
|
||||
@@ -96,8 +98,6 @@ public:
|
||||
|
||||
void Save(QTextStream& Stream, const char* ObjectName, const char* VariableName, bool SaveEmpty) const;
|
||||
bool Load(QTextStream& Stream, const QString& Token, const char* VariableName);
|
||||
bool SaveUndoData(QDataStream& Stream) const;
|
||||
bool LoadUndoData(QDataStream& Stream);
|
||||
|
||||
protected:
|
||||
T mValue;
|
||||
|
||||
+53
-39
@@ -19,6 +19,11 @@
|
||||
static const std::array<QLatin1String, static_cast<int>(lcLightType::Count)> gLightTypes = { QLatin1String("POINT"), QLatin1String("SPOT"), QLatin1String("DIRECTIONAL"), QLatin1String("AREA") };
|
||||
static const std::array<QLatin1String, static_cast<int>(lcLightAreaShape::Count)> gLightAreaShapes = { QLatin1String("RECTANGLE"), QLatin1String("SQUARE"), QLatin1String("DISK"), QLatin1String("ELLIPSE") };
|
||||
|
||||
lcLight::lcLight()
|
||||
: lcObject(lcObjectType::Light)
|
||||
{
|
||||
}
|
||||
|
||||
lcLight::lcLight(const lcVector3& Position, lcLightType LightType)
|
||||
: lcObject(lcObjectType::Light), mLightType(LightType)
|
||||
{
|
||||
@@ -1529,49 +1534,58 @@ void lcLight::RemoveKeyFrames()
|
||||
mPOVRayFadePower.RemoveAllKeys();
|
||||
}
|
||||
|
||||
bool lcLight::SaveUndoData(QDataStream& Stream, const lcModel* Model) const
|
||||
lcLightHistoryState lcLight::GetHistoryState(const lcModel* Model) const
|
||||
{
|
||||
static_assert(sizeof(lcLight) == 704);
|
||||
Q_UNUSED(Model);
|
||||
lcLightHistoryState State;
|
||||
|
||||
Stream << mName;
|
||||
Stream << mLightType;
|
||||
Stream << mCastShadow;
|
||||
Stream << mAreaShape;
|
||||
Stream << mHidden;
|
||||
State.Id = mId;
|
||||
State.Hidden = mHidden;
|
||||
State.Name = mName;
|
||||
State.LightType = mLightType;
|
||||
State.CastShadow = mCastShadow;
|
||||
State.Position = mPosition;
|
||||
State.Rotation = mRotation;
|
||||
State.Color = mColor;
|
||||
State.BlenderPower = mBlenderPower;
|
||||
State.BlenderRadius = mBlenderRadius;
|
||||
State.BlenderAngle = mBlenderAngle;
|
||||
State.POVRayPower = mPOVRayPower;
|
||||
State.POVRayFadeDistance = mPOVRayFadeDistance;
|
||||
State.POVRayFadePower = mPOVRayFadePower;
|
||||
State.SpotConeAngle = mSpotConeAngle;
|
||||
State.SpotPenumbraAngle = mSpotPenumbraAngle;
|
||||
State.POVRaySpotTightness = mPOVRaySpotTightness;
|
||||
State.AreaShape = mAreaShape;
|
||||
State.AreaSizeX = mAreaSizeX;
|
||||
State.AreaSizeY = mAreaSizeY;
|
||||
State.POVRayAreaGridX = mPOVRayAreaGridX;
|
||||
State.POVRayAreaGridY = mPOVRayAreaGridY;
|
||||
|
||||
return mPosition.SaveUndoData(Stream) && mRotation.SaveUndoData(Stream) && mColor.SaveUndoData(Stream) &&
|
||||
mSpotConeAngle.SaveUndoData(Stream) && mSpotPenumbraAngle.SaveUndoData(Stream) && mPOVRaySpotTightness.SaveUndoData(Stream) &&
|
||||
mPOVRayAreaGridX.SaveUndoData(Stream) && mPOVRayAreaGridY.SaveUndoData(Stream) && mBlenderRadius.SaveUndoData(Stream) &&
|
||||
mBlenderAngle.SaveUndoData(Stream) && mAreaSizeX.SaveUndoData(Stream) && mAreaSizeY.SaveUndoData(Stream) &&
|
||||
mBlenderPower.SaveUndoData(Stream) && mPOVRayPower.SaveUndoData(Stream) && mPOVRayFadeDistance.SaveUndoData(Stream) &&
|
||||
mPOVRayFadePower.SaveUndoData(Stream);
|
||||
return State;
|
||||
}
|
||||
|
||||
bool lcLight::LoadUndoData(QDataStream& Stream, const lcModel* Model)
|
||||
void lcLight::SetHistoryState(const lcLightHistoryState& State, const lcModel* Model)
|
||||
{
|
||||
Q_UNUSED(Model);
|
||||
|
||||
Stream >> mName;
|
||||
Stream >> mLightType;
|
||||
Stream >> mCastShadow;
|
||||
Stream >> mAreaShape;
|
||||
Stream >> mHidden;
|
||||
|
||||
return mPosition.LoadUndoData(Stream) &&
|
||||
mRotation.LoadUndoData(Stream) &&
|
||||
mColor.LoadUndoData(Stream) &&
|
||||
mSpotConeAngle.LoadUndoData(Stream) &&
|
||||
mSpotPenumbraAngle.LoadUndoData(Stream) &&
|
||||
mPOVRaySpotTightness.LoadUndoData(Stream) &&
|
||||
mPOVRayAreaGridX.LoadUndoData(Stream) &&
|
||||
mPOVRayAreaGridY.LoadUndoData(Stream) &&
|
||||
mBlenderRadius.LoadUndoData(Stream) &&
|
||||
mBlenderAngle.LoadUndoData(Stream) &&
|
||||
mAreaSizeX.LoadUndoData(Stream) &&
|
||||
mAreaSizeY.LoadUndoData(Stream) &&
|
||||
mBlenderPower.LoadUndoData(Stream) &&
|
||||
mPOVRayPower.LoadUndoData(Stream) &&
|
||||
mPOVRayFadeDistance.LoadUndoData(Stream) &&
|
||||
mPOVRayFadePower.LoadUndoData(Stream);
|
||||
mId = State.Id;
|
||||
mHidden = State.Hidden;
|
||||
mName = State.Name;
|
||||
mLightType = State.LightType;
|
||||
mCastShadow = State.CastShadow;
|
||||
mPosition = State.Position;
|
||||
mRotation = State.Rotation;
|
||||
mColor = State.Color;
|
||||
mBlenderPower = State.BlenderPower;
|
||||
mBlenderRadius = State.BlenderRadius;
|
||||
mBlenderAngle = State.BlenderAngle;
|
||||
mPOVRayPower = State.POVRayPower;
|
||||
mPOVRayFadeDistance = State.POVRayFadeDistance;
|
||||
mPOVRayFadePower = State.POVRayFadePower;
|
||||
mSpotConeAngle = State.SpotConeAngle;
|
||||
mSpotPenumbraAngle = State.SpotPenumbraAngle;
|
||||
mPOVRaySpotTightness = State.POVRaySpotTightness;
|
||||
mAreaShape = State.AreaShape;
|
||||
mAreaSizeX = State.AreaSizeX;
|
||||
mAreaSizeY = State.AreaSizeY;
|
||||
mPOVRayAreaGridX = State.POVRayAreaGridX;
|
||||
mPOVRayAreaGridY = State.POVRayAreaGridY;
|
||||
}
|
||||
|
||||
+40
-2
@@ -28,9 +28,47 @@ enum class lcLightAreaShape
|
||||
Count
|
||||
};
|
||||
|
||||
struct lcLightHistoryState
|
||||
{
|
||||
lcObjectId Id;
|
||||
bool Hidden;
|
||||
QString Name;
|
||||
lcLightType LightType;
|
||||
bool CastShadow;
|
||||
lcObjectProperty<lcVector3> Position;
|
||||
lcObjectProperty<lcMatrix33> Rotation;
|
||||
lcObjectProperty<lcVector3> Color;
|
||||
lcObjectProperty<float> BlenderPower;
|
||||
lcObjectProperty<float> BlenderRadius;
|
||||
lcObjectProperty<float> BlenderAngle;
|
||||
lcObjectProperty<float> POVRayPower;
|
||||
lcObjectProperty<float> POVRayFadeDistance;
|
||||
lcObjectProperty<float> POVRayFadePower;
|
||||
lcObjectProperty<float> SpotConeAngle;
|
||||
lcObjectProperty<float> SpotPenumbraAngle;
|
||||
lcObjectProperty<float> POVRaySpotTightness;
|
||||
lcLightAreaShape AreaShape;
|
||||
lcObjectProperty<float> AreaSizeX;
|
||||
lcObjectProperty<float> AreaSizeY;
|
||||
lcObjectProperty<int> POVRayAreaGridX;
|
||||
lcObjectProperty<int> POVRayAreaGridY;
|
||||
|
||||
bool operator==(const lcLightHistoryState& Other) const
|
||||
{
|
||||
return Id == Other.Id && Hidden == Other.Hidden && Name == Other.Name && LightType == Other.LightType &&
|
||||
CastShadow == Other.CastShadow && Position == Other.Position && Rotation == Other.Rotation && Color == Other.Color &&
|
||||
BlenderPower == Other.BlenderPower && BlenderRadius == Other.BlenderRadius && BlenderAngle == Other.BlenderAngle &&
|
||||
POVRayPower == Other.POVRayPower && POVRayFadeDistance == Other.POVRayFadeDistance && POVRayFadePower == Other.POVRayFadePower &&
|
||||
SpotConeAngle == Other.SpotConeAngle && SpotPenumbraAngle == Other.SpotPenumbraAngle &&
|
||||
POVRaySpotTightness == Other.POVRaySpotTightness && AreaShape == Other.AreaShape && AreaSizeX == Other.AreaSizeX &&
|
||||
AreaSizeY == Other.AreaSizeY && POVRayAreaGridX == Other.POVRayAreaGridX && POVRayAreaGridY == Other.POVRayAreaGridY;
|
||||
}
|
||||
};
|
||||
|
||||
class lcLight : public lcObject
|
||||
{
|
||||
public:
|
||||
lcLight();
|
||||
lcLight(const lcVector3& Position, lcLightType LightType);
|
||||
virtual ~lcLight() = default;
|
||||
|
||||
@@ -161,8 +199,8 @@ public:
|
||||
bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override;
|
||||
bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) override;
|
||||
void RemoveKeyFrames() override;
|
||||
bool SaveUndoData(QDataStream& Stream, const lcModel* Model) const override;
|
||||
bool LoadUndoData(QDataStream& Stream, const lcModel* Model) override;
|
||||
lcLightHistoryState GetHistoryState(const lcModel* Model) const;
|
||||
void SetHistoryState(const lcLightHistoryState& State, const lcModel* Model);
|
||||
|
||||
void InsertTime(lcStep Start, lcStep Time);
|
||||
void RemoveTime(lcStep Start, lcStep Time);
|
||||
|
||||
+4
-1
@@ -1,9 +1,12 @@
|
||||
#include "lc_global.h"
|
||||
#include "object.h"
|
||||
|
||||
lcObjectId lcObject::mNextId;
|
||||
|
||||
lcObject::lcObject(lcObjectType ObjectType)
|
||||
: mObjectType(ObjectType)
|
||||
: mObjectType(ObjectType), mId(mNextId)
|
||||
{
|
||||
mNextId = static_cast<lcObjectId>(static_cast<uint32_t>(mNextId) + 1);
|
||||
}
|
||||
|
||||
lcObject::~lcObject()
|
||||
|
||||
+10
-2
@@ -10,6 +10,8 @@ enum class lcObjectType
|
||||
Light
|
||||
};
|
||||
|
||||
enum class lcObjectId : uint32_t;
|
||||
|
||||
struct lcObjectSection
|
||||
{
|
||||
lcObject* Object = nullptr;
|
||||
@@ -89,6 +91,11 @@ public:
|
||||
return mObjectType;
|
||||
}
|
||||
|
||||
lcObjectId GetId() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
bool IsSelected() const
|
||||
{
|
||||
return mSelected;
|
||||
@@ -139,8 +146,6 @@ public:
|
||||
virtual bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const = 0;
|
||||
virtual bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) = 0;
|
||||
virtual void RemoveKeyFrames() = 0;
|
||||
virtual bool SaveUndoData(QDataStream& Stream, const lcModel* Model) const = 0;
|
||||
virtual bool LoadUndoData(QDataStream& Stream, const lcModel* Model) = 0;
|
||||
virtual QString GetName() const = 0;
|
||||
static QString GetCheckpointString(lcObjectPropertyId PropertyId);
|
||||
|
||||
@@ -151,4 +156,7 @@ protected:
|
||||
bool mHidden = false;
|
||||
bool mSelected = false;
|
||||
quint32 mFocusedSection = LC_OBJECT_SECTION_INVALID;
|
||||
lcObjectId mId = static_cast<lcObjectId>(0);
|
||||
|
||||
static lcObjectId mNextId;
|
||||
};
|
||||
|
||||
+49
-68
@@ -20,15 +20,17 @@
|
||||
|
||||
constexpr float LC_PIECE_CONTROL_POINT_SIZE = 10.0f;
|
||||
|
||||
lcPiece::lcPiece()
|
||||
: lcObject(lcObjectType::Piece)
|
||||
{
|
||||
}
|
||||
|
||||
lcPiece::lcPiece(PieceInfo* Info)
|
||||
: lcObject(lcObjectType::Piece)
|
||||
{
|
||||
SetPieceInfo(Info, QString(), true, true);
|
||||
mColorIndex = gDefaultColor;
|
||||
mColorCode = 16;
|
||||
mStepShow = 1;
|
||||
mStepHide = LC_STEP_MAX;
|
||||
mGroup = nullptr;
|
||||
mPivotMatrix = lcMatrix44Identity();
|
||||
}
|
||||
|
||||
@@ -935,89 +937,68 @@ void lcPiece::RemoveKeyFrames()
|
||||
mRotation.RemoveAllKeys();
|
||||
}
|
||||
|
||||
bool lcPiece::SaveUndoData(QDataStream& Stream, const lcModel* Model) const
|
||||
lcPieceHistoryState lcPiece::GetHistoryState(const lcModel* Model) const
|
||||
{
|
||||
static_assert(sizeof(lcPiece) == 384);
|
||||
lcPieceHistoryState State;
|
||||
|
||||
Stream << mFileLine;
|
||||
Stream << mID;
|
||||
State.Id = mId;
|
||||
State.Hidden = mHidden;
|
||||
State.FileLine = mFileLine;
|
||||
State.PieceId = mID;
|
||||
State.GroupIndex = ~0;
|
||||
State.ColorIndex = mColorIndex;
|
||||
State.ColorCode = mColorCode;
|
||||
State.StepShow = mStepShow;
|
||||
State.StepHide = mStepHide;
|
||||
State.PivotMatrix = mPivotMatrix;
|
||||
State.PivotPointValid = mPivotPointValid;
|
||||
State.ControlPoints = mControlPoints;
|
||||
State.Position = mPosition;
|
||||
State.Rotation = mRotation;
|
||||
|
||||
const std::vector<std::unique_ptr<lcGroup>>& Groups = Model->GetGroups();
|
||||
uint64_t ParentIndex = UINT64_MAX;
|
||||
|
||||
if (mGroup)
|
||||
for (ParentIndex = 0; ParentIndex < Groups.size(); ParentIndex++)
|
||||
if (mGroup == Groups[ParentIndex].get())
|
||||
{
|
||||
for (size_t GroupIndex = 0; GroupIndex < Groups.size(); GroupIndex++)
|
||||
{
|
||||
if (mGroup == Groups[GroupIndex].get())
|
||||
{
|
||||
State.GroupIndex = GroupIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Stream << ParentIndex;
|
||||
Stream << mColorIndex;
|
||||
Stream << mColorCode;
|
||||
|
||||
Stream << mStepShow;
|
||||
Stream << mStepHide;
|
||||
|
||||
Stream << mPivotMatrix;
|
||||
Stream << mPivotPointValid;
|
||||
|
||||
Stream << mHidden;
|
||||
|
||||
size_t ControlPointCount = mControlPoints.size();
|
||||
qint64 DataSize = ControlPointCount * sizeof(lcPieceControlPoint);
|
||||
|
||||
if (Stream.writeRawData(reinterpret_cast<const char*>(&ControlPointCount), sizeof(ControlPointCount)) != sizeof(ControlPointCount))
|
||||
return false;
|
||||
|
||||
if (Stream.writeRawData(reinterpret_cast<const char*>(mControlPoints.data()), DataSize) != DataSize)
|
||||
return false;
|
||||
|
||||
return mPosition.SaveUndoData(Stream) && mRotation.SaveUndoData(Stream);
|
||||
return State;
|
||||
}
|
||||
|
||||
bool lcPiece::LoadUndoData(QDataStream& Stream, const lcModel* Model)
|
||||
void lcPiece::SetHistoryState(const lcPieceHistoryState& State, const lcModel* Model)
|
||||
{
|
||||
Stream >> mFileLine;
|
||||
Stream >> mID;
|
||||
const std::vector<std::unique_ptr<lcGroup>>& Groups = Model->GetGroups();
|
||||
|
||||
mId = State.Id;
|
||||
mHidden = State.Hidden;
|
||||
mFileLine = State.FileLine;
|
||||
mID = State.PieceId;
|
||||
mGroup = (State.GroupIndex < Groups.size()) ? Groups[State.GroupIndex].get() : nullptr;;
|
||||
mColorIndex = State.ColorIndex;
|
||||
mColorCode = State.ColorCode;
|
||||
mStepShow = State.StepShow;
|
||||
mStepHide = State.StepHide;
|
||||
mPivotMatrix = State.PivotMatrix;
|
||||
mPivotPointValid = State.PivotPointValid;
|
||||
mControlPoints = State.ControlPoints;
|
||||
mPosition = State.Position;
|
||||
mRotation = State.Rotation;
|
||||
|
||||
PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(mID.toLatin1(), nullptr, true, false);
|
||||
|
||||
SetPieceInfo(Info, mID, true, false);
|
||||
|
||||
const std::vector<std::unique_ptr<lcGroup>>& Groups = Model->GetGroups();
|
||||
uint64_t ParentIndex;
|
||||
|
||||
Stream >> ParentIndex;
|
||||
|
||||
mGroup = ParentIndex < Groups.size() ? Groups[ParentIndex].get() : nullptr;
|
||||
|
||||
Stream >> mColorIndex;
|
||||
Stream >> mColorCode;
|
||||
|
||||
Stream >> mStepShow;
|
||||
Stream >> mStepHide;
|
||||
|
||||
Stream >> mPivotMatrix;
|
||||
Stream >> mPivotPointValid;
|
||||
|
||||
Stream >> mHidden;
|
||||
|
||||
size_t ControlPointCount;
|
||||
|
||||
if (Stream.readRawData(reinterpret_cast<char*>(&ControlPointCount), sizeof(ControlPointCount)) != sizeof(ControlPointCount))
|
||||
return false;
|
||||
|
||||
mControlPoints.resize(ControlPointCount);
|
||||
|
||||
qsizetype DataSize = ControlPointCount * sizeof(lcPieceControlPoint);
|
||||
|
||||
if (Stream.readRawData(reinterpret_cast<char*>(mControlPoints.data()), DataSize) != DataSize)
|
||||
return false;
|
||||
|
||||
UpdateMesh();
|
||||
|
||||
// std::vector<bool> mTrainTrackConnections;
|
||||
|
||||
return mPosition.LoadUndoData(Stream) && mRotation.LoadUndoData(Stream);
|
||||
// std::vector<bool> mTrainTrackConnections;
|
||||
}
|
||||
|
||||
void lcPiece::AddMainModelRenderMeshes(lcScene* Scene, bool Highlight, bool Fade) const
|
||||
|
||||
+40
-7
@@ -21,11 +21,44 @@ struct lcPieceControlPoint
|
||||
{
|
||||
lcMatrix44 Transform;
|
||||
float Scale;
|
||||
|
||||
bool operator==(const lcPieceControlPoint& Other) const
|
||||
{
|
||||
return Transform == Other.Transform && Scale == Other.Scale;
|
||||
}
|
||||
};
|
||||
|
||||
struct lcPieceHistoryState
|
||||
{
|
||||
lcObjectId Id;
|
||||
bool Hidden;
|
||||
int FileLine;
|
||||
QString PieceId;
|
||||
uint32_t GroupIndex;
|
||||
int ColorIndex;
|
||||
quint32 ColorCode;
|
||||
lcStep StepShow;
|
||||
lcStep StepHide;
|
||||
lcMatrix44 PivotMatrix;
|
||||
bool PivotPointValid;
|
||||
std::vector<lcPieceControlPoint> ControlPoints;
|
||||
lcObjectProperty<lcVector3> Position;
|
||||
lcObjectProperty<lcMatrix33> Rotation;
|
||||
|
||||
bool operator==(const lcPieceHistoryState& Other) const
|
||||
{
|
||||
return Id == Other.Id && Hidden == Other.Hidden && FileLine == Other.FileLine && PieceId == Other.PieceId &&
|
||||
GroupIndex == Other.GroupIndex && ColorIndex == Other.ColorIndex && ColorCode == Other.ColorCode &&
|
||||
StepShow == Other.StepShow && StepHide == Other.StepHide && PivotMatrix == Other.PivotMatrix &&
|
||||
PivotPointValid == Other.PivotPointValid && ControlPoints == Other.ControlPoints &&
|
||||
Position == Other.Position && Rotation == Other.Rotation;
|
||||
}
|
||||
};
|
||||
|
||||
class lcPiece : public lcObject
|
||||
{
|
||||
public:
|
||||
lcPiece();
|
||||
lcPiece(PieceInfo* Info);
|
||||
lcPiece(const lcPiece& Other);
|
||||
virtual ~lcPiece();
|
||||
@@ -60,8 +93,8 @@ public:
|
||||
bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override;
|
||||
bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) override;
|
||||
void RemoveKeyFrames() override;
|
||||
bool SaveUndoData(QDataStream& Stream, const lcModel* Model) const override;
|
||||
bool LoadUndoData(QDataStream& Stream, const lcModel* Model) override;
|
||||
lcPieceHistoryState GetHistoryState(const lcModel* Model) const;
|
||||
void SetHistoryState(const lcPieceHistoryState& State, const lcModel* Model);
|
||||
|
||||
void AddMainModelRenderMeshes(lcScene* Scene, bool Highlight, bool Fade) const;
|
||||
void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const;
|
||||
@@ -240,10 +273,10 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
PieceInfo* mPieceInfo;
|
||||
PieceInfo* mPieceInfo = nullptr;
|
||||
|
||||
lcMatrix44 mModelWorld;
|
||||
lcMatrix44 mPivotMatrix;
|
||||
lcMatrix44 mPivotMatrix = lcMatrix44Identity();
|
||||
|
||||
protected:
|
||||
void UpdateMesh();
|
||||
@@ -266,13 +299,13 @@ protected:
|
||||
int mFileLine = -1;
|
||||
QString mID;
|
||||
|
||||
lcGroup* mGroup;
|
||||
lcGroup* mGroup = nullptr;
|
||||
|
||||
int mColorIndex;
|
||||
quint32 mColorCode;
|
||||
|
||||
lcStep mStepShow;
|
||||
lcStep mStepHide;
|
||||
lcStep mStepShow = 1;
|
||||
lcStep mStepHide = LC_STEP_MAX;
|
||||
|
||||
bool mPivotPointValid = false;
|
||||
std::vector<lcPieceControlPoint> mControlPoints;
|
||||
|
||||
Reference in New Issue
Block a user