Store piece transformations as matrices to allow scaling.

This commit is contained in:
leo 2015-01-10 20:30:37 +00:00
parent 1de2bffb73
commit 12d0094806
11 changed files with 309 additions and 211 deletions

View file

@ -23,6 +23,7 @@ struct lcModelPartsEntry;
class lcVector2;
class lcVector3;
class lcVector4;
class lcMatrix33;
class lcMatrix44;
class lcContext;

View file

@ -75,7 +75,6 @@ void lcPiecesLibrary::RemoveTemporaryPieces()
delete Info;
}
}
}
PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, bool CreatePlaceholder)

View file

@ -159,6 +159,47 @@ public:
float x, y, z, w;
};
class lcMatrix33
{
public:
lcMatrix33()
{
}
lcMatrix33(const lcVector3& _x, const lcVector3& _y, const lcVector3& _z)
{
r[0] = _x;
r[1] = _y;
r[2] = _z;
}
explicit lcMatrix33(const lcMatrix44& Matrix);
operator const float*() const
{
return (const float*)this;
}
operator float*()
{
return (float*)this;
}
const lcVector3& operator[](int i) const
{
return r[i];
}
lcVector3& operator[](int i)
{
return r[i];
}
void Orthonormalize();
lcVector3 r[3];
};
class lcMatrix44
{
public:
@ -174,6 +215,19 @@ public:
r[3] = _w;
}
lcMatrix44(const lcMatrix33& Rotation, const lcVector3& Translation)
{
r[0] = lcVector4(Rotation[0][0], Rotation[0][1], Rotation[0][2], 0.0f);
r[1] = lcVector4(Rotation[1][0], Rotation[1][1], Rotation[1][2], 0.0f);
r[2] = lcVector4(Rotation[2][0], Rotation[2][1], Rotation[2][2], 0.0f);
r[3] = lcVector4(Translation, 1.0f);
}
lcVector3 GetTranslation() const
{
return lcVector3(r[3][0], r[3][1], r[3][2]);
}
void SetTranslation(const lcVector3& Translation)
{
r[3] = lcVector4(Translation[0], Translation[1], Translation[2], 1.0f);
@ -469,6 +523,11 @@ inline lcuint32 lcColorFromVector3(const lcVector3& Color)
return LC_RGB(Color[0] * 255, Color[1] * 255, Color[2] * 255);
}
inline lcVector3 lcMul(const lcVector3& a, const lcMatrix33& b)
{
return b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2];
}
inline lcVector3 lcMul31(const lcVector3& a, const lcMatrix44& b)
{
lcVector4 v = b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2] + b.r[3];
@ -502,6 +561,19 @@ inline lcVector4 lcMul4(const lcVector4& a, const lcMatrix44& b)
return b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2] + b.r[3] * a[3];
}
inline lcMatrix33 lcMul(const lcMatrix33& a, const lcMatrix33& b)
{
lcVector3 Col0(b.r[0][0], b.r[1][0], b.r[2][0]);
lcVector3 Col1(b.r[0][1], b.r[1][1], b.r[2][1]);
lcVector3 Col2(b.r[0][2], b.r[1][2], b.r[2][2]);
lcVector3 Ret0(lcDot(a.r[0], Col0), lcDot(a.r[0], Col1), lcDot(a.r[0], Col2));
lcVector3 Ret1(lcDot(a.r[1], Col0), lcDot(a.r[1], Col1), lcDot(a.r[1], Col2));
lcVector3 Ret2(lcDot(a.r[2], Col0), lcDot(a.r[2], Col1), lcDot(a.r[2], Col2));
return lcMatrix33(Ret0, Ret1, Ret2);
}
inline lcMatrix44 lcMul(const lcMatrix44& a, const lcMatrix44& b)
{
lcVector4 Col0(b.r[0][0], b.r[1][0], b.r[2][0], b.r[3][0]);
@ -517,6 +589,145 @@ inline lcMatrix44 lcMul(const lcMatrix44& a, const lcMatrix44& b)
return lcMatrix44(Ret0, Ret1, Ret2, Ret3);
}
inline lcMatrix33::lcMatrix33(const lcMatrix44& Matrix)
{
r[0] = lcVector3(Matrix.r[0].x, Matrix.r[0].y, Matrix.r[0].z);
r[1] = lcVector3(Matrix.r[1].x, Matrix.r[1].y, Matrix.r[1].z);
r[2] = lcVector3(Matrix.r[2].x, Matrix.r[2].y, Matrix.r[2].z);
}
inline void lcMatrix33::Orthonormalize()
{
r[0] = lcNormalize(r[0]);
r[1] = lcNormalize(r[1] - lcDot(r[1], r[0]) * r[0]);
r[2] = r[2] - lcDot(r[2], r[0]) * r[0];
r[2] -= lcDot(r[2], r[1]) * r[1];
r[2] = lcNormalize(r[2]);
}
inline lcMatrix33 lcMatrix33Identity()
{
lcMatrix33 m;
m.r[0] = lcVector3(1.0f, 0.0f, 0.0f);
m.r[1] = lcVector3(0.0f, 1.0f, 0.0f);
m.r[2] = lcVector3(0.0f, 0.0f, 1.0f);
return m;
}
inline lcMatrix33 lcMatrix33RotationX(const float Radians)
{
float s, c;
s = sinf(Radians);
c = cosf(Radians);
lcMatrix33 m;
m.r[0] = lcVector3(1.0f, 0.0f, 0.0f);
m.r[1] = lcVector3(0.0f, c, s);
m.r[2] = lcVector3(0.0f, -s, c);
return m;
}
inline lcMatrix33 lcMatrix33RotationY(const float Radians)
{
float s, c;
s = sinf(Radians);
c = cosf(Radians);
lcMatrix33 m;
m.r[0] = lcVector3( c, 0.0f, -s);
m.r[1] = lcVector3(0.0f, 1.0f, 0.0f);
m.r[2] = lcVector3( s, 0.0f, c);
return m;
}
inline lcMatrix33 lcMatrix33RotationZ(const float Radians)
{
float s, c;
s = sinf(Radians);
c = cosf(Radians);
lcMatrix33 m;
m.r[0] = lcVector3( c, s, 0.0f);
m.r[1] = lcVector3( -s, c, 0.0f);
m.r[2] = lcVector3(0.0f, 0.0f, 1.0f);
return m;
}
inline lcMatrix33 lcMatrix33FromAxisAngle(const lcVector3& Axis, const float Radians)
{
float s, c, mag, xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
s = sinf(Radians);
c = cosf(Radians);
mag = Axis.Length();
if (mag == 0.0f)
return lcMatrix33Identity();
lcVector3 Normal = Axis * (1.0f / mag);
xx = Normal[0] * Normal[0];
yy = Normal[1] * Normal[1];
zz = Normal[2] * Normal[2];
xy = Normal[0] * Normal[1];
yz = Normal[1] * Normal[2];
zx = Normal[2] * Normal[0];
xs = Normal[0] * s;
ys = Normal[1] * s;
zs = Normal[2] * s;
one_c = 1.0f - c;
lcMatrix33 m;
m.r[0] = lcVector3((one_c * xx) + c, (one_c * xy) + zs, (one_c * zx) - ys);
m.r[1] = lcVector3((one_c * xy) - zs, (one_c * yy) + c, (one_c * yz) + xs);
m.r[2] = lcVector3((one_c * zx) + ys, (one_c * yz) - xs, (one_c * zz) + c);
return m;
}
inline lcMatrix33 lcMatrix33AffineInverse(const lcMatrix33& m)
{
lcMatrix33 Inv;
Inv.r[0] = lcVector3(m.r[0][0], m.r[1][0], m.r[2][0]);
Inv.r[1] = lcVector3(m.r[0][1], m.r[1][1], m.r[2][1]);
Inv.r[2] = lcVector3(m.r[0][2], m.r[1][2], m.r[2][2]);
return Inv;
}
inline lcMatrix33 lcMatrix33FromEulerAngles(const lcVector3& Radians)
{
float CosYaw, SinYaw, CosPitch, SinPitch, CosRoll, SinRoll;
CosRoll = cosf(Radians[0]);
SinRoll = sinf(Radians[0]);
CosPitch = cosf(Radians[1]);
SinPitch = sinf(Radians[1]);
CosYaw = cosf(Radians[2]);
SinYaw = sinf(Radians[2]);
lcMatrix33 m;
m.r[0] = lcVector3(CosYaw * CosPitch, SinYaw * CosPitch, -SinPitch);
m.r[1] = lcVector3(CosYaw * SinPitch * SinRoll - SinYaw * CosRoll, CosYaw * CosRoll + SinYaw * SinPitch * SinRoll, CosPitch * SinRoll);
m.r[2] = lcVector3(CosYaw * SinPitch * CosRoll + SinYaw * SinRoll, SinYaw * SinPitch * CosRoll - CosYaw * SinRoll, CosPitch * CosRoll);
return m;
}
inline lcMatrix44 lcMatrix44Identity()
{
lcMatrix44 m;

View file

@ -444,13 +444,10 @@ void lcModel::LoadLDraw(QIODevice& Device)
{
float* Matrix = IncludeTransform;
lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f),
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform);
AxisAngle[3] *= LC_RTOD;
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(Matrix[12], Matrix[14], -Matrix[13], 1.0f));
Piece->SetPieceInfo(Info);
Piece->Initialize(lcVector3(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y), AxisAngle, CurrentStep);
Piece->Initialize(Transform, CurrentStep);
Piece->SetColorCode(ColorCode);
Piece->CreateName(mPieces);
mPieces.Add(Piece);
@ -463,13 +460,10 @@ void lcModel::LoadLDraw(QIODevice& Device)
{
float* Matrix = IncludeTransform;
lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f),
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform);
AxisAngle[3] *= LC_RTOD;
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(Matrix[12], Matrix[14], -Matrix[13], 1.0f));
Piece->SetPieceInfo(Info);
Piece->Initialize(lcVector3(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y), AxisAngle, CurrentStep);
Piece->Initialize(Transform, CurrentStep);
Piece->SetColorCode(ColorCode);
Piece->CreateName(mPieces);
mPieces.Add(Piece);
@ -574,14 +568,13 @@ bool lcModel::LoadBinary(lcFile* file)
file->ReadU8(&group, 1);
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;
lcMatrix44 WorldMatrix = lcMul(lcMatrix44RotationZ(rot[2] * LC_DTOR), lcMul(lcMatrix44RotationY(rot[1] * LC_DTOR), lcMatrix44RotationX(rot[0] * LC_DTOR)));
WorldMatrix.SetTranslation(pos);
PieceInfo* pInfo = Library->FindPiece(name, true);
lcPiece* pPiece = new lcPiece(pInfo);
pPiece->Initialize(pos, AxisAngle, step);
pPiece->Initialize(WorldMatrix, step);
pPiece->SetColorCode(lcGetColorCodeFromOriginalColor(color));
pPiece->CreateName(mPieces);
mPieces.Add(pPiece);
@ -1747,24 +1740,23 @@ void lcModel::AddPiece()
}
}
lcVector3 Position(0, 0, 0);
lcVector4 Rotation(0, 0, 1, 0);
lcMatrix44 WorldMatrix;
if (Last != NULL)
{
lcVector3 Dist(0, 0, Last->mPieceInfo->m_fDimensions[2] - CurPiece->m_fDimensions[5]);
Dist = SnapPosition(Dist);
Position = lcMul31(Dist, Last->mModelWorld);
Rotation = Last->mRotation;
WorldMatrix = Last->mModelWorld;
WorldMatrix.SetTranslation(lcMul31(Dist, Last->mModelWorld));
}
else
{
Position[2] = -CurPiece->m_fDimensions[5];
WorldMatrix = lcMatrix44Translation(lcVector3(0.0f, 0.0f, -CurPiece->m_fDimensions[5]));
}
lcPiece* Piece = new lcPiece(CurPiece);
Piece->Initialize(Position, Rotation, mCurrentStep);
Piece->Initialize(WorldMatrix, mCurrentStep);
Piece->SetColorIndex(gMainWindow->mColorIndex);
Piece->CreateName(mPieces);
mPieces.Add(Piece);
@ -1993,30 +1985,21 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Update)
lcVector3 Center;
if (Focus)
Center = Focus->mPosition;
Center = Focus->mModelWorld.GetTranslation();
else
Center = lcVector3((Bounds[0] + Bounds[3]) / 2.0f, (Bounds[1] + Bounds[4]) / 2.0f, (Bounds[2] + Bounds[5]) / 2.0f);
lcVector4 RotationQuaternion(0, 0, 0, 1);
lcVector4 WorldToFocusQuaternion, FocusToWorldQuaternion;
lcMatrix33 RotationMatrix = lcMatrix33Identity();
lcMatrix33 WorldToFocusMatrix, FocusToWorldMatrix;
if (Angles[0] != 0.0f)
{
lcVector4 q = lcQuaternionRotationX(Angles[0] * LC_DTOR);
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
}
RotationMatrix = lcMul(lcMatrix33RotationX(Angles[0] * LC_DTOR), RotationMatrix);
if (Angles[1] != 0.0f)
{
lcVector4 q = lcQuaternionRotationY(Angles[1] * LC_DTOR);
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
}
RotationMatrix = lcMul(lcMatrix33RotationY(Angles[1] * LC_DTOR), RotationMatrix);
if (Angles[2] != 0.0f)
{
lcVector4 q = lcQuaternionRotationZ(Angles[2] * LC_DTOR);
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
}
RotationMatrix = lcMul(lcMatrix33RotationZ(Angles[2] * LC_DTOR), RotationMatrix);
const lcPreferences& Preferences = lcGetPreferences();
if (Preferences.mForceGlobalTransforms)
@ -2024,12 +2007,10 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Update)
if (Focus)
{
const lcVector4& Rotation = Focus->mRotation;
FocusToWorldMatrix = lcMatrix33(Focus->mModelWorld);
WorldToFocusMatrix = lcMatrix33AffineInverse(FocusToWorldMatrix);
WorldToFocusQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], -Rotation[3] * LC_DTOR));
FocusToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], Rotation[3] * LC_DTOR));
RotationQuaternion = lcQuaternionMultiply(FocusToWorldQuaternion, RotationQuaternion);
RotationMatrix = lcMul(FocusToWorldMatrix, RotationMatrix);
}
bool Rotated = false;
@ -2041,33 +2022,40 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Update)
if (!Piece->IsSelected())
continue;
const lcVector4& Rotation = Piece->mRotation;
lcVector3 Distance = Piece->mPosition - Center;
lcVector4 LocalToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], Rotation[3] * LC_DTOR));
lcVector4 NewRotation, NewLocalToWorldQuaternion;
lcVector3 Distance = Piece->mModelWorld.GetTranslation() - Center;
lcMatrix33 LocalToWorldMatrix = lcMatrix33(Piece->mModelWorld);
lcMatrix33 NewLocalToWorldMatrix;
if (Focus)
{
lcVector4 LocalToFocusQuaternion = lcQuaternionMultiply(WorldToFocusQuaternion, LocalToWorldQuaternion);
NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToFocusQuaternion);
lcMatrix33 LocalToFocusMatrix = lcMul(WorldToFocusMatrix, LocalToWorldMatrix);
NewLocalToWorldMatrix = lcMul(RotationMatrix, LocalToFocusMatrix);
lcVector4 WorldToLocalQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], -Rotation[3] * LC_DTOR));
lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix);
Distance = lcQuaternionMul(Distance, WorldToLocalQuaternion);
Distance = lcQuaternionMul(Distance, NewLocalToWorldQuaternion);
Distance = lcMul(Distance, WorldToLocalMatrix);
Distance = lcMul(Distance, NewLocalToWorldMatrix);
}
else
{
NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToWorldQuaternion);
NewLocalToWorldMatrix = lcMul(RotationMatrix, LocalToWorldMatrix);
Distance = lcQuaternionMul(Distance, RotationQuaternion);
Distance = lcMul(Distance, RotationMatrix);
}
NewRotation = lcQuaternionToAxisAngle(NewLocalToWorldQuaternion);
NewRotation[3] *= LC_RTOD;
NewLocalToWorldMatrix.Orthonormalize();
// NewLocalToWorldMatrix[0].Normalize();
// NewLocalToWorldMatrix[1].Normalize();
// NewLocalToWorldMatrix[2].Normalize();
qDebug() << lcCross(NewLocalToWorldMatrix[0], NewLocalToWorldMatrix[1]).Length() << lcCross(NewLocalToWorldMatrix[2], NewLocalToWorldMatrix[1]).Length() << lcCross(NewLocalToWorldMatrix[0], NewLocalToWorldMatrix[2]).Length();
qDebug() << NewLocalToWorldMatrix[0].Length() << NewLocalToWorldMatrix[1].Length() << NewLocalToWorldMatrix[2].Length();
Piece->SetPosition(Center + Distance, mCurrentStep, gMainWindow->GetAddKeys());
Piece->SetRotation(NewRotation, mCurrentStep, gMainWindow->GetAddKeys());
Piece->SetRotation(NewLocalToWorldMatrix, mCurrentStep, gMainWindow->GetAddKeys());
Piece->UpdatePosition(mCurrentStep);
Rotated = true;
}
@ -2134,28 +2122,16 @@ void lcModel::TransformSelectedObjects(lcTransformType TransformType, const lcVe
case LC_TRANSFORM_ABSOLUTE_ROTATION:
{
lcVector4 RotationQuaternion(0, 0, 0, 1);
lcMatrix33 RotationMatrix = lcMatrix33Identity();
if (Transform[0] != 0.0f)
{
lcVector4 q = lcQuaternionRotationX(Transform[0] * LC_DTOR);
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
}
RotationMatrix = lcMul(lcMatrix33RotationX(Transform[0] * LC_DTOR), RotationMatrix);
if (Transform[1] != 0.0f)
{
lcVector4 q = lcQuaternionRotationY(Transform[1] * LC_DTOR);
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
}
RotationMatrix = lcMul(lcMatrix33RotationY(Transform[1] * LC_DTOR), RotationMatrix);
if (Transform[2] != 0.0f)
{
lcVector4 q = lcQuaternionRotationZ(Transform[2] * LC_DTOR);
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
}
lcVector4 NewRotation = lcQuaternionToAxisAngle(RotationQuaternion);
NewRotation[3] *= LC_RTOD;
RotationMatrix = lcMul(lcMatrix33RotationZ(Transform[2] * LC_DTOR), RotationMatrix);
bool Rotated = false;
@ -2165,7 +2141,7 @@ void lcModel::TransformSelectedObjects(lcTransformType TransformType, const lcVe
if (Piece->IsSelected())
{
Piece->SetRotation(NewRotation, mCurrentStep, gMainWindow->GetAddKeys());
Piece->SetRotation(RotationMatrix, mCurrentStep, gMainWindow->GetAddKeys());
Piece->UpdatePosition(mCurrentStep);
Rotated = true;
}
@ -2197,7 +2173,7 @@ void lcModel::SetObjectProperty(lcObject* Object, lcObjectPropertyType ObjectPro
const lcVector3& Position = *(lcVector3*)Value;
lcPiece* Piece = (lcPiece*)Object;
if (Piece->mPosition != Position)
if (Piece->mModelWorld.GetTranslation() != Position)
{
Piece->SetPosition(Position, mCurrentStep, gMainWindow->GetAddKeys());
Piece->UpdatePosition(mCurrentStep);
@ -2208,12 +2184,14 @@ void lcModel::SetObjectProperty(lcObject* Object, lcObjectPropertyType ObjectPro
case LC_PIECE_PROPERTY_ROTATION:
{
const lcVector4& Rotation = *(lcVector4*)Value;
const lcVector3& Rotation = *(lcVector3*)Value;
lcPiece* Piece = (lcPiece*)Object;
if (Rotation != Piece->mRotation)
if (Rotation != lcMatrix44ToEulerAngles(Piece->mModelWorld))
{
Piece->SetRotation(Rotation, mCurrentStep, gMainWindow->GetAddKeys());
lcMatrix33 RotationMatrix = lcMatrix33FromEulerAngles(Rotation);
Piece->SetRotation(RotationMatrix, mCurrentStep, gMainWindow->GetAddKeys());
Piece->UpdatePosition(mCurrentStep);
CheckPointString = tr("Rotating");
@ -2465,7 +2443,7 @@ bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const
if (Piece->IsFocused())
{
Center = Piece->mPosition;
Center = Piece->mModelWorld.GetTranslation();
return true;
}
@ -3080,10 +3058,10 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept)
}
}
void lcModel::InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation)
void lcModel::InsertPieceToolClicked(const lcMatrix44& WorldMatrix)
{
lcPiece* Piece = new lcPiece(gMainWindow->mPreviewWidget->GetCurrentPiece());
Piece->Initialize(Position, Rotation, mCurrentStep);
Piece->Initialize(WorldMatrix, mCurrentStep);
Piece->SetColorIndex(gMainWindow->mColorIndex);
Piece->UpdatePosition(mCurrentStep);
Piece->CreateName(mPieces);
@ -3434,12 +3412,10 @@ void lcModel::ShowArrayDialog()
ModelWorld.r[3] += lcVector4(Center, 0.0f);
Position = lcVector3(ModelWorld.r[3].x, ModelWorld.r[3].y, ModelWorld.r[3].z);
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(ModelWorld);
AxisAngle[3] *= LC_RTOD;
ModelWorld.SetTranslation(Position + Offset);
lcPiece* NewPiece = new lcPiece(Piece->mPieceInfo);
NewPiece->Initialize(Position + Offset, AxisAngle, mCurrentStep);
NewPiece->Initialize(ModelWorld, mCurrentStep);
NewPiece->SetColorIndex(Piece->mColorIndex);
NewPieces.Add(NewPiece);
@ -3477,10 +3453,7 @@ void lcModel::ShowMinifigDialog()
lcPiece* Piece = new lcPiece(Minifig.Parts[PartIdx]);
lcVector3 Position(Minifig.Matrices[PartIdx][3][0], Minifig.Matrices[PartIdx][3][1], Minifig.Matrices[PartIdx][3][2]);
lcVector4 Rotation = lcMatrix44ToAxisAngle(Minifig.Matrices[PartIdx]);
Rotation[3] *= LC_RTOD;
Piece->Initialize(Position, Rotation, mCurrentStep);
Piece->Initialize(Minifig.Matrices[PartIdx], mCurrentStep);
Piece->SetColorIndex(Minifig.Colors[PartIdx]);
Piece->CreateName(mPieces);
Piece->SetGroup(Group);

View file

@ -267,7 +267,7 @@ public:
void BeginMouseTool();
void EndMouseTool(lcTool Tool, bool Accept);
void InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation);
void InsertPieceToolClicked(const lcMatrix44& WorldMatrix);
void PointLightToolClicked(const lcVector3& Position);
void BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target);
void UpdateSpotLightTool(const lcVector3& Position);

View file

@ -131,7 +131,7 @@ protected:
const int Count = sizeof(T) / sizeof(float);
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
Stream >> Value[ValueIdx];
Stream >> ((float*)&Value)[ValueIdx];
lcObjectKey<T>& Key = Keys.Add();
Key.Step = Step;

View file

@ -37,7 +37,7 @@ lcPiece::lcPiece(PieceInfo* pPieceInfo)
mPieceInfo->AddRef();
ChangeKey(mPositionKeys, lcVector3(0.0f, 0.0f, 0.0f), 1, true);
ChangeKey(mRotationKeys, lcVector4(0.0f, 0.0f, 1.0f, 0.0f), 1, true);
ChangeKey(mRotationKeys, lcMatrix33Identity(), 1, true);
}
lcPiece::~lcPiece()
@ -183,7 +183,7 @@ bool lcPiece::FileLoad(lcFile& file)
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);
ChangeKey(mRotationKeys, lcMatrix33FromAxisAngle(lcVector3(param[0], param[1], param[2]), param[3] * LC_DTOR), time, true);
}
file.ReadU32(&n, 1);
@ -215,7 +215,7 @@ bool lcPiece::FileLoad(lcFile& file)
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);
ChangeKey(mRotationKeys, lcMatrix33FromAxisAngle(lcVector3(param[0], param[1], param[2]), param[3] * LC_DTOR), time, true);
}
file.ReadU32(&keys, 1);
@ -254,12 +254,8 @@ bool lcPiece::FileLoad(lcFile& file)
file.ReadU8(&b, 1);
time = b;
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(mRotationKeys, AxisAngle, time, true);
ChangeKey(mPositionKeys, ModelWorld.GetTranslation(), 1, true);
ChangeKey(mRotationKeys, lcMatrix33(ModelWorld), time, true);
lcint32 bl;
file.ReadS32(&bl, 1);
@ -275,10 +271,7 @@ bool lcPiece::FileLoad(lcFile& file)
ModelWorld = lcMul(lcMatrix44RotationZ(Rotation[2] * LC_DTOR), lcMul(lcMatrix44RotationY(Rotation[1] * LC_DTOR), lcMul(lcMatrix44RotationX(Rotation[0] * LC_DTOR), ModelWorld)));
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(mRotationKeys, AxisAngle, 1, true);
ChangeKey(mRotationKeys, lcMatrix33(ModelWorld), 1, true);
}
}
}
@ -374,62 +367,12 @@ bool lcPiece::FileLoad(lcFile& file)
return true;
}
void lcPiece::FileSave(lcFile& file) const
{
file.WriteU8(LC_PIECE_SAVE_VERSION);
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);
file.WriteU8(lcMin(mStepShow, 254U));
file.WriteU8(lcMin(mStepHide, 255U));
file.WriteU16(1); // m_nFrameShow
file.WriteU16(100); // m_nFrameHide
// version 8
file.WriteU8(mState & LC_PIECE_HIDDEN ? 1 : 0);
lcuint8 Length = strlen(m_strName);
file.WriteU8(Length);
file.WriteBuffer(m_strName, Length);
// version 7
lcint32 GroupIndex = lcGetActiveModel()->GetGroups().FindIndex(mGroup);
file.WriteS32(GroupIndex);
}
void lcPiece::Initialize(const lcVector3& Position, const lcVector4& AxisAngle, lcStep Step)
void lcPiece::Initialize(const lcMatrix44& WorldMatrix, lcStep Step)
{
mStepShow = Step;
ChangeKey(mPositionKeys, Position, 1, true);
ChangeKey(mRotationKeys, AxisAngle, 1, true);
ChangeKey(mPositionKeys, WorldMatrix.GetTranslation(), 1, true);
ChangeKey(mRotationKeys, lcMatrix33(WorldMatrix), 1, true);
UpdatePosition(Step);
}
@ -609,11 +552,11 @@ void lcPiece::DrawInterface(lcContext* Context, const lcMatrix44& ViewMatrix) co
void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance)
{
mPosition += Distance;
lcVector3 Position = mModelWorld.GetTranslation() + Distance;
ChangeKey(mPositionKeys, mPosition, Step, AddKey);
ChangeKey(mPositionKeys, Position, Step, AddKey);
mModelWorld.SetTranslation(mPosition);
mModelWorld.SetTranslation(Position);
}
bool lcPiece::IsVisible(lcStep Step)
@ -658,9 +601,8 @@ lcGroup* lcPiece::GetTopGroup()
void lcPiece::UpdatePosition(lcStep Step)
{
mPosition = CalculateKey(mPositionKeys, Step);
mRotation = CalculateKey(mRotationKeys, Step);
lcVector3 Position = CalculateKey(mPositionKeys, Step);
lcMatrix33 Rotation = CalculateKey(mRotationKeys, Step);
mModelWorld = lcMatrix44FromAxisAngle(lcVector3(mRotation[0], mRotation[1], mRotation[2]), mRotation[3] * LC_DTOR);
mModelWorld.SetTranslation(mPosition);
mModelWorld = lcMatrix44(Rotation, Position);
}

View file

@ -82,7 +82,7 @@ public:
switch (Section)
{
case LC_PIECE_SECTION_POSITION:
return mPosition;
return mModelWorld.GetTranslation();
}
return lcVector3(0.0f, 0.0f, 0.0f);
@ -117,12 +117,11 @@ public:
}
bool IsVisible(lcStep Step);
void Initialize(const lcVector3& Position, const lcVector4& AxisAngle, lcStep Step);
void Initialize(const lcMatrix44& WorldMatrix, lcStep Step);
void CreateName(const lcArray<lcPiece*>& Pieces);
void CompareBoundingBox(float box[6]);
void SetPieceInfo(PieceInfo* pPieceInfo);
bool FileLoad(lcFile& file);
void FileSave(lcFile& file) const;
void UpdatePosition(lcStep Step);
void Move(lcStep Step, bool AddKey, const lcVector3& Distance);
@ -181,7 +180,7 @@ public:
ChangeKey(mPositionKeys, Position, Step, AddKey);
}
void SetRotation(const lcVector4& Rotation, lcStep Step, bool AddKey)
void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey)
{
ChangeKey(mRotationKeys, Rotation, Step, AddKey);
}
@ -193,12 +192,10 @@ public:
lcuint32 mColorCode;
lcMatrix44 mModelWorld;
lcVector3 mPosition;
lcVector4 mRotation;
protected:
lcArray<lcObjectKey<lcVector3>> mPositionKeys;
lcArray<lcObjectKey<lcVector4>> mRotationKeys;
lcArray<lcObjectKey<lcMatrix33>> mRotationKeys;
// Atributes
lcGroup* mGroup;

View file

@ -230,7 +230,7 @@ lcVector3 View::GetMoveDirection(const lcVector3& Direction) const
return axis;
}
void View::GetPieceInsertPosition(lcVector3& Position, lcVector4& Rotation) const
lcMatrix44 View::GetPieceInsertPosition() const
{
PieceInfo* CurPiece = gMainWindow->mPreviewWidget->GetCurrentPiece();
lcPiece* HitPiece = (lcPiece*)FindObjectUnderPointer(true).Object;
@ -240,10 +240,11 @@ void View::GetPieceInsertPosition(lcVector3& Position, lcVector4& Rotation) cons
lcVector3 Dist(0, 0, HitPiece->mPieceInfo->m_fDimensions[2] - CurPiece->m_fDimensions[5]);
Dist = mModel->SnapPosition(Dist);
Position = lcMul31(Dist, HitPiece->mModelWorld);
Rotation = HitPiece->mRotation;
lcVector3 Position = lcMul31(Dist, HitPiece->mModelWorld);
lcMatrix44 WorldMatrix = HitPiece->mModelWorld;
WorldMatrix.SetTranslation(Position);
return;
return WorldMatrix;
}
lcVector3 ClickPoints[2] = { lcVector3((float)mInputState.x, (float)mInputState.y, 0.0f), lcVector3((float)mInputState.x, (float)mInputState.y, 1.0f) };
@ -254,13 +255,10 @@ void View::GetPieceInsertPosition(lcVector3& Position, lcVector4& Rotation) cons
if (lcLinePlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(0, 0, 1, CurPiece->m_fDimensions[5])))
{
Intersection = mModel->SnapPosition(Intersection);
Position = Intersection;
Rotation = lcVector4(0, 0, 1, 0);
return;
return lcMatrix44Translation(Intersection);
}
Position = UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f));
Rotation = lcVector4(0, 0, 1, 0);
return lcMatrix44Translation(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f)));
}
lcObjectSection View::FindObjectUnderPointer(bool PiecesOnly) const
@ -360,16 +358,7 @@ void View::OnDraw()
PieceInfo* Info = gMainWindow->mPreviewWidget->GetCurrentPiece();
if (Info)
{
lcVector3 Position;
lcVector4 Rotation;
GetPieceInsertPosition(Position, Rotation);
lcMatrix44 WorldMatrix = lcMatrix44FromAxisAngle(lcVector3(Rotation[0], Rotation[1], Rotation[2]), Rotation[3] * LC_DTOR);
WorldMatrix.SetTranslation(Position);
Info->AddRenderMeshes(Scene, WorldMatrix, gMainWindow->mColorIndex, true, true);
}
Info->AddRenderMeshes(Scene, GetPieceInsertPosition(), gMainWindow->mColorIndex, true, true);
}
mContext->SetDefaultState();
@ -1108,10 +1097,6 @@ void View::DrawGrid()
if (CurPiece)
{
lcVector3 Position;
lcVector4 Rotation;
GetPieceInsertPosition(Position, Rotation);
lcVector3 Points[8] =
{
lcVector3(CurPiece->m_fDimensions[0], CurPiece->m_fDimensions[1], CurPiece->m_fDimensions[5]),
@ -1124,12 +1109,11 @@ void View::DrawGrid()
lcVector3(CurPiece->m_fDimensions[3], CurPiece->m_fDimensions[1], CurPiece->m_fDimensions[2])
};
lcMatrix44 ModelWorld = lcMatrix44FromAxisAngle(lcVector3(Rotation[0], Rotation[1], Rotation[2]), Rotation[3] * LC_DTOR);
ModelWorld.SetTranslation(Position);
lcMatrix44 WorldMatrix = GetPieceInsertPosition();
for (int i = 0; i < 8; i++)
{
lcVector3 Point = lcMul31(Points[i], ModelWorld);
lcVector3 Point = lcMul31(Points[i], WorldMatrix);
if (Point[0] < BoundingBox[0]) BoundingBox[0] = Point[0];
if (Point[1] < BoundingBox[1]) BoundingBox[1] = Point[1];
@ -1422,12 +1406,7 @@ void View::BeginPieceDrag()
void View::EndPieceDrag(bool Accept)
{
if (Accept)
{
lcVector3 Position;
lcVector4 Rotation;
GetPieceInsertPosition(Position, Rotation);
mModel->InsertPieceToolClicked(Position, Rotation);
}
mModel->InsertPieceToolClicked(GetPieceInsertPosition());
mDragState = LC_DRAGSTATE_NONE;
UpdateTrackTool();
@ -1998,10 +1977,7 @@ void View::OnLeftButtonDown()
if (!CurPiece)
break;
lcVector3 Position;
lcVector4 Rotation;
GetPieceInsertPosition(Position, Rotation);
mModel->InsertPieceToolClicked(Position, Rotation);
mModel->InsertPieceToolClicked(GetPieceInsertPosition());
if (!mInputState.Control)
gMainWindow->SetTool(LC_TOOL_SELECT);

View file

@ -89,7 +89,7 @@ public:
LC_CURSOR_TYPE GetCursor() const;
lcVector3 GetMoveDirection(const lcVector3& Direction) const;
void GetPieceInsertPosition(lcVector3& Position, lcVector4& Rotation) const;
lcMatrix44 GetPieceInsertPosition() const;
lcObjectSection FindObjectUnderPointer(bool PiecesOnly) const;
lcArray<lcObject*> FindObjectsInBox(float x1, float y1, float x2, float y2) const;

View file

@ -523,7 +523,7 @@ void lcQPropertiesTree::slotReturnPressed()
if (Item == partPositionX || Item == partPositionY || Item == partPositionZ)
{
lcVector3 Position = Piece->mPosition;
lcVector3 Position = Piece->mModelWorld.GetTranslation();
float Value = Editor->text().toFloat();
if (Item == partPositionX)
@ -547,9 +547,8 @@ void lcQPropertiesTree::slotReturnPressed()
else if (Item == partRotationZ)
Rotation[2] = Value;
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(lcMatrix44FromEulerAngles(Rotation * LC_DTOR));
AxisAngle[3] *= LC_RTOD;
Model->SetObjectProperty(focusObject, LC_PIECE_PROPERTY_ROTATION, &AxisAngle);
Rotation *= LC_DTOR;
Model->SetObjectProperty(focusObject, LC_PIECE_PROPERTY_ROTATION, &Rotation);
}
else if (Item == partShow)
{
@ -781,7 +780,7 @@ void lcQPropertiesTree::setPart(lcObject *newFocusObject)
focusObject = newFocusObject;
lcPiece *part = (lcPiece*)focusObject;
lcVector3 position = part->mPosition;
lcVector3 position = part->mModelWorld.GetTranslation();
partPositionX->setText(1, QString::number(position[0]));
partPositionX->setData(0, PropertyValueRole, position[0]);
partPositionY->setText(1, QString::number(position[1]));