diff --git a/common/camera.cpp b/common/camera.cpp index 3ec04fe5..e29790af 100644 --- a/common/camera.cpp +++ b/common/camera.cpp @@ -15,13 +15,6 @@ #define LC_CAMERA_SAVE_VERSION 7 // LeoCAD 0.80 -static LC_OBJECT_KEY_INFO camera_key_info[LC_CK_COUNT] = -{ - { "Camera Position", 3, LC_CK_EYE }, - { "Camera Target", 3, LC_CK_TARGET }, - { "Camera Up Vector", 3, LC_CK_UP } -}; - lcCamera::lcCamera(bool Simple) : lcObject(LC_OBJECT_CAMERA) { @@ -36,9 +29,9 @@ lcCamera::lcCamera(bool Simple) mOrthoTarget = mTargetPosition; mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f); - ChangeKey(1, true, mPosition, LC_CK_EYE); - ChangeKey(1, true, mTargetPosition, LC_CK_TARGET); - ChangeKey(1, true, mUpVector, LC_CK_UP); + ChangeKey(mPositionKeys, mPosition, 1, true); + ChangeKey(mTargetPositionKeys, mTargetPosition, 1, true); + ChangeKey(mUpVectorKeys, mUpVector, 1, true); UpdatePosition(1); } @@ -59,11 +52,9 @@ lcCamera::lcCamera(float ex, float ey, float ez, float tx, float ty, float tz) Initialize(); - float eye[3] = { ex, ey, ez }, target[3] = { tx, ty, tz }; - - ChangeKey(1, true, eye, LC_CK_EYE); - ChangeKey(1, true, target, LC_CK_TARGET); - ChangeKey(1, true, UpVector, LC_CK_UP); + ChangeKey(mPositionKeys, lcVector3(ex, ey, ez), 1, true); + ChangeKey(mTargetPositionKeys, lcVector3(tx, ty, tz), 1, true); + ChangeKey(mUpVectorKeys, UpVector, 1, true); UpdatePosition(1); } @@ -83,9 +74,6 @@ void lcCamera::Initialize() m_pTR = NULL; memset(m_strName, 0, sizeof(m_strName)); - - float *values[] = { mPosition, mTargetPosition, mUpVector }; - RegisterKeys(values, camera_key_info, LC_CK_COUNT); } void lcCamera::CreateName(const lcArray& Cameras) @@ -115,37 +103,20 @@ QJsonObject lcCamera::Save() if (IsOrtho()) Camera[QStringLiteral("Orthographic")] = QStringLiteral("true"); - QJsonArray PositionKeys, TargetPositionKeys, UpVectorKeys; - - for (LC_OBJECT_KEY* Node = m_pInstructionKeys; Node; Node = Node->next) - { - QJsonObject Key; - - Key[QStringLiteral("Step")] = QString::number(Node->Step); - Key["Value"] = QStringLiteral("%1 %2 %3").arg(QString::number(Node->param[0]), QString::number(Node->param[1]), QString::number(Node->param[2])); - - if (Node->type == LC_CK_EYE) - PositionKeys.append(Key); - else if (Node->type == LC_CK_TARGET) - TargetPositionKeys.append(Key); - else if (Node->type == LC_CK_UP) - UpVectorKeys.append(Key); - } - - if (PositionKeys.size() == 1) - Camera[QStringLiteral("Position")] = PositionKeys.first().toObject()[QStringLiteral("Value")].toString(); + if (mPositionKeys.GetSize() < 2) + Camera[QStringLiteral("Position")] = QStringLiteral("%1 %2 %3").arg(QString::number(mPosition[0]), QString::number(mPosition[1]), QString::number(mPosition[2])); else - Camera[QStringLiteral("PositionKeys")] = PositionKeys; - - if (TargetPositionKeys.size() == 1) - Camera[QStringLiteral("TargetPosition")] = TargetPositionKeys.first().toObject()[QStringLiteral("Value")].toString(); - else - Camera[QStringLiteral("UpVectorKeys")] = UpVectorKeys; - - if (UpVectorKeys.size() == 1) - Camera[QStringLiteral("UpVector")] = UpVectorKeys.first().toObject()[QStringLiteral("Value")].toString(); + Camera[QStringLiteral("PositionKeys")] = SaveKeys(mPositionKeys); + + if (mTargetPositionKeys.GetSize() < 2) + Camera[QStringLiteral("TargetPosition")] = QStringLiteral("%1 %2 %3").arg(QString::number(mTargetPosition[0]), QString::number(mTargetPosition[1]), QString::number(mTargetPosition[2])); else - Camera[QStringLiteral("TargetPositionKeys")] = TargetPositionKeys; + Camera[QStringLiteral("TargetPositionKeys")] = SaveKeys(mTargetPositionKeys); + + if (mUpVectorKeys.GetSize() < 2) + Camera[QStringLiteral("UpVector")] = QStringLiteral("%1 %2 %3").arg(QString::number(mUpVector[0]), QString::number(mUpVector[1]), QString::number(mUpVector[2])); + else + Camera[QStringLiteral("UpVectorKeys")] = SaveKeys(mUpVectorKeys); return Camera; } @@ -168,9 +139,39 @@ bool lcCamera::FileLoad(lcFile& file) return false; if (version > 5) - if (!lcObject::FileLoad(file)) + { + if (file.ReadU8() != 1) return false; + lcuint16 time; + float param[4]; + lcuint8 type; + lcuint32 n; + + file.ReadU32(&n, 1); + while (n--) + { + file.ReadU16(&time, 1); + file.ReadFloats(param, 4); + file.ReadU8(&type, 1); + + if (type == 0) + ChangeKey(mPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); + else if (type == 1) + ChangeKey(mTargetPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); + else if (type == 2) + ChangeKey(mUpVectorKeys, lcVector3(param[0], param[1], param[2]), time, true); + } + + file.ReadU32(&n, 1); + while (n--) + { + file.ReadU16(&time, 1); + file.ReadFloats(param, 4); + file.ReadU8(&type, 1); + } + } + if (version == 4) { file.ReadBuffer(m_strName, 80); @@ -194,19 +195,19 @@ bool lcCamera::FileLoad(lcFile& file) f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; - ChangeKey(1, true, f, LC_CK_EYE); + ChangeKey(mPositionKeys, lcVector3(f[0], f[1], f[2]), 1, true); file.ReadDoubles(d, 3); f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; - ChangeKey(1, true, f, LC_CK_TARGET); + ChangeKey(mTargetPositionKeys, lcVector3(f[0], f[1], f[2]), 1, true); file.ReadDoubles(d, 3); f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; - ChangeKey(1, true, f, LC_CK_UP); + ChangeKey(mUpVectorKeys, lcVector3(f[0], f[1], f[2]), 1, true); } if (version == 3) @@ -230,17 +231,17 @@ bool lcCamera::FileLoad(lcFile& file) f[0] = (float)eye[0]; f[1] = (float)eye[1]; f[2] = (float)eye[2]; - ChangeKey(step, true, f, LC_CK_EYE); + ChangeKey(mPositionKeys, lcVector3(f[0], f[1], f[2]), step, true); f[0] = (float)target[0]; f[1] = (float)target[1]; f[2] = (float)target[2]; - ChangeKey(step, true, f, LC_CK_TARGET); + ChangeKey(mTargetPositionKeys, lcVector3(f[0], f[1], f[2]), step, true); f[0] = (float)up[0]; f[1] = (float)up[1]; f[2] = (float)up[2]; - ChangeKey(step, true, f, LC_CK_UP); + ChangeKey(mUpVectorKeys, lcVector3(f[0], f[1], f[2]), step, true); file.ReadS32(); // snapshot file.ReadS32(); // cam @@ -270,7 +271,12 @@ bool lcCamera::FileLoad(lcFile& file) file.ReadFloats(param, 3); file.ReadU8(&type, 1); - ChangeKey(time, true, param, type); + if (type == 0) + ChangeKey(mPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); + else if (type == 1) + ChangeKey(mTargetPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); + else if (type == 2) + ChangeKey(mUpVectorKeys, lcVector3(param[0], param[1], param[2]), time, true); } n = file.ReadS32(); @@ -318,15 +324,11 @@ bool lcCamera::FileLoad(lcFile& file) m_zFar *= 25.0f; m_zNear *= 25.0f; - for (LC_OBJECT_KEY* Key = m_pInstructionKeys; Key; Key = Key->next) - { - if (Key->type == LC_CK_EYE || Key->type == LC_CK_TARGET) - { - Key->param[0] *= 25.0f; - Key->param[1] *= 25.0f; - Key->param[2] *= 25.0f; - } - } + for (int KeyIdx = 0; KeyIdx < mPositionKeys.GetSize(); KeyIdx++) + mPositionKeys[KeyIdx].Value *= 25.0f; + + for (int KeyIdx = 0; KeyIdx < mTargetPositionKeys.GetSize(); KeyIdx++) + mTargetPositionKeys[KeyIdx].Value *= 25.0f; } return true; @@ -336,7 +338,43 @@ void lcCamera::FileSave(lcFile& file) const { file.WriteU8(LC_CAMERA_SAVE_VERSION); - lcObject::FileSave(file); + file.WriteU8(1); + file.WriteU32(mPositionKeys.GetSize() + mTargetPositionKeys.GetSize() + mUpVectorKeys.GetSize()); + + for (int KeyIdx = 0; KeyIdx < mPositionKeys.GetSize(); KeyIdx++) + { + lcObjectKey& Key = mPositionKeys[KeyIdx]; + + lcuint16 Step = lcMin(Key.Step, 0xFFFFU); + file.WriteU16(Step); + file.WriteFloats(Key.Value, 3); + file.WriteFloat(0); + file.WriteU8(0); + } + + for (int KeyIdx = 0; KeyIdx < mTargetPositionKeys.GetSize(); KeyIdx++) + { + lcObjectKey& Key = mTargetPositionKeys[KeyIdx]; + + lcuint16 Step = lcMin(Key.Step, 0xFFFFU); + file.WriteU16(Step); + file.WriteFloats(Key.Value, 3); + file.WriteFloat(0); + file.WriteU8(1); + } + + for (int KeyIdx = 0; KeyIdx < mUpVectorKeys.GetSize(); KeyIdx++) + { + lcObjectKey& Key = mUpVectorKeys[KeyIdx]; + + lcuint16 Step = lcMin(Key.Step, 0xFFFFU); + file.WriteU16(Step); + file.WriteFloats(Key.Value, 3); + file.WriteFloat(0); + file.WriteU8(2); + } + + file.WriteU32(0); lcuint8 ch = (lcuint8)strlen(m_strName); file.WriteU8(ch); @@ -362,20 +400,19 @@ void lcCamera::Move(lcStep Step, bool AddKey, const lcVector3& Distance) { mPosition += Distance; lcAlign(mOrthoTarget, mPosition, mTargetPosition); - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); } if (IsSelected(LC_CAMERA_SECTION_TARGET)) { mTargetPosition += Distance; - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); } - - if (IsSelected(LC_CAMERA_SECTION_UPVECTOR)) + else if (IsSelected(LC_CAMERA_SECTION_UPVECTOR)) { mUpVector += Distance; mUpVector.Normalize(); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_UP); + ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); } lcVector3 FrontVector(mTargetPosition - mPosition); @@ -390,7 +427,9 @@ void lcCamera::Move(lcStep Step, bool AddKey, const lcVector3& Distance) void lcCamera::UpdatePosition(lcStep Step) { - CalculateKeys(Step); + mPosition = CalculateKey(mPositionKeys, Step); + mTargetPosition = CalculateKey(mTargetPositionKeys, Step); + mUpVector = CalculateKey(mUpVectorKeys, Step); lcVector3 FrontVector(mPosition - mTargetPosition); lcVector3 SideVector = lcCross(FrontVector, mUpVector); @@ -661,6 +700,20 @@ void lcCamera::BoxTest(lcObjectBoxTest& ObjectBoxTest) const } } +void lcCamera::InsertTime(lcStep Start, lcStep Time) +{ + lcObject::InsertTime(mPositionKeys, Start, Time); + lcObject::InsertTime(mTargetPositionKeys, Start, Time); + lcObject::InsertTime(mUpVectorKeys, Start, Time); +} + +void lcCamera::RemoveTime(lcStep Start, lcStep Time) +{ + lcObject::RemoveTime(mPositionKeys, Start, Time); + lcObject::RemoveTime(mTargetPositionKeys, Start, Time); + lcObject::RemoveTime(mUpVectorKeys, Start, Time); +} + void lcCamera::ZoomExtents(View* view, const lcVector3& Center, const lcVector3* Points, int NumPoints, lcStep Step, bool AddKey) { int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; @@ -678,8 +731,8 @@ void lcCamera::ZoomExtents(View* view, const lcVector3& Center, const lcVector3* if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } @@ -704,8 +757,8 @@ void lcCamera::ZoomRegion(const lcVector3* Points, float RatioX, float RatioY, l if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } @@ -729,8 +782,8 @@ void lcCamera::Zoom(float Distance, lcStep Step, bool AddKey) if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } @@ -748,8 +801,8 @@ void lcCamera::Pan(float DistanceX, float DistanceY, lcStep Step, bool AddKey) if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } @@ -780,9 +833,9 @@ void lcCamera::Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPo if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); - ChangeKey(Step, AddKey, mUpVector, LC_CK_UP); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); + ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); UpdatePosition(Step); } @@ -797,7 +850,7 @@ void lcCamera::Roll(float Distance, lcStep Step, bool AddKey) if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mUpVector, LC_CK_UP); + ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); UpdatePosition(Step); } @@ -809,8 +862,8 @@ void lcCamera::Center(lcVector3& point, lcStep Step, bool AddKey) if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } @@ -847,9 +900,9 @@ void lcCamera::SetViewpoint(LC_VIEWPOINT Viewpoint, lcStep Step, bool AddKey) if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); - ChangeKey(Step, AddKey, mUpVector, LC_CK_UP); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); + ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); UpdatePosition(Step); } @@ -917,8 +970,8 @@ void lcCamera::SetFocalPoint(const lcVector3& focus, lcStep Step, bool AddKey) if (IsSimple()) AddKey = false; - ChangeKey(Step, AddKey, mPosition, LC_CK_EYE); - ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } diff --git a/common/camera.h b/common/camera.h index 56690d16..5c5dd09d 100644 --- a/common/camera.h +++ b/common/camera.h @@ -47,14 +47,6 @@ typedef enum LC_CAMERA_MAIN, LC_CAMERA_USER } LC_CAMERA_TYPES; -enum LC_CK_TYPES -{ - LC_CK_EYE, - LC_CK_TARGET, - LC_CK_UP, - LC_CK_COUNT -}; - class lcCamera : public lcObject { public: @@ -248,10 +240,28 @@ public: bool IsHidden() const { return (mState & LC_CAMERA_HIDDEN) != 0; } + void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey) + { + ChangeKey(mPositionKeys, Position, Step, AddKey); + } + + void SetTargetPosition(const lcVector3& TargetPosition, lcStep Step, bool AddKey) + { + ChangeKey(mTargetPositionKeys, TargetPosition, Step, AddKey); + } + + void SetUpVector(const lcVector3& UpVector, lcStep Step, bool AddKey) + { + ChangeKey(mPositionKeys, UpVector, Step, AddKey); + } + public: virtual void RayTest(lcObjectRayTest& ObjectRayTest) const; virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const; + void InsertTime(lcStep Start, lcStep Time); + void RemoveTime(lcStep Start, lcStep Time); + bool FileLoad(lcFile& file); void FileSave(lcFile& file) const; void Select(bool bSelecting, bool bFocus, bool bMultiple); @@ -290,6 +300,10 @@ public: TiledRender* m_pTR; protected: + lcArray> mPositionKeys; + lcArray> mTargetPositionKeys; + lcArray> mUpVectorKeys; + void Initialize(); lcuint32 mState; diff --git a/common/lc_array.h b/common/lc_array.h index 6f8a01e5..03af47cc 100644 --- a/common/lc_array.h +++ b/common/lc_array.h @@ -120,6 +120,20 @@ public: Add(Obj); } + T& InsertAt(int Index) + { + if (Index >= mLength) + AllocGrow(Index - mLength + 1); + else + AllocGrow(1); + + mLength++; + for (int i = mLength - 1; i > Index; i--) + mData[i] = mData[i - 1]; + + return mData[Index]; + } + void InsertAt(int Index, const T& NewItem) { if (Index >= mLength) diff --git a/common/light.cpp b/common/light.cpp index eefb79e4..4939141d 100644 --- a/common/light.cpp +++ b/common/light.cpp @@ -11,31 +11,11 @@ #include "lc_application.h" #include "lc_context.h" -static LC_OBJECT_KEY_INFO light_key_info[LC_LK_COUNT] = -{ - { "Light Position", 3, LC_LK_POSITION }, - { "Light Target", 3, LC_LK_TARGET }, - { "Ambient Color", 3, LC_LK_AMBIENT_COLOR }, - { "Diffuse Color", 3, LC_LK_DIFFUSE_COLOR }, - { "Specular Color", 3, LC_LK_SPECULAR_COLOR }, - { "Constant Attenuation", 1, LC_LK_CONSTANT_ATTENUATION }, - { "Linear Attenuation", 1, LC_LK_LINEAR_ATTENUATION }, - { "Quadratic Attenuation", 1, LC_LK_QUADRATIC_ATTENUATION }, - { "Spot Cutoff", 1, LC_LK_SPOT_CUTOFF }, - { "Spot Exponent", 1, LC_LK_SPOT_EXPONENT } -}; - // New omni light. lcLight::lcLight(float px, float py, float pz) : lcObject(LC_OBJECT_LIGHT) { - Initialize(); - - float pos[] = { px, py, pz }, target[] = { 0, 0, 0 }; - - ChangeKey(1, true, pos, LC_LK_POSITION); - ChangeKey(1, true, target, LC_LK_TARGET); - + Initialize(lcVector3(px, py, pz), lcVector3(0.0f, 0.0f, 0.0f)); UpdatePosition(1); } @@ -43,41 +23,23 @@ lcLight::lcLight(float px, float py, float pz) lcLight::lcLight(float px, float py, float pz, float tx, float ty, float tz) : lcObject(LC_OBJECT_LIGHT) { - Initialize(); - - float pos[] = { px, py, pz }, target[] = { tx, ty, tz }; - - ChangeKey(1, true, pos, LC_LK_POSITION); - ChangeKey(1, true, target, LC_LK_TARGET); - + Initialize(lcVector3(px, py, pz), lcVector3(tx, ty, tz)); UpdatePosition(1); } -void lcLight::Initialize() +void lcLight::Initialize(const lcVector3& Position, const lcVector3& TargetPosition) { mState = 0; memset(m_strName, 0, sizeof(m_strName)); - mAmbientColor[3] = 1.0f; - mDiffuseColor[3] = 1.0f; - mSpecularColor[3] = 1.0f; - - float *values[] = { mPosition, mTargetPosition, mAmbientColor, mDiffuseColor, mSpecularColor, - &mConstantAttenuation, &mLinearAttenuation, &mQuadraticAttenuation, &mSpotCutoff, &mSpotExponent }; - RegisterKeys(values, light_key_info, LC_LK_COUNT); - - // set the default values - float ambient[] = { 0, 0, 0 }, diffuse[] = { 0.8f, 0.8f, 0.8f }, specular[] = { 1, 1, 1 }; - float constant = 1, linear = 0, quadratic = 0, cutoff = 30, exponent = 0; - - ChangeKey(1, true, ambient, LC_LK_AMBIENT_COLOR); - ChangeKey(1, true, diffuse, LC_LK_DIFFUSE_COLOR); - ChangeKey(1, true, specular, LC_LK_SPECULAR_COLOR); - ChangeKey(1, true, &constant, LC_LK_CONSTANT_ATTENUATION); - ChangeKey(1, true, &linear, LC_LK_LINEAR_ATTENUATION); - ChangeKey(1, true, &quadratic, LC_LK_QUADRATIC_ATTENUATION); - ChangeKey(1, true, &cutoff, LC_LK_SPOT_CUTOFF); - ChangeKey(1, true, &exponent, LC_LK_SPOT_EXPONENT); + ChangeKey(mPositionKeys, Position, 1, true); + ChangeKey(mTargetPositionKeys, TargetPosition, 1, true); + ChangeKey(mAmbientColorKeys, lcVector4(0.0f, 0.0f, 0.0f, 1.0f), 1, true); + ChangeKey(mDiffuseColorKeys, lcVector4(0.8f, 0.8f, 0.8f, 1.0f), 1, true); + ChangeKey(mSpecularColorKeys, lcVector4(1.0f, 1.0f, 1.0f, 1.0f), 1, true); + ChangeKey(mAttenuationKeys, lcVector3(1.0f, 0.0f, 0.0f), 1, true); + ChangeKey(mSpotCutoffKeys, 30.0f, 1, true); + ChangeKey(mSpotExponentKeys, 0.0f, 1, true); } lcLight::~lcLight() @@ -229,21 +191,50 @@ void lcLight::Move(lcStep Step, bool AddKey, const lcVector3& Distance) if (IsSelected(LC_LIGHT_SECTION_POSITION)) { mPosition += Distance; - - ChangeKey(Step, AddKey, mPosition, LC_LK_POSITION); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); } if (IsSelected(LC_LIGHT_SECTION_TARGET)) { mTargetPosition += Distance; - - ChangeKey(Step, AddKey, mTargetPosition, LC_LK_TARGET); + ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); } } +void lcLight::InsertTime(lcStep Start, lcStep Time) +{ + lcObject::InsertTime(mPositionKeys, Start, Time); + lcObject::InsertTime(mTargetPositionKeys, Start, Time); + lcObject::InsertTime(mAmbientColorKeys, Start, Time); + lcObject::InsertTime(mDiffuseColorKeys, Start, Time); + lcObject::InsertTime(mSpecularColorKeys, Start, Time); + lcObject::InsertTime(mAttenuationKeys, Start, Time); + lcObject::InsertTime(mSpotCutoffKeys, Start, Time); + lcObject::InsertTime(mSpotExponentKeys, Start, Time); +} + +void lcLight::RemoveTime(lcStep Start, lcStep Time) +{ + lcObject::RemoveTime(mPositionKeys, Start, Time); + lcObject::RemoveTime(mTargetPositionKeys, Start, Time); + lcObject::RemoveTime(mAmbientColorKeys, Start, Time); + lcObject::RemoveTime(mDiffuseColorKeys, Start, Time); + lcObject::RemoveTime(mSpecularColorKeys, Start, Time); + lcObject::RemoveTime(mAttenuationKeys, Start, Time); + lcObject::RemoveTime(mSpotCutoffKeys, Start, Time); + lcObject::RemoveTime(mSpotExponentKeys, Start, Time); +} + void lcLight::UpdatePosition(lcStep Step) { - CalculateKeys(Step); + mPosition = CalculateKey(mPositionKeys, Step); + mTargetPosition = CalculateKey(mTargetPositionKeys, Step); + mAmbientColor = CalculateKey(mAmbientColorKeys, Step); + mDiffuseColor = CalculateKey(mDiffuseColorKeys, Step); + mSpecularColor = CalculateKey(mSpecularColorKeys, Step); + mAttenuation = CalculateKey(mAttenuationKeys, Step); + mSpotCutoff = CalculateKey(mSpotCutoffKeys, Step); + mSpotExponent = CalculateKey(mSpotExponentKeys, Step); if (IsPointLight()) { @@ -573,9 +564,9 @@ bool lcLight::Setup(int LightIndex) if (!IsDirectionalLight()) { - glLightf(LightName, GL_CONSTANT_ATTENUATION, mConstantAttenuation); - glLightf(LightName, GL_LINEAR_ATTENUATION, mLinearAttenuation); - glLightf(LightName, GL_QUADRATIC_ATTENUATION, mQuadraticAttenuation); + glLightf(LightName, GL_CONSTANT_ATTENUATION, mAttenuation[0]); + glLightf(LightName, GL_LINEAR_ATTENUATION, mAttenuation[1]); + glLightf(LightName, GL_QUADRATIC_ATTENUATION, mAttenuation[2]); lcVector4 Position(mPosition, 1.0f); glLightfv(LightName, GL_POSITION, Position); diff --git a/common/light.h b/common/light.h index e51fb17a..318d7a53 100644 --- a/common/light.h +++ b/common/light.h @@ -24,21 +24,6 @@ enum lcLightSection LC_LIGHT_SECTION_TARGET }; -enum LC_LK_TYPES -{ - LC_LK_POSITION, - LC_LK_TARGET, - LC_LK_AMBIENT_COLOR, - LC_LK_DIFFUSE_COLOR, - LC_LK_SPECULAR_COLOR, - LC_LK_CONSTANT_ATTENUATION, - LC_LK_LINEAR_ATTENUATION, - LC_LK_QUADRATIC_ATTENUATION, - LC_LK_SPOT_CUTOFF, - LC_LK_SPOT_EXPONENT, - LC_LK_COUNT -}; - class lcLight : public lcObject { public: @@ -192,6 +177,9 @@ public: virtual void RayTest(lcObjectRayTest& ObjectRayTest) const; virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const; + void InsertTime(lcStep Start, lcStep Time); + void RemoveTime(lcStep Start, lcStep Time); + bool IsVisible() const { return (mState & LC_LIGHT_HIDDEN) == 0; } @@ -220,14 +208,21 @@ public: lcVector4 mAmbientColor; lcVector4 mDiffuseColor; lcVector4 mSpecularColor; - float mConstantAttenuation; - float mLinearAttenuation; - float mQuadraticAttenuation; + lcVector3 mAttenuation; float mSpotCutoff; float mSpotExponent; protected: - void Initialize(); + lcArray> mPositionKeys; + lcArray> mTargetPositionKeys; + lcArray> mAmbientColorKeys; + lcArray> mDiffuseColorKeys; + lcArray> mSpecularColorKeys; + lcArray> mAttenuationKeys; + lcArray> mSpotCutoffKeys; + lcArray> mSpotExponentKeys; + + void Initialize(const lcVector3& Position, const lcVector3& TargetPosition); float m_fCone; lcuint32 mState; diff --git a/common/object.cpp b/common/object.cpp index fd735162..918c7d52 100644 --- a/common/object.cpp +++ b/common/object.cpp @@ -1,242 +1,45 @@ #include "lc_global.h" -#include "lc_math.h" -#include -#include -#include -#include "project.h" #include "object.h" -#include "lc_file.h" -#include "lc_application.h" - -#define LC_KEY_SAVE_VERSION 1 // LeoCAD 0.73 lcObject::lcObject(lcObjectType ObjectType) + : mObjectType(ObjectType) { - m_pInstructionKeys = NULL; - - mObjectType = ObjectType; - m_pKeyValues = NULL; } lcObject::~lcObject() { - delete []m_pKeyValues; - RemoveKeys(); } -bool lcObject::FileLoad(lcFile& file) +QJsonArray lcObject::SaveKeys(const lcArray>& Keys) { - lcuint8 version = file.ReadU8(); + QJsonArray KeyArray; - if (version > LC_KEY_SAVE_VERSION) - return false; - - lcuint16 time; - float param[4]; - lcuint8 type; - lcuint32 n; - - file.ReadU32(&n, 1); - while (n--) - { - file.ReadU16(&time, 1); - file.ReadFloats(param, 4); - file.ReadU8(&type, 1); - - ChangeKey(time, true, param, type); - } - - file.ReadU32(&n, 1); - while (n--) - { - file.ReadU16(&time, 1); - file.ReadFloats(param, 4); - file.ReadU8(&type, 1); - } - - return true; -} - -void lcObject::FileSave(lcFile& file) const -{ - LC_OBJECT_KEY *node; - lcuint32 n; - - file.WriteU8(LC_KEY_SAVE_VERSION); - - for (n = 0, node = m_pInstructionKeys; node; node = node->next) - n++; - file.WriteU32(n); - - for (node = m_pInstructionKeys; node; node = node->next) + for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++) { - lcuint16 Step = lcMin(node->Step, 0xFFFFU); - file.WriteU16(Step); - file.WriteFloats(node->param, 4); - file.WriteU8(node->type); + lcObjectKey& Key = Keys[KeyIdx]; + QJsonObject KeyObject; + + KeyObject[QStringLiteral("Step")] = QString::number(Key.Step); + KeyObject[QStringLiteral("Value")] = QStringLiteral("%1 %2 %3").arg(QString::number(Key.Value[0]), QString::number(Key.Value[1]), QString::number(Key.Value[2])); + KeyArray.append(KeyObject); } - file.WriteU32(0); + return KeyArray; } -// ============================================================================= -// Key handling - -static LC_OBJECT_KEY* AddNode(LC_OBJECT_KEY *node, lcStep Step, unsigned char nType) +QJsonArray lcObject::SaveKeys(const lcArray>& Keys) { - LC_OBJECT_KEY* newnode = (LC_OBJECT_KEY*)malloc(sizeof(LC_OBJECT_KEY)); + QJsonArray KeyArray; - if (node) - { - newnode->next = node->next; - node->next = newnode; - } - else - newnode->next = NULL; - - newnode->type = nType; - newnode->Step = Step; - newnode->param[0] = newnode->param[1] = newnode->param[2] = newnode->param[3] = 0; - - return newnode; -} - -void lcObject::RegisterKeys(float *values[], LC_OBJECT_KEY_INFO* info, int count) -{ - int i; - - m_pKeyValues = new float* [count]; - - for (i = 0; i < count; i++) - m_pKeyValues[i] = values[i]; - - m_pInstructionKeys = AddNode(NULL, 1, 0); - - for (i = count-1; i > 0; i--) - AddNode(m_pInstructionKeys, 1, i); - - m_pKeyInfo = info; - m_nKeyInfoCount = count; -} - -void lcObject::RemoveKeys() -{ - LC_OBJECT_KEY *node, *prev; - - for (node = m_pInstructionKeys; node;) - { - prev = node; - node = node->next; - free(prev); - } -} - -void lcObject::ChangeKey(lcStep Step, bool AddKey, const float *param, unsigned char nKeyType) -{ - LC_OBJECT_KEY *node, *poskey = NULL, *newpos = NULL; - node = m_pInstructionKeys; - - while (node) + for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++) { - if ((node->Step <= Step) && (node->type == nKeyType)) - poskey = node; + lcObjectKey& Key = Keys[KeyIdx]; + QJsonObject KeyObject; - node = node->next; + KeyObject[QStringLiteral("Step")] = QString::number(Key.Step); + KeyObject[QStringLiteral("Value")] = QStringLiteral("%1 %2 %3 %4").arg(QString::number(Key.Value[0]), QString::number(Key.Value[1]), QString::number(Key.Value[2]), QString::number(Key.Value[3])); + KeyArray.append(KeyObject); } - if (AddKey) - { - if (poskey) - { - if (poskey->Step != Step) - newpos = AddNode(poskey, Step, nKeyType); - } - else - newpos = AddNode(poskey, Step, nKeyType); - } - - if (newpos == NULL) - newpos = poskey; - - for (int i = 0; i < m_pKeyInfo[nKeyType].size; i++) - newpos->param[i] = param[i]; -} - -void lcObject::CalculateKeys(lcStep Step) -{ - LC_OBJECT_KEY* prev[32]; - - for (LC_OBJECT_KEY* node = m_pInstructionKeys; node; node = node->next) - if (node->Step <= Step) - prev[node->type] = node; - - for (int i = 0; i < m_nKeyInfoCount; i++) - { - LC_OBJECT_KEY *p = prev[i]; - - for (int j = 0; j < m_pKeyInfo[i].size; j++) - m_pKeyValues[i][j] = p->param[j]; - } -} - -void lcObject::InsertTime(lcStep Start, lcStep Time) -{ - LC_OBJECT_KEY *node, *prev = NULL; - bool end[32]; - - for (int i = 0; i < m_nKeyInfoCount; i++) - end[i] = false; - - node = m_pInstructionKeys; - - for (; node != NULL; prev = node, node = node->next) - { - // skip everything before the start time - if ((node->Step < Start) || (node->Step == 1)) - continue; - - // there's already a key at the end, delete this one - if (end[node->type]) - { - prev->next = node->next; - free(node); - node = prev; - - continue; - } - - if (node->Step >= LC_STEP_MAX - Time) - { - node->Step = LC_STEP_MAX; - end[node->type] = true; - } - else - node->Step += Time; - } -} - -void lcObject::RemoveTime(lcStep Start, lcStep Time) -{ - LC_OBJECT_KEY *node = m_pInstructionKeys, *prev = NULL; - - for (; node != NULL; prev = node, node = node->next) - { - // skip everything before the start time - if ((node->Step < Start) || (node->Step == 1)) - continue; - - if (node->Step < Start + Time) - { - // delete this key - prev->next = node->next; - free(node); - node = prev; - - continue; - } - - node->Step -= Time; - if (node->Step < 1) - node->Step = 1; - } + return KeyArray; } diff --git a/common/object.h b/common/object.h index 893d4f65..9d056e18 100644 --- a/common/object.h +++ b/common/object.h @@ -14,20 +14,11 @@ enum lcObjectType LC_OBJECT_LIGHT }; -// key handling -struct LC_OBJECT_KEY +template +struct lcObjectKey { lcStep Step; - float param[4]; - unsigned char type; - LC_OBJECT_KEY* next; -}; - -struct LC_OBJECT_KEY_INFO -{ - const char *description; - unsigned char size; // number of floats - unsigned char type; + T Value; }; struct lcObjectSection @@ -96,39 +87,120 @@ public: virtual const char* GetName() const = 0; protected: - virtual bool FileLoad(lcFile& file); - virtual void FileSave(lcFile& file) const; + QJsonArray SaveKeys(const lcArray>& Keys); + QJsonArray SaveKeys(const lcArray>& Keys); -public: - void ChangeKey(lcStep Step, bool AddKey, const float *param, unsigned char keytype); - virtual void InsertTime(lcStep Start, lcStep Time); - virtual void RemoveTime(lcStep Start, lcStep Time); - - int GetKeyTypeCount() const + template + const T& CalculateKey(const lcArray>& Keys, lcStep Step) { - return m_nKeyInfoCount; + lcObjectKey* PreviousKey = &Keys[0]; + + for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++) + { + if (Keys[KeyIdx].Step > Step) + break; + + PreviousKey = &Keys[KeyIdx]; + } + + return PreviousKey->Value; } - const LC_OBJECT_KEY_INFO* GetKeyTypeInfo(int index) const + template + void ChangeKey(lcArray>& Keys, const T& Value, lcStep Step, bool AddKey) { - return &m_pKeyInfo[index]; + lcObjectKey* Key; + + for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++) + { + Key = &Keys[KeyIdx]; + + if (Key->Step == Step) + { + Key->Value = Value; + + return; + } + + if (Key->Step > Step) + { + if (AddKey) + { + Key = &Keys.InsertAt(KeyIdx); + Key->Step = Step; + } + else if (KeyIdx) + Key = &Keys[KeyIdx - 1]; + + Key->Value = Value; + + return; + } + } + + if (AddKey || Keys.GetSize() == 0) + { + Key = &Keys.Add(); + + Key->Step = Step; + Key->Value = Value; + } + else + { + Key = &Keys[Keys.GetSize() - 1]; + Key->Value = Value; + } } - const float* GetKeyTypeValue(int index) const + template + void InsertTime(lcArray>& Keys, lcStep Start, lcStep Time) { - return m_pKeyValues[index]; + bool EndKey = false; + + for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++) + { + lcObjectKey& Key = Keys[KeyIdx]; + + if ((Key.Step < Start) || (Key.Step == 1)) + continue; + + if (EndKey) + { + Keys.RemoveIndex(KeyIdx); + KeyIdx--; + continue; + } + + if (Key.Step >= LC_STEP_MAX - Time) + { + Key.Step = LC_STEP_MAX; + EndKey = true; + } + else + Key.Step += Time; + } } -protected: - void RegisterKeys(float *values[], LC_OBJECT_KEY_INFO* info, int count); - void CalculateKeys(lcStep Step); - void RemoveKeys(); + template + void RemoveTime(lcArray>& Keys, lcStep Start, lcStep Time) + { + for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++) + { + lcObjectKey& Key = Keys[KeyIdx]; - LC_OBJECT_KEY* m_pInstructionKeys; - float **m_pKeyValues; + if ((Key.Step < Start) || (Key.Step == 1)) + continue; - LC_OBJECT_KEY_INFO *m_pKeyInfo; - int m_nKeyInfoCount; + if (Key.Step < Start + Time) + { + Keys.RemoveIndex(KeyIdx); + KeyIdx--; + continue; + } + + Key.Step -= Time; + } + } private: lcObjectType mObjectType; diff --git a/common/piece.cpp b/common/piece.cpp index 2b76effe..89df59d9 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -1,6 +1,3 @@ -// A piece object in the LeoCAD world. -// - #include "lc_global.h" #include "lc_mesh.h" #include "lc_colors.h" @@ -18,12 +15,6 @@ #define LC_PIECE_SAVE_VERSION 12 // LeoCAD 0.80 -static LC_OBJECT_KEY_INFO piece_key_info[LC_PK_COUNT] = -{ - { "Position", 3, LC_PK_POSITION }, - { "Rotation", 4, LC_PK_ROTATION } -}; - ///////////////////////////////////////////////////////////////////////////// // Piece construction/destruction @@ -42,12 +33,8 @@ lcPiece::lcPiece(PieceInfo* pPieceInfo) if (mPieceInfo != NULL) mPieceInfo->AddRef(); - float *values[] = { mPosition, mRotation }; - RegisterKeys (values, piece_key_info, LC_PK_COUNT); - - float pos[3] = { 0, 0, 0 }, rot[4] = { 0, 0, 1, 0 }; - ChangeKey(1, true, pos, LC_PK_POSITION); - ChangeKey(1, true, rot, LC_PK_ROTATION); + ChangeKey(mPositionKeys, lcVector3(0.0f, 0.0f, 0.0f), 1, true); + ChangeKey(mRotationKeys, lcVector4(0.0f, 0.0f, 1.0f, 0.0f), 1, true); } lcPiece::~lcPiece() @@ -69,36 +56,15 @@ QJsonObject lcPiece::Save() if (IsHidden()) Piece[QStringLiteral("Hidden")] = QStringLiteral("true"); - QJsonArray PositionKeys, RotationKeys; - - for (LC_OBJECT_KEY* Node = m_pInstructionKeys; Node; Node = Node->next) - { - QJsonObject Key; - - Key[QStringLiteral("Step")] = QString::number(Node->Step); - - if (Node->type == LC_PK_POSITION) - { - Key["Value"] = QStringLiteral("%1 %2 %3").arg(QString::number(Node->param[0]), QString::number(Node->param[1]), QString::number(Node->param[2])); - PositionKeys.append(Key); - } - else if (Node->type == LC_PK_ROTATION) - { - Key["Value"] = QStringLiteral("%1 %2 %3 %4").arg(QString::number(Node->param[0]), QString::number(Node->param[1]), QString::number(Node->param[2]), QString::number(Node->param[3])); - RotationKeys.append(Key); - } - } - - if (PositionKeys.size() == 1 && RotationKeys.size() == 1) - { - Piece[QStringLiteral("Position")] = PositionKeys.first().toObject()["Value"].toString(); - Piece[QStringLiteral("Rotation")] = RotationKeys.first().toObject()["Value"].toString(); - } + if (mPositionKeys.GetSize() < 2) + Piece[QStringLiteral("Position")] = QStringLiteral("%1 %2 %3").arg(QString::number(mPosition[0]), QString::number(mPosition[1]), QString::number(mPosition[2])); else - { - Piece["PositionKeys"] = PositionKeys; - Piece["RotationKeys"] = RotationKeys; - } + Piece[QStringLiteral("PositionKeys")] = SaveKeys(mPositionKeys); + + if (mRotationKeys.GetSize() < 2) + Piece[QStringLiteral("Rotation")] = QStringLiteral("%1 %2 %3 %4").arg(QString::number(mRotation[0]), QString::number(mRotation[1]), QString::number(mRotation[2]), QString::number(mRotation[3])); + else + Piece[QStringLiteral("RotationKeys")] = SaveKeys(mRotationKeys); return Piece; } @@ -120,16 +86,44 @@ void lcPiece::SetPieceInfo(PieceInfo* pPieceInfo) bool lcPiece::FileLoad(lcFile& file) { - lcuint8 version, ch; + lcuint8 version, ch; - version = file.ReadU8(); + version = file.ReadU8(); - if (version > LC_PIECE_SAVE_VERSION) - return false; + if (version > LC_PIECE_SAVE_VERSION) + return false; - if (version > 8) - if (!lcObject::FileLoad (file)) - return false; + if (version > 8) + { + if (file.ReadU8() != 1) + return false; + + lcuint16 time; + float param[4]; + lcuint8 type; + lcuint32 n; + + file.ReadU32(&n, 1); + while (n--) + { + file.ReadU16(&time, 1); + file.ReadFloats(param, 4); + file.ReadU8(&type, 1); + + if (type == 0) + ChangeKey(mPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); + else if (type == 1) + ChangeKey(mRotationKeys, lcVector4(param[0], param[1], param[2], param[3]), time, true); + } + + file.ReadU32(&n, 1); + while (n--) + { + file.ReadU16(&time, 1); + file.ReadFloats(param, 4); + file.ReadU8(&type, 1); + } + } if (version < 9) { @@ -148,7 +142,10 @@ bool lcPiece::FileLoad(lcFile& file) file.ReadU16(&time, 1); file.ReadU8(&type, 1); - ChangeKey(time, true, param, type); + if (type == 0) + ChangeKey(mPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); + else if (type == 1) + ChangeKey(mRotationKeys, lcVector4(param[0], param[1], param[2], param[3]), time, true); } file.ReadU32(&keys, 1); @@ -187,12 +184,12 @@ bool lcPiece::FileLoad(lcFile& file) file.ReadU8(&b, 1); time = b; - ChangeKey(1, true, ModelWorld.r[3], LC_PK_POSITION); + ChangeKey(mPositionKeys, lcVector3(ModelWorld.r[3][0], ModelWorld.r[3][1], ModelWorld.r[3][2]), 1, true); lcVector4 AxisAngle = lcMatrix44ToAxisAngle(ModelWorld); AxisAngle[3] *= LC_RTOD; - ChangeKey(time, true, AxisAngle, LC_PK_ROTATION); + ChangeKey(mRotationKeys, AxisAngle, time, true); lcint32 bl; file.ReadS32(&bl, 1); @@ -207,11 +204,11 @@ bool lcPiece::FileLoad(lcFile& file) lcMatrix44 ModelWorld = lcMatrix44Translation(Translation); ModelWorld = lcMul(lcMatrix44RotationZ(Rotation[2] * LC_DTOR), lcMul(lcMatrix44RotationY(Rotation[1] * LC_DTOR), lcMul(lcMatrix44RotationX(Rotation[0] * LC_DTOR), ModelWorld))); - ChangeKey(1, true, ModelWorld.r[3], LC_PK_POSITION); + ChangeKey(mPositionKeys, lcVector3(ModelWorld.r[3][0], ModelWorld.r[3][1], ModelWorld.r[3][2]), 1, true); lcVector4 AxisAngle = lcMatrix44ToAxisAngle(ModelWorld); AxisAngle[3] *= LC_RTOD; - ChangeKey(1, true, AxisAngle, LC_PK_ROTATION); + ChangeKey(mRotationKeys, AxisAngle, 1, true); } } } @@ -300,15 +297,8 @@ bool lcPiece::FileLoad(lcFile& file) if (version < 12) { - for (LC_OBJECT_KEY* Key = m_pInstructionKeys; Key; Key = Key->next) - { - if (Key->type == LC_PK_POSITION) - { - Key->param[0] *= 25.0f; - Key->param[1] *= 25.0f; - Key->param[2] *= 25.0f; - } - } + for (int KeyIdx = 0; KeyIdx < mPositionKeys.GetSize(); KeyIdx++) + mPositionKeys[KeyIdx].Value *= 25.0f; } return true; @@ -318,7 +308,32 @@ void lcPiece::FileSave(lcFile& file) const { file.WriteU8(LC_PIECE_SAVE_VERSION); - lcObject::FileSave(file); + file.WriteU8(1); + file.WriteU32(mPositionKeys.GetSize() + mRotationKeys.GetSize()); + + for (int KeyIdx = 0; KeyIdx < mPositionKeys.GetSize(); KeyIdx++) + { + lcObjectKey& Key = mPositionKeys[KeyIdx]; + + lcuint16 Step = lcMin(Key.Step, 0xFFFFU); + file.WriteU16(Step); + file.WriteFloats(Key.Value, 3); + file.WriteFloat(0); + file.WriteU8(0); + } + + for (int KeyIdx = 0; KeyIdx < mRotationKeys.GetSize(); KeyIdx++) + { + lcObjectKey& Key = mRotationKeys[KeyIdx]; + + lcuint16 Step = lcMin(Key.Step, 0xFFFFU); + file.WriteU16(Step); + file.WriteFloats(Key.Value, 4); + file.WriteU8(1); + } + + file.WriteU32(0); + file.WriteBuffer(mPieceInfo->m_strName, LC_PIECE_NAME_LEN); file.WriteU32(mColorCode); @@ -339,13 +354,12 @@ void lcPiece::FileSave(lcFile& file) const file.WriteS32(GroupIndex); } -void lcPiece::Initialize(float x, float y, float z, lcStep Step) +void lcPiece::Initialize(const lcVector3& Position, const lcVector4& AxisAngle, lcStep Step) { mStepShow = Step; - float pos[3] = { x, y, z }, rot[4] = { 0, 0, 1, 0 }; - ChangeKey(1, true, pos, LC_PK_POSITION); - ChangeKey(1, true, rot, LC_PK_ROTATION); + ChangeKey(mPositionKeys, Position, 1, true); + ChangeKey(mRotationKeys, AxisAngle, 1, true); UpdatePosition(1); } @@ -397,7 +411,8 @@ void lcPiece::InsertTime(lcStep Start, lcStep Time) } } - lcObject::InsertTime(Start, Time); + lcObject::InsertTime(mPositionKeys, Start, Time); + lcObject::InsertTime(mRotationKeys, Start, Time); } void lcPiece::RemoveTime(lcStep Start, lcStep Time) @@ -429,7 +444,8 @@ void lcPiece::RemoveTime(lcStep Start, lcStep Time) } } - lcObject::RemoveTime(Start, Time); + lcObject::RemoveTime(mPositionKeys, Start, Time); + lcObject::RemoveTime(mRotationKeys, Start, Time); } void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const @@ -518,7 +534,7 @@ void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance) { mPosition += Distance; - ChangeKey(Step, AddKey, mPosition, LC_PK_POSITION); + ChangeKey(mPositionKeys, mPosition, Step, AddKey); mModelWorld.SetTranslation(mPosition); } @@ -565,7 +581,8 @@ lcGroup* lcPiece::GetTopGroup() void lcPiece::UpdatePosition(lcStep Step) { - CalculateKeys(Step); + mPosition = CalculateKey(mPositionKeys, Step); + mRotation = CalculateKey(mRotationKeys, Step); mModelWorld = lcMatrix44FromAxisAngle(lcVector3(mRotation[0], mRotation[1], mRotation[2]), mRotation[3] * LC_DTOR); mModelWorld.SetTranslation(mPosition); diff --git a/common/piece.h b/common/piece.h index e9adcea5..9c6d7fc1 100644 --- a/common/piece.h +++ b/common/piece.h @@ -19,13 +19,6 @@ enum lcPieceSection LC_PIECE_SECTION_POSITION }; -enum LC_PK_TYPES -{ - LC_PK_POSITION, - LC_PK_ROTATION, - LC_PK_COUNT -}; - class lcPiece : public lcObject { public: @@ -101,8 +94,8 @@ public: virtual void RayTest(lcObjectRayTest& ObjectRayTest) const; virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const; - virtual void InsertTime(lcStep Start, lcStep Time); - virtual void RemoveTime(lcStep Start, lcStep Time); + void InsertTime(lcStep Start, lcStep Time); + void RemoveTime(lcStep Start, lcStep Time); bool IsHidden() { @@ -123,7 +116,7 @@ public: } bool IsVisible(lcStep Step); - void Initialize(float x, float y, float z, lcStep Step); + void Initialize(const lcVector3& Position, const lcVector4& AxisAngle, lcStep Step); void CreateName(const lcArray& Pieces); void CompareBoundingBox(float box[6]); void SetPieceInfo(PieceInfo* pPieceInfo); @@ -182,6 +175,16 @@ public: mColorCode = lcGetColorCode(ColorIndex); } + void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey) + { + ChangeKey(mPositionKeys, Position, Step, AddKey); + } + + void SetRotation(const lcVector4& Rotation, lcStep Step, bool AddKey) + { + ChangeKey(mRotationKeys, Rotation, Step, AddKey); + } + public: PieceInfo* mPieceInfo; @@ -193,6 +196,9 @@ public: lcVector4 mRotation; protected: + lcArray> mPositionKeys; + lcArray> mRotationKeys; + // Atributes lcGroup* mGroup; diff --git a/common/project.cpp b/common/project.cpp index 9756dc85..6c780bf9 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -188,27 +188,9 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) if (fv < 0.6f) // old view { - lcCamera* pCam = new lcCamera(false); - pCam->CreateName(mCameras); - mCameras.Add(pCam); - double eye[3], target[3]; file->ReadDoubles(eye, 3); file->ReadDoubles(target, 3); - float tmp[3] = { (float)eye[0], (float)eye[1], (float)eye[2] }; - pCam->ChangeKey(1, false, tmp, LC_CK_EYE); - tmp[0] = (float)target[0]; tmp[1] = (float)target[1]; tmp[2] = (float)target[2]; - pCam->ChangeKey(1, false, tmp, LC_CK_TARGET); - - // Create up vector - lcVector3 UpVector(0, 0, 1), FrontVector((float)(eye[0] - target[0]), (float)(eye[1] - target[1]), (float)(eye[2] - target[2])), SideVector; - FrontVector.Normalize(); - if (FrontVector == UpVector) - SideVector = lcVector3(1, 0, 0); - else - SideVector = lcCross(FrontVector, UpVector); - UpVector = lcNormalize(lcCross(SideVector, FrontVector)); - pCam->ChangeKey(1, false, UpVector, LC_CK_UP); } if (bMerge) @@ -262,7 +244,7 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) else { char name[LC_PIECE_NAME_LEN]; - float pos[3], rot[3]; + lcVector3 pos, rot; lcuint8 color, step, group; file->ReadFloats(pos, 3); @@ -272,19 +254,19 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) file->ReadU8(&step, 1); file->ReadU8(&group, 1); - PieceInfo* pInfo = Library->FindPiece(name, true); - lcPiece* pPiece = new lcPiece(pInfo); - - pPiece->Initialize(pos[0], pos[1], pos[2], step); - pPiece->SetColorCode(lcGetColorCodeFromOriginalColor(color)); - pPiece->CreateName(mPieces); - mPieces.Add(pPiece); - + pos *= 25.0f; lcMatrix44 ModelWorld = lcMul(lcMatrix44RotationZ(rot[2] * LC_DTOR), lcMul(lcMatrix44RotationY(rot[1] * LC_DTOR), lcMatrix44RotationX(rot[0] * LC_DTOR))); lcVector4 AxisAngle = lcMatrix44ToAxisAngle(ModelWorld); AxisAngle[3] *= LC_RTOD; - pPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION); + PieceInfo* pInfo = Library->FindPiece(name, true); + lcPiece* pPiece = new lcPiece(pInfo); + + pPiece->Initialize(pos, AxisAngle, step); + pPiece->SetColorCode(lcGetColorCodeFromOriginalColor(color)); + pPiece->CreateName(mPieces); + mPieces.Add(pPiece); + // pPiece->SetGroup((lcGroup*)group); SystemPieceComboAdd(pInfo->m_strDescription); } @@ -850,11 +832,10 @@ void Project::FileReadLDraw(lcFile* file, const lcMatrix44& CurrentTransform, in lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform); AxisAngle[3] *= LC_RTOD; - pPiece->Initialize(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y, *nStep); + pPiece->Initialize(lcVector3(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y), AxisAngle, *nStep); pPiece->SetColorCode(ColorCode); pPiece->CreateName(mPieces); mPieces.Add(pPiece); - pPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION); SystemPieceComboAdd(pInfo->m_strDescription); (*nOk)++; } @@ -909,11 +890,10 @@ void Project::FileReadLDraw(lcFile* file, const lcMatrix44& CurrentTransform, in lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform); AxisAngle[3] *= LC_RTOD; - pPiece->Initialize(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y, *nStep); + pPiece->Initialize(lcVector3(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y), AxisAngle, *nStep); pPiece->SetColorCode(ColorCode); pPiece->CreateName(mPieces); mPieces.Add(pPiece); - pPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION); SystemPieceComboAdd(Info->m_strDescription); (*nOk)++; } @@ -3932,13 +3912,11 @@ void Project::HandleCommand(LC_COMMANDS id) GetPieceInsertPosition(Last, Pos, Rot); - pPiece->Initialize(Pos[0], Pos[1], Pos[2], mCurrentStep); - - pPiece->ChangeKey(mCurrentStep, false, Rot, LC_PK_ROTATION); + pPiece->Initialize(Pos, Rot, mCurrentStep); pPiece->UpdatePosition(mCurrentStep); } else - pPiece->Initialize(0, 0, 0, mCurrentStep); + pPiece->Initialize(lcVector3(0, 0, 0), lcVector4(0, 0, 1, 0), mCurrentStep); pPiece->SetColorIndex(gMainWindow->mColorIndex); pPiece->CreateName(mPieces); @@ -4087,16 +4065,14 @@ void Project::HandleCommand(LC_COMMANDS id) lcPiece* pPiece = new lcPiece(Minifig.Parts[i]); - lcVector4& Position = Minifig.Matrices[i][3]; + lcVector3 Position(Minifig.Matrices[i][3][0], Minifig.Matrices[i][3][1], Minifig.Matrices[i][3][2]); lcVector4 Rotation = lcMatrix44ToAxisAngle(Minifig.Matrices[i]); Rotation[3] *= LC_RTOD; - pPiece->Initialize(Position[0], Position[1], Position[2], mCurrentStep); + pPiece->Initialize(Position, Rotation, mCurrentStep); pPiece->SetColorIndex(Minifig.Colors[i]); pPiece->CreateName(mPieces); mPieces.Add(pPiece); pPiece->SetSelected(true); - - pPiece->ChangeKey(1, false, Rotation, LC_PK_ROTATION); pPiece->UpdatePosition(mCurrentStep); SystemPieceComboAdd(Minifig.Parts[i]->m_strDescription); @@ -4219,9 +4195,8 @@ void Project::HandleCommand(LC_COMMANDS id) AxisAngle[3] *= LC_RTOD; lcPiece* NewPiece = new lcPiece(pPiece->mPieceInfo); - NewPiece->Initialize(Position[0] + Offset[0], Position[1] + Offset[1], Position[2] + Offset[2], mCurrentStep); + NewPiece->Initialize(Position + Offset, AxisAngle, mCurrentStep); NewPiece->SetColorIndex(pPiece->mColorIndex); - NewPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION); lcObjectSection ObjectSection; ObjectSection.Object = NewPiece; @@ -5698,7 +5673,7 @@ bool Project::RotateSelectedObjects(lcVector3& Delta, lcVector3& Remainder, bool pos[1] = Center[1] + Distance[1]; pos[2] = Center[2] + Distance[2]; - Piece->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), pos, LC_PK_POSITION); + Piece->SetPosition(pos, mCurrentStep, gMainWindow->GetAddKeys()); } rot[0] = NewRotation[0]; @@ -5706,7 +5681,7 @@ bool Project::RotateSelectedObjects(lcVector3& Delta, lcVector3& Remainder, bool rot[2] = NewRotation[2]; rot[3] = NewRotation[3] * LC_RTOD; - Piece->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), rot, LC_PK_ROTATION); + Piece->SetRotation(rot, mCurrentStep, gMainWindow->GetAddKeys()); Piece->UpdatePosition(mCurrentStep); } @@ -5832,7 +5807,7 @@ void Project::TransformSelectedObjects(lcTransformType Type, const lcVector3& Tr if (Piece->IsSelected()) { - Piece->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), NewRotation, LC_PK_ROTATION); + Piece->SetRotation(NewRotation, mCurrentStep, gMainWindow->GetAddKeys()); Piece->UpdatePosition(mCurrentStep); nSel++; } @@ -5869,12 +5844,12 @@ void Project::ModifyObject(lcObject* Object, lcObjectProperty Property, void* Va case LC_PIECE_PROPERTY_POSITION: { const lcVector3& Position = *(lcVector3*)Value; - lcPiece* Part = (lcPiece*)Object; + lcPiece* Piece = (lcPiece*)Object; - if (Part->mPosition != Position) + if (Piece->mPosition != Position) { - Part->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), Position, LC_PK_POSITION); - Part->UpdatePosition(mCurrentStep); + Piece->SetPosition(Position, mCurrentStep, gMainWindow->GetAddKeys()); + Piece->UpdatePosition(mCurrentStep); CheckPointString = "Moving"; } @@ -5883,12 +5858,12 @@ void Project::ModifyObject(lcObject* Object, lcObjectProperty Property, void* Va case LC_PIECE_PROPERTY_ROTATION: { const lcVector4& Rotation = *(lcVector4*)Value; - lcPiece* Part = (lcPiece*)Object; + lcPiece* Piece = (lcPiece*)Object; - if (Rotation != Part->mRotation) + if (Rotation != Piece->mRotation) { - Part->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), Rotation, LC_PK_ROTATION); - Part->UpdatePosition(mCurrentStep); + Piece->SetRotation(Rotation, mCurrentStep, gMainWindow->GetAddKeys()); + Piece->UpdatePosition(mCurrentStep); CheckPointString = "Rotating"; } @@ -5951,14 +5926,14 @@ void Project::ModifyObject(lcObject* Object, lcObjectProperty Property, void* Va } break; case LC_CAMERA_PROPERTY_POSITION: - { + { const lcVector3& Position = *(lcVector3*)Value; - lcCamera* camera = (lcCamera*)Object; + lcCamera* Camera = (lcCamera*)Object; - if (camera->mPosition != Position) + if (Camera->mPosition != Position) { - camera->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), Position, LC_CK_EYE); - camera->UpdatePosition(mCurrentStep); + Camera->SetPosition(Position, mCurrentStep, gMainWindow->GetAddKeys()); + Camera->UpdatePosition(mCurrentStep); CheckPointString = "Camera"; } @@ -5967,12 +5942,12 @@ void Project::ModifyObject(lcObject* Object, lcObjectProperty Property, void* Va case LC_CAMERA_PROPERTY_TARGET: { const lcVector3& TargetPosition = *(lcVector3*)Value; - lcCamera* camera = (lcCamera*)Object; + lcCamera* Camera = (lcCamera*)Object; - if (camera->mTargetPosition != TargetPosition) + if (Camera->mTargetPosition != TargetPosition) { - camera->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), TargetPosition, LC_CK_TARGET); - camera->UpdatePosition(mCurrentStep); + Camera->SetTargetPosition(TargetPosition, mCurrentStep, gMainWindow->GetAddKeys()); + Camera->UpdatePosition(mCurrentStep); CheckPointString = "Camera"; } @@ -5981,12 +5956,12 @@ void Project::ModifyObject(lcObject* Object, lcObjectProperty Property, void* Va case LC_CAMERA_PROPERTY_UPVECTOR: { const lcVector3& Up = *(lcVector3*)Value; - lcCamera* camera = (lcCamera*)Object; + lcCamera* Camera = (lcCamera*)Object; - if (camera->mUpVector != Up) + if (Camera->mUpVector != Up) { - camera->ChangeKey(mCurrentStep, gMainWindow->GetAddKeys(), Up, LC_CK_UP); - camera->UpdatePosition(mCurrentStep); + Camera->SetUpVector(Up, mCurrentStep, gMainWindow->GetAddKeys()); + Camera->UpdatePosition(mCurrentStep); CheckPointString = "Camera"; } @@ -6154,9 +6129,8 @@ void Project::EndMouseTool(lcTool Tool, bool Accept) void Project::InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation) { lcPiece* Piece = new lcPiece(m_pCurPiece); - Piece->Initialize(Position[0], Position[1], Position[2], mCurrentStep); + Piece->Initialize(Position, Rotation, mCurrentStep); Piece->SetColorIndex(gMainWindow->mColorIndex); - Piece->ChangeKey(mCurrentStep, false, Rotation, LC_PK_ROTATION); Piece->UpdatePosition(mCurrentStep); Piece->CreateName(mPieces); mPieces.Add(Piece);