00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #include <OSGConfig.h>
00043 #include <OSGLog.h>
00044 #include <OSGImage.h>
00045 #include <OSGBaseFunctions.h>
00046
00047 #include "OSGImageFunctions.h"
00048
00049
00050 OSG_USING_NAMESPACE
00051
00052 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00053 #pragma warning(disable : 383)
00054 #endif
00055 #ifdef __sgi
00056 #pragma set woff 1209
00057 #endif
00058
00059
00060
00061
00062
00063
00064
00067 OSG_SYSTEMLIB_DLLMAPPING
00068 bool createComposedImage ( std::vector<ImagePtr> imageVec,
00069 ImagePtr image,
00070 SliceDataType sliceDataType )
00071 {
00072 UInt32 dataSize, i, n = imageVec.size();
00073 Int32 w, h;
00074 UInt8 *destData, *srcData;
00075 Image::PixelFormat pf;
00076 Image::Type dt;
00077 bool needColor, needAlpha, needCopy = false;
00078 ImagePtr copy = Image::create();
00079 UInt32 depth, frameCount, sideCount;
00080
00081 if (n) {
00082 for (i = 0; i < n; i++) {
00083 if ( i == 0 ) {
00084 pf = Image::PixelFormat(imageVec[0]->getPixelFormat());
00085 dt = Image::Type(imageVec[0]->getDataType());
00086 w = imageVec[0]->getWidth();
00087 h = imageVec[0]->getHeight();
00088 needAlpha = imageVec[0]->hasAlphaChannel();
00089 needColor = imageVec[0]->hasColorChannel();
00090 }
00091 else {
00092 needAlpha |= imageVec[i]->hasAlphaChannel();
00093 needColor |= imageVec[i]->hasColorChannel();
00094 if (Image::PixelFormat(imageVec[i]->getPixelFormat()) != pf) {
00095 needCopy = true;
00096 FWARNING (( "Image has different PF while composing\n" ));
00097 pf = Image::OSG_INVALID_PF;
00098 }
00099 if (Image::Type(imageVec[i]->getDataType()) != dt) {
00100 needCopy = true;
00101 FWARNING (( "Image has different DT while composing\n" ));
00102 dt = Image::OSG_INVALID_IMAGEDATATYPE;
00103 }
00104 if (imageVec[i]->getWidth() != w) {
00105 needCopy = true;
00106 FWARNING (( "Image has different width while composing\n" ));
00107 w = osgMax ( w, imageVec[i]->getWidth());
00108 }
00109 if (imageVec[i]->getHeight() != h) {
00110 needCopy = true;
00111 FWARNING (( "Image has different height while composing\n" ));
00112 h = osgMax ( h, imageVec[i]->getHeight());
00113 }
00114 }
00115 }
00116
00117 if (pf == Image::OSG_INVALID_PF) {
00118 if (needColor)
00119 if (needAlpha)
00120 pf = OSG::Image::OSG_RGBA_PF;
00121 else
00122 pf = OSG::Image::OSG_RGB_PF;
00123 else
00124 if (needAlpha)
00125 pf = OSG::Image::OSG_LA_PF;
00126 else
00127 pf = OSG::Image::OSG_L_PF;
00128 }
00129
00130 if (dt == Image::OSG_INVALID_IMAGEDATATYPE)
00131 dt = Image::OSG_UINT8_IMAGEDATA;
00132
00133 depth = frameCount = sideCount = 1;
00134 switch (sliceDataType) {
00135 case FRAME_SDT:
00136 frameCount = n;
00137 break;
00138 case SIDE_SDT:
00139 sideCount = n;
00140 case INVALID_SDT:
00141 case DEPTH_SDT:
00142 default:
00143 depth = n;
00144 break;
00145 }
00146
00147 image->set( pf, w, h, depth, 1, frameCount, 0.0,
00148 0, dt, true, sideCount );
00149
00150 destData = image->getData();
00151 dataSize = image->getSize() / n;
00152
00153 if (needCopy) {
00154 FLOG (("Image data/type/size missmatch while composing\n"));
00155 }
00156
00157 for (i = 0; i < n; i++) {
00158 if (needCopy) {
00159 copy->set(imageVec[i]);
00160 if ( Image::PixelFormat(copy->getPixelFormat()) != pf )
00161 copy->reformat(pf);
00162 if ( Image::Type(copy->getDataType()) != dt )
00163 copy->convertDataTypeTo(dt);
00164 if ( (w != copy->getWidth()) || (h != copy->getHeight()))
00165 copy->scale(w,h,copy->getDepth());
00166 srcData = copy->getData();
00167 }
00168 else
00169 srcData = imageVec[i]->getData();
00170
00171 memcpy ( destData, srcData, dataSize );
00172 destData += dataSize;
00173 }
00174 }
00175
00176 subRefCP(copy);
00177
00178 imageVec[0]->dump();
00179 image->dump();
00180
00181 return true;
00182 }
00183
00184
00187 OSG_SYSTEMLIB_DLLMAPPING
00188 bool OSG::createNormalMapFromBump ( ImagePtr image,
00189 ImagePtr dst,
00190 Vec3f normalMapScale)
00191 {
00192 if (image == NullFC || image->getDepth() > 1 ||
00193 image->getPixelFormat() != Image::OSG_L_PF)
00194 {
00195 FFATAL(("No valid Normalmap given!\n"));
00196 return false;
00197 }
00198
00199 bool cpImg = false;
00200
00201 if (dst == NullFC)
00202 {
00203 dst = Image::create();
00204 cpImg = true;
00205 }
00206
00207 Int32 w = image->getWidth();
00208 Int32 h = image->getHeight();
00209
00210 unsigned char *srcData = image->getData();
00211
00212 beginEditCP(dst);
00213
00214 dst->set(Image::OSG_RGB_PF, w, h);
00215
00216 unsigned char *dstData = dst->getData();
00217
00218 Vec3f scale(normalMapScale);
00219
00220 if (scale[0] == 0.0f || scale[1] == 0.0f || scale[2] == 0.0f)
00221 {
00222 Real32 a = Real32(w) / Real32(h);
00223
00224 if(a < 1.0f)
00225 {
00226 scale[0] = 1.0f;
00227 scale[1] = 1.0f / a;
00228 }
00229 else
00230 {
00231 scale[0] = a;
00232 scale[1] = 1.0f;
00233 }
00234 scale[2] = 1.0f;
00235 }
00236
00237 Int32 i, j;
00238
00239 for (i=1; i<w-1; i++)
00240 {
00241 for (j=1; j<h-1; j++)
00242 {
00243 Vec3f dfdi(2.0f, 0.0f, (Real32)(srcData[(i+1) + j*w] - srcData[(i-1) + j*w]) / 255.0f);
00244 Vec3f dfdj(0.0f, 2.0f, (Real32)(srcData[ i + (j+1)*w] - srcData[ i + (j-1)*w]) / 255.0f);
00245 Vec3f n = dfdi.cross(dfdj);
00246
00247 n[0] *= scale[0];
00248 n[1] *= scale[1];
00249 n[2] *= scale[2];
00250 n.normalize();
00251
00252 dstData[(j*w+i)*3+0] = (unsigned char)((n[0]+1)*127.5);
00253 dstData[(j*w+i)*3+1] = (unsigned char)((n[1]+1)*127.5);
00254 dstData[(j*w+i)*3+2] = (unsigned char)((n[2]+1)*127.5);
00255 }
00256 }
00257
00258
00259 for (i=0; i<w; i++)
00260 {
00261 dstData[i*3+0] = dstData[(w+i)*3+0];
00262 dstData[i*3+1] = dstData[(w+i)*3+1];
00263 dstData[i*3+2] = dstData[(w+i)*3+2];
00264
00265 dstData[((h-1)*w+i)*3+0] = dstData[((h-2)*w+1)*3+0];
00266 dstData[((h-1)*w+i)*3+1] = dstData[((h-2)*w+1)*3+1];
00267 dstData[((h-1)*w+i)*3+2] = dstData[((h-2)*w+1)*3+2];
00268 }
00269
00270 for (j=0; j<h; j++)
00271 {
00272 dstData[(j*w)*3+0] = dstData[(j*w+1)*3+0];
00273 dstData[(j*w)*3+1] = dstData[(j*w+1)*3+1];
00274 dstData[(j*w)*3+2] = dstData[(j*w+1)*3+2];
00275
00276 dstData[(j*w+(w-1))*3+0] = dstData[(j*w+(w-2))*3+0];
00277 dstData[(j*w+(w-1))*3+1] = dstData[(j*w+(w-2))*3+1];
00278 dstData[(j*w+(w-1))*3+2] = dstData[(j*w+(w-2))*3+2];
00279 }
00280
00281 endEditCP(dst);
00282
00283 if (cpImg)
00284 {
00285 beginEditCP(image);
00286 image->set(dst);
00287 endEditCP(image);
00288 }
00289
00290
00291
00292 return true;
00293 }
00294
00295
00296
00299 OSG_SYSTEMLIB_DLLMAPPING
00300 void OSG::createNormalVolume ( ImagePtr inImage,
00301 ImagePtr outImage,
00302 AlphaValue alphaValue )
00303 {
00304 UInt8 *data = 0, *ds;
00305 Int32 w, h, d, x, y, z, md, ld, hd, xs, ys, zs, ps, ls, ss, os;
00306 Real32 g;
00307 const Real32 gMax = 441.67295593, gF = 255.0/gMax;
00308 Image::PixelFormat pf;
00309 ImagePtr copy;
00310
00311 if ( (inImage->getPixelFormat() != Image::OSG_L_PF) ||
00312 (inImage->getDataType() != Image::OSG_UINT8_IMAGEDATA) ) {
00313
00314 copy = Image::create();
00315 FLOG (("Create copy to reformat/convert Image\n"));
00316
00317 if (inImage->getPixelFormat() != Image::OSG_L_PF)
00318 inImage->reformat(Image::OSG_L_PF,copy);
00319 else
00320 copy->set(inImage);
00321 inImage = copy;
00322
00323 if (inImage->getDataType() != Image::OSG_UINT8_IMAGEDATA)
00324 inImage->convertDataTypeTo(Image::OSG_UINT8_IMAGEDATA);
00325 }
00326
00327 pf = (alphaValue == NONE_AVT) ? Image::OSG_RGB_PF : Image::OSG_RGBA_PF;
00328 w = inImage->getWidth();
00329 h = inImage->getHeight();
00330 d = inImage->getDepth();
00331 data = inImage->getData();
00332 ps = inImage->getBpp();
00333 ls = ps * w;
00334 ss = ls * h;
00335 os = 0;
00336
00337 beginEditCP(outImage);
00338
00339 outImage->set( pf, w, h, d );
00340
00341 ds = outImage->getData();
00342
00343 for (z = 0; z < d; z++) {
00344 for (y = 0; y < h; y++) {
00345 for (x = 0; x < w; x++) {
00346 md = data[(x*ps) + (y*ls) + (z*ss) + os];
00347
00348 ld = (x > 0) ? data[((x-1)*ps) + (y*ls) + (z*ss) + os] : 0;
00349 hd = (x < (w-1)) ? data[((x+1)*ps) + (y*ls) + (z*ss) + os] : 0;
00350 xs = (ld - hd);
00351
00352 ld = (y > 0) ? data[(x*ps) + ((y-1)*ls) + (z*ss) + os] : 0;
00353 hd = (y < (h-1)) ? data[(x*ps) + ((y+1)*ls) + (z*ss) + os] : 0;
00354 ys = (ld - hd);
00355
00356 ld = (z > 0) ? data[(x*ps) + (y*ls) + ((z-1)*ss) + os] : 0;
00357 hd = (z < (d-1)) ? data[(x*ps) + (y*ls) + ((z+1)*ss) + os] : 0;
00358 zs = (ld - hd);
00359
00360 *ds++ = xs / 2 + 127;
00361 *ds++ = ys / 2 + 127;
00362 *ds++ = zs / 2 + 127;
00363
00364 switch (alphaValue) {
00365 case NONE_AVT:
00366 break;
00367 case SOURCE_AVT:
00368 *ds++ = md;
00369 break;
00370 case GRADIENT_AVT:
00371 *ds++ = osgMax ( int(osgsqrt ( xs * xs + ys * ys + zs * zs ) * gF),
00372 255 );
00373 break;
00374 }
00375
00376 }
00377 }
00378 }
00379
00380 endEditCP(outImage);
00381
00382 if (copy != osg::NullFC)
00383 subRefCP(copy);
00384
00385 return;
00386 }
00387
00388
00389
00395 OSG_SYSTEMLIB_DLLMAPPING
00396 bool OSG::create2DPreIntegrationLUT ( ImagePtr dst,
00397 ImagePtr src,
00398 Real32 thickness)
00399 {
00400 if (src == NullFC || dst == NullFC ||
00401 src->getHeight() > 1 || src->getDepth() > 1 ||
00402 src->getPixelFormat() != Image::OSG_RGBA_PF)
00403 {
00404 FFATAL(("No appropriate image given!\n"));
00405 return false;
00406 }
00407
00408 unsigned char *dataSrc = src->getData();
00409 UInt32 width = src->getWidth();
00410
00411 beginEditCP( dst );
00412 {
00413 dst->set(Image::OSG_RGBA_PF, width, width);
00414
00415 unsigned char *dataDst = dst->getData();
00416
00417 for (Int32 x = 0; x < (Int32)width; x++)
00418 {
00419 for (Int32 y = 0; y < (Int32)width; y++)
00420 {
00421 Int32 n = 10 + 2 * abs(x-y);
00422 Real64 step = thickness / n;
00423
00424 Real64 dr = 0.0,
00425 dg = 0.0,
00426 db = 0.0,
00427 dtau = 0.0;
00428
00429 for (Int32 i = 0; i < n; i++)
00430 {
00431 Real64 w = x + (y-x) * (Real64)i/n;
00432
00433 if ((Int32)(w + 1) >= (Int32)width)
00434 w = (Real64)(width - 1) - 0.5/n;
00435
00436 Int32 pos = ((Int32)w) * 4;
00437
00438 Real64 e = exp(-dtau), scale = step * (1.0 / 255.0),
00439 f = w - floor(w), invF = 1 - f;
00440
00441 Real64 tau = scale * (dataSrc[pos + 3] * f + dataSrc[pos+4 + 3] * invF);
00442 Real64 r = e * scale * (dataSrc[pos + 0] * f + dataSrc[pos+4 + 0] * invF);
00443 Real64 g = e * scale * (dataSrc[pos + 1] * f + dataSrc[pos+4 + 1] * invF);
00444 Real64 b = e * scale * (dataSrc[pos + 2] * f + dataSrc[pos+4 + 2] * invF);
00445
00446 dr += r;
00447 dg += g;
00448 db += b;
00449 dtau += tau;
00450 }
00451
00452 dataDst[(x*width+y)*4+0] = (unsigned char)((dr > 1.0 ? 1.0 : dr)*255);
00453 dataDst[(x*width+y)*4+1] = (unsigned char)((dg > 1.0 ? 1.0 : dg)*255);
00454 dataDst[(x*width+y)*4+2] = (unsigned char)((db > 1.0 ? 1.0 : db)*255);
00455 dataDst[(x*width+y)*4+3] = (unsigned char)((1.0 - exp(-dtau))*255);
00456 }
00457 }
00458 }
00459 endEditCP( dst );
00460
00461
00462
00463 return true;
00464 }
00465
00466
00467
00470 OSG_SYSTEMLIB_DLLMAPPING
00471 bool OSG::splitRGBA(ImagePtr rgba,
00472 ImagePtr rgb,
00473 ImagePtr alpha)
00474 {
00475 if (rgba == NullFC || rgba->getDepth() > 1 ||
00476 rgba->getPixelFormat() != Image::OSG_RGBA_PF)
00477 {
00478 FFATAL(("No appropriate image given!\n"));
00479 return false;
00480 }
00481
00482 if (rgb == NullFC)
00483 rgb = Image::create();
00484 if (alpha == NullFC)
00485 alpha = Image::create();
00486
00487 Int32 w = rgba->getWidth();
00488 Int32 h = rgba->getHeight();
00489
00490 beginEditCP( rgb );
00491 beginEditCP( alpha );
00492 {
00493 rgb->set(Image::OSG_RGB_PF, w, h);
00494 alpha->set(Image::OSG_L_PF, w, h);
00495
00496 unsigned char *data = rgb->getData();
00497 unsigned char *dataRgba = rgba->getData();
00498 unsigned char *dataAlpha = alpha->getData();
00499
00500 for (Int32 i=0; i<(w * h); i++)
00501 {
00502 data[0] = dataRgba[0];
00503 data[1] = dataRgba[1];
00504 data[2] = dataRgba[2];
00505 dataAlpha[0] = dataRgba[3];
00506
00507 data += 3;
00508 dataRgba += 4;
00509 dataAlpha++;
00510 }
00511 }
00512 endEditCP( alpha );
00513 endEditCP( rgb );
00514
00515
00516
00517
00518 return true;
00519 }
00520
00521
00524 OSG_SYSTEMLIB_DLLMAPPING
00525 bool OSG::mergeRGBA(ImagePtr rgb,
00526 ImagePtr alpha,
00527 ImagePtr rgba)
00528 {
00529 if (rgb == NullFC || alpha == NullFC ||
00530 rgb->getDepth() > 1 || alpha->getDepth() > 1 ||
00531 rgb->getPixelFormat() != Image::OSG_RGB_PF ||
00532 alpha->getPixelFormat() != Image::OSG_L_PF)
00533 {
00534 FFATAL(("No appropriate images given!\n"));
00535 return false;
00536 }
00537
00538 Int32 w = rgb->getWidth();
00539 Int32 h = rgb->getHeight();
00540
00541 if (w != alpha->getWidth() || h != alpha->getHeight())
00542 {
00543 FFATAL(("Colour and Alpha Images must be of same size!\n"));
00544 return false;
00545 }
00546
00547 if (rgba == NullFC)
00548 rgba = Image::create();
00549
00550 beginEditCP( rgba );
00551 {
00552 rgba->set(Image::OSG_RGBA_PF, w, h);
00553
00554 unsigned char *data = rgba->getData();
00555 unsigned char *dataRgb = rgb->getData();
00556 unsigned char *dataAlpha = alpha->getData();
00557
00558 for (Int32 i=0; i<(w * h); i++)
00559 {
00560 data[0] = dataRgb[0];
00561 data[1] = dataRgb[1];
00562 data[2] = dataRgb[2];
00563 data[3] = *dataAlpha;
00564 data += 4;
00565 dataRgb += 3;
00566 dataAlpha++;
00567 }
00568 }
00569 endEditCP( rgba );
00570
00571
00572
00573 return true;
00574 }
00575
00576
00579 OSG_SYSTEMLIB_DLLMAPPING
00580 bool OSG::createPhongTexture(ImagePtr image,
00581 UInt32 size,
00582 Real32 specular_exponent,
00583 Real32 ka,
00584 Real32 kd,
00585 Real32 ks)
00586 {
00587 if (image == NullFC)
00588 image = Image::create();
00589
00590 beginEditCP( image );
00591 {
00592 image->set(Image::OSG_L_PF, size, size);
00593 unsigned char *textureMap = image->getData();
00594
00595 UInt32 i, j, index = 0;
00596 Real32 x = 0, y = 0;
00597
00598 Real32 specular_factor, diffuse_factor;
00599 Real32 textureRadius = 0.95f;
00600 Real32 textureStep = (2.0 * textureRadius) / Real32(size-1);
00601
00602 y = - textureRadius;
00603 for (j=0; j<size; j++)
00604 {
00605 x = -textureRadius;
00606 for (i=0; i<size; i++)
00607 {
00608 diffuse_factor = sqrt(1.0 - x * x);
00609 specular_factor = pow( diffuse_factor * sqrt (1.0f - y * y) - x * y,
00610 specular_exponent );
00611 textureMap[index++] = (unsigned char)((ka + kd * diffuse_factor + ks * specular_factor) * 255);
00612 x += textureStep;
00613 }
00614 y += textureStep;
00615 }
00616 }
00617 endEditCP( image );
00618
00619
00620
00621 return true;
00622 }
00623
00624
00625
00628 OSG_SYSTEMLIB_DLLMAPPING
00629 bool OSG::createNormalizationCubeMap(std::vector<ImagePtr> imageVec,
00630 UInt32 size)
00631 {
00632 int i, j;
00633
00634 if (imageVec.size() < 6)
00635 {
00636 FFATAL(("Only %d images given - need six\n", imageVec.size()));
00637 return false;
00638 }
00639
00640 for (i=0; i<6; i++)
00641 {
00642 if (imageVec[i] == NullFC)
00643 {
00644 FFATAL(("Image[%d] is Null\n", i));
00645 return false;
00646 }
00647 }
00648
00649 unsigned char *data = NULL;
00650 Vec3f n;
00651
00652 size = osgnextpower2(size);
00653
00654 float size2 = size / 2.0f;
00655 float offset = 0.5f;
00656
00657 ImagePtr imagePosX = imageVec[0];
00658
00659
00660 beginEditCP( imagePosX );
00661 imagePosX->set(Image::OSG_RGB_PF, size, size);
00662 data = imagePosX->getData();
00663
00664 for (j=0; j<size; j++) {
00665 for (i=0; i<size; i++) {
00666
00667 n[0] = size2;
00668 n[1] = -((float)j + offset - size2);
00669 n[2] = -((float)i + offset - size2);
00670 n.normalize();
00671
00672 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00673 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00674 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00675 data += 3;
00676 }
00677 }
00678 endEditCP( imagePosX );
00679
00680 ImagePtr imageNegX = imageVec[1];
00681
00682
00683 beginEditCP( imageNegX );
00684 imageNegX->set(Image::OSG_RGB_PF, size, size);
00685 data = imageNegX->getData();
00686
00687 for (j=0; j<size; j++) {
00688 for (i=0; i<size; i++) {
00689
00690 n[0] = -size2;
00691 n[1] = -((float)j + offset - size2);
00692 n[2] = ((float)i + offset - size2);
00693 n.normalize();
00694
00695 data[0]= (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00696 data[1]= (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00697 data[2]= (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00698 data += 3;
00699 }
00700 }
00701 endEditCP( imageNegX );
00702
00703 ImagePtr imagePosY = imageVec[2];
00704
00705
00706 beginEditCP( imagePosY );
00707 imagePosY->set(Image::OSG_RGB_PF, size, size);
00708 data = imagePosY->getData();
00709
00710 for (j=0; j<size; j++) {
00711 for (i=0; i<size; i++) {
00712
00713 n[0] = ((float)i + offset - size2);
00714 n[1] = size2;
00715 n[2] = ((float)j + offset - size2);
00716 n.normalize();
00717
00718 data[0]= (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00719 data[1]= (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00720 data[2]= (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00721 data += 3;
00722 }
00723 }
00724 endEditCP( imagePosY );
00725
00726 ImagePtr imageNegY = imageVec[3];
00727
00728
00729 beginEditCP( imageNegY );
00730 imageNegY->set(Image::OSG_RGB_PF, size, size);
00731 data = imageNegY->getData();
00732
00733 for (j=0; j<size; j++) {
00734 for (i=0; i<size; i++) {
00735
00736 n[0]= ((float)i + offset - size2);
00737 n[1]= -size2;
00738 n[2]= -((float)j + offset - size2);
00739 n.normalize();
00740
00741 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00742 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00743 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00744 data += 3;
00745 }
00746 }
00747 endEditCP( imageNegY );
00748
00749 ImagePtr imagePosZ = imageVec[4];
00750
00751
00752 beginEditCP( imagePosZ );
00753 imagePosZ->set(Image::OSG_RGB_PF, size, size);
00754 data = imagePosZ->getData();
00755
00756 for (j=0; j<size; j++) {
00757 for (i=0; i<size; i++) {
00758
00759 n[0] = ((float)i + offset - size2);
00760 n[1] = -((float)j + offset - size2);
00761 n[2] = size2;
00762 n.normalize();
00763
00764 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00765 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00766 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00767 data += 3;
00768 }
00769 }
00770 endEditCP( imagePosZ );
00771
00772 ImagePtr imageNegZ = imageVec[5];
00773
00774
00775 beginEditCP( imageNegZ );
00776 imageNegZ->set(Image::OSG_RGB_PF, size, size);
00777 data = imageNegZ->getData();
00778
00779 for (j=0; j<size; j++) {
00780 for (i=0; i<size; i++) {
00781
00782 n[0] = -((float)i + offset - size2);
00783 n[1] = -((float)j + offset - size2);
00784 n[2] = -size2;
00785 n.normalize();
00786
00787 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00788 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00789 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00790 data += 3;
00791 }
00792 }
00793 endEditCP( imageNegZ );
00794
00795 return true;
00796 }
00797
00798
00799
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 namespace
00840 {
00841
00842
00843 #define MAXB 0x100
00844
00845 Int32 p[MAXB + MAXB + 2];
00846 Real32 g3[MAXB + MAXB + 2][3];
00847 Real32 g2[MAXB + MAXB + 2][2];
00848 Real32 g1[MAXB + MAXB + 2];
00849 Int32 start = 1;
00850 Int32 B = 0x100;
00851 Int32 BM = 0xff;
00852
00853
00854 void setNoiseFrequency(Int32 frequency)
00855 {
00856 start = 1;
00857 B = frequency;
00858 BM = B-1;
00859 }
00860
00861 Real32 lerp(Real32 t, Real32 a, Real32 b)
00862 {
00863 return (1 - t) * a + t * b;
00864 }
00865
00866 Real32 sCurve(Real32 t)
00867 {
00868 return t * t * (3.0f - 2.0f * t);
00869 }
00870
00871 Real32 at2(Real32 *q, Real32 rx, Real32 ry)
00872 {
00873 return rx * q[0] + ry * q[1];
00874 }
00875
00876 Real32 at3(Real32 *q, Real32 rx, Real32 ry, Real32 rz)
00877 {
00878 return rx * q[0] + ry * q[1] + rz * q[2];
00879 }
00880
00881 void setup(Real32 *vec, UInt8 i,
00882 Real32 &t,
00883 Int32 &b0, Int32 &b1,
00884 Real32 &r0, Real32 &r1)
00885 {
00886 t = vec[i] + 0x1000;
00887 b0 = ((Int32)t) & BM;
00888 b1 = (b0 + 1) & BM;
00889 r0 = t - (Int32)t;
00890 r1 = r0 - 1.0f;
00891 }
00892
00893 void normalize2(Real32 v[2])
00894 {
00895 Real32 s = sqrt(v[0] * v[0] + v[1] * v[1]);
00896 v[0] = v[0] / s;
00897 v[1] = v[1] / s;
00898 }
00899
00900 void normalize3(Real32 v[3])
00901 {
00902 Real32 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00903 v[0] = v[0] / s;
00904 v[1] = v[1] / s;
00905 v[2] = v[2] / s;
00906 }
00907
00908 void init(void)
00909 {
00910 Int32 i, j, k;
00911
00912 srand(30757);
00913 for (i = 0 ; i < B ; i++)
00914 {
00915 p[i] = i;
00916 g1[i] = (Real32)((rand() % (B + B)) - B) / B;
00917
00918 for (j = 0 ; j < 2 ; j++)
00919 g2[i][j] = (Real32)((rand() % (B + B)) - B) / B;
00920 normalize2(g2[i]);
00921
00922 for (j = 0 ; j < 3 ; j++)
00923 g3[i][j] = (Real32)((rand() % (B + B)) - B) / B;
00924 normalize3(g3[i]);
00925 }
00926
00927 while (--i)
00928 {
00929 k = p[i];
00930 p[i] = p[j = rand() % B];
00931 p[j] = k;
00932 }
00933
00934 for (i = 0 ; i < B + 2 ; i++)
00935 {
00936 p[B + i] = p[i];
00937 g1[B + i] = g1[i];
00938 for (j = 0 ; j < 2 ; j++)
00939 g2[B + i][j] = g2[i][j];
00940 for (j = 0 ; j < 3 ; j++)
00941 g3[B + i][j] = g3[i][j];
00942 }
00943 }
00944
00945 Real32 noise1(Real32 vec[1])
00946 {
00947 Int32 bx0, bx1;
00948 Real32 rx0, rx1, sx, t, u, v;
00949
00950 if (start)
00951 {
00952 start = 0;
00953 init();
00954 }
00955
00956 setup(vec, 0, t, bx0, bx1, rx0, rx1);
00957
00958 sx = sCurve(rx0);
00959
00960 u = rx0 * g1[ p[ bx0 ] ];
00961 v = rx1 * g1[ p[ bx1 ] ];
00962
00963 return lerp(sx, u, v);
00964 }
00965
00966 Real32 noise2(Real32 vec[2])
00967 {
00968 Int32 bx0, bx1, by0, by1, b00, b10, b01, b11;
00969 Real32 rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
00970 Int32 i, j;
00971
00972 if (start)
00973 {
00974 start = 0;
00975 init();
00976 }
00977
00978 setup(vec, 0, t, bx0, bx1, rx0, rx1);
00979 setup(vec, 1, t, by0, by1, ry0, ry1);
00980
00981 i = p[ bx0 ];
00982 j = p[ bx1 ];
00983
00984 b00 = p[ i + by0 ];
00985 b10 = p[ j + by0 ];
00986 b01 = p[ i + by1 ];
00987 b11 = p[ j + by1 ];
00988
00989 sx = sCurve(rx0);
00990 sy = sCurve(ry0);
00991
00992 q = g2[ b00 ] ; u = at2(q, rx0,ry0);
00993 q = g2[ b10 ] ; v = at2(q, rx1,ry0);
00994 a = lerp(sx, u, v);
00995
00996 q = g2[ b01 ] ; u = at2(q, rx0,ry1);
00997 q = g2[ b11 ] ; v = at2(q, rx1,ry1);
00998 b = lerp(sx, u, v);
00999
01000 return lerp(sy, a, b);
01001 }
01002
01003 Real32 noise3(Real32 vec[3])
01004 {
01005 Int32 bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
01006 Real32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
01007 Int32 i, j;
01008
01009 if (start)
01010 {
01011 start = 0;
01012 init();
01013 }
01014
01015 setup(vec, 0, t, bx0, bx1, rx0, rx1);
01016 setup(vec, 1, t, by0, by1, ry0, ry1);
01017 setup(vec, 2, t, bz0, bz1, rz0, rz1);
01018
01019 i = p[ bx0 ];
01020 j = p[ bx1 ];
01021
01022 b00 = p[ i + by0 ];
01023 b10 = p[ j + by0 ];
01024 b01 = p[ i + by1 ];
01025 b11 = p[ j + by1 ];
01026
01027 t = sCurve(rx0);
01028 sy = sCurve(ry0);
01029 sz = sCurve(rz0);
01030
01031 q = g3[ b00 + bz0 ] ; u = at3(q, rx0,ry0,rz0);
01032 q = g3[ b10 + bz0 ] ; v = at3(q, rx1,ry0,rz0);
01033 a = lerp(t, u, v);
01034
01035 q = g3[ b01 + bz0 ] ; u = at3(q, rx0,ry1,rz0);
01036 q = g3[ b11 + bz0 ] ; v = at3(q, rx1,ry1,rz0);
01037 b = lerp(t, u, v);
01038
01039 c = lerp(sy, a, b);
01040
01041 q = g3[ b00 + bz1 ] ; u = at3(q, rx0,ry0,rz1);
01042 q = g3[ b10 + bz1 ] ; v = at3(q, rx1,ry0,rz1);
01043 a = lerp(t, u, v);
01044
01045 q = g3[ b01 + bz1 ] ; u = at3(q, rx0,ry1,rz1);
01046 q = g3[ b11 + bz1 ] ; v = at3(q, rx1,ry1,rz1);
01047 b = lerp(t, u, v);
01048
01049 d = lerp(sy, a, b);
01050
01051 return lerp(sz, c, d);
01052 }
01053
01054 Real32 noise(Real32 vec[], Int32 len)
01055 {
01056
01057 switch (len)
01058 {
01059 case 1: return noise1(vec);
01060 case 2: return noise2(vec);
01061 case 3: return noise3(vec);
01062 case 0:
01063 default: return 0.0f;
01064 }
01065 }
01066
01067 };
01068
01069
01074 OSG_SYSTEMLIB_DLLMAPPING
01075 bool OSG::createNoise(ImagePtr image,
01076 Image::PixelFormat pixelformat,
01077 UInt16 numOctaves,
01078 UInt16 size,
01079 UInt8 dim,
01080 bool splitOctaves)
01081 {
01082 Int32 f, i, j, k, c, w, h, mult = 1, frequency = 4;
01083 Real32 ni[3], amp = 0.5, inci, incj, inck;
01084 unsigned char *data, *ptr = NULL;
01085 bool ok = true;
01086
01087 if (image == NullFC)
01088 {
01089 FFATAL (("No output image given\n"));
01090 return false;
01091 }
01092
01093 switch (dim)
01094 {
01095 case 1:
01096 ok = image->set(pixelformat, size);
01097 w = h = 1;
01098 break;
01099 case 2:
01100 ok = image->set(pixelformat, size, size);
01101 w = size;
01102 h = 1;
01103 break;
01104 case 3:
01105 ok = image->set(pixelformat, size, size, size);
01106 w = h = size;
01107 break;
01108 default:
01109 ok = image->set(pixelformat, size, size);
01110 dim = 2;
01111 w = size;
01112 h = 1;
01113 FWARNING(("createNoise: Use [1|2|3] for image dimension (default 2)\n"));
01114 break;
01115 }
01116
01117 if ( ! (ok && (data = image->getData())) )
01118 {
01119 FFATAL(("createNoise: Could not create image\n"));
01120 return false;
01121 }
01122
01123 UInt16 ncomp = image->getComponents();
01124
01125 if(splitOctaves && numOctaves > ncomp)
01126 {
01127 FWARNING(("createNoise: try to split %d octaves, but only have %d"
01128 " components!\n", numOctaves, ncomp ));
01129 numOctaves = ncomp;
01130 }
01131
01132 for (f=0; f<numOctaves; ++f, frequency*=2, amp*=0.5)
01133 {
01134 ptr = data;
01135
01136 setNoiseFrequency(frequency);
01137 ni[0] = ni[1] = ni[2] = 0;
01138 inci = 1.0 / (size / (Real32)frequency);
01139 incj = 1.0 / (size / (Real32)frequency);
01140 inck = 1.0 / (size / (Real32)frequency);
01141
01142 for (i=0; i<size; ++i, ni[0]+=inci)
01143 {
01144 for (j=0; j<w; ++j, ni[1]+=incj)
01145 {
01146 for (k=0; k<h; ++k, ni[2]+=inck)
01147 {
01148
01149 if (splitOctaves)
01150 {
01151 *(ptr+f) = (UInt8)(((noise(ni, dim) + 1) * amp) * 128.0);
01152
01153 ptr+=ncomp;
01154 }
01155 else
01156 {
01157 for(c = 0; c < ncomp; ++c, ++ptr, ni[0] += 1)
01158 (*ptr) += (UInt8)(((noise(ni, dim) + 1) * amp) * 128.0);
01159
01160 ni[0] -= ncomp;
01161 }
01162 }
01163 }
01164 }
01165 FNOTICE(("Generated %dD noise: octave %d/%d...\n", dim, f+1, numOctaves));
01166 }
01167
01168 return true;
01169 }
01170