1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_BASEGFX_RASTER_RASTERCONVERT3D_HXX
21 #define INCLUDED_BASEGFX_RASTER_RASTERCONVERT3D_HXX
23 #include <sal/types.h>
26 #include <osl/diagnose.h>
28 #include <basegfx/color/bcolor.hxx>
29 #include <basegfx/vector/b3dvector.hxx>
30 #include <basegfx/point/b2dpoint.hxx>
31 #include <basegfx/vector/b2dvector.hxx>
32 #include <basegfx/basegfxdllapi.h>
40 // interpolators for double precision
56 ip_single(double fVal
, double fInc
)
61 double getVal() const { return mfVal
; }
62 double getInc() const { return mfInc
; }
64 void increment(double fStep
) { mfVal
+= fStep
* mfInc
; }
66 } // end of namespace basegfx
82 ip_double(double fXVal
, double fXInc
, double fYVal
, double fYInc
)
87 const ip_single
& getX() const { return maX
; }
88 const ip_single
& getY() const { return maY
; }
90 void increment(double fStep
) { maX
.increment(fStep
); maY
.increment(fStep
); }
92 } // end of namespace basegfx
110 ip_triple(double fXVal
, double fXInc
, double fYVal
, double fYInc
, double fZVal
, double fZInc
)
116 const ip_single
& getX() const { return maX
; }
117 const ip_single
& getY() const { return maY
; }
118 const ip_single
& getZ() const { return maZ
; }
120 void increment(double fStep
) { maX
.increment(fStep
); maY
.increment(fStep
); maZ
.increment(fStep
); }
122 } // end of namespace basegfx
125 // InterpolatorProvider3D to have a common source for allocating interpolators
126 // which may then be addressed using the index to the vectors
130 #define SCANLINE_EMPTY_INDEX (0xffffffff)
132 class InterpolatorProvider3D
135 ::std::vector
< ip_triple
> maColorInterpolators
;
136 ::std::vector
< ip_triple
> maNormalInterpolators
;
137 ::std::vector
< ip_double
> maTextureInterpolators
;
138 ::std::vector
< ip_triple
> maInverseTextureInterpolators
;
141 sal_uInt32
addColorInterpolator(const BColor
& rA
, const BColor
& rB
, double fInvYDelta
)
143 double aDeltaRed(rB
.getRed() - rA
.getRed());
145 if(fTools::equalZero(aDeltaRed
))
151 aDeltaRed
*= fInvYDelta
;
154 double aDeltaGreen(rB
.getGreen() - rA
.getGreen());
156 if(fTools::equalZero(aDeltaGreen
))
162 aDeltaGreen
*= fInvYDelta
;
165 double aDeltaBlue(rB
.getBlue() - rA
.getBlue());
167 if(fTools::equalZero(aDeltaBlue
))
173 aDeltaBlue
*= fInvYDelta
;
176 maColorInterpolators
.push_back(
178 rA
.getRed(), aDeltaRed
,
179 rA
.getGreen(), aDeltaGreen
,
180 rA
.getBlue(), aDeltaBlue
));
182 return (maColorInterpolators
.size() - 1);
185 sal_uInt32
addNormalInterpolator(const B3DVector
& rA
, const B3DVector
& rB
, double fInvYDelta
)
187 double aDeltaX(rB
.getX() - rA
.getX());
189 if(fTools::equalZero(aDeltaX
))
195 aDeltaX
*= fInvYDelta
;
198 double aDeltaY(rB
.getY() - rA
.getY());
200 if(fTools::equalZero(aDeltaY
))
206 aDeltaY
*= fInvYDelta
;
209 double aDeltaZ(rB
.getZ() - rA
.getZ());
211 if(fTools::equalZero(aDeltaZ
))
217 aDeltaZ
*= fInvYDelta
;
220 maNormalInterpolators
.push_back(
224 rA
.getZ(), aDeltaZ
));
226 return (maNormalInterpolators
.size() - 1);
229 sal_uInt32
addTextureInterpolator(const B2DPoint
& rA
, const B2DPoint
& rB
, double fInvYDelta
)
231 double aDeltaX(rB
.getX() - rA
.getX());
233 if(fTools::equalZero(aDeltaX
))
239 aDeltaX
*= fInvYDelta
;
242 double aDeltaY(rB
.getY() - rA
.getY());
244 if(fTools::equalZero(aDeltaY
))
250 aDeltaY
*= fInvYDelta
;
253 maTextureInterpolators
.push_back(
256 rA
.getY(), aDeltaY
));
258 return (maTextureInterpolators
.size() - 1);
261 sal_uInt32
addInverseTextureInterpolator(const B2DPoint
& rA
, const B2DPoint
& rB
, double fZEyeA
, double fZEyeB
, double fInvYDelta
)
263 double fZDelta(fZEyeB
- fZEyeA
);
264 const double fInvZEyeA(fTools::equalZero(fZEyeA
) ? fZEyeA
: 1.0 / fZEyeA
);
265 double fInvZEyeB(fInvZEyeA
);
267 if(fTools::equalZero(fZDelta
))
273 fInvZEyeB
= fTools::equalZero(fZEyeB
) ? fZEyeB
: 1.0 / fZEyeB
;
274 fZDelta
= (fInvZEyeB
- fInvZEyeA
) * fInvYDelta
;
277 const B2DPoint
aInvA(rA
* fInvZEyeA
);
278 const B2DPoint
aInvB(rB
* fInvZEyeB
);
279 const double aDeltaX((aInvB
.getX() - aInvA
.getX()) * fInvYDelta
);
280 const double aDeltaY((aInvB
.getY() - aInvA
.getY()) * fInvYDelta
);
282 maInverseTextureInterpolators
.push_back(
284 aInvA
.getX(), aDeltaX
,
285 aInvA
.getY(), aDeltaY
,
286 fInvZEyeA
, fZDelta
));
288 return (maInverseTextureInterpolators
.size() - 1);
293 maColorInterpolators
.clear();
294 maNormalInterpolators
.clear();
295 maTextureInterpolators
.clear();
296 maInverseTextureInterpolators
.clear();
300 InterpolatorProvider3D() {}
302 ::std::vector
< ip_triple
>& getColorInterpolators() { return maColorInterpolators
; }
303 ::std::vector
< ip_triple
>& getNormalInterpolators() { return maNormalInterpolators
; }
304 ::std::vector
< ip_double
>& getTextureInterpolators() { return maTextureInterpolators
; }
305 ::std::vector
< ip_triple
>& getInverseTextureInterpolators() { return maInverseTextureInterpolators
; }
307 } // end of namespace basegfx
310 // RasterConversionLineEntry3D for Rasterconversion of 3D PolyPolygons
314 class RasterConversionLineEntry3D
322 sal_uInt32 mnColorIndex
;
323 sal_uInt32 mnNormalIndex
;
324 sal_uInt32 mnTextureIndex
;
325 sal_uInt32 mnInverseTextureIndex
;
328 RasterConversionLineEntry3D(const double& rfX
, const double& rfDeltaX
, const double& rfZ
, const double& rfDeltaZ
, sal_Int32 nY
, sal_uInt32 nCount
)
329 : maX(rfX
, rfDeltaX
),
333 mnColorIndex(SCANLINE_EMPTY_INDEX
),
334 mnNormalIndex(SCANLINE_EMPTY_INDEX
),
335 mnTextureIndex(SCANLINE_EMPTY_INDEX
),
336 mnInverseTextureIndex(SCANLINE_EMPTY_INDEX
)
339 void setColorIndex(sal_uInt32 nIndex
) { mnColorIndex
= nIndex
; }
340 void setNormalIndex(sal_uInt32 nIndex
) { mnNormalIndex
= nIndex
; }
341 void setTextureIndex(sal_uInt32 nIndex
) { mnTextureIndex
= nIndex
; }
342 void setInverseTextureIndex(sal_uInt32 nIndex
) { mnInverseTextureIndex
= nIndex
; }
344 bool operator<(const RasterConversionLineEntry3D
& rComp
) const
348 return maX
.getVal() < rComp
.maX
.getVal();
351 return mnY
< rComp
.mnY
;
354 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep
)
367 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep
, InterpolatorProvider3D
& rProvider
)
369 const double fStep((double)nStep
);
370 maX
.increment(fStep
);
371 maZ
.increment(fStep
);
374 if(SCANLINE_EMPTY_INDEX
!= mnColorIndex
)
376 rProvider
.getColorInterpolators()[mnColorIndex
].increment(fStep
);
379 if(SCANLINE_EMPTY_INDEX
!= mnNormalIndex
)
381 rProvider
.getNormalInterpolators()[mnNormalIndex
].increment(fStep
);
384 if(SCANLINE_EMPTY_INDEX
!= mnTextureIndex
)
386 rProvider
.getTextureInterpolators()[mnTextureIndex
].increment(fStep
);
389 if(SCANLINE_EMPTY_INDEX
!= mnInverseTextureIndex
)
391 rProvider
.getInverseTextureInterpolators()[mnInverseTextureIndex
].increment(fStep
);
396 const ip_single
& getX() const { return maX
; }
397 sal_Int32
getY() const { return mnY
; }
398 const ip_single
& getZ() const { return maZ
; }
399 sal_uInt32
getColorIndex() const { return mnColorIndex
; }
400 sal_uInt32
getNormalIndex() const { return mnNormalIndex
; }
401 sal_uInt32
getTextureIndex() const { return mnTextureIndex
; }
402 sal_uInt32
getInverseTextureIndex() const { return mnInverseTextureIndex
; }
404 } // end of namespace basegfx
407 // the basic RasterConverter itself. Only one method needs to be overridden. The
408 // class itself is pure virtual
412 class BASEGFX_DLLPUBLIC RasterConverter3D
: public InterpolatorProvider3D
415 // the line entries for an area conversion run
416 ::std::vector
< RasterConversionLineEntry3D
> maLineEntries
;
418 struct lineComparator
420 bool operator()(const RasterConversionLineEntry3D
* pA
, const RasterConversionLineEntry3D
* pB
)
422 OSL_ENSURE(pA
&& pB
, "lineComparator: empty pointer (!)");
423 return pA
->getX().getVal() < pB
->getX().getVal();
427 void addArea(const B3DPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
);
428 void addArea(const B3DPolyPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
);
429 void addEdge(const B3DPolygon
& rFill
, sal_uInt32 a
, sal_uInt32 b
, const B3DHomMatrix
* pViewToEye
);
431 void rasterconvertB3DArea(sal_Int32 nStartLine
, sal_Int32 nStopLine
);
432 void rasterconvertB3DEdge(const B3DPolygon
& rLine
, sal_uInt32 nA
, sal_uInt32 nB
, sal_Int32 nStartLine
, sal_Int32 nStopLine
, sal_uInt16 nLineWidth
);
434 virtual void processLineSpan(const RasterConversionLineEntry3D
& rA
, const RasterConversionLineEntry3D
& rB
, sal_Int32 nLine
, sal_uInt32 nSpanCount
) = 0;
438 virtual ~RasterConverter3D();
440 void rasterconvertB3DPolyPolygon(const B3DPolyPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
, sal_Int32 nStartLine
, sal_Int32 nStopLine
);
441 void rasterconvertB3DPolygon(const B3DPolygon
& rLine
, sal_Int32 nStartLine
, sal_Int32 nStopLine
, sal_uInt16 nLineWidth
);
443 } // end of namespace basegfx
445 #endif // INCLUDED_BASEGFX_RASTER_RASTERCONVERT3D_HXX
447 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */