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 _BGFX_RASTER_RASTERCONVERT3D_HXX
21 #define _BGFX_RASTER_RASTERCONVERT3D_HXX
23 #include <sal/types.h>
25 #include <basegfx/color/bcolor.hxx>
26 #include <basegfx/vector/b3dvector.hxx>
27 #include <basegfx/point/b2dpoint.hxx>
28 #include <basegfx/vector/b2dvector.hxx>
29 #include <basegfx/basegfxdllapi.h>
31 //////////////////////////////////////////////////////////////////////////////
40 //////////////////////////////////////////////////////////////////////////////
41 // interpolators for double precision
57 ip_single(double fVal
, double fInc
)
62 double getVal() const { return mfVal
; }
63 double getInc() const { return mfInc
; }
65 void increment(double fStep
) { mfVal
+= fStep
* mfInc
; }
67 } // end of namespace basegfx
83 ip_double(double fXVal
, double fXInc
, double fYVal
, double fYInc
)
88 const ip_single
& getX() const { return maX
; }
89 const ip_single
& getY() const { return maY
; }
91 void increment(double fStep
) { maX
.increment(fStep
); maY
.increment(fStep
); }
93 } // end of namespace basegfx
111 ip_triple(double fXVal
, double fXInc
, double fYVal
, double fYInc
, double fZVal
, double fZInc
)
117 const ip_single
& getX() const { return maX
; }
118 const ip_single
& getY() const { return maY
; }
119 const ip_single
& getZ() const { return maZ
; }
121 void increment(double fStep
) { maX
.increment(fStep
); maY
.increment(fStep
); maZ
.increment(fStep
); }
123 } // end of namespace basegfx
125 //////////////////////////////////////////////////////////////////////////////
126 // InterpolatorProvider3D to have a common source for allocating interpolators
127 // which may then be addressed using the index to the vectors
131 #define SCANLINE_EMPTY_INDEX (0xffffffff)
133 class InterpolatorProvider3D
136 ::std::vector
< ip_triple
> maColorInterpolators
;
137 ::std::vector
< ip_triple
> maNormalInterpolators
;
138 ::std::vector
< ip_double
> maTextureInterpolators
;
139 ::std::vector
< ip_triple
> maInverseTextureInterpolators
;
142 sal_uInt32
addColorInterpolator(const BColor
& rA
, const BColor
& rB
, double fInvYDelta
)
144 B3DVector
aDelta(rB
.getRed() - rA
.getRed(), rB
.getGreen() - rA
.getGreen(), rB
.getBlue() - rA
.getBlue());
145 aDelta
*= fInvYDelta
;
146 maColorInterpolators
.push_back(ip_triple(rA
.getRed(), aDelta
.getX(), rA
.getGreen(), aDelta
.getY(), rA
.getBlue(), aDelta
.getZ()));
147 return (maColorInterpolators
.size() - 1L);
150 sal_uInt32
addNormalInterpolator(const B3DVector
& rA
, const B3DVector
& rB
, double fInvYDelta
)
152 B3DVector
aDelta(rB
.getX() - rA
.getX(), rB
.getY() - rA
.getY(), rB
.getZ() - rA
.getZ());
153 aDelta
*= fInvYDelta
;
154 maNormalInterpolators
.push_back(ip_triple(rA
.getX(), aDelta
.getX(), rA
.getY(), aDelta
.getY(), rA
.getZ(), aDelta
.getZ()));
155 return (maNormalInterpolators
.size() - 1L);
158 sal_uInt32
addTextureInterpolator(const B2DPoint
& rA
, const B2DPoint
& rB
, double fInvYDelta
)
160 B2DVector
aDelta(rB
.getX() - rA
.getX(), rB
.getY() - rA
.getY());
161 aDelta
*= fInvYDelta
;
162 maTextureInterpolators
.push_back(ip_double(rA
.getX(), aDelta
.getX(), rA
.getY(), aDelta
.getY()));
163 return (maTextureInterpolators
.size() - 1L);
166 sal_uInt32
addInverseTextureInterpolator(const B2DPoint
& rA
, const B2DPoint
& rB
, double fZEyeA
, double fZEyeB
, double fInvYDelta
)
168 const double fInvZEyeA(fTools::equalZero(fZEyeA
) ? fZEyeA
: 1.0 / fZEyeA
);
169 const double fInvZEyeB(fTools::equalZero(fZEyeB
) ? fZEyeB
: 1.0 / fZEyeB
);
170 const B2DPoint
aInvA(rA
* fInvZEyeA
);
171 const B2DPoint
aInvB(rB
* fInvZEyeB
);
172 double fZDelta(fInvZEyeB
- fInvZEyeA
);
173 B2DVector
aDelta(aInvB
.getX() - aInvA
.getX(), aInvB
.getY() - aInvA
.getY());
175 fZDelta
*= fInvYDelta
;
176 aDelta
*= fInvYDelta
;
178 maInverseTextureInterpolators
.push_back(ip_triple(aInvA
.getX(), aDelta
.getX(), aInvA
.getY(), aDelta
.getY(), fInvZEyeA
, fZDelta
));
179 return (maInverseTextureInterpolators
.size() - 1L);
184 maColorInterpolators
.clear();
185 maNormalInterpolators
.clear();
186 maTextureInterpolators
.clear();
187 maInverseTextureInterpolators
.clear();
191 InterpolatorProvider3D() {}
193 ::std::vector
< ip_triple
>& getColorInterpolators() { return maColorInterpolators
; }
194 ::std::vector
< ip_triple
>& getNormalInterpolators() { return maNormalInterpolators
; }
195 ::std::vector
< ip_double
>& getTextureInterpolators() { return maTextureInterpolators
; }
196 ::std::vector
< ip_triple
>& getInverseTextureInterpolators() { return maInverseTextureInterpolators
; }
198 } // end of namespace basegfx
200 //////////////////////////////////////////////////////////////////////////////
201 // RasterConversionLineEntry3D for Raterconversion of 3D PolyPolygons
205 class RasterConversionLineEntry3D
213 sal_uInt32 mnColorIndex
;
214 sal_uInt32 mnNormalIndex
;
215 sal_uInt32 mnTextureIndex
;
216 sal_uInt32 mnInverseTextureIndex
;
219 RasterConversionLineEntry3D(const double& rfX
, const double& rfDeltaX
, const double& rfZ
, const double& rfDeltaZ
, sal_Int32 nY
, sal_uInt32 nCount
)
220 : maX(rfX
, rfDeltaX
),
224 mnColorIndex(SCANLINE_EMPTY_INDEX
),
225 mnNormalIndex(SCANLINE_EMPTY_INDEX
),
226 mnTextureIndex(SCANLINE_EMPTY_INDEX
),
227 mnInverseTextureIndex(SCANLINE_EMPTY_INDEX
)
230 void setColorIndex(sal_uInt32 nIndex
) { mnColorIndex
= nIndex
; }
231 void setNormalIndex(sal_uInt32 nIndex
) { mnNormalIndex
= nIndex
; }
232 void setTextureIndex(sal_uInt32 nIndex
) { mnTextureIndex
= nIndex
; }
233 void setInverseTextureIndex(sal_uInt32 nIndex
) { mnInverseTextureIndex
= nIndex
; }
235 bool operator<(const RasterConversionLineEntry3D
& rComp
) const
239 return maX
.getVal() < rComp
.maX
.getVal();
242 return mnY
< rComp
.mnY
;
245 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep
)
258 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep
, InterpolatorProvider3D
& rProvider
)
260 const double fStep((double)nStep
);
261 maX
.increment(fStep
);
262 maZ
.increment(fStep
);
265 if(SCANLINE_EMPTY_INDEX
!= mnColorIndex
)
267 rProvider
.getColorInterpolators()[mnColorIndex
].increment(fStep
);
270 if(SCANLINE_EMPTY_INDEX
!= mnNormalIndex
)
272 rProvider
.getNormalInterpolators()[mnNormalIndex
].increment(fStep
);
275 if(SCANLINE_EMPTY_INDEX
!= mnTextureIndex
)
277 rProvider
.getTextureInterpolators()[mnTextureIndex
].increment(fStep
);
280 if(SCANLINE_EMPTY_INDEX
!= mnInverseTextureIndex
)
282 rProvider
.getInverseTextureInterpolators()[mnInverseTextureIndex
].increment(fStep
);
287 const ip_single
& getX() const { return maX
; }
288 sal_Int32
getY() const { return mnY
; }
289 const ip_single
& getZ() const { return maZ
; }
290 sal_uInt32
getColorIndex() const { return mnColorIndex
; }
291 sal_uInt32
getNormalIndex() const { return mnNormalIndex
; }
292 sal_uInt32
getTextureIndex() const { return mnTextureIndex
; }
293 sal_uInt32
getInverseTextureIndex() const { return mnInverseTextureIndex
; }
295 } // end of namespace basegfx
297 //////////////////////////////////////////////////////////////////////////////
298 // the basic RaterConverter itself. Only one method needs to be overloaded. The
299 // class itself is strictly virtual
303 class BASEGFX_DLLPUBLIC RasterConverter3D
: public InterpolatorProvider3D
306 // the line entries for an area conversion run
307 ::std::vector
< RasterConversionLineEntry3D
> maLineEntries
;
309 struct lineComparator
311 bool operator()(const RasterConversionLineEntry3D
* pA
, const RasterConversionLineEntry3D
* pB
)
313 OSL_ENSURE(pA
&& pB
, "lineComparator: empty pointer (!)");
314 return pA
->getX().getVal() < pB
->getX().getVal();
318 void addArea(const B3DPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
);
319 void addArea(const B3DPolyPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
);
320 void addEdge(const B3DPolygon
& rFill
, sal_uInt32 a
, sal_uInt32 b
, const B3DHomMatrix
* pViewToEye
);
322 void rasterconvertB3DArea(sal_Int32 nStartLine
, sal_Int32 nStopLine
);
323 void rasterconvertB3DEdge(const B3DPolygon
& rLine
, sal_uInt32 nA
, sal_uInt32 nB
, sal_Int32 nStartLine
, sal_Int32 nStopLine
, sal_uInt16 nLineWidth
);
325 virtual void processLineSpan(const RasterConversionLineEntry3D
& rA
, const RasterConversionLineEntry3D
& rB
, sal_Int32 nLine
, sal_uInt32 nSpanCount
) = 0;
329 virtual ~RasterConverter3D();
331 void rasterconvertB3DPolyPolygon(const B3DPolyPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
, sal_Int32 nStartLine
, sal_Int32 nStopLine
);
332 void rasterconvertB3DPolygon(const B3DPolygon
& rLine
, sal_Int32 nStartLine
, sal_Int32 nStopLine
, sal_uInt16 nLineWidth
);
334 } // end of namespace basegfx
336 //////////////////////////////////////////////////////////////////////////////
338 #endif /* _BGFX_RASTER_RASTERCONVERT3D_HXX */
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */