1 18 package org.apache.batik.ext.awt.image.rendered; 19 20 import java.awt.Rectangle ; 21 import java.awt.image.DataBufferInt ; 22 import java.awt.image.Raster ; 23 import java.awt.image.RenderedImage ; 24 import java.awt.image.SinglePixelPackedSampleModel ; 25 26 32 public final class BumpMap { 33 37 private RenderedImage texture; 38 39 42 private double surfaceScale, surfaceScaleX, surfaceScaleY; 43 44 47 private double scaleX, scaleY; 48 49 54 public BumpMap(RenderedImage texture, 55 double surfaceScale, 56 double scaleX, double scaleY){ 57 this.texture = texture; 58 this.surfaceScaleX = surfaceScale*scaleX; 59 this.surfaceScaleY = surfaceScale*scaleY; 60 this.surfaceScale = surfaceScale; 61 this.scaleX = scaleX; 62 this.scaleY = scaleY; 63 } 64 65 68 public final double getSurfaceScale(){ 69 return surfaceScale; 70 } 71 72 76 public final double[][][] getNormalArray 77 (final int x, final int y, 78 final int w, final int h) 79 { 80 final double[][][] N = new double[h][w][4]; 81 82 Rectangle srcRect = new Rectangle (x-1, y-1, w+2, h+2); 83 Rectangle srcBound = new Rectangle 84 (texture.getMinX(), texture.getMinY(), 85 texture.getWidth(), texture.getHeight()); 86 87 if (srcRect.intersects(srcBound) == false) 88 return N; 89 90 srcRect = srcRect.intersection(srcBound); 91 final Raster r = texture.getData(srcRect); 92 93 srcRect = r.getBounds(); 94 95 100 final DataBufferInt db = (DataBufferInt )r.getDataBuffer(); 101 102 103 final int[] pixels = db.getBankData()[0]; 104 105 final SinglePixelPackedSampleModel sppsm; 106 sppsm = (SinglePixelPackedSampleModel )r.getSampleModel(); 107 108 109 final int scanStride = sppsm.getScanlineStride(); 110 final int scanStridePP = scanStride + 1; 111 final int scanStrideMM = scanStride - 1; 112 double prpc=0, prcc=0, prnc=0; 113 double crpc=0, crcc=0, crnc=0; 114 double nrpc=0, nrcc=0, nrnc=0; 115 double invNorm; 116 117 final double quarterSurfaceScaleX = surfaceScaleX / 4f; 118 final double quarterSurfaceScaleY = surfaceScaleY / 4f; 119 final double halfSurfaceScaleX = surfaceScaleX / 2f; 120 final double halfSurfaceScaleY = surfaceScaleY /2; 121 final double thirdSurfaceScaleX = surfaceScaleX / 3f; 122 final double thirdSurfaceScaleY = surfaceScaleY / 3f; 123 final double twoThirdSurfaceScaleX = surfaceScaleX * 2 / 3f; 124 final double twoThirdSurfaceScaleY = surfaceScaleY * 2 / 3f; 125 126 final double pixelScale = 1.0/255; 127 128 if(w <= 0) 129 return N; 130 if(h <= 0) 132 return N; 133 134 final int xEnd = Math.min(srcRect.x+srcRect.width -1, x+w); 135 final int yEnd = Math.min(srcRect.y+srcRect.height-1, y+h); 136 final int offset = 137 (db.getOffset() + 138 sppsm.getOffset(srcRect.x -r.getSampleModelTranslateX(), 139 srcRect.y -r.getSampleModelTranslateY())); 140 141 int yloc=y; 142 if (yloc < srcRect.y) { 143 yloc = srcRect.y; 144 } 145 146 if (yloc == srcRect.y) { 148 if (yloc == yEnd) { 149 final double [][] NRow = N[yloc-y]; 151 int xloc=x; 152 if (xloc < srcRect.x) 153 xloc = srcRect.x; 154 int p = (offset + (xloc-srcRect.x) + 155 scanStride*(yloc-srcRect.y)); 156 157 crcc = (pixels[p] >>> 24)*pixelScale; 158 159 if (xloc != srcRect.x) { 160 crpc = (pixels[p - 1] >>> 24)*pixelScale; 161 } 162 else if (xloc < xEnd) { 163 crnc = (pixels[p+1] >>> 24)*pixelScale; 165 166 final double [] n = NRow[xloc-x]; 167 168 n[0] = 2*surfaceScaleX*(crcc - crnc); 169 invNorm = 1.0/Math.sqrt(n[0]*n[0] + 1); 170 n[0] *= invNorm; 171 n[1] = 0; 172 n[2] = invNorm; 173 n[3] = crcc*surfaceScale; 174 p++; 175 xloc++; 176 crpc = crcc; 177 crcc = crnc; 178 } else { 179 crpc = crcc; 181 } 182 183 for (; xloc<xEnd; xloc++) { 184 crnc = (pixels[p+1] >>> 24)*pixelScale; 186 final double [] n = NRow[xloc-x]; 187 188 n[0] = surfaceScaleX * (crpc - crnc ); 189 invNorm = 1.0/Math.sqrt(n[0]*n[0] + 1); 190 n[0] *= invNorm; 191 n[1] = 0; 192 n[2] = invNorm; 193 n[3] = crcc*surfaceScale; 194 p++; 195 crpc = crcc; 196 crcc = crnc; 197 } 198 199 if ((xloc < x+w) && 200 (xloc == srcRect.x+srcRect.width-1)) { 201 final double [] n = NRow[xloc-x]; 203 204 n[0] = 2*surfaceScaleX*(crpc - crcc); 205 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 206 n[0] *= invNorm; 207 n[1] *= invNorm; 208 n[2] = invNorm; 209 n[3] = crcc*surfaceScale; 210 } 211 return N; 212 } 213 214 final double [][] NRow = N[yloc-y]; 215 int p = offset + scanStride*(yloc-srcRect.y); 216 int xloc=x; 217 if (xloc < srcRect.x) 218 xloc = srcRect.x; 219 p += xloc-srcRect.x; 220 221 crcc = (pixels[p] >>> 24)*pixelScale; 222 nrcc = (pixels[p + scanStride] >>> 24)*pixelScale; 223 224 if (xloc != srcRect.x) { 225 crpc = (pixels[p - 1] >>> 24)*pixelScale; 226 nrpc = (pixels[p + scanStrideMM] >>> 24)*pixelScale; 227 } 228 else if (xloc < xEnd) { 229 crnc = (pixels[p+1] >>> 24)*pixelScale; 231 nrnc = (pixels[p + scanStridePP] >>> 24)*pixelScale; 232 233 final double [] n = NRow[xloc-x]; 234 235 n[0] = - twoThirdSurfaceScaleX * 236 ((2*crnc + nrnc - 2*crcc - nrcc)); 237 n[1] = - twoThirdSurfaceScaleY * 238 ((2*nrcc + nrnc - 2*crcc - crnc)); 239 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 240 n[0] *= invNorm; 241 n[1] *= invNorm; 242 n[2] = invNorm; 243 n[3] = crcc*surfaceScale; 244 p++; 245 xloc++; 246 crpc = crcc; 247 nrpc = nrcc; 248 crcc = crnc; 249 nrcc = nrnc; 250 } else { 251 crpc = crcc; 253 nrpc = nrcc; 254 } 255 256 for (; xloc<xEnd; xloc++) { 257 crnc = (pixels[p+1] >>> 24)*pixelScale; 259 nrnc = (pixels[p + scanStridePP] >>> 24)*pixelScale; 260 261 final double [] n = NRow[xloc-x]; 262 263 n[0] = - thirdSurfaceScaleX * (( 2*crnc + nrnc) 264 - (2*crpc + nrpc)); 265 n[1] = - halfSurfaceScaleY *(( nrpc + 2*nrcc + nrnc) 266 - (crpc + 2*crcc + crnc)); 267 268 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 269 n[0] *= invNorm; 270 n[1] *= invNorm; 271 n[2] = invNorm; 272 n[3] = crcc*surfaceScale; 273 p++; 274 crpc = crcc; 275 nrpc = nrcc; 276 crcc = crnc; 277 nrcc = nrnc; 278 } 279 280 if ((xloc < x+w) && 281 (xloc == srcRect.x+srcRect.width-1)) { 282 final double [] n = NRow[xloc-x]; 284 285 n[0] = - twoThirdSurfaceScaleX *(( 2*crcc + nrcc) 286 - (2*crpc + nrpc)); 287 n[1] = - twoThirdSurfaceScaleY *(( 2*nrcc + nrpc) 288 - (2*crcc + crpc)); 289 290 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 291 n[0] *= invNorm; 292 n[1] *= invNorm; 293 n[2] = invNorm; 294 n[3] = crcc*surfaceScale; 295 } 296 yloc++; 297 } 298 299 for (; yloc<yEnd; yloc++) { 300 final double [][] NRow = N[yloc-y]; 301 int p = offset + scanStride*(yloc-srcRect.y); 302 303 int xloc=x; 304 if (xloc < srcRect.x) 305 xloc = srcRect.x; 306 307 p += xloc-srcRect.x; 308 309 prcc = (pixels[p - scanStride] >>> 24)*pixelScale; 310 crcc = (pixels[p] >>> 24)*pixelScale; 311 nrcc = (pixels[p + scanStride] >>> 24)*pixelScale; 312 313 if (xloc != srcRect.x) { 314 prpc = (pixels[p - scanStridePP] >>> 24)*pixelScale; 315 crpc = (pixels[p - 1] >>> 24)*pixelScale; 316 nrpc = (pixels[p + scanStrideMM] >>> 24)*pixelScale; 317 } 318 else if (xloc < xEnd) { 319 crnc = (pixels[p+1] >>> 24)*pixelScale; 321 prnc = (pixels[p - scanStrideMM] >>> 24)*pixelScale; 322 nrnc = (pixels[p + scanStridePP] >>> 24)*pixelScale; 323 324 final double [] n = NRow[xloc-x]; 325 326 n[0] = - halfSurfaceScaleX *(( prnc + 2*crnc + nrnc) 327 - (prcc + 2*crcc + nrcc)); 328 n[1] = - thirdSurfaceScaleY *(( 2*prcc + prnc) 329 - ( 2*crcc + crnc)); 330 331 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 332 n[0] *= invNorm; 333 n[1] *= invNorm; 334 n[2] = invNorm; 335 n[3] = crcc*surfaceScale; 336 337 p++; 338 xloc++; 339 340 prpc = prcc; 341 crpc = crcc; 342 nrpc = nrcc; 343 prcc = prnc; 344 crcc = crnc; 345 nrcc = nrnc; 346 } else { 347 prpc = prcc; 349 crpc = crcc; 350 nrpc = nrcc; 351 } 352 353 for (; xloc<xEnd; xloc++) { 354 prnc = (pixels[p - scanStrideMM] >>> 24)*pixelScale; 356 crnc = (pixels[p+1] >>> 24)*pixelScale; 357 nrnc = (pixels[p + scanStridePP] >>> 24)*pixelScale; 358 359 final double [] n = NRow[xloc-x]; 360 361 n[0] = - quarterSurfaceScaleX *(( prnc + 2*crnc + nrnc) 362 - (prpc + 2*crpc + nrpc)); 363 n[1] = - quarterSurfaceScaleY *(( nrpc + 2*nrcc + nrnc) 364 - (prpc + 2*prcc + prnc)); 365 366 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 367 n[0] *= invNorm; 368 n[1] *= invNorm; 369 n[2] = invNorm; 370 n[3] = crcc*surfaceScale; 371 372 p++; 373 prpc = prcc; 374 crpc = crcc; 375 nrpc = nrcc; 376 prcc = prnc; 377 crcc = crnc; 378 nrcc = nrnc; 379 } 380 381 if ((xloc < x+w) && 382 (xloc == srcRect.x+srcRect.width-1)) { 383 final double [] n = NRow[xloc-x]; 385 386 n[0] = - halfSurfaceScaleX *( (prcc + 2*crcc + nrcc) 387 -(prpc + 2*crpc + nrpc)); 388 n[1] = - thirdSurfaceScaleY *(( nrpc + 2*nrcc) 389 - ( prpc + 2*prcc)); 390 391 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 392 n[0] *= invNorm; 393 n[1] *= invNorm; 394 n[2] = invNorm; 395 n[3] = crcc*surfaceScale; 396 } 397 } 398 399 if ((yloc < y+h) && 400 (yloc == srcRect.y+srcRect.height-1)) { 401 final double [][] NRow = N[yloc-y]; 402 int p = offset + scanStride*(yloc-srcRect.y); 403 int xloc=x; 404 if (xloc < srcRect.x) 405 xloc = srcRect.x; 406 407 p += xloc-srcRect.x; 408 409 crcc = (pixels[p] >>> 24)*pixelScale; 410 prcc = (pixels[p - scanStride] >>> 24)*pixelScale; 411 412 if (xloc != srcRect.x) { 413 prpc = (pixels[p - scanStridePP] >>> 24)*pixelScale; 414 crpc = (pixels[p - 1] >>> 24)*pixelScale; 415 } 416 else if (xloc < xEnd) { 417 crnc = (pixels[p + 1] >>> 24)*pixelScale; 419 prnc = (pixels[p - scanStrideMM] >>> 24)*pixelScale; 420 421 final double [] n = NRow[xloc-x]; 422 423 n[0] = - twoThirdSurfaceScaleX * ((2*crnc + prnc - 2*crcc - prcc)); 424 n[1] = - twoThirdSurfaceScaleY * ((2*crcc + crnc - 2*prcc - prnc)); 425 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 426 n[0] *= invNorm; 427 n[1] *= invNorm; 428 n[2] = invNorm; 429 n[3] = crcc*surfaceScale; 430 431 p++; 432 xloc++; 433 crpc = crcc; 434 prpc = prcc; 435 crcc = crnc; 436 prcc = prnc; 437 } else { 438 crpc = crcc; 440 prpc = prcc; 441 } 442 443 for (; xloc<xEnd; xloc++) { 444 crnc = (pixels[p + 1] >>> 24)*pixelScale; 446 prnc = (pixels[p - scanStrideMM] >>> 24)*pixelScale; 447 448 452 final double [] n = NRow[xloc-x]; 453 454 n[0] = - thirdSurfaceScaleX *(( 2*crnc + prnc) 455 - (2*crpc + prpc)); 456 n[1] = - halfSurfaceScaleY *(( crpc + 2*crcc + crnc) 457 - (prpc + 2*prcc + prnc)); 458 459 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 460 n[0] *= invNorm; 461 n[1] *= invNorm; 462 n[2] = invNorm; 463 n[3] = crcc*surfaceScale; 464 465 p++; 466 crpc = crcc; 467 prpc = prcc; 468 crcc = crnc; 469 prcc = prnc; 470 } 471 472 if ((xloc < x+w) && 473 (xloc == srcRect.x+srcRect.width-1)) { 474 final double [] n = NRow[xloc-x]; 476 477 n[0] = - twoThirdSurfaceScaleX *(( 2*crcc + prcc) 478 - (2*crpc + prpc)); 479 n[1] = - twoThirdSurfaceScaleY *(( 2*crcc + crpc) 480 - (2*prcc + prpc)); 481 482 invNorm = 1.0/Math.sqrt(n[0]*n[0] + n[1]*n[1] + 1); 483 n[0] *= invNorm; 484 n[1] *= invNorm; 485 n[2] = invNorm; 486 n[3] = crcc*surfaceScale; 487 } 488 } 489 return N; 490 } 491 } 492 493 | Popular Tags |