Added synth support for shock absorbers.

This commit is contained in:
leo 2016-05-01 00:20:37 +00:00
parent e6c6ef9490
commit a0db9ce210
10 changed files with 338 additions and 89 deletions

View file

@ -195,6 +195,11 @@ public:
return ~0;
}
virtual lcuint32 GetAllowedTransforms() const
{
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
}
virtual lcVector3 GetSectionPosition(lcuint32 Section) const
{
switch (Section)

View file

@ -9,6 +9,7 @@
#include "lc_profile.h"
#include "lc_library.h"
#include "lc_texture.h"
#include "lc_synth.h"
#include "pieceinf.h"
#include "view.h"
#include "preview.h"
@ -3007,7 +3008,8 @@ void lcModel::GetSelectionInformation(int* Flags, lcArray<lcObject*>& Selection,
*Flags |= LC_SEL_PIECE | LC_SEL_SELECTED;
if (Piece->mPieceInfo->GetSynthInfo())
lcSynthInfo* SynthInfo = Piece->mPieceInfo->GetSynthInfo();
if (SynthInfo && SynthInfo->CanAddControlPoints())
{
*Flags |= LC_SEL_CAN_ADD_CONTROL_POINT;

View file

@ -35,7 +35,11 @@ void lcSynthInit()
{ "32235", LC_SYNTH_PIECE_FLEXIBLE_AXLE, 360.00f, 75 }, // Technic Axle Flexible 19
{ "76384", LC_SYNTH_PIECE_STRING_BRAIDED, 200.00f, 46 }, // String Braided 11L with End Studs
{ "75924", LC_SYNTH_PIECE_STRING_BRAIDED, 400.00f, 96 }, // String Braided 21L with End Studs
{ "572C02", LC_SYNTH_PIECE_STRING_BRAIDED, 800.00f, 196 } // String Braided 41L with End Studs
{ "572C02", LC_SYNTH_PIECE_STRING_BRAIDED, 800.00f, 196 }, // String Braided 41L with End Studs
{ "73129", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 }, // Technic Shock Absorber 6.5L
{ "41838", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 }, // Technic Shock Absorber 6.5L Soft
{ "76138", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 }, // Technic Shock Absorber 6.5L Stiff
{ "76537", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 } // Technic Shock Absorber 6.5L Extra Stiff
};
for (unsigned int InfoIdx = 0; InfoIdx < sizeof(HoseInfo) / sizeof(HoseInfo[0]); InfoIdx++)
@ -43,7 +47,7 @@ void lcSynthInit()
PieceInfo* Info = Library->FindPiece(HoseInfo[InfoIdx].PartID, NULL, false);
if (Info)
Info->SetSynthInfo(new lcSynthInfo(HoseInfo[InfoIdx].Type, HoseInfo[InfoIdx].Length, HoseInfo[InfoIdx].NumSections));
Info->SetSynthInfo(new lcSynthInfo(HoseInfo[InfoIdx].Type, HoseInfo[InfoIdx].Length, HoseInfo[InfoIdx].NumSections, Info));
}
// "758C01" // Hose Flexible 12L
@ -51,39 +55,58 @@ void lcSynthInit()
// "73590B" // Hose Flexible 8.5L with Tabs
}
lcSynthInfo::lcSynthInfo(lcSynthType Type, float Length, int NumSections)
: mType(Type), mLength(Length), mNumSections(NumSections)
lcSynthInfo::lcSynthInfo(lcSynthType Type, float Length, int NumSections, PieceInfo* Info)
: mType(Type), mLength(Length), mNumSections(NumSections), mPieceInfo(Info)
{
float EdgeSectionLength;
float MidSectionLength;
mRigidEdges = false;
switch (mType)
{
case LC_SYNTH_PIECE_RIBBED_HOSE:
EdgeSectionLength = 6.25f;
MidSectionLength = 6.25f;
mRigidEdges = false;
mCurve = true;
break;
case LC_SYNTH_PIECE_FLEXIBLE_AXLE:
EdgeSectionLength = 30.0f;
MidSectionLength = 4.0f;
mRigidEdges = true;
mCurve = true;
break;
case LC_SYNTH_PIECE_STRING_BRAIDED:
EdgeSectionLength = 8.0f;
MidSectionLength = 4.0f;
mRigidEdges = true;
mCurve = true;
break;
case LC_SYNTH_PIECE_SHOCK_ABSORBER:
EdgeSectionLength = 0.0f;
MidSectionLength = 0.0f;
mRigidEdges = false;
mCurve = false;
break;
}
mStart.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f));
if (mType != LC_SYNTH_PIECE_SHOCK_ABSORBER)
{
mStart.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f));
mMiddle.Transform = lcMatrix44Identity();
mEnd.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f));
}
else
{
mStart.Transform = lcMatrix44Identity();
mMiddle.Transform = lcMatrix44Identity();
mEnd.Transform = lcMatrix44Identity();
}
mStart.Length = EdgeSectionLength;
mMiddle.Transform = lcMatrix44Identity();
mMiddle.Length = MidSectionLength;
mEnd.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f));
mEnd.Length = EdgeSectionLength;
}
@ -106,14 +129,27 @@ void lcSynthInfo::GetDefaultControlPoints(lcArray<lcPieceControlPoint>& ControlP
case LC_SYNTH_PIECE_STRING_BRAIDED:
Scale = 12.0f;
break;
case LC_SYNTH_PIECE_SHOCK_ABSORBER:
Scale = 1.0f;
break;
}
float HalfLength = mLength / 2.0f;
Scale = lcMin(Scale, HalfLength);
ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(-HalfLength, 0.0f, 0.0f));
if (mType != LC_SYNTH_PIECE_SHOCK_ABSORBER)
{
ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(-HalfLength, 0.0f, 0.0f));
ControlPoints[1].Transform = lcMatrix44Translation(lcVector3( HalfLength, 0.0f, 0.0f));
}
else
{
ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, -mLength));
ControlPoints[1].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, 0.0f));
}
ControlPoints[0].Scale = Scale;
ControlPoints[1].Transform = lcMatrix44Translation(lcVector3( HalfLength, 0.0f, 0.0f));
ControlPoints[1].Scale = Scale;
}
@ -162,7 +198,7 @@ float lcSynthInfo::GetSectionTwist(const lcMatrix44& StartTransform, const lcMat
return 0.0f;
}
void lcSynthInfo::CalculateSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, void (*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const
void lcSynthInfo::CalculateCurveSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, void (*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const
{
float SectionLength = 0.0f;
@ -276,6 +312,18 @@ void lcSynthInfo::CalculateSections(const lcArray<lcPieceControlPoint>& ControlP
}
}
void lcSynthInfo::CalculateLineSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const
{
for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize(); ControlPointIdx++)
{
lcMatrix44 Transform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform);
Sections.Add(Transform);
if (SectionCallback)
SectionCallback(Transform.GetTranslation(), ControlPointIdx, 1.0f, CallbackParam);
}
}
void lcSynthInfo::AddRibbedHoseParts(lcMemFile& File, const lcArray<lcMatrix44>& Sections) const
{
char Line[256];
@ -541,10 +589,47 @@ void lcSynthInfo::AddStringBraidedParts(lcMemFile& File, lcLibraryMeshData& Mesh
}
}
void lcSynthInfo::AddShockAbsorberParts(lcMemFile& File, lcArray<lcMatrix44>& Sections) const
{
char Line[256];
lcVector3 Offset;
Offset = Sections[0].GetTranslation();
sprintf(Line, "1 0 %f %f %f 1 0 0 0 1 0 0 0 1 4254.DAT\n", Offset[0], Offset[1], Offset[2]);
File.WriteBuffer(Line, strlen(Line));
Offset = Sections[1].GetTranslation();
sprintf(Line, "1 16 %f %f %f 1 0 0 0 1 0 0 0 1 4255.DAT\n", Offset[0], Offset[1], Offset[2]);
File.WriteBuffer(Line, strlen(Line));
float Distance = Sections[0].GetTranslation().y - Sections[1].GetTranslation().y;
float Scale = (Distance - 66.0f) / 44.0f;
const char* SpringPart;
if (!strcmp(mPieceInfo->m_strName, "73129"))
SpringPart = "70038";
else if (!strcmp(mPieceInfo->m_strName, "41838"))
SpringPart = "41837";
else if (!strcmp(mPieceInfo->m_strName, "76138"))
SpringPart = "71953";
else if (!strcmp(mPieceInfo->m_strName, "76537"))
SpringPart = "22977";
else
return;
Offset = Sections[0].GetTranslation();
sprintf(Line, "1 494 %f %f %f 1 0 0 0 %f 0 0 0 1 %s.DAT\n", Offset[0], Offset[1] - 10 - 44.0f * Scale, Offset[2], Scale, SpringPart);
File.WriteBuffer(Line, strlen(Line));
}
lcMesh* lcSynthInfo::CreateMesh(const lcArray<lcPieceControlPoint>& ControlPoints) const
{
lcArray<lcMatrix44> Sections;
CalculateSections(ControlPoints, Sections, NULL, NULL);
if (mCurve)
CalculateCurveSections(ControlPoints, Sections, NULL, NULL);
else
CalculateLineSections(ControlPoints, Sections, NULL, NULL);
lcLibraryMeshData MeshData;
lcMemFile File; // todo: rewrite this to pass the parts directly
@ -562,6 +647,10 @@ lcMesh* lcSynthInfo::CreateMesh(const lcArray<lcPieceControlPoint>& ControlPoint
case LC_SYNTH_PIECE_STRING_BRAIDED:
AddStringBraidedParts(File, MeshData, Sections);
break;
case LC_SYNTH_PIECE_SHOCK_ABSORBER:
AddShockAbsorberParts(File, Sections);
break;
}
File.WriteU8(0);
@ -613,7 +702,7 @@ int lcSynthInfo::InsertControlPoint(lcArray<lcPieceControlPoint>& ControlPoints,
SynthInsertParam.BestSegment = -1;
SynthInsertParam.BestDistance = FLT_MAX;
CalculateSections(ControlPoints, Sections, lcSynthInsertCallback, &SynthInsertParam);
CalculateCurveSections(ControlPoints, Sections, lcSynthInsertCallback, &SynthInsertParam);
if (SynthInsertParam.BestSegment != -1)
{

View file

@ -8,7 +8,8 @@ enum lcSynthType
{
LC_SYNTH_PIECE_RIBBED_HOSE,
LC_SYNTH_PIECE_FLEXIBLE_AXLE,
LC_SYNTH_PIECE_STRING_BRAIDED
LC_SYNTH_PIECE_STRING_BRAIDED,
LC_SYNTH_PIECE_SHOCK_ABSORBER
};
struct lcSynthComponent
@ -22,7 +23,17 @@ class lcLibraryMeshData;
class lcSynthInfo
{
public:
lcSynthInfo(lcSynthType Type, float Length, int NumSections);
lcSynthInfo(lcSynthType Type, float Length, int NumSections, PieceInfo* Info);
bool CanAddControlPoints() const
{
return mCurve;
}
bool IsCurve() const
{
return mCurve;
}
void GetDefaultControlPoints(lcArray<lcPieceControlPoint>& ControlPoints) const;
int InsertControlPoint(lcArray<lcPieceControlPoint>& ControlPoints, const lcVector3& Start, const lcVector3& End) const;
@ -30,15 +41,19 @@ public:
protected:
float GetSectionTwist(const lcMatrix44& StartTransform, const lcMatrix44& EndTransform) const;
void CalculateSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const;
void CalculateCurveSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const;
void CalculateLineSections(const lcArray<lcPieceControlPoint>& ControlPoints, lcArray<lcMatrix44>& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const;
void AddRibbedHoseParts(lcMemFile& File, const lcArray<lcMatrix44>& Sections) const;
void AddFlexibleAxleParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray<lcMatrix44>& Sections) const;
void AddStringBraidedParts(lcMemFile& File, lcLibraryMeshData& MeshData, lcArray<lcMatrix44>& Sections) const;
void AddShockAbsorberParts(lcMemFile& File, lcArray<lcMatrix44>& Sections) const;
PieceInfo* mPieceInfo;
lcSynthType mType;
lcSynthComponent mStart;
lcSynthComponent mMiddle;
lcSynthComponent mEnd;
bool mCurve;
float mLength;
int mNumSections;
bool mRigidEdges;

View file

@ -156,6 +156,11 @@ public:
return ~0;
}
virtual lcuint32 GetAllowedTransforms() const
{
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
}
virtual lcVector3 GetSectionPosition(lcuint32 Section) const
{
switch (Section)

View file

@ -44,6 +44,16 @@ struct lcObjectBoxTest
lcArray<lcObject*> Objects;
};
#define LC_OBJECT_TRANSFORM_MOVE_X 0x001
#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002
#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004
#define LC_OBJECT_TRANSFORM_ROTATE_X 0x010
#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020
#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040
#define LC_OBJECT_TRANSFORM_SCALE_X 0x100
#define LC_OBJECT_TRANSFORM_SCALE_Y 0x200
#define LC_OBJECT_TRANSFORM_SCALE_Z 0x400
class lcObject
{
public:
@ -80,6 +90,7 @@ public:
virtual void SetFocused(lcuint32 Section, bool Focused) = 0;
virtual lcuint32 GetFocusSection() const = 0;
virtual lcuint32 GetAllowedTransforms() const = 0;
virtual lcVector3 GetSectionPosition(lcuint32 Section) const = 0;
virtual void RayTest(lcObjectRayTest& ObjectRayTest) const = 0;
virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const = 0;

View file

@ -735,16 +735,30 @@ void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix)
mState |= LC_PIECE_PIVOT_POINT_VALID;
}
lcuint32 lcPiece::GetAllowedTransforms() const
{
lcuint32 Section = GetFocusSection();
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
if (mPieceInfo->GetSynthInfo()->IsCurve())
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z | LC_OBJECT_TRANSFORM_SCALE_X;
else
return LC_OBJECT_TRANSFORM_MOVE_Z;
}
bool lcPiece::InsertControlPoint(const lcVector3& WorldStart, const lcVector3& WorldEnd)
{
if (!mPieceInfo->GetSynthInfo())
lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo();
if (!SynthInfo || !SynthInfo->CanAddControlPoints())
return false;
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld);
lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix);
lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix);
int ControlPointIndex = mPieceInfo->GetSynthInfo()->InsertControlPoint(mControlPoints, Start, End);
int ControlPointIndex = SynthInfo->InsertControlPoint(mControlPoints, Start, End);
if (ControlPointIndex)
{
SetFocused(GetFocusSection(), false);

View file

@ -288,6 +288,8 @@ public:
return LC_PIECE_SECTION_INVALID;
}
virtual lcuint32 GetAllowedTransforms() const;
virtual lcVector3 GetSectionPosition(lcuint32 Section) const
{
switch (Section)

View file

@ -12,6 +12,7 @@
#include "preview.h"
#include "piece.h"
#include "pieceinf.h"
#include "lc_synth.h"
lcVertexBuffer View::mRotateMoveVertexBuffer;
lcIndexBuffer View::mRotateMoveIndexBuffer;
@ -680,64 +681,85 @@ void View::DrawSelectMoveOverlay()
mContext->SetVertexBuffer(mRotateMoveVertexBuffer);
mContext->SetVertexFormat(0, 3, 0, 0);
lcObject* Focus = mModel->GetFocusObject();
lcuint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
if (mTrackButton == LC_TRACKBUTTON_NONE || (mTrackTool >= LC_TRACKTOOL_MOVE_X && mTrackTool <= LC_TRACKTOOL_MOVE_XYZ))
{
if ((mTrackTool == LC_TRACKTOOL_MOVE_X) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ))
if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_X)
{
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
}
else if (mTrackButton == LC_TRACKBUTTON_NONE)
{
mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
if ((mTrackTool == LC_TRACKTOOL_MOVE_X) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ))
{
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
}
else if (mTrackButton == LC_TRACKBUTTON_NONE)
{
mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
}
}
if ((mTrackTool == LC_TRACKTOOL_MOVE_Y) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ))
if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y)
{
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2);
}
else if (mTrackButton == LC_TRACKBUTTON_NONE)
{
mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2);
if ((mTrackTool == LC_TRACKTOOL_MOVE_Y) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ) && (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y))
{
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2);
}
else if (mTrackButton == LC_TRACKBUTTON_NONE)
{
mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2);
}
}
if ((mTrackTool == LC_TRACKTOOL_MOVE_Z) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ))
if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z)
{
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2);
}
else if (mTrackButton == LC_TRACKBUTTON_NONE)
{
mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2);
if ((mTrackTool == LC_TRACKTOOL_MOVE_Z) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ) && (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z))
{
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2);
}
else if (mTrackButton == LC_TRACKBUTTON_NONE)
{
mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2);
}
}
}
if (gMainWindow->GetTool() == LC_TOOL_SELECT && mTrackButton == LC_TRACKBUTTON_NONE && AnyPiecesSelected)
{
if (mTrackTool == LC_TRACKTOOL_ROTATE_X)
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
else
mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f);
if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_X)
{
if (mTrackTool == LC_TRACKTOOL_ROTATE_X)
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
else
mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, 108 * 2);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, 108 * 2);
}
if (mTrackTool == LC_TRACKTOOL_ROTATE_Y)
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
else
mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f);
if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Y)
{
if (mTrackTool == LC_TRACKTOOL_ROTATE_Y)
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
else
mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 120) * 2);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 120) * 2);
}
if (mTrackTool == LC_TRACKTOOL_ROTATE_Z)
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
else
mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f);
if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Z)
{
if (mTrackTool == LC_TRACKTOOL_ROTATE_Z)
mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
else
mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 240) * 2);
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 240) * 2);
}
}
if ((mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ))
@ -757,13 +779,12 @@ void View::DrawSelectMoveOverlay()
glDisable(GL_BLEND);
}
lcObject* Focus = mModel->GetFocusObject();
if (Focus && Focus->IsPiece())
{
lcPiece* Piece = (lcPiece*)Focus;
lcuint32 Section = Piece->GetFocusSection();
if (Section >= LC_PIECE_SECTION_CONTROL_POINT_1 && Section <= LC_PIECE_SECTION_CONTROL_POINT_8)
if (Section >= LC_PIECE_SECTION_CONTROL_POINT_1 && Section <= LC_PIECE_SECTION_CONTROL_POINT_8 && Piece->mPieceInfo->GetSynthInfo()->IsCurve())
{
int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_1;
float Strength = Piece->GetControlPoints()[ControlPointIndex].Scale;
@ -1774,11 +1795,11 @@ void View::UpdateTrackTool()
lcuint32 Section = Piece->GetFocusSection();
if (Section >= LC_PIECE_SECTION_CONTROL_POINT_1 && Section <= LC_PIECE_SECTION_CONTROL_POINT_8)
{
ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_1;
}
}
lcuint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++)
{
lcVector4 Plane(PlaneNormals[AxisIndex], -lcDot(PlaneNormals[AxisIndex], OverlayCenter));
@ -1801,41 +1822,50 @@ void View::UpdateTrackTool()
{
lcTrackTool PlaneModes[] = { LC_TRACKTOOL_MOVE_YZ, LC_TRACKTOOL_MOVE_XZ, LC_TRACKTOOL_MOVE_XY };
NewTrackTool = PlaneModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(PlaneModes[AxisIndex], AllowedTransforms))
{
NewTrackTool = PlaneModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
}
}
if (CurrentTool == LC_TOOL_SELECT && Proj1 > OverlayRotateArrowStart && Proj1 < OverlayRotateArrowEnd && Proj2 > OverlayRotateArrowStart && Proj2 < OverlayRotateArrowEnd && mModel->AnyPiecesSelected())
{
lcTrackTool PlaneModes[] = { LC_TRACKTOOL_ROTATE_X, LC_TRACKTOOL_ROTATE_Y, LC_TRACKTOOL_ROTATE_Z };
NewTrackTool = PlaneModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(PlaneModes[AxisIndex], AllowedTransforms))
{
NewTrackTool = PlaneModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
}
}
if (fabs(Proj1) < OverlayMoveArrowCapRadius && Proj2 > 0.0f && Proj2 < OverlayMoveArrowSize)
{
lcTrackTool DirModes[] = { LC_TRACKTOOL_MOVE_Z, LC_TRACKTOOL_MOVE_X, LC_TRACKTOOL_MOVE_Y };
NewTrackTool = DirModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(DirModes[AxisIndex], AllowedTransforms))
{
NewTrackTool = DirModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
}
}
if (fabs(Proj2) < OverlayMoveArrowCapRadius && Proj1 > 0.0f && Proj1 < OverlayMoveArrowSize)
{
lcTrackTool DirModes[] = { LC_TRACKTOOL_MOVE_Y, LC_TRACKTOOL_MOVE_Z, LC_TRACKTOOL_MOVE_X };
NewTrackTool = DirModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(DirModes[AxisIndex], AllowedTransforms))
{
NewTrackTool = DirModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
}
}
if (ControlPointIndex != -1)
lcPiece* Piece = (lcPiece*)Focus;
if (ControlPointIndex != -1 && Piece->mPieceInfo->GetSynthInfo()->IsCurve())
{
lcPiece* Piece = (lcPiece*)Focus;
float Strength = Piece->GetControlPoints()[ControlPointIndex].Scale;
const float ScaleStart = (2.0f - OverlayScaleRadius) * OverlayScale + Strength;
const float ScaleEnd = (2.0f + OverlayScaleRadius) * OverlayScale + Strength;
@ -1844,30 +1874,38 @@ void View::UpdateTrackTool()
{
if (Proj2 > ScaleStart && Proj2 < ScaleEnd)
{
NewTrackTool = LC_TRACKTOOL_SCALE_PLUS;
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_PLUS, AllowedTransforms))
{
NewTrackTool = LC_TRACKTOOL_SCALE_PLUS;
ClosestIntersectionDistance = IntersectionDistance;
}
}
else if (Proj2 < -ScaleStart && Proj2 > -ScaleEnd)
{
NewTrackTool = LC_TRACKTOOL_SCALE_MINUS;
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_MINUS, AllowedTransforms))
{
NewTrackTool = LC_TRACKTOOL_SCALE_MINUS;
ClosestIntersectionDistance = IntersectionDistance;
}
}
}
else if (AxisIndex == 2 && fabs(Proj2) < OverlayScaleRadius * OverlayScale)
{
if (Proj1 > ScaleStart && Proj1 < ScaleEnd)
{
NewTrackTool = LC_TRACKTOOL_SCALE_PLUS;
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_PLUS, AllowedTransforms))
{
NewTrackTool = LC_TRACKTOOL_SCALE_PLUS;
ClosestIntersectionDistance = IntersectionDistance;
}
}
else if (Proj1 < -ScaleStart && Proj1 > -ScaleEnd)
{
NewTrackTool = LC_TRACKTOOL_SCALE_MINUS;
ClosestIntersectionDistance = IntersectionDistance;
if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_MINUS, AllowedTransforms))
{
NewTrackTool = LC_TRACKTOOL_SCALE_MINUS;
ClosestIntersectionDistance = IntersectionDistance;
}
}
}
}
@ -2106,6 +2144,73 @@ void View::UpdateTrackTool()
}
}
bool View::IsTrackToolAllowed(lcTrackTool TrackTool, lcuint32 AllowedTransforms) const
{
switch (TrackTool)
{
case LC_TRACKTOOL_NONE:
case LC_TRACKTOOL_INSERT:
case LC_TRACKTOOL_POINTLIGHT:
case LC_TRACKTOOL_SPOTLIGHT:
case LC_TRACKTOOL_CAMERA:
case LC_TRACKTOOL_SELECT:
return true;
case LC_TRACKTOOL_MOVE_X:
return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_X;
case LC_TRACKTOOL_MOVE_Y:
return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y;
case LC_TRACKTOOL_MOVE_Z:
return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z;
case LC_TRACKTOOL_MOVE_XY:
return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y);
case LC_TRACKTOOL_MOVE_XZ:
return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Z);
case LC_TRACKTOOL_MOVE_YZ:
return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z);
case LC_TRACKTOOL_MOVE_XYZ:
return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z);
case LC_TRACKTOOL_ROTATE_X:
return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_X;
case LC_TRACKTOOL_ROTATE_Y:
return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Y;
case LC_TRACKTOOL_ROTATE_Z:
return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Z;
case LC_TRACKTOOL_ROTATE_XY:
return (AllowedTransforms & (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y)) == (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y);
case LC_TRACKTOOL_ROTATE_XYZ:
return (AllowedTransforms & (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z)) == (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z);
case LC_TRACKTOOL_SCALE_PLUS:
case LC_TRACKTOOL_SCALE_MINUS:
return AllowedTransforms & (LC_OBJECT_TRANSFORM_SCALE_X | LC_OBJECT_TRANSFORM_SCALE_Y | LC_OBJECT_TRANSFORM_SCALE_Z);
case LC_TRACKTOOL_ERASER:
case LC_TRACKTOOL_PAINT:
case LC_TRACKTOOL_ZOOM:
case LC_TRACKTOOL_PAN:
case LC_TRACKTOOL_ORBIT_X:
case LC_TRACKTOOL_ORBIT_Y:
case LC_TRACKTOOL_ORBIT_XY:
case LC_TRACKTOOL_ROLL:
case LC_TRACKTOOL_ZOOM_REGION:
return true;
}
return false;
}
void View::StartTracking(lcTrackButton TrackButton)
{
LC_ASSERT(mTrackButton == LC_TRACKBUTTON_NONE);

View file

@ -133,6 +133,7 @@ protected:
void DrawViewport();
void UpdateTrackTool();
bool IsTrackToolAllowed(lcTrackTool TrackTool, lcuint32 AllowedTransforms) const;
lcTool GetCurrentTool() const;
lcTrackTool GetOverrideTrackTool(Qt::MouseButton Button) const;
float GetOverlayScale() const;