Moved keys to separate arrays.

This commit is contained in:
leo 2014-08-31 00:53:12 +00:00
parent 07e6fce3ce
commit 4c0c815682
10 changed files with 515 additions and 576 deletions

View file

@ -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<lcCamera*>& 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<lcVector3>& 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<lcVector3>& 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<lcVector3>& 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);
}

View file

@ -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<lcObjectKey<lcVector3>> mPositionKeys;
lcArray<lcObjectKey<lcVector3>> mTargetPositionKeys;
lcArray<lcObjectKey<lcVector3>> mUpVectorKeys;
void Initialize();
lcuint32 mState;

View file

@ -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)

View file

@ -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);

View file

@ -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<lcObjectKey<lcVector3>> mPositionKeys;
lcArray<lcObjectKey<lcVector3>> mTargetPositionKeys;
lcArray<lcObjectKey<lcVector4>> mAmbientColorKeys;
lcArray<lcObjectKey<lcVector4>> mDiffuseColorKeys;
lcArray<lcObjectKey<lcVector4>> mSpecularColorKeys;
lcArray<lcObjectKey<lcVector3>> mAttenuationKeys;
lcArray<lcObjectKey<float>> mSpotCutoffKeys;
lcArray<lcObjectKey<float>> mSpotExponentKeys;
void Initialize(const lcVector3& Position, const lcVector3& TargetPosition);
float m_fCone;
lcuint32 mState;

View file

@ -1,242 +1,45 @@
#include "lc_global.h"
#include "lc_math.h"
#include <stdlib.h>
#include <float.h>
#include <math.h>
#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<lcObjectKey<lcVector3>>& 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<lcVector3>& 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<lcObjectKey<lcVector4>>& 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<lcVector4>& 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;
}

View file

@ -14,20 +14,11 @@ enum lcObjectType
LC_OBJECT_LIGHT
};
// key handling
struct LC_OBJECT_KEY
template<typename T>
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<lcObjectKey<lcVector3>>& Keys);
QJsonArray SaveKeys(const lcArray<lcObjectKey<lcVector4>>& 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<typename T>
const T& CalculateKey(const lcArray<lcObjectKey<T>>& Keys, lcStep Step)
{
return m_nKeyInfoCount;
lcObjectKey<T>* 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<typename T>
void ChangeKey(lcArray<lcObjectKey<T>>& Keys, const T& Value, lcStep Step, bool AddKey)
{
return &m_pKeyInfo[index];
lcObjectKey<T>* 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<typename T>
void InsertTime(lcArray<lcObjectKey<T>>& Keys, lcStep Start, lcStep Time)
{
return m_pKeyValues[index];
bool EndKey = false;
for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++)
{
lcObjectKey<T>& 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<typename T>
void RemoveTime(lcArray<lcObjectKey<T>>& Keys, lcStep Start, lcStep Time)
{
for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++)
{
lcObjectKey<T>& 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;

View file

@ -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<lcVector3>& 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<lcVector4>& 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);

View file

@ -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<lcPiece*>& 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<lcObjectKey<lcVector3>> mPositionKeys;
lcArray<lcObjectKey<lcVector4>> mRotationKeys;
// Atributes
lcGroup* mGroup;

View file

@ -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);