1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _BGFX_RASTER_RASTERCONVERT3D_HXX 25 #define _BGFX_RASTER_RASTERCONVERT3D_HXX 26 27 #include <sal/types.h> 28 #include <vector> 29 #include <basegfx/color/bcolor.hxx> 30 #include <basegfx/vector/b3dvector.hxx> 31 #include <basegfx/point/b2dpoint.hxx> 32 #include <basegfx/vector/b2dvector.hxx> 33 #include <basegfx/basegfxdllapi.h> 34 35 ////////////////////////////////////////////////////////////////////////////// 36 // predeclarations 37 38 namespace basegfx 39 { 40 class B3DPolygon; 41 class B3DPolyPolygon; 42 } 43 44 ////////////////////////////////////////////////////////////////////////////// 45 // interpolators for double precision 46 47 namespace basegfx 48 { 49 class BASEGFX_DLLPUBLIC ip_single 50 { 51 private: 52 double mfVal; 53 double mfInc; 54 55 public: ip_single()56 ip_single() 57 : mfVal(0.0), 58 mfInc(0.0) 59 {} 60 ip_single(double fVal,double fInc)61 ip_single(double fVal, double fInc) 62 : mfVal(fVal), 63 mfInc(fInc) 64 {} 65 getVal() const66 double getVal() const { return mfVal; } getInc() const67 double getInc() const { return mfInc; } 68 increment(double fStep)69 void increment(double fStep) { mfVal += fStep * mfInc; } 70 }; 71 } // end of namespace basegfx 72 73 namespace basegfx 74 { 75 class BASEGFX_DLLPUBLIC ip_double 76 { 77 private: 78 ip_single maX; 79 ip_single maY; 80 81 public: ip_double()82 ip_double() 83 : maX(), 84 maY() 85 {} 86 ip_double(double fXVal,double fXInc,double fYVal,double fYInc)87 ip_double(double fXVal, double fXInc, double fYVal, double fYInc) 88 : maX(fXVal, fXInc), 89 maY(fYVal, fYInc) 90 {} 91 getX() const92 const ip_single& getX() const { return maX; } getY() const93 const ip_single& getY() const { return maY; } 94 increment(double fStep)95 void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); } 96 }; 97 } // end of namespace basegfx 98 99 namespace basegfx 100 { 101 class BASEGFX_DLLPUBLIC ip_triple 102 { 103 private: 104 ip_single maX; 105 ip_single maY; 106 ip_single maZ; 107 108 public: ip_triple()109 ip_triple() 110 : maX(), 111 maY(), 112 maZ() 113 {} 114 ip_triple(double fXVal,double fXInc,double fYVal,double fYInc,double fZVal,double fZInc)115 ip_triple(double fXVal, double fXInc, double fYVal, double fYInc, double fZVal, double fZInc) 116 : maX(fXVal, fXInc), 117 maY(fYVal, fYInc), 118 maZ(fZVal, fZInc) 119 {} 120 getX() const121 const ip_single& getX() const { return maX; } getY() const122 const ip_single& getY() const { return maY; } getZ() const123 const ip_single& getZ() const { return maZ; } 124 increment(double fStep)125 void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); maZ.increment(fStep); } 126 }; 127 } // end of namespace basegfx 128 129 ////////////////////////////////////////////////////////////////////////////// 130 // InterpolatorProvider3D to have a common source for allocating interpolators 131 // which may then be addressed using the index to the vectors 132 133 namespace basegfx 134 { 135 #define SCANLINE_EMPTY_INDEX (0xffffffff) 136 137 class BASEGFX_DLLPUBLIC InterpolatorProvider3D 138 { 139 private: 140 ::std::vector< ip_triple > maColorInterpolators; 141 ::std::vector< ip_triple > maNormalInterpolators; 142 ::std::vector< ip_double > maTextureInterpolators; 143 ::std::vector< ip_triple > maInverseTextureInterpolators; 144 145 protected: addColorInterpolator(const BColor & rA,const BColor & rB,double fInvYDelta)146 sal_uInt32 addColorInterpolator(const BColor& rA, const BColor& rB, double fInvYDelta) 147 { 148 double aDeltaRed(rB.getRed() - rA.getRed()); 149 150 if(fTools::equalZero(aDeltaRed)) 151 { 152 aDeltaRed = 0.0; 153 } 154 else 155 { 156 aDeltaRed *= fInvYDelta; 157 } 158 159 double aDeltaGreen(rB.getGreen() - rA.getGreen()); 160 161 if(fTools::equalZero(aDeltaGreen)) 162 { 163 aDeltaGreen = 0.0; 164 } 165 else 166 { 167 aDeltaGreen *= fInvYDelta; 168 } 169 170 double aDeltaBlue(rB.getBlue() - rA.getBlue()); 171 172 if(fTools::equalZero(aDeltaBlue)) 173 { 174 aDeltaBlue = 0.0; 175 } 176 else 177 { 178 aDeltaBlue *= fInvYDelta; 179 } 180 181 maColorInterpolators.push_back( 182 ip_triple( 183 rA.getRed(), aDeltaRed, 184 rA.getGreen(), aDeltaGreen, 185 rA.getBlue(), aDeltaBlue)); 186 187 return (maColorInterpolators.size() - 1); 188 } 189 addNormalInterpolator(const B3DVector & rA,const B3DVector & rB,double fInvYDelta)190 sal_uInt32 addNormalInterpolator(const B3DVector& rA, const B3DVector& rB, double fInvYDelta) 191 { 192 double aDeltaX(rB.getX() - rA.getX()); 193 194 if(fTools::equalZero(aDeltaX)) 195 { 196 aDeltaX = 0.0; 197 } 198 else 199 { 200 aDeltaX *= fInvYDelta; 201 } 202 203 double aDeltaY(rB.getY() - rA.getY()); 204 205 if(fTools::equalZero(aDeltaY)) 206 { 207 aDeltaY = 0.0; 208 } 209 else 210 { 211 aDeltaY *= fInvYDelta; 212 } 213 214 double aDeltaZ(rB.getZ() - rA.getZ()); 215 216 if(fTools::equalZero(aDeltaZ)) 217 { 218 aDeltaZ = 0.0; 219 } 220 else 221 { 222 aDeltaZ *= fInvYDelta; 223 } 224 225 maNormalInterpolators.push_back( 226 ip_triple( 227 rA.getX(), aDeltaX, 228 rA.getY(), aDeltaY, 229 rA.getZ(), aDeltaZ)); 230 231 return (maNormalInterpolators.size() - 1); 232 } 233 addTextureInterpolator(const B2DPoint & rA,const B2DPoint & rB,double fInvYDelta)234 sal_uInt32 addTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fInvYDelta) 235 { 236 double aDeltaX(rB.getX() - rA.getX()); 237 238 if(fTools::equalZero(aDeltaX)) 239 { 240 aDeltaX = 0.0; 241 } 242 else 243 { 244 aDeltaX *= fInvYDelta; 245 } 246 247 double aDeltaY(rB.getY() - rA.getY()); 248 249 if(fTools::equalZero(aDeltaY)) 250 { 251 aDeltaY = 0.0; 252 } 253 else 254 { 255 aDeltaY *= fInvYDelta; 256 } 257 258 maTextureInterpolators.push_back( 259 ip_double( 260 rA.getX(), aDeltaX, 261 rA.getY(), aDeltaY)); 262 263 return (maTextureInterpolators.size() - 1); 264 } 265 addInverseTextureInterpolator(const B2DPoint & rA,const B2DPoint & rB,double fZEyeA,double fZEyeB,double fInvYDelta)266 sal_uInt32 addInverseTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fZEyeA, double fZEyeB, double fInvYDelta) 267 { 268 double fZDelta(fZEyeB - fZEyeA); 269 const double fInvZEyeA(fTools::equalZero(fZEyeA) ? fZEyeA : 1.0 / fZEyeA); 270 double fInvZEyeB(fInvZEyeA); 271 272 if(fTools::equalZero(fZDelta)) 273 { 274 fZDelta = 0.0; 275 } 276 else 277 { 278 fInvZEyeB = fTools::equalZero(fZEyeB) ? fZEyeB : 1.0 / fZEyeB; 279 fZDelta = (fInvZEyeB - fInvZEyeA) * fInvYDelta; 280 } 281 282 const B2DPoint aInvA(rA * fInvZEyeA); 283 const B2DPoint aInvB(rB * fInvZEyeB); 284 const double aDeltaX((aInvB.getX() - aInvA.getX()) * fInvYDelta); 285 const double aDeltaY((aInvB.getY() - aInvA.getY()) * fInvYDelta); 286 287 maInverseTextureInterpolators.push_back( 288 ip_triple( 289 aInvA.getX(), aDeltaX, 290 aInvA.getY(), aDeltaY, 291 fInvZEyeA, fZDelta)); 292 293 return (maInverseTextureInterpolators.size() - 1); 294 } 295 reset()296 void reset() 297 { 298 maColorInterpolators.clear(); 299 maNormalInterpolators.clear(); 300 maTextureInterpolators.clear(); 301 maInverseTextureInterpolators.clear(); 302 } 303 304 public: InterpolatorProvider3D()305 InterpolatorProvider3D() {} 306 getColorInterpolators()307 ::std::vector< ip_triple >& getColorInterpolators() { return maColorInterpolators; } getNormalInterpolators()308 ::std::vector< ip_triple >& getNormalInterpolators() { return maNormalInterpolators; } getTextureInterpolators()309 ::std::vector< ip_double >& getTextureInterpolators() { return maTextureInterpolators; } getInverseTextureInterpolators()310 ::std::vector< ip_triple >& getInverseTextureInterpolators() { return maInverseTextureInterpolators; } 311 }; 312 } // end of namespace basegfx 313 314 ////////////////////////////////////////////////////////////////////////////// 315 // RasterConversionLineEntry3D for Raterconversion of 3D PolyPolygons 316 317 namespace basegfx 318 { 319 class BASEGFX_DLLPUBLIC RasterConversionLineEntry3D 320 { 321 private: 322 ip_single maX; 323 ip_single maZ; 324 sal_Int32 mnY; 325 sal_uInt32 mnCount; 326 327 sal_uInt32 mnColorIndex; 328 sal_uInt32 mnNormalIndex; 329 sal_uInt32 mnTextureIndex; 330 sal_uInt32 mnInverseTextureIndex; 331 332 public: RasterConversionLineEntry3D(const double & rfX,const double & rfDeltaX,const double & rfZ,const double & rfDeltaZ,sal_Int32 nY,sal_uInt32 nCount)333 RasterConversionLineEntry3D(const double& rfX, const double& rfDeltaX, const double& rfZ, const double& rfDeltaZ, sal_Int32 nY, sal_uInt32 nCount) 334 : maX(rfX, rfDeltaX), 335 maZ(rfZ, rfDeltaZ), 336 mnY(nY), 337 mnCount(nCount), 338 mnColorIndex(SCANLINE_EMPTY_INDEX), 339 mnNormalIndex(SCANLINE_EMPTY_INDEX), 340 mnTextureIndex(SCANLINE_EMPTY_INDEX), 341 mnInverseTextureIndex(SCANLINE_EMPTY_INDEX) 342 {} 343 setColorIndex(sal_uInt32 nIndex)344 void setColorIndex(sal_uInt32 nIndex) { mnColorIndex = nIndex; } setNormalIndex(sal_uInt32 nIndex)345 void setNormalIndex(sal_uInt32 nIndex) { mnNormalIndex = nIndex; } setTextureIndex(sal_uInt32 nIndex)346 void setTextureIndex(sal_uInt32 nIndex) { mnTextureIndex = nIndex; } setInverseTextureIndex(sal_uInt32 nIndex)347 void setInverseTextureIndex(sal_uInt32 nIndex) { mnInverseTextureIndex = nIndex; } 348 operator <(const RasterConversionLineEntry3D & rComp) const349 bool operator<(const RasterConversionLineEntry3D& rComp) const 350 { 351 if(mnY == rComp.mnY) 352 { 353 return maX.getVal() < rComp.maX.getVal(); 354 } 355 356 return mnY < rComp.mnY; 357 } 358 decrementRasterConversionLineEntry3D(sal_uInt32 nStep)359 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep) 360 { 361 if(nStep >= mnCount) 362 { 363 return false; 364 } 365 else 366 { 367 mnCount -= nStep; 368 return true; 369 } 370 } 371 incrementRasterConversionLineEntry3D(sal_uInt32 nStep,InterpolatorProvider3D & rProvider)372 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep, InterpolatorProvider3D& rProvider) 373 { 374 const double fStep((double)nStep); 375 maX.increment(fStep); 376 maZ.increment(fStep); 377 mnY += nStep; 378 379 if(SCANLINE_EMPTY_INDEX != mnColorIndex) 380 { 381 rProvider.getColorInterpolators()[mnColorIndex].increment(fStep); 382 } 383 384 if(SCANLINE_EMPTY_INDEX != mnNormalIndex) 385 { 386 rProvider.getNormalInterpolators()[mnNormalIndex].increment(fStep); 387 } 388 389 if(SCANLINE_EMPTY_INDEX != mnTextureIndex) 390 { 391 rProvider.getTextureInterpolators()[mnTextureIndex].increment(fStep); 392 } 393 394 if(SCANLINE_EMPTY_INDEX != mnInverseTextureIndex) 395 { 396 rProvider.getInverseTextureInterpolators()[mnInverseTextureIndex].increment(fStep); 397 } 398 } 399 400 // data read access getX() const401 const ip_single& getX() const { return maX; } getY() const402 sal_Int32 getY() const { return mnY; } getZ() const403 const ip_single& getZ() const { return maZ; } getColorIndex() const404 sal_uInt32 getColorIndex() const { return mnColorIndex; } getNormalIndex() const405 sal_uInt32 getNormalIndex() const { return mnNormalIndex; } getTextureIndex() const406 sal_uInt32 getTextureIndex() const { return mnTextureIndex; } getInverseTextureIndex() const407 sal_uInt32 getInverseTextureIndex() const { return mnInverseTextureIndex; } 408 }; 409 } // end of namespace basegfx 410 411 ////////////////////////////////////////////////////////////////////////////// 412 // the basic RaterConverter itself. Only one method needs to be overloaded. The 413 // class itself is strictly virtual 414 415 namespace basegfx 416 { 417 class BASEGFX_DLLPUBLIC RasterConverter3D : public InterpolatorProvider3D 418 { 419 private: 420 // the line entries for an area conversion run 421 ::std::vector< RasterConversionLineEntry3D > maLineEntries; 422 423 struct lineComparator 424 { operator ()basegfx::RasterConverter3D::lineComparator425 bool operator()(const RasterConversionLineEntry3D* pA, const RasterConversionLineEntry3D* pB) 426 { 427 OSL_ENSURE(pA && pB, "lineComparator: empty pointer (!)"); 428 return pA->getX().getVal() < pB->getX().getVal(); 429 } 430 }; 431 432 void addArea(const B3DPolygon& rFill, const B3DHomMatrix* pViewToEye); 433 void addArea(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye); 434 void addEdge(const B3DPolygon& rFill, sal_uInt32 a, sal_uInt32 b, const B3DHomMatrix* pViewToEye); 435 436 void rasterconvertB3DArea(sal_Int32 nStartLine, sal_Int32 nStopLine); 437 void rasterconvertB3DEdge(const B3DPolygon& rLine, sal_uInt32 nA, sal_uInt32 nB, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth); 438 439 virtual void processLineSpan(const RasterConversionLineEntry3D& rA, const RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) = 0; 440 441 public: 442 RasterConverter3D(); 443 virtual ~RasterConverter3D(); 444 445 void rasterconvertB3DPolyPolygon(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye, sal_Int32 nStartLine, sal_Int32 nStopLine); 446 void rasterconvertB3DPolygon(const B3DPolygon& rLine, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth); 447 }; 448 } // end of namespace basegfx 449 450 ////////////////////////////////////////////////////////////////////////////// 451 452 #endif /* _BGFX_RASTER_RASTERCONVERT3D_HXX */ 453