Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / include / basegfx / raster / rasterconvert3d.hxx
blob090258b3681a20725ea059926a128c7cf1982ab1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
24 #include <vector>
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>
34 namespace basegfx
36 class B3DPolygon;
37 class B3DPolyPolygon;
40 // interpolators for double precision
42 namespace basegfx
44 class ip_single
46 private:
47 double mfVal;
48 double mfInc;
50 public:
51 ip_single()
52 : mfVal(0.0),
53 mfInc(0.0)
56 ip_single(double fVal, double fInc)
57 : mfVal(fVal),
58 mfInc(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
68 namespace basegfx
70 class ip_double
72 private:
73 ip_single maX;
74 ip_single maY;
76 public:
77 ip_double()
78 : maX(),
79 maY()
82 ip_double(double fXVal, double fXInc, double fYVal, double fYInc)
83 : maX(fXVal, fXInc),
84 maY(fYVal, 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
94 namespace basegfx
96 class ip_triple
98 private:
99 ip_single maX;
100 ip_single maY;
101 ip_single maZ;
103 public:
104 ip_triple()
105 : maX(),
106 maY(),
107 maZ()
110 ip_triple(double fXVal, double fXInc, double fYVal, double fYInc, double fZVal, double fZInc)
111 : maX(fXVal, fXInc),
112 maY(fYVal, fYInc),
113 maZ(fZVal, 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
128 namespace basegfx
130 #define SCANLINE_EMPTY_INDEX (0xffffffff)
132 class InterpolatorProvider3D
134 private:
135 ::std::vector< ip_triple > maColorInterpolators;
136 ::std::vector< ip_triple > maNormalInterpolators;
137 ::std::vector< ip_double > maTextureInterpolators;
138 ::std::vector< ip_triple > maInverseTextureInterpolators;
140 protected:
141 sal_uInt32 addColorInterpolator(const BColor& rA, const BColor& rB, double fInvYDelta)
143 double aDeltaRed(rB.getRed() - rA.getRed());
145 if(fTools::equalZero(aDeltaRed))
147 aDeltaRed = 0.0;
149 else
151 aDeltaRed *= fInvYDelta;
154 double aDeltaGreen(rB.getGreen() - rA.getGreen());
156 if(fTools::equalZero(aDeltaGreen))
158 aDeltaGreen = 0.0;
160 else
162 aDeltaGreen *= fInvYDelta;
165 double aDeltaBlue(rB.getBlue() - rA.getBlue());
167 if(fTools::equalZero(aDeltaBlue))
169 aDeltaBlue = 0.0;
171 else
173 aDeltaBlue *= fInvYDelta;
176 maColorInterpolators.push_back(
177 ip_triple(
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))
191 aDeltaX = 0.0;
193 else
195 aDeltaX *= fInvYDelta;
198 double aDeltaY(rB.getY() - rA.getY());
200 if(fTools::equalZero(aDeltaY))
202 aDeltaY = 0.0;
204 else
206 aDeltaY *= fInvYDelta;
209 double aDeltaZ(rB.getZ() - rA.getZ());
211 if(fTools::equalZero(aDeltaZ))
213 aDeltaZ = 0.0;
215 else
217 aDeltaZ *= fInvYDelta;
220 maNormalInterpolators.push_back(
221 ip_triple(
222 rA.getX(), aDeltaX,
223 rA.getY(), aDeltaY,
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))
235 aDeltaX = 0.0;
237 else
239 aDeltaX *= fInvYDelta;
242 double aDeltaY(rB.getY() - rA.getY());
244 if(fTools::equalZero(aDeltaY))
246 aDeltaY = 0.0;
248 else
250 aDeltaY *= fInvYDelta;
253 maTextureInterpolators.push_back(
254 ip_double(
255 rA.getX(), aDeltaX,
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))
269 fZDelta = 0.0;
271 else
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(
283 ip_triple(
284 aInvA.getX(), aDeltaX,
285 aInvA.getY(), aDeltaY,
286 fInvZEyeA, fZDelta));
288 return (maInverseTextureInterpolators.size() - 1);
291 void reset()
293 maColorInterpolators.clear();
294 maNormalInterpolators.clear();
295 maTextureInterpolators.clear();
296 maInverseTextureInterpolators.clear();
299 public:
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
312 namespace basegfx
314 class RasterConversionLineEntry3D
316 private:
317 ip_single maX;
318 ip_single maZ;
319 sal_Int32 mnY;
320 sal_uInt32 mnCount;
322 sal_uInt32 mnColorIndex;
323 sal_uInt32 mnNormalIndex;
324 sal_uInt32 mnTextureIndex;
325 sal_uInt32 mnInverseTextureIndex;
327 public:
328 RasterConversionLineEntry3D(const double& rfX, const double& rfDeltaX, const double& rfZ, const double& rfDeltaZ, sal_Int32 nY, sal_uInt32 nCount)
329 : maX(rfX, rfDeltaX),
330 maZ(rfZ, rfDeltaZ),
331 mnY(nY),
332 mnCount(nCount),
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
346 if(mnY == rComp.mnY)
348 return maX.getVal() < rComp.maX.getVal();
351 return mnY < rComp.mnY;
354 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep)
356 if(nStep >= mnCount)
358 return false;
360 else
362 mnCount -= nStep;
363 return true;
367 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep, InterpolatorProvider3D& rProvider)
369 const double fStep((double)nStep);
370 maX.increment(fStep);
371 maZ.increment(fStep);
372 mnY += nStep;
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);
395 // data read access
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
410 namespace basegfx
412 class BASEGFX_DLLPUBLIC RasterConverter3D : public InterpolatorProvider3D
414 private:
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;
436 public:
437 RasterConverter3D();
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: */