leocad/common/object.cpp

229 lines
5.2 KiB
C++
Raw Normal View History

#include "lc_global.h"
2011-09-07 23:06:51 +02:00
#include "object.h"
2023-10-02 01:24:42 +02:00
#define LC_OBJECT_ATTRIBUTE(T) \
2023-12-28 20:32:25 +01:00
template void lcObjectProperty<T>::SaveKeysLDraw(QTextStream& Stream, const char* ObjectName, const char* VariableName) const; \
template void lcObjectProperty<T>::LoadKeysLDraw(QTextStream& Stream); \
template const T& lcObjectProperty<T>::CalculateKey(lcStep Step) const; \
template void lcObjectProperty<T>::ChangeKey(const T& Value, lcStep Step, bool AddKey); \
template void lcObjectProperty<T>::InsertTime(lcStep Start, lcStep Time); \
template void lcObjectProperty<T>::RemoveTime(lcStep Start, lcStep Time); \
2023-12-27 21:03:41 +01:00
template void lcObjectProperty<T>::Save(QTextStream& Stream, const char* ObjectName, const char* VariableName) const; \
2023-12-28 20:32:25 +01:00
template bool lcObjectProperty<T>::Load(QTextStream& Stream, const QString& Token, const char* VariableName);
2023-10-02 01:24:42 +02:00
LC_OBJECT_ATTRIBUTE(float);
2023-11-20 03:05:43 +01:00
LC_OBJECT_ATTRIBUTE(lcVector2i);
2023-10-02 01:24:42 +02:00
LC_OBJECT_ATTRIBUTE(lcVector2);
LC_OBJECT_ATTRIBUTE(lcVector3);
LC_OBJECT_ATTRIBUTE(lcVector4);
LC_OBJECT_ATTRIBUTE(lcMatrix33);
2014-05-01 20:42:11 +02:00
lcObject::lcObject(lcObjectType ObjectType)
2014-08-31 02:53:12 +02:00
: mObjectType(ObjectType)
2011-09-07 23:06:51 +02:00
{
}
2014-05-01 20:42:11 +02:00
lcObject::~lcObject()
2011-09-07 23:06:51 +02:00
{
}
2023-10-02 01:24:42 +02:00
template<typename T>
2023-12-23 21:50:54 +01:00
static void SaveValue(QTextStream& Stream, const T& Value)
2023-10-02 01:24:42 +02:00
{
constexpr int Count = sizeof(T) / sizeof(float);
for (int ValueIndex = 0; ValueIndex < Count; ValueIndex++)
Stream << ((const float*)&Value)[ValueIndex] << ' ';
}
2023-08-07 11:31:33 +02:00
2023-12-23 21:50:54 +01:00
template<>
void SaveValue(QTextStream& Stream, const lcVector2i& Value)
{
constexpr int Count = sizeof(lcVector2i) / sizeof(int);
for (int ValueIndex = 0; ValueIndex < Count; ValueIndex++)
Stream << ((const int*)&Value)[ValueIndex] << ' ';
}
template<typename T>
2023-12-23 21:50:54 +01:00
static void LoadValue(QTextStream& Stream, T& Value)
{
2021-11-15 03:34:24 +01:00
constexpr int Count = sizeof(T) / sizeof(float);
2023-10-02 01:24:42 +02:00
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
Stream >> ((float*)&Value)[ValueIdx];
}
2023-12-23 21:50:54 +01:00
template<>
void LoadValue(QTextStream& Stream, lcVector2i& Value)
{
constexpr int Count = sizeof(lcVector2i) / sizeof(int);
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
Stream >> ((int*)&Value)[ValueIdx];
}
2023-10-02 01:24:42 +02:00
template<typename T>
2023-12-28 20:32:25 +01:00
void lcObjectProperty<T>::SaveKeysLDraw(QTextStream& Stream, const char* ObjectName, const char* VariableName) const
2023-10-02 01:24:42 +02:00
{
for (const lcObjectKey<T>& Key : mKeys)
{
2023-10-02 01:24:42 +02:00
Stream << QLatin1String("0 !LEOCAD ") << ObjectName << ' ' << VariableName << "_KEY " << Key.Step << ' ';
2023-12-23 21:50:54 +01:00
SaveValue(Stream, Key.Value);
Stream << QLatin1String("\r\n");
}
}
template<typename T>
2023-12-28 20:32:25 +01:00
void lcObjectProperty<T>::LoadKeysLDraw(QTextStream& Stream)
{
QString Token;
Stream >> Token;
2021-11-15 03:34:24 +01:00
const int Step = Token.toInt();
T Value;
2021-11-15 03:34:24 +01:00
constexpr int Count = sizeof(T) / sizeof(float);
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
Stream >> ((float*)&Value)[ValueIdx];
ChangeKey(Value, Step, true);
}
template<typename T>
2023-12-28 20:32:25 +01:00
const T& lcObjectProperty<T>::CalculateKey(lcStep Step) const
{
const lcObjectKey<T>* PreviousKey = &mKeys[0];
for (const lcObjectKey<T>& Key : mKeys)
{
if (Key.Step > Step)
break;
PreviousKey = &Key;
}
return PreviousKey->Value;
}
template<typename T>
2023-12-28 20:32:25 +01:00
void lcObjectProperty<T>::ChangeKey(const T& Value, lcStep Step, bool AddKey)
{
2021-01-06 00:19:53 +01:00
for (typename std::vector<lcObjectKey<T>>::iterator KeyIt = mKeys.begin(); KeyIt != mKeys.end(); KeyIt++)
{
2021-01-05 21:27:45 +01:00
if (KeyIt->Step < Step)
continue;
2021-01-05 21:27:45 +01:00
if (KeyIt->Step == Step)
KeyIt->Value = Value;
else if (AddKey)
mKeys.insert(KeyIt, lcObjectKey<T>{ Step, Value });
else if (KeyIt == mKeys.begin())
KeyIt->Value = Value;
else
{
2021-01-05 21:27:45 +01:00
KeyIt = KeyIt - 1;
KeyIt->Value = Value;
}
2021-01-05 21:27:45 +01:00
return;
}
2021-01-05 21:27:45 +01:00
if (AddKey || mKeys.empty())
mKeys.emplace_back(lcObjectKey<T>{ Step, Value });
else
2021-01-05 21:27:45 +01:00
mKeys.back().Value = Value;
}
template<typename T>
2023-12-28 20:32:25 +01:00
void lcObjectProperty<T>::InsertTime(lcStep Start, lcStep Time)
{
bool EndKey = false;
2021-01-06 00:19:53 +01:00
for (typename std::vector<lcObjectKey<T>>::iterator KeyIt = mKeys.begin(); KeyIt != mKeys.end();)
{
2021-01-05 21:27:45 +01:00
if ((KeyIt->Step < Start) || (KeyIt->Step == 1))
{
KeyIt++;
continue;
2021-01-05 21:27:45 +01:00
}
if (EndKey)
{
2021-01-05 21:27:45 +01:00
KeyIt = mKeys.erase(KeyIt);
continue;
}
2021-01-05 21:27:45 +01:00
if (KeyIt->Step >= LC_STEP_MAX - Time)
{
2021-01-05 21:27:45 +01:00
KeyIt->Step = LC_STEP_MAX;
EndKey = true;
}
else
2021-01-05 21:27:45 +01:00
KeyIt->Step += Time;
KeyIt++;
}
}
template<typename T>
2023-12-28 20:32:25 +01:00
void lcObjectProperty<T>::RemoveTime(lcStep Start, lcStep Time)
{
2021-01-06 00:19:53 +01:00
for (typename std::vector<lcObjectKey<T>>::iterator KeyIt = mKeys.begin(); KeyIt != mKeys.end();)
{
2021-01-05 21:27:45 +01:00
if ((KeyIt->Step < Start) || (KeyIt->Step == 1))
{
KeyIt++;
continue;
2021-01-05 21:27:45 +01:00
}
2021-01-05 21:27:45 +01:00
if (KeyIt->Step < Start + Time)
{
2021-01-05 21:27:45 +01:00
KeyIt = mKeys.erase(KeyIt);
continue;
}
2021-01-05 21:27:45 +01:00
KeyIt->Step -= Time;
KeyIt++;
}
}
2023-10-02 01:24:42 +02:00
2023-12-27 21:03:41 +01:00
template<typename T>
void lcObjectProperty<T>::Save(QTextStream& Stream, const char* ObjectName, const char* VariableName) const
{
if (GetSize() == 1)
{
Stream << QLatin1String("0 !LEOCAD ") << ObjectName << ' ' << VariableName << ' ';
SaveValue(Stream, mValue);
Stream << QLatin1String("\r\n");
}
else
SaveKeysLDraw(Stream, ObjectName, VariableName);
}
template<typename T>
bool lcObjectProperty<T>::Load(QTextStream& Stream, const QString& Token, const char* VariableName)
{
if (Token == VariableName)
{
LoadValue(Stream, mValue);
ChangeKey(mValue, 1, true);
return true;
}
if (Token.endsWith(QLatin1String("_KEY")) && Token.leftRef(Token.size() - 4) == VariableName)
{
LoadKeysLDraw(Stream);
return true;
}
return false;
}