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