mirror of
https://github.com/leozide/leocad
synced 2025-01-29 20:34:50 +01:00
Fixed mouse selection of submodels.
This commit is contained in:
parent
7716e0ae37
commit
0aae5d339f
8 changed files with 132 additions and 83 deletions
|
@ -677,7 +677,7 @@ void lcCamera::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
lcVector3 End = lcMul31(ObjectRayTest.End, mWorldView);
|
||||
|
||||
float Distance;
|
||||
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcCamera*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_POSITION;
|
||||
|
@ -693,7 +693,7 @@ void lcCamera::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
Start = lcMul31(ObjectRayTest.Start, WorldView);
|
||||
End = lcMul31(ObjectRayTest.End, WorldView);
|
||||
|
||||
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcCamera*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_TARGET;
|
||||
|
@ -709,7 +709,7 @@ void lcCamera::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
Start = lcMul31(ObjectRayTest.Start, WorldView);
|
||||
End = lcMul31(ObjectRayTest.End, WorldView);
|
||||
|
||||
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcCamera*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_UPVECTOR;
|
||||
|
|
|
@ -1377,7 +1377,7 @@ inline bool lcTriangleIntersectsPlanes(float* p1, float* p2, float* p3, const lc
|
|||
}
|
||||
|
||||
// Return true if a ray intersects a bounding box, and calculates the distance from the start of the ray (adapted from Graphics Gems).
|
||||
inline bool lcBoundingBoxRayMinIntersectDistance(const lcVector3& Min, const lcVector3& Max, const lcVector3& Start, const lcVector3& End, float* Dist, lcVector3* Intersection)
|
||||
inline bool lcBoundingBoxRayIntersectDistance(const lcVector3& Min, const lcVector3& Max, const lcVector3& Start, const lcVector3& End, float* Dist, lcVector3* Intersection)
|
||||
{
|
||||
bool MiddleQuadrant[3];
|
||||
bool Inside = true;
|
||||
|
|
|
@ -473,7 +473,7 @@ void lcModel::LoadLDraw(QTextStream& Stream)
|
|||
}
|
||||
}
|
||||
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
UpdateBackgroundTexture();
|
||||
|
||||
delete Piece;
|
||||
|
@ -772,7 +772,7 @@ bool lcModel::LoadBinary(lcFile* file)
|
|||
}
|
||||
|
||||
UpdateBackgroundTexture();
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
/*
|
||||
gMainWindow->UpdateFocusObject(GetFocusObject());
|
||||
|
||||
|
@ -874,7 +874,7 @@ void lcModel::Paste()
|
|||
Merge(Model);
|
||||
SaveCheckpoint(tr("Pasting"));
|
||||
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
gMainWindow->UpdateAllViews();
|
||||
}
|
||||
|
||||
|
@ -937,7 +937,7 @@ void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface)
|
|||
Scene.TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare);
|
||||
}
|
||||
|
||||
void lcModel::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const
|
||||
void lcModel::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const
|
||||
{
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
|
@ -1108,6 +1108,37 @@ void lcModel::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
|
|||
mLights[LightIdx]->BoxTest(ObjectBoxTest);
|
||||
}
|
||||
|
||||
bool lcModel::SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const
|
||||
{
|
||||
bool MinIntersect = false;
|
||||
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
lcPiece* Piece = mPieces[PieceIdx];
|
||||
|
||||
if (Piece->GetStepHide() == LC_STEP_MAX && Piece->mPieceInfo->MinIntersectDist(Piece->mModelWorld, WorldStart, WorldEnd, MinDistance))
|
||||
MinIntersect = true;
|
||||
}
|
||||
|
||||
return MinIntersect;
|
||||
}
|
||||
|
||||
bool lcModel::SubModelBoxTest(const lcVector4 Planes[6]) const
|
||||
{
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
lcPiece* Piece = mPieces[PieceIdx];
|
||||
|
||||
if (Piece->GetStepHide() != LC_STEP_MAX)
|
||||
continue;
|
||||
|
||||
if (Piece->mPieceInfo->BoxTest(Piece->mModelWorld, Planes))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void lcModel::SaveCheckpoint(const QString& Description)
|
||||
{
|
||||
lcModelHistoryEntry* ModelHistoryEntry = new lcModelHistoryEntry();
|
||||
|
@ -1171,7 +1202,7 @@ void lcModel::ShowFirstStep()
|
|||
|
||||
mCurrentStep = 1;
|
||||
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
UpdateSelection();
|
||||
gMainWindow->UpdateFocusObject(GetFocusObject());
|
||||
gMainWindow->UpdateAllViews();
|
||||
|
@ -1187,7 +1218,7 @@ void lcModel::ShowLastStep()
|
|||
|
||||
mCurrentStep = LastStep;
|
||||
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
UpdateSelection();
|
||||
gMainWindow->UpdateFocusObject(GetFocusObject());
|
||||
gMainWindow->UpdateAllViews();
|
||||
|
@ -1201,7 +1232,7 @@ void lcModel::ShowPreviousStep()
|
|||
|
||||
mCurrentStep--;
|
||||
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
UpdateSelection();
|
||||
gMainWindow->UpdateFocusObject(GetFocusObject());
|
||||
gMainWindow->UpdateAllViews();
|
||||
|
@ -1215,7 +1246,7 @@ void lcModel::ShowNextStep()
|
|||
|
||||
mCurrentStep++;
|
||||
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
UpdateSelection();
|
||||
gMainWindow->UpdateFocusObject(GetFocusObject());
|
||||
gMainWindow->UpdateAllViews();
|
||||
|
@ -1249,7 +1280,7 @@ void lcModel::InsertStep()
|
|||
mLights[LightIdx]->InsertTime(mCurrentStep, 1);
|
||||
|
||||
SaveCheckpoint(tr("Inserting Step"));
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
gMainWindow->UpdateFocusObject(GetFocusObject());
|
||||
gMainWindow->UpdateAllViews();
|
||||
UpdateSelection();
|
||||
|
@ -1272,7 +1303,7 @@ void lcModel::RemoveStep()
|
|||
mLights[LightIdx]->RemoveTime(mCurrentStep, 1);
|
||||
|
||||
SaveCheckpoint(tr("Removing Step"));
|
||||
CalculateStep();
|
||||
CalculateStep(mCurrentStep);
|
||||
gMainWindow->UpdateFocusObject(GetFocusObject());
|
||||
gMainWindow->UpdateAllViews();
|
||||
UpdateSelection();
|
||||
|
|
|
@ -209,11 +209,13 @@ public:
|
|||
void Paste();
|
||||
|
||||
void GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface) const;
|
||||
void AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const;
|
||||
void SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const;
|
||||
void DrawBackground(lcContext* Context);
|
||||
|
||||
void RayTest(lcObjectRayTest& ObjectRayTest) const;
|
||||
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const;
|
||||
bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const;
|
||||
bool SubModelBoxTest(const lcVector4 Planes[6]) const;
|
||||
|
||||
bool AnyPiecesSelected() const;
|
||||
bool AnyObjectsSelected() const;
|
||||
|
|
|
@ -135,7 +135,7 @@ void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
lcVector3 End = lcMul31(ObjectRayTest.End, mWorldLight);
|
||||
|
||||
float Distance;
|
||||
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION;
|
||||
|
@ -151,7 +151,7 @@ void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
Start = lcMul31(ObjectRayTest.Start, WorldTarget);
|
||||
End = lcMul31(ObjectRayTest.End, WorldTarget);
|
||||
|
||||
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_TARGET;
|
||||
|
|
|
@ -539,21 +539,7 @@ void lcPiece::RemoveTime(lcStep Start, lcStep Time)
|
|||
|
||||
void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const
|
||||
{
|
||||
lcVector3 Min(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]);
|
||||
lcVector3 Max(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2]);
|
||||
|
||||
lcMatrix44 WorldModel = lcMatrix44AffineInverse(mModelWorld);
|
||||
|
||||
lcVector3 Start = lcMul31(ObjectRayTest.Start, WorldModel);
|
||||
lcVector3 End = lcMul31(ObjectRayTest.End, WorldModel);
|
||||
|
||||
float Distance;
|
||||
if (!lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) || (Distance >= ObjectRayTest.Distance))
|
||||
return;
|
||||
|
||||
lcVector3 Intersection;
|
||||
|
||||
if (mPieceInfo->mMesh->MinIntersectDist(Start, End, ObjectRayTest.Distance, Intersection))
|
||||
if (mPieceInfo->MinIntersectDist(mModelWorld, ObjectRayTest.Start, ObjectRayTest.End, ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcPiece*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = 0;
|
||||
|
@ -562,56 +548,7 @@ void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
|
||||
void lcPiece::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
|
||||
{
|
||||
lcVector3 Box[8] =
|
||||
{
|
||||
lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2])
|
||||
};
|
||||
|
||||
lcMatrix44 WorldToLocal = lcMatrix44FromAxisAngle(lcVector3(mRotation[0], mRotation[1], mRotation[2]), -mRotation[3] * LC_DTOR);
|
||||
WorldToLocal.SetTranslation(lcMul31(lcVector3(-mPosition[0], -mPosition[1], -mPosition[2]), WorldToLocal));
|
||||
|
||||
const int NumPlanes = 6;
|
||||
lcVector4 LocalPlanes[NumPlanes];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NumPlanes; i++)
|
||||
{
|
||||
lcVector3 PlaneNormal = lcMul30(ObjectBoxTest.Planes[i], WorldToLocal);
|
||||
LocalPlanes[i] = lcVector4(PlaneNormal, ObjectBoxTest.Planes[i][3] - lcDot3(WorldToLocal[3], PlaneNormal));
|
||||
}
|
||||
|
||||
int Outcodes[8];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
Outcodes[i] = 0;
|
||||
|
||||
for (int j = 0; j < NumPlanes; j++)
|
||||
{
|
||||
if (lcDot3(Box[i], LocalPlanes[j]) + LocalPlanes[j][3] > 0)
|
||||
Outcodes[i] |= 1 << j;
|
||||
}
|
||||
}
|
||||
|
||||
int OutcodesOR = 0, OutcodesAND = 0x3f;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
OutcodesAND &= Outcodes[i];
|
||||
OutcodesOR |= Outcodes[i];
|
||||
}
|
||||
|
||||
if (OutcodesAND != 0)
|
||||
return;
|
||||
|
||||
if (OutcodesOR == 0 || mPieceInfo->mMesh->IntersectsPlanes(LocalPlanes))
|
||||
if (mPieceInfo->BoxTest(mModelWorld, ObjectBoxTest.Planes))
|
||||
ObjectBoxTest.Objects.Add(const_cast<lcPiece*>(this));
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,83 @@ void PieceInfo::Unload()
|
|||
}
|
||||
}
|
||||
|
||||
bool PieceInfo::MinIntersectDist(const lcMatrix44& WorldMatrix, const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const
|
||||
{
|
||||
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(WorldMatrix);
|
||||
lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix);
|
||||
lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix);
|
||||
|
||||
if (mFlags & LC_PIECE_MODEL)
|
||||
return mModel->SubModelMinIntersectDist(Start, End, MinDistance);
|
||||
|
||||
lcVector3 Min(m_fDimensions[3], m_fDimensions[4], m_fDimensions[5]);
|
||||
lcVector3 Max(m_fDimensions[0], m_fDimensions[1], m_fDimensions[2]);
|
||||
|
||||
float Distance;
|
||||
if (!lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) || (Distance >= MinDistance))
|
||||
return false;
|
||||
|
||||
lcVector3 Intersection;
|
||||
|
||||
return mMesh->MinIntersectDist(Start, End, MinDistance, Intersection);
|
||||
}
|
||||
|
||||
bool PieceInfo::BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 WorldPlanes[6]) const
|
||||
{
|
||||
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(WorldMatrix);
|
||||
|
||||
const int NumCorners = 8;
|
||||
const int NumPlanes = 6;
|
||||
lcVector4 LocalPlanes[NumPlanes];
|
||||
|
||||
for (int PlaneIdx = 0; PlaneIdx < NumPlanes; PlaneIdx++)
|
||||
{
|
||||
lcVector3 PlaneNormal = lcMul30(WorldPlanes[PlaneIdx], InverseWorldMatrix);
|
||||
LocalPlanes[PlaneIdx] = lcVector4(PlaneNormal, WorldPlanes[PlaneIdx][3] - lcDot3(InverseWorldMatrix[3], PlaneNormal));
|
||||
}
|
||||
|
||||
if (mFlags & LC_PIECE_MODEL)
|
||||
return mModel->SubModelBoxTest(LocalPlanes);
|
||||
|
||||
lcVector3 Box[NumCorners] =
|
||||
{
|
||||
lcVector3(m_fDimensions[0], m_fDimensions[1], m_fDimensions[5]),
|
||||
lcVector3(m_fDimensions[3], m_fDimensions[1], m_fDimensions[5]),
|
||||
lcVector3(m_fDimensions[0], m_fDimensions[1], m_fDimensions[2]),
|
||||
lcVector3(m_fDimensions[3], m_fDimensions[4], m_fDimensions[5]),
|
||||
lcVector3(m_fDimensions[3], m_fDimensions[4], m_fDimensions[2]),
|
||||
lcVector3(m_fDimensions[0], m_fDimensions[4], m_fDimensions[2]),
|
||||
lcVector3(m_fDimensions[0], m_fDimensions[4], m_fDimensions[5]),
|
||||
lcVector3(m_fDimensions[3], m_fDimensions[1], m_fDimensions[2])
|
||||
};
|
||||
|
||||
int Outcodes[NumCorners];
|
||||
|
||||
for (int CornerIdx = 0; CornerIdx < NumCorners; CornerIdx++)
|
||||
{
|
||||
Outcodes[CornerIdx] = 0;
|
||||
|
||||
for (int PlaneIdx = 0; PlaneIdx < NumPlanes; PlaneIdx++)
|
||||
{
|
||||
if (lcDot3(Box[CornerIdx], LocalPlanes[PlaneIdx]) + LocalPlanes[PlaneIdx][3] > 0)
|
||||
Outcodes[CornerIdx] |= 1 << PlaneIdx;
|
||||
}
|
||||
}
|
||||
|
||||
int OutcodesOR = 0, OutcodesAND = 0x3f;
|
||||
|
||||
for (int CornerIdx = 0; CornerIdx < NumCorners; CornerIdx++)
|
||||
{
|
||||
OutcodesAND &= Outcodes[CornerIdx];
|
||||
OutcodesOR |= Outcodes[CornerIdx];
|
||||
}
|
||||
|
||||
if (OutcodesAND != 0)
|
||||
return false;
|
||||
|
||||
return OutcodesOR == 0 || mMesh->IntersectsPlanes(LocalPlanes);
|
||||
}
|
||||
|
||||
// Zoom extents for the preview window and print catalog
|
||||
void PieceInfo::ZoomExtents(float Fov, float Aspect, float* EyePos) const
|
||||
{
|
||||
|
@ -149,7 +226,7 @@ void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, i
|
|||
{
|
||||
if (mFlags & LC_PIECE_MODEL)
|
||||
{
|
||||
mModel->AddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected);
|
||||
mModel->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,8 @@ public:
|
|||
|
||||
void SetModel(lcModel* Model);
|
||||
bool IncludesModel(const lcModel* Model) const;
|
||||
bool MinIntersectDist(const lcMatrix44& WorldMatrix, const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const;
|
||||
bool BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 Planes[6]) const;
|
||||
|
||||
public:
|
||||
lcMesh* mMesh;
|
||||
|
|
Loading…
Add table
Reference in a new issue