1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef _BGFX_RASTER_RASTERCONVERT3D_HXX 29 #define _BGFX_RASTER_RASTERCONVERT3D_HXX 30 31 #include <sal/types.h> 32 #include <vector> 33 #include <basegfx/color/bcolor.hxx> 34 #include <basegfx/vector/b3dvector.hxx> 35 #include <basegfx/point/b2dpoint.hxx> 36 #include <basegfx/vector/b2dvector.hxx> 37 38 ////////////////////////////////////////////////////////////////////////////// 39 // predeclarations 40 41 namespace basegfx 42 { 43 class B3DPolygon; 44 class B3DPolyPolygon; 45 } 46 47 ////////////////////////////////////////////////////////////////////////////// 48 // interpolators for double precision 49 50 namespace basegfx 51 { 52 class ip_single 53 { 54 private: 55 double mfVal; 56 double mfInc; 57 58 public: 59 ip_single() 60 : mfVal(0.0), 61 mfInc(0.0) 62 {} 63 64 ip_single(double fVal, double fInc) 65 : mfVal(fVal), 66 mfInc(fInc) 67 {} 68 69 double getVal() const { return mfVal; } 70 double getInc() const { return mfInc; } 71 72 void increment(double fStep) { mfVal += fStep * mfInc; } 73 }; 74 } // end of namespace basegfx 75 76 namespace basegfx 77 { 78 class ip_double 79 { 80 private: 81 ip_single maX; 82 ip_single maY; 83 84 public: 85 ip_double() 86 : maX(), 87 maY() 88 {} 89 90 ip_double(double fXVal, double fXInc, double fYVal, double fYInc) 91 : maX(fXVal, fXInc), 92 maY(fYVal, fYInc) 93 {} 94 95 const ip_single& getX() const { return maX; } 96 const ip_single& getY() const { return maY; } 97 98 void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); } 99 }; 100 } // end of namespace basegfx 101 102 namespace basegfx 103 { 104 class ip_triple 105 { 106 private: 107 ip_single maX; 108 ip_single maY; 109 ip_single maZ; 110 111 public: 112 ip_triple() 113 : maX(), 114 maY(), 115 maZ() 116 {} 117 118 ip_triple(double fXVal, double fXInc, double fYVal, double fYInc, double fZVal, double fZInc) 119 : maX(fXVal, fXInc), 120 maY(fYVal, fYInc), 121 maZ(fZVal, fZInc) 122 {} 123 124 const ip_single& getX() const { return maX; } 125 const ip_single& getY() const { return maY; } 126 const ip_single& getZ() const { return maZ; } 127 128 void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); maZ.increment(fStep); } 129 }; 130 } // end of namespace basegfx 131 132 ////////////////////////////////////////////////////////////////////////////// 133 // InterpolatorProvider3D to have a common source for allocating interpolators 134 // which may then be addressed using the index to the vectors 135 136 namespace basegfx 137 { 138 #define SCANLINE_EMPTY_INDEX (0xffffffff) 139 140 class InterpolatorProvider3D 141 { 142 private: 143 ::std::vector< ip_triple > maColorInterpolators; 144 ::std::vector< ip_triple > maNormalInterpolators; 145 ::std::vector< ip_double > maTextureInterpolators; 146 ::std::vector< ip_triple > maInverseTextureInterpolators; 147 148 protected: 149 sal_uInt32 addColorInterpolator(const BColor& rA, const BColor& rB, double fInvYDelta) 150 { 151 B3DVector aDelta(rB.getRed() - rA.getRed(), rB.getGreen() - rA.getGreen(), rB.getBlue() - rA.getBlue()); 152 aDelta *= fInvYDelta; 153 maColorInterpolators.push_back(ip_triple(rA.getRed(), aDelta.getX(), rA.getGreen(), aDelta.getY(), rA.getBlue(), aDelta.getZ())); 154 return (maColorInterpolators.size() - 1L); 155 } 156 157 sal_uInt32 addNormalInterpolator(const B3DVector& rA, const B3DVector& rB, double fInvYDelta) 158 { 159 B3DVector aDelta(rB.getX() - rA.getX(), rB.getY() - rA.getY(), rB.getZ() - rA.getZ()); 160 aDelta *= fInvYDelta; 161 maNormalInterpolators.push_back(ip_triple(rA.getX(), aDelta.getX(), rA.getY(), aDelta.getY(), rA.getZ(), aDelta.getZ())); 162 return (maNormalInterpolators.size() - 1L); 163 } 164 165 sal_uInt32 addTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fInvYDelta) 166 { 167 B2DVector aDelta(rB.getX() - rA.getX(), rB.getY() - rA.getY()); 168 aDelta *= fInvYDelta; 169 maTextureInterpolators.push_back(ip_double(rA.getX(), aDelta.getX(), rA.getY(), aDelta.getY())); 170 return (maTextureInterpolators.size() - 1L); 171 } 172 173 sal_uInt32 addInverseTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fZEyeA, double fZEyeB, double fInvYDelta) 174 { 175 const double fInvZEyeA(fTools::equalZero(fZEyeA) ? fZEyeA : 1.0 / fZEyeA); 176 const double fInvZEyeB(fTools::equalZero(fZEyeB) ? fZEyeB : 1.0 / fZEyeB); 177 const B2DPoint aInvA(rA * fInvZEyeA); 178 const B2DPoint aInvB(rB * fInvZEyeB); 179 double fZDelta(fInvZEyeB - fInvZEyeA); 180 B2DVector aDelta(aInvB.getX() - aInvA.getX(), aInvB.getY() - aInvA.getY()); 181 182 fZDelta *= fInvYDelta; 183 aDelta *= fInvYDelta; 184 185 maInverseTextureInterpolators.push_back(ip_triple(aInvA.getX(), aDelta.getX(), aInvA.getY(), aDelta.getY(), fInvZEyeA, fZDelta)); 186 return (maInverseTextureInterpolators.size() - 1L); 187 } 188 189 void reset() 190 { 191 maColorInterpolators.clear(); 192 maNormalInterpolators.clear(); 193 maTextureInterpolators.clear(); 194 maInverseTextureInterpolators.clear(); 195 } 196 197 public: 198 InterpolatorProvider3D() {} 199 200 ::std::vector< ip_triple >& getColorInterpolators() { return maColorInterpolators; } 201 ::std::vector< ip_triple >& getNormalInterpolators() { return maNormalInterpolators; } 202 ::std::vector< ip_double >& getTextureInterpolators() { return maTextureInterpolators; } 203 ::std::vector< ip_triple >& getInverseTextureInterpolators() { return maInverseTextureInterpolators; } 204 }; 205 } // end of namespace basegfx 206 207 ////////////////////////////////////////////////////////////////////////////// 208 // RasterConversionLineEntry3D for Raterconversion of 3D PolyPolygons 209 210 namespace basegfx 211 { 212 class RasterConversionLineEntry3D 213 { 214 private: 215 ip_single maX; 216 ip_single maZ; 217 sal_Int32 mnY; 218 sal_uInt32 mnCount; 219 220 sal_uInt32 mnColorIndex; 221 sal_uInt32 mnNormalIndex; 222 sal_uInt32 mnTextureIndex; 223 sal_uInt32 mnInverseTextureIndex; 224 225 public: 226 RasterConversionLineEntry3D(const double& rfX, const double& rfDeltaX, const double& rfZ, const double& rfDeltaZ, sal_Int32 nY, sal_uInt32 nCount) 227 : maX(rfX, rfDeltaX), 228 maZ(rfZ, rfDeltaZ), 229 mnY(nY), 230 mnCount(nCount), 231 mnColorIndex(SCANLINE_EMPTY_INDEX), 232 mnNormalIndex(SCANLINE_EMPTY_INDEX), 233 mnTextureIndex(SCANLINE_EMPTY_INDEX), 234 mnInverseTextureIndex(SCANLINE_EMPTY_INDEX) 235 {} 236 237 void setColorIndex(sal_uInt32 nIndex) { mnColorIndex = nIndex; } 238 void setNormalIndex(sal_uInt32 nIndex) { mnNormalIndex = nIndex; } 239 void setTextureIndex(sal_uInt32 nIndex) { mnTextureIndex = nIndex; } 240 void setInverseTextureIndex(sal_uInt32 nIndex) { mnInverseTextureIndex = nIndex; } 241 242 bool operator<(const RasterConversionLineEntry3D& rComp) const 243 { 244 if(mnY == rComp.mnY) 245 { 246 return maX.getVal() < rComp.maX.getVal(); 247 } 248 249 return mnY < rComp.mnY; 250 } 251 252 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep) 253 { 254 if(nStep >= mnCount) 255 { 256 return false; 257 } 258 else 259 { 260 mnCount -= nStep; 261 return true; 262 } 263 } 264 265 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep, InterpolatorProvider3D& rProvider) 266 { 267 const double fStep((double)nStep); 268 maX.increment(fStep); 269 maZ.increment(fStep); 270 mnY += nStep; 271 272 if(SCANLINE_EMPTY_INDEX != mnColorIndex) 273 { 274 rProvider.getColorInterpolators()[mnColorIndex].increment(fStep); 275 } 276 277 if(SCANLINE_EMPTY_INDEX != mnNormalIndex) 278 { 279 rProvider.getNormalInterpolators()[mnNormalIndex].increment(fStep); 280 } 281 282 if(SCANLINE_EMPTY_INDEX != mnTextureIndex) 283 { 284 rProvider.getTextureInterpolators()[mnTextureIndex].increment(fStep); 285 } 286 287 if(SCANLINE_EMPTY_INDEX != mnInverseTextureIndex) 288 { 289 rProvider.getInverseTextureInterpolators()[mnInverseTextureIndex].increment(fStep); 290 } 291 } 292 293 // data read access 294 const ip_single& getX() const { return maX; } 295 sal_Int32 getY() const { return mnY; } 296 const ip_single& getZ() const { return maZ; } 297 sal_uInt32 getColorIndex() const { return mnColorIndex; } 298 sal_uInt32 getNormalIndex() const { return mnNormalIndex; } 299 sal_uInt32 getTextureIndex() const { return mnTextureIndex; } 300 sal_uInt32 getInverseTextureIndex() const { return mnInverseTextureIndex; } 301 }; 302 } // end of namespace basegfx 303 304 ////////////////////////////////////////////////////////////////////////////// 305 // the basic RaterConverter itself. Only one method needs to be overloaded. The 306 // class itself is strictly virtual 307 308 namespace basegfx 309 { 310 class RasterConverter3D : public InterpolatorProvider3D 311 { 312 private: 313 // the line entries for an area conversion run 314 ::std::vector< RasterConversionLineEntry3D > maLineEntries; 315 316 struct lineComparator 317 { 318 bool operator()(const RasterConversionLineEntry3D* pA, const RasterConversionLineEntry3D* pB) 319 { 320 OSL_ENSURE(pA && pB, "lineComparator: empty pointer (!)"); 321 return pA->getX().getVal() < pB->getX().getVal(); 322 } 323 }; 324 325 void addArea(const B3DPolygon& rFill, const B3DHomMatrix* pViewToEye); 326 void addArea(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye); 327 void addEdge(const B3DPolygon& rFill, sal_uInt32 a, sal_uInt32 b, const B3DHomMatrix* pViewToEye); 328 329 void rasterconvertB3DArea(sal_Int32 nStartLine, sal_Int32 nStopLine); 330 void rasterconvertB3DEdge(const B3DPolygon& rLine, sal_uInt32 nA, sal_uInt32 nB, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth); 331 332 virtual void processLineSpan(const RasterConversionLineEntry3D& rA, const RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) = 0; 333 334 public: 335 RasterConverter3D(); 336 virtual ~RasterConverter3D(); 337 338 void rasterconvertB3DPolyPolygon(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye, sal_Int32 nStartLine, sal_Int32 nStopLine); 339 void rasterconvertB3DPolygon(const B3DPolygon& rLine, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth); 340 }; 341 } // end of namespace basegfx 342 343 ////////////////////////////////////////////////////////////////////////////// 344 345 #endif /* _BGFX_RASTER_RASTERCONVERT3D_HXX */ 346