mirror of
https://github.com/leozide/leocad
synced 2025-01-30 20:34:56 +01:00
Fixed a few rotation bugs in flexible objects.
This commit is contained in:
parent
8de6f06113
commit
6547969d24
3 changed files with 83 additions and 39 deletions
|
@ -79,12 +79,11 @@ lcSynthInfo::lcSynthInfo(lcSynthType Type, float Length, int NumSections)
|
|||
break;
|
||||
}
|
||||
|
||||
mStart.Transform = lcMatrix44Identity();
|
||||
mStart.Transform[1][1] = -1.0f;
|
||||
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));
|
||||
mStart.Length = EdgeSectionLength;
|
||||
mMiddle.Transform = lcMatrix44Identity();
|
||||
mMiddle.Length = MidSectionLength;
|
||||
mEnd.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));
|
||||
mEnd.Length = EdgeSectionLength;
|
||||
}
|
||||
|
||||
|
@ -109,16 +108,60 @@ void lcSynthInfo::GetDefaultControlPoints(lcArray<lcPieceControlPoint>& ControlP
|
|||
break;
|
||||
}
|
||||
|
||||
lcMatrix33 RotationY = lcMatrix33RotationY(LC_PI / 2.0f);
|
||||
float HalfLength = mLength / 2.0f;
|
||||
Scale = lcMin(Scale, HalfLength);
|
||||
|
||||
ControlPoints[0].Transform = lcMatrix44(RotationY, lcVector3(-HalfLength, 0.0f, 0.0f));
|
||||
ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(-HalfLength, 0.0f, 0.0f));
|
||||
ControlPoints[0].Scale = Scale;
|
||||
ControlPoints[1].Transform = lcMatrix44(RotationY, lcVector3( HalfLength, 0.0f, 0.0f));
|
||||
ControlPoints[1].Transform = lcMatrix44Translation(lcVector3( HalfLength, 0.0f, 0.0f));
|
||||
ControlPoints[1].Scale = Scale;
|
||||
}
|
||||
|
||||
float lcSynthInfo::GetSectionTwist(const lcMatrix44& StartTransform, const lcMatrix44& EndTransform) const
|
||||
{
|
||||
lcVector3 StartTangent(StartTransform[1].x, StartTransform[1].y, StartTransform[1].z);
|
||||
lcVector3 EndTangent(EndTransform[1].x, EndTransform[1].y, EndTransform[1].z);
|
||||
lcVector3 StartUp(StartTransform[2].x, StartTransform[2].y, StartTransform[2].z);
|
||||
lcVector3 EndUp(EndTransform[2].x, EndTransform[2].y, EndTransform[2].z);
|
||||
|
||||
float TangentDot = lcDot(StartTangent, EndTangent);
|
||||
float UpDot = lcDot(StartUp, EndUp);
|
||||
|
||||
if (TangentDot > 0.99f && UpDot > 0.99f)
|
||||
return 0.0f;
|
||||
|
||||
if (fabs(TangentDot) > 0.99f)
|
||||
{
|
||||
return acosf(lcClamp(lcDot(EndUp, StartUp), -1.0f, 1.0f));
|
||||
}
|
||||
else if (TangentDot > -0.99f)
|
||||
{
|
||||
lcVector3 Axis = lcCross(StartTangent, EndTangent);
|
||||
float Angle = acosf(lcClamp(TangentDot, -1.0f, 1.0f));
|
||||
|
||||
lcMatrix33 Rotation = lcMatrix33FromAxisAngle(Axis, Angle);
|
||||
lcVector3 AdjustedStartUp = lcMul(StartUp, Rotation);
|
||||
return acosf(lcClamp(lcDot(EndUp, AdjustedStartUp), -1.0f, 1.0f));
|
||||
}
|
||||
|
||||
lcVector3 StartSide(StartTransform[0].x, StartTransform[0].y, StartTransform[0].z);
|
||||
lcVector3 EndSide(EndTransform[0].x, EndTransform[0].y, EndTransform[0].z);
|
||||
|
||||
float SideDot = lcDot(StartSide, EndSide);
|
||||
|
||||
if (fabs(SideDot) < 0.99f)
|
||||
{
|
||||
lcVector3 Axis = lcCross(StartSide, EndSide);
|
||||
float Angle = acosf(SideDot);
|
||||
|
||||
lcMatrix33 Rotation = lcMatrix33FromAxisAngle(Axis, Angle);
|
||||
lcVector3 AdjustedStartUp = lcMul(StartUp, Rotation);
|
||||
return acosf(lcClamp(lcDot(EndUp, AdjustedStartUp), -1.0f, 1.0f));
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
float SectionLength = 0.0f;
|
||||
|
@ -129,7 +172,7 @@ void lcSynthInfo::CalculateSections(const lcArray<lcPieceControlPoint>& ControlP
|
|||
|
||||
lcMatrix44 StartTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform);
|
||||
lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx + 1].Transform);
|
||||
StartTransform = lcMatrix44(lcMul(lcMatrix33(StartTransform), lcMatrix33(mStart.Transform)), StartTransform.GetTranslation());
|
||||
StartTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mStart.Transform), lcMatrix33(StartTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), StartTransform.GetTranslation());
|
||||
|
||||
if (ControlPointIdx == 0)
|
||||
{
|
||||
|
@ -143,10 +186,8 @@ void lcSynthInfo::CalculateSections(const lcArray<lcPieceControlPoint>& ControlP
|
|||
|
||||
Sections.Add(StartTransform);
|
||||
}
|
||||
else
|
||||
StartTransform = lcMatrix44(lcMul(lcMatrix33(StartTransform), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), StartTransform.GetTranslation());
|
||||
|
||||
EndTransform = lcMatrix44(lcMul(lcMatrix33(EndTransform), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation());
|
||||
EndTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mEnd.Transform), lcMatrix33(EndTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation());
|
||||
|
||||
SegmentControlPoints[0] = StartTransform.GetTranslation();
|
||||
SegmentControlPoints[1] = lcMul31(lcVector3(0.0f, ControlPoints[ControlPointIdx].Scale, 0.0f), StartTransform);
|
||||
|
@ -166,27 +207,19 @@ void lcSynthInfo::CalculateSections(const lcArray<lcPieceControlPoint>& ControlP
|
|||
CurvePoints.Add(Position);
|
||||
}
|
||||
|
||||
int CurrentPointIndex = 0;
|
||||
|
||||
lcVector3 StartUp(lcMul30(lcVector3(1.0f, 0.0f, 0.0f), StartTransform));
|
||||
lcVector3 EndUp(lcMul30(lcVector3(1.0f, 0.0f, 0.0f), EndTransform));
|
||||
lcVector4 UpRotation;
|
||||
float UpDot = lcDot(StartUp, EndUp);
|
||||
|
||||
if (UpDot < 0.99f)
|
||||
UpRotation = lcVector4(lcCross(StartUp, EndUp), acosf(UpDot));
|
||||
else
|
||||
UpRotation = lcVector4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float CurrentSegmentLength = 0.0f;
|
||||
float TotalSegmentLength = 0.0f;
|
||||
|
||||
for (int PointIdx = 0; PointIdx < CurvePoints.GetSize() - 1; PointIdx++)
|
||||
TotalSegmentLength += lcLength(CurvePoints[PointIdx] - CurvePoints[PointIdx + 1]);
|
||||
|
||||
lcVector3 StartUp(lcMul30(lcVector3(1.0f, 0.0f, 0.0f), StartTransform));
|
||||
float Twist = GetSectionTwist(StartTransform, EndTransform);
|
||||
int CurrentPointIndex = 0;
|
||||
|
||||
while (CurrentPointIndex < CurvePoints.GetSize() - 1)
|
||||
{
|
||||
float Length = lcLength(CurvePoints[CurrentPointIndex] - CurvePoints[CurrentPointIndex + 1]);
|
||||
float Length = lcLength(CurvePoints[CurrentPointIndex + 1] - CurvePoints[CurrentPointIndex]);
|
||||
CurrentSegmentLength += Length;
|
||||
SectionLength -= Length;
|
||||
CurrentPointIndex++;
|
||||
|
@ -197,12 +230,22 @@ void lcSynthInfo::CalculateSections(const lcArray<lcPieceControlPoint>& ControlP
|
|||
float t = (float)CurrentPointIndex / (float)(NumCurvePoints - 1);
|
||||
float it = 1.0f - t;
|
||||
|
||||
lcVector3 Tangent = -3.0f * it * it * SegmentControlPoints[0] + (3.0f * it * it - 6.0f * t * it) * SegmentControlPoints[1] + (-3.0f * t * t + 6.0f * t * it) * SegmentControlPoints[2] + 3.0f * t * t * SegmentControlPoints[3];
|
||||
lcVector3 Up = lcMul(StartUp, lcMatrix33FromAxisAngle(lcVector3(UpRotation[0], UpRotation[1], UpRotation[2]), UpRotation[3] * (CurrentSegmentLength / TotalSegmentLength)));
|
||||
lcVector3 Side = lcCross(Tangent, Up);
|
||||
Up = lcCross(Side, Tangent);
|
||||
lcVector3 Tangent = lcNormalize(-3.0f * it * it * SegmentControlPoints[0] + (3.0f * it * it - 6.0f * t * it) * SegmentControlPoints[1] + (-3.0f * t * t + 6.0f * t * it) * SegmentControlPoints[2] + 3.0f * t * t * SegmentControlPoints[3]);
|
||||
lcVector3 Up;
|
||||
|
||||
Sections.Add(lcMatrix44(lcMatrix33(lcNormalize(Up), lcNormalize(Tangent), lcNormalize(Side)), CurvePoints[CurrentPointIndex]));
|
||||
if (Twist)
|
||||
{
|
||||
Up = lcMul(StartUp, lcMatrix33FromAxisAngle(Tangent, Twist * (CurrentSegmentLength / TotalSegmentLength)));
|
||||
CurrentSegmentLength = 0.0f;
|
||||
}
|
||||
else
|
||||
Up = StartUp;
|
||||
|
||||
lcVector3 Side = lcNormalize(lcCross(Tangent, Up));
|
||||
Up = lcNormalize(lcCross(Side, Tangent));
|
||||
StartUp = Up;
|
||||
|
||||
Sections.Add(lcMatrix44(lcMatrix33(Up, Tangent, Side), CurvePoints[CurrentPointIndex]));
|
||||
|
||||
if (SectionCallback)
|
||||
SectionCallback(CurvePoints[CurrentPointIndex], ControlPointIdx, t, CallbackParam);
|
||||
|
@ -219,7 +262,7 @@ void lcSynthInfo::CalculateSections(const lcArray<lcPieceControlPoint>& ControlP
|
|||
while (Sections.GetSize() < mNumSections + 2)
|
||||
{
|
||||
lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPoints.GetSize() - 1].Transform);
|
||||
EndTransform = lcMatrix44(lcMul(lcMatrix33(EndTransform), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation());
|
||||
EndTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mEnd.Transform), lcMatrix33(EndTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation());
|
||||
lcVector3 Position = lcMul31(lcVector3(0.0f, SectionLength, 0.0f), EndTransform);
|
||||
EndTransform.SetTranslation(Position);
|
||||
Sections.Add(EndTransform);
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
lcMesh* CreateMesh(const lcArray<lcPieceControlPoint>& ControlPoints) const;
|
||||
|
||||
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 AddRibbedHoseParts(lcMemFile& File, const lcArray<lcMatrix44>& Sections) const;
|
||||
void AddFlexibleAxleParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray<lcMatrix44>& Sections) const;
|
||||
|
|
|
@ -775,8 +775,8 @@ void View::DrawSelectMoveOverlay()
|
|||
lcVector3 Verts[38];
|
||||
int NumVerts = 0;
|
||||
|
||||
Verts[NumVerts++] = lcVector3(0.0f, 0.0f, Length - OverlayScaleRadius);
|
||||
Verts[NumVerts++] = lcVector3(0.0f, 0.0f, OverlayScaleRadius - Length);
|
||||
Verts[NumVerts++] = lcVector3(Length - OverlayScaleRadius, 0.0f, 0.0f);
|
||||
Verts[NumVerts++] = lcVector3(OverlayScaleRadius - Length, 0.0f, 0.0f);
|
||||
|
||||
float SinTable[9], CosTable[9];
|
||||
|
||||
|
@ -791,8 +791,8 @@ void View::DrawSelectMoveOverlay()
|
|||
float x = CosTable[Step];
|
||||
float y = SinTable[Step];
|
||||
|
||||
Verts[NumVerts++] = lcVector3(x * OverlayScaleInnerRadius, 0.0f, y * OverlayScaleInnerRadius + Length);
|
||||
Verts[NumVerts++] = lcVector3(x * OverlayScaleRadius, 0.0f, y * OverlayScaleRadius + Length);
|
||||
Verts[NumVerts++] = lcVector3(Length + x * OverlayScaleInnerRadius, 0.0f, y * OverlayScaleInnerRadius);
|
||||
Verts[NumVerts++] = lcVector3(Length + x * OverlayScaleRadius, 0.0f, y * OverlayScaleRadius);
|
||||
}
|
||||
|
||||
for (int Step = 0; Step <= 8; Step++)
|
||||
|
@ -800,8 +800,8 @@ void View::DrawSelectMoveOverlay()
|
|||
float x = CosTable[Step];
|
||||
float y = SinTable[Step];
|
||||
|
||||
Verts[NumVerts++] = lcVector3(x * OverlayScaleInnerRadius, 0.0f, y * OverlayScaleInnerRadius - Length);
|
||||
Verts[NumVerts++] = lcVector3(x * OverlayScaleRadius, 0.0f, y * OverlayScaleRadius - Length);
|
||||
Verts[NumVerts++] = lcVector3(-Length + x * OverlayScaleInnerRadius, 0.0f, y * OverlayScaleInnerRadius);
|
||||
Verts[NumVerts++] = lcVector3(-Length + x * OverlayScaleRadius, 0.0f, y * OverlayScaleRadius);
|
||||
}
|
||||
|
||||
if (mTrackTool == LC_TRACKTOOL_SCALE_PLUS || mTrackTool == LC_TRACKTOOL_SCALE_MINUS)
|
||||
|
@ -1812,7 +1812,7 @@ void View::UpdateTrackTool()
|
|||
const float ScaleStart = (2.0f - OverlayScaleRadius) * OverlayScale + Strength;
|
||||
const float ScaleEnd = (2.0f + OverlayScaleRadius) * OverlayScale + Strength;
|
||||
|
||||
if (AxisIndex == 0 && fabs(Proj1) < OverlayScaleRadius * OverlayScale)
|
||||
if (AxisIndex == 1 && fabs(Proj1) < OverlayScaleRadius * OverlayScale)
|
||||
{
|
||||
if (Proj2 > ScaleStart && Proj2 < ScaleEnd)
|
||||
{
|
||||
|
@ -1827,7 +1827,7 @@ void View::UpdateTrackTool()
|
|||
ClosestIntersectionDistance = IntersectionDistance;
|
||||
}
|
||||
}
|
||||
else if (AxisIndex == 1 && fabs(Proj2) < OverlayScaleRadius * OverlayScale)
|
||||
else if (AxisIndex == 2 && fabs(Proj2) < OverlayScaleRadius * OverlayScale)
|
||||
{
|
||||
if (Proj1 > ScaleStart && Proj1 < ScaleEnd)
|
||||
{
|
||||
|
@ -2592,9 +2592,9 @@ void View::OnMouseMove()
|
|||
{
|
||||
lcVector3 Direction;
|
||||
if (mTrackTool == LC_TRACKTOOL_SCALE_PLUS)
|
||||
Direction = lcVector3(0.0f, 0.0f, 1.0f);
|
||||
Direction = lcVector3(1.0f, 0.0f, 0.0f);
|
||||
else
|
||||
Direction = lcVector3(0.0f, 0.0f, -1.0f);
|
||||
Direction = lcVector3(-1.0f, 0.0f, 0.0f);
|
||||
|
||||
Direction = lcMul(Direction, RelativeRotation);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue