Scan submodels when dragging a new piece into the model.

This commit is contained in:
Leonardo Zide
2021-12-23 17:27:38 -08:00
parent 4c97a4d514
commit 2d315d2ba2
8 changed files with 87 additions and 24 deletions
+9 -3
View File
@@ -1572,7 +1572,7 @@ void lcModel::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
Light->BoxTest(ObjectBoxTest);
}
bool lcModel::SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const
bool lcModel::SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance, const PieceInfo*& HitPieceInfo, lcMatrix44& HitTransform) const
{
bool MinIntersect = false;
@@ -1582,8 +1582,14 @@ bool lcModel::SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVect
const lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix);
const lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix);
if (Piece->IsVisibleInSubModel() && Piece->mPieceInfo->MinIntersectDist(Start, End, MinDistance)) // todo: this should check for piece->mMesh first
MinIntersect = true;
if (Piece->IsVisibleInSubModel())
{
if (Piece->mPieceInfo->MinIntersectDist(Start, End, MinDistance, HitPieceInfo, HitTransform)) // todo: this should check for piece->mMesh first
{
MinIntersect = true;
HitTransform = lcMul(HitTransform, Piece->mModelWorld);
}
}
}
return MinIntersect;
+1 -1
View File
@@ -239,7 +239,7 @@ public:
void RayTest(lcObjectRayTest& ObjectRayTest) const;
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const;
bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const;
bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance, const PieceInfo*& HitPieceInfo, lcMatrix44& HitTransform) const;
bool SubModelBoxTest(const lcVector4 Planes[6]) const;
void SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const;
void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const;
+43 -9
View File
@@ -412,19 +412,23 @@ lcVector3 lcView::GetMoveDirection(const lcVector3& Direction) const
lcMatrix44 lcView::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const
{
lcPiece* HitPiece = (lcPiece*)FindObjectUnderPointer(true, IgnoreSelected).Object;
lcModel* ActiveModel = GetActiveModel();
if (HitPiece)
const PieceInfo* HitPieceInfo;
lcMatrix44 HitTransform;
std::tie(HitPieceInfo, HitTransform) = FindPieceInfoUnderPointer(IgnoreSelected);
if (HitPieceInfo)
{
lcVector3 Position(0, 0, HitPiece->GetBoundingBox().Max.z - Info->GetBoundingBox().Min.z);
lcVector3 Position(0, 0, HitPieceInfo->GetBoundingBox().Max.z - Info->GetBoundingBox().Min.z);
if (gMainWindow->GetRelativeTransform())
Position = lcMul31(ActiveModel->SnapPosition(Position), HitPiece->mModelWorld);
Position = lcMul31(ActiveModel->SnapPosition(Position), HitTransform);
else
Position = ActiveModel->SnapPosition(lcMul31(Position, HitPiece->mModelWorld));
Position = ActiveModel->SnapPosition(lcMul31(Position, HitTransform));
lcMatrix44 WorldMatrix = HitPiece->mModelWorld;
lcMatrix44 WorldMatrix = HitTransform;
WorldMatrix.SetTranslation(Position);
return WorldMatrix;
@@ -523,9 +527,6 @@ lcObjectSection lcView::FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelec
ObjectRayTest.ViewCamera = mCamera;
ObjectRayTest.Start = StartEnd[0];
ObjectRayTest.End = StartEnd[1];
ObjectRayTest.Distance = FLT_MAX;
ObjectRayTest.ObjectSection.Object = nullptr;
ObjectRayTest.ObjectSection.Section = 0;;
lcModel* ActiveModel = GetActiveModel();
@@ -542,6 +543,39 @@ lcObjectSection lcView::FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelec
return ObjectRayTest.ObjectSection;
}
std::pair<const PieceInfo*, lcMatrix44> lcView::FindPieceInfoUnderPointer(bool IgnoreSelected) const
{
lcVector3 StartEnd[2] =
{
lcVector3((float)mMouseX, (float)mMouseY, 0.0f),
lcVector3((float)mMouseX, (float)mMouseY, 1.0f)
};
UnprojectPoints(StartEnd, 2);
lcObjectRayTest ObjectRayTest;
ObjectRayTest.PiecesOnly = true;
ObjectRayTest.IgnoreSelected = IgnoreSelected;
ObjectRayTest.ViewCamera = mCamera;
ObjectRayTest.Start = StartEnd[0];
ObjectRayTest.End = StartEnd[1];
lcModel* ActiveModel = GetActiveModel();
if (ActiveModel != mModel)
{
lcMatrix44 InverseMatrix = lcMatrix44AffineInverse(mActiveSubmodelTransform);
ObjectRayTest.Start = lcMul31(ObjectRayTest.Start, InverseMatrix);
ObjectRayTest.End = lcMul31(ObjectRayTest.End, InverseMatrix);
}
ActiveModel->RayTest(ObjectRayTest);
return { ObjectRayTest.HitPieceInfo, ObjectRayTest.HitTransform };
}
lcArray<lcObject*> lcView::FindObjectsInBox(float x1, float y1, float x2, float y2) const
{
float Left, Top, Bottom, Right;
+1
View File
@@ -256,6 +256,7 @@ public:
lcVector3 GetCameraLightInsertPosition() const;
void GetRayUnderPointer(lcVector3& Start, lcVector3& End) const;
lcObjectSection FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelected) const;
std::pair<const PieceInfo*, lcMatrix44> FindPieceInfoUnderPointer(bool IgnoreSelected) const;
lcArray<lcObject*> FindObjectsInBox(float x1, float y1, float x2, float y2) const;
lcVector3 ProjectPoint(const lcVector3& Point) const;
+5 -3
View File
@@ -49,8 +49,8 @@ protected:
struct lcObjectSection
{
lcObject* Object;
quint32 Section;
lcObject* Object = nullptr;
quint32 Section = 0;
};
struct lcObjectRayTest
@@ -60,8 +60,10 @@ struct lcObjectRayTest
bool IgnoreSelected;
lcVector3 Start;
lcVector3 End;
float Distance;
float Distance = FLT_MAX;
lcObjectSection ObjectSection;
const PieceInfo* HitPieceInfo = nullptr;
lcMatrix44 HitTransform;
};
struct lcObjectBoxTest
+11 -3
View File
@@ -475,10 +475,18 @@ void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const
ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_POSITION;
}
}
else if (mPieceInfo->MinIntersectDist(Start, End, ObjectRayTest.Distance))
else
{
ObjectRayTest.ObjectSection.Object = const_cast<lcPiece*>(this);
ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_POSITION;
const PieceInfo* HitPieceInfo = nullptr;
lcMatrix44 HitTransform = lcMatrix44Identity();
if (mPieceInfo->MinIntersectDist(Start, End, ObjectRayTest.Distance, HitPieceInfo, HitTransform))
{
ObjectRayTest.ObjectSection.Object = const_cast<lcPiece*>(this);
ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_POSITION;
ObjectRayTest.HitPieceInfo = HitPieceInfo;
ObjectRayTest.HitTransform = lcMul(HitTransform, mModelWorld);
}
}
if (AreControlPointsVisible())
+16 -4
View File
@@ -197,31 +197,43 @@ void PieceInfo::Unload()
}
}
bool PieceInfo::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const
bool PieceInfo::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance, const PieceInfo*& HitPieceInfo, lcMatrix44& HitTransform) const
{
bool Intersect = false;
if (IsPlaceholder() || IsModel() || IsProject())
{
float Distance;
if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, nullptr) || (Distance >= MinDistance))
return false;
if (IsPlaceholder())
{
HitPieceInfo = this;
HitTransform = lcMatrix44Identity();
return true;
}
if (IsModel())
Intersect |= mModel->SubModelMinIntersectDist(Start, End, MinDistance);
Intersect |= mModel->SubModelMinIntersectDist(Start, End, MinDistance, HitPieceInfo, HitTransform);
else if (IsProject())
{
const lcModel* const Model = mProject->GetMainModel();
if (Model)
Intersect |= Model->SubModelMinIntersectDist(Start, End, MinDistance);
Intersect |= Model->SubModelMinIntersectDist(Start, End, MinDistance, HitPieceInfo, HitTransform);
}
}
if (mMesh)
Intersect = mMesh->MinIntersectDist(Start, End, MinDistance);
{
if (mMesh->MinIntersectDist(Start, End, MinDistance))
{
HitPieceInfo = this;
HitTransform = lcMatrix44Identity();
Intersect = true;
}
}
return Intersect;
}
+1 -1
View File
@@ -169,7 +169,7 @@ public:
void CreateProject(Project* Project, const char* PieceName);
bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& WorldMatrix) const;
bool IncludesModel(const lcModel* Model) const;
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const;
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance, const PieceInfo*& HitPieceInfo, lcMatrix44& HitTransform) const;
bool BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 Planes[6]) const;
void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const;
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const;