Scan submodels when dragging a new piece into the model.
This commit is contained in:
+9
-3
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user