#i105323# speedup of 3D handling mostly for CustomShapes; HitTest and interactions optimized

This commit is contained in:
Armin Le Grand
2009-09-29 15:35:35 +02:00
parent 56fba7ddfd
commit 9d16cddca2

View File

@@ -875,10 +875,16 @@ namespace basegfx
} }
else else
{ {
bool bRetval(false);
const B3DVector aPlaneNormal(rCandidate.getNormal()); const B3DVector aPlaneNormal(rCandidate.getNormal());
if(!aPlaneNormal.equalZero()) if(!aPlaneNormal.equalZero())
{ {
const sal_uInt32 nPointCount(rCandidate.count());
if(nPointCount)
{
B3DPoint aCurrentPoint(rCandidate.getB3DPoint(nPointCount - 1));
const double fAbsX(fabs(aPlaneNormal.getX())); const double fAbsX(fabs(aPlaneNormal.getX()));
const double fAbsY(fabs(aPlaneNormal.getY())); const double fAbsY(fabs(aPlaneNormal.getY()));
const double fAbsZ(fabs(aPlaneNormal.getZ())); const double fAbsZ(fabs(aPlaneNormal.getZ()));
@@ -886,41 +892,130 @@ namespace basegfx
if(fAbsX > fAbsY && fAbsX > fAbsZ) if(fAbsX > fAbsY && fAbsX > fAbsZ)
{ {
// normal points mostly in X-Direction, use YZ-Polygon projection for check // normal points mostly in X-Direction, use YZ-Polygon projection for check
B3DHomMatrix aTrans; // x -> y, y -> z
for(sal_uInt32 a(0); a < nPointCount; a++)
{
const B3DPoint aPreviousPoint(aCurrentPoint);
aCurrentPoint = rCandidate.getB3DPoint(a);
aTrans.set(0, 0, 0.0); // cross-over in Z?
aTrans.set(0, 1, 1.0); const bool bCompZA(fTools::more(aPreviousPoint.getZ(), rPoint.getZ()));
aTrans.set(1, 1, 0.0); const bool bCompZB(fTools::more(aCurrentPoint.getZ(), rPoint.getZ()));
aTrans.set(1, 2, 1.0);
const B2DPolygon aYZ(createB2DPolygonFromB3DPolygon(rCandidate, aTrans)); if(bCompZA != bCompZB)
{
// cross-over in Y?
const bool bCompYA(fTools::more(aPreviousPoint.getY(), rPoint.getY()));
const bool bCompYB(fTools::more(aCurrentPoint.getY(), rPoint.getY()));
return isInside(aYZ, B2DPoint(rPoint.getY(), rPoint.getZ()), bWithBorder); if(bCompYA == bCompYB)
{
if(bCompYA)
{
bRetval = !bRetval;
}
}
else
{
const double fCompare(
aCurrentPoint.getY() - (aCurrentPoint.getZ() - rPoint.getZ()) *
(aPreviousPoint.getY() - aCurrentPoint.getY()) /
(aPreviousPoint.getZ() - aCurrentPoint.getZ()));
if(fTools::more(fCompare, rPoint.getY()))
{
bRetval = !bRetval;
}
}
}
}
} }
else if(fAbsY > fAbsX && fAbsY > fAbsZ) else if(fAbsY > fAbsX && fAbsY > fAbsZ)
{ {
// normal points mostly in Y-Direction, use XZ-Polygon projection for check // normal points mostly in Y-Direction, use XZ-Polygon projection for check
B3DHomMatrix aTrans; // x -> x, y -> z
for(sal_uInt32 a(0); a < nPointCount; a++)
{
const B3DPoint aPreviousPoint(aCurrentPoint);
aCurrentPoint = rCandidate.getB3DPoint(a);
aTrans.set(1, 1, 0.0); // cross-over in Z?
aTrans.set(1, 2, 1.0); const bool bCompZA(fTools::more(aPreviousPoint.getZ(), rPoint.getZ()));
const bool bCompZB(fTools::more(aCurrentPoint.getZ(), rPoint.getZ()));
const B2DPolygon aXZ(createB2DPolygonFromB3DPolygon(rCandidate, aTrans)); if(bCompZA != bCompZB)
{
// cross-over in X?
const bool bCompXA(fTools::more(aPreviousPoint.getX(), rPoint.getX()));
const bool bCompXB(fTools::more(aCurrentPoint.getX(), rPoint.getX()));
return isInside(aXZ, B2DPoint(rPoint.getX(), rPoint.getZ()), bWithBorder); if(bCompXA == bCompXB)
{
if(bCompXA)
{
bRetval = !bRetval;
}
}
else
{
const double fCompare(
aCurrentPoint.getX() - (aCurrentPoint.getZ() - rPoint.getZ()) *
(aPreviousPoint.getX() - aCurrentPoint.getX()) /
(aPreviousPoint.getZ() - aCurrentPoint.getZ()));
if(fTools::more(fCompare, rPoint.getX()))
{
bRetval = !bRetval;
}
}
}
}
} }
else else
{ {
// normal points mostly in Z-Direction, use XY-Polygon projection for check // normal points mostly in Z-Direction, use XY-Polygon projection for check
B3DHomMatrix aTrans; // x -> x, y -> y
for(sal_uInt32 a(0); a < nPointCount; a++)
{
const B3DPoint aPreviousPoint(aCurrentPoint);
aCurrentPoint = rCandidate.getB3DPoint(a);
const B2DPolygon aXY(createB2DPolygonFromB3DPolygon(rCandidate, aTrans)); // cross-over in Y?
const bool bCompYA(fTools::more(aPreviousPoint.getY(), rPoint.getY()));
const bool bCompYB(fTools::more(aCurrentPoint.getY(), rPoint.getY()));
return isInside(aXY, B2DPoint(rPoint.getX(), rPoint.getY()), bWithBorder); if(bCompYA != bCompYB)
{
// cross-over in X?
const bool bCompXA(fTools::more(aPreviousPoint.getX(), rPoint.getX()));
const bool bCompXB(fTools::more(aCurrentPoint.getX(), rPoint.getX()));
if(bCompXA == bCompXB)
{
if(bCompXA)
{
bRetval = !bRetval;
}
}
else
{
const double fCompare(
aCurrentPoint.getX() - (aCurrentPoint.getY() - rPoint.getY()) *
(aPreviousPoint.getX() - aCurrentPoint.getX()) /
(aPreviousPoint.getY() - aCurrentPoint.getY()));
if(fTools::more(fCompare, rPoint.getX()))
{
bRetval = !bRetval;
}
}
}
}
}
} }
} }
return false; return bRetval;
} }
} }