00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <Inventor/nodes/SoMaterial.h>
00028 # include <Inventor/nodes/SoShapeHints.h>
00029 # include <Inventor/SbClip.h>
00030 # include <Inventor/nodes/SoCoordinate3.h>
00031 # include <Inventor/nodes/SoComplexity.h>
00032 # include <Inventor/nodes/SoMaterial.h>
00033 # include <Inventor/nodes/SoTexture3.h>
00034 # include <Inventor/nodes/SoTextureCoordinate3.h>
00035 # include <Inventor/nodes/SoFaceSet.h>
00036 # include <Inventor/nodes/SoLineSet.h>
00037 # include <Inventor/nodes/SoBaseColor.h>
00038 # include <Inventor/draggers/SoTransformerDragger.h>
00039
00040 # include <float.h>
00041 # include <cstring>
00042 #endif
00043
00044 #include "../Base/Console.h"
00045
00046
00047 #include "View3DInventorExamples.h"
00048
00049 #include <Inventor/SbPlane.h>
00050 #include <Inventor/Qt/SoQt.h>
00051 #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
00052 #include <Inventor/SoDB.h>
00053 #include <Inventor/actions/SoSearchAction.h>
00054 #include <Inventor/manips/SoPointLightManip.h>
00055 #include <Inventor/nodes/SoSeparator.h>
00056 #include <Inventor/draggers/SoTransformerDragger.h>
00057 #include <Inventor/SbBasic.h>
00058 #include <Inventor/nodes/SoShapeHints.h>
00059 #include <Inventor/nodes/SoSeparator.h>
00060 #include <Inventor/nodes/SoTexture2.h>
00061 #include <Inventor/nodes/SoCube.h>
00062 #include <Inventor/sensors/SoTimerSensor.h>
00063
00064
00065
00066 unsigned char * generateTexture(int w, int h, int d)
00067 {
00068 int val;
00069 float x,y,z;
00070
00071 unsigned char * bitmap = new unsigned char[w*h*d];
00072
00073 for (int k = 0;k<d;k++) {
00074 z = k*360/d;
00075 for (int j = 0;j<h;j++) {
00076 y = (j-h/2)/2;
00077 for (int i = 0;i<w;i++) {
00078 x = (i-w/2)/2;
00079 val = int(x*x + y*y*sin(2*x*M_PI/w + z*M_PI/180));
00080 val = abs(val%512);
00081 if (val >= 256) val = 511-val;
00082 bitmap[k*w*h + j*h + i] = val;
00083 }
00084 }
00085 }
00086
00087
00088 return bitmap;
00089 }
00090
00091 void doClipping(SbVec3f trans, SbRotation rot)
00092 {
00093 SbMatrix mat;
00094 SbVec3f normal;
00095
00096 mat.setTransform(trans, rot, SbVec3f(1,1,1));
00097 mat.multDirMatrix(SbVec3f(0, -1, 0), normal);
00098 SbPlane plane(normal, trans);
00099
00100 const float coords[][3] = {
00101 {-5,-5,-5},
00102 {5,-5,-5},
00103 {5,5,-5},
00104 {-5,5,-5},
00105 {-5,-5,5},
00106 {5,-5,5},
00107 {5,5,5},
00108 {-5,5,5}
00109 };
00110 const int indices[] = {
00111 0,3,2,1,-1,
00112 0,1,5,4,-1,
00113 2,6,5,1,-1,
00114 3,7,6,2,-1,
00115 3,0,4,7,-1,
00116 7,4,5,6,-1
00117 };
00118
00119
00120
00121 SbClip clip;
00122 SoMFVec3f * globalVerts =
00123 (SoMFVec3f *)SoDB::getGlobalField(SbName("globalVerts"));
00124 SoMFVec3f * globalTVerts =
00125 (SoMFVec3f *)SoDB::getGlobalField(SbName("globalTVerts"));
00126 SoMFInt32 * globalnv =
00127 (SoMFInt32 *)SoDB::getGlobalField(SbName("globalnv"));
00128 globalVerts->startEditing();
00129 globalVerts->setNum(0);
00130 globalTVerts->startEditing();
00131 globalTVerts->setNum(0);
00132 globalnv->startEditing();
00133 globalnv->setNum(0);
00134 int i;
00135 for (i = 0;i<6*5;i++) {
00136 if (indices[i] == -1) {
00137 clip.clip(plane);
00138 int numVerts = clip.getNumVertices();
00139 if (numVerts > 0) {
00140 for (int j = 0;j<numVerts;j++) {
00141 SbVec3f v;
00142 clip.getVertex(j, v);
00143 globalVerts->set1Value(globalVerts->getNum(), v);
00144 v += SbVec3f(5, 5, 5);
00145 v /= 10.0;
00146 globalTVerts->set1Value(globalTVerts->getNum(), v);
00147 }
00148 globalnv->set1Value(globalnv->getNum(), numVerts);
00149 }
00150 clip.reset();
00151 }
00152 else clip.addVertex(coords[indices[i]]);
00153 }
00154 globalVerts->finishEditing();
00155 globalTVerts->finishEditing();
00156 globalnv->finishEditing();
00157
00158
00159
00160 const SbVec3f planecoords[] = {
00161 SbVec3f(-10,0,-10),
00162 SbVec3f(10,0,-10),
00163 SbVec3f(10,0,10),
00164 SbVec3f(-10,0,10)
00165 };
00166
00167
00168 clip.reset();
00169 for (i = 0;i<4;i++) {
00170 SbVec3f v;
00171 mat.multVecMatrix(planecoords[i], v);
00172 clip.addVertex(v);
00173 }
00174 for (i = 0;i<6*5;i+=5) {
00175 SbPlane p(coords[indices[i+2]],
00176 coords[indices[i+1]],
00177 coords[indices[i]]);
00178 clip.clip(p);
00179 }
00180 int numVerts = clip.getNumVertices();
00181 SoMFVec3f * planeVerts =
00182 (SoMFVec3f *)SoDB::getGlobalField(SbName("planeVerts"));
00183 SoMFVec3f * planeTVerts =
00184 (SoMFVec3f *)SoDB::getGlobalField(SbName("planeTVerts"));
00185 planeVerts->startEditing();
00186 planeVerts->setNum(0);
00187 planeTVerts->startEditing();
00188 planeTVerts->setNum(0);
00189 for (i = 0;i<numVerts;i++) {
00190 SbVec3f v;
00191 clip.getVertex(i, v);
00192 planeVerts->set1Value(planeVerts->getNum(), v);
00193 v += SbVec3f(5, 5, 5);
00194 v /= 10.0;
00195 planeTVerts->set1Value(planeTVerts->getNum(), v);
00196 }
00197 planeVerts->finishEditing();
00198 planeTVerts->finishEditing();
00199 }
00200
00201 void draggerCB(void * data, SoDragger * dragger)
00202 {
00203 SoTransformerDragger * drag = (SoTransformerDragger *)dragger;
00204 doClipping(drag->translation.getValue(), drag->rotation.getValue());
00205 }
00206
00207 void Texture3D(SoSeparator * root)
00208 {
00209
00210 SoDB::createGlobalField("globalVerts", SoMFVec3f::getClassTypeId());
00211 SoDB::createGlobalField("globalTVerts", SoMFVec3f::getClassTypeId());
00212 SoDB::createGlobalField("globalnv", SoMFInt32::getClassTypeId());
00213 SoDB::createGlobalField("planeVerts", SoMFVec3f::getClassTypeId());
00214 SoDB::createGlobalField("planeTVerts", SoMFVec3f::getClassTypeId());
00215
00216 doClipping(SbVec3f(0,0,0), SbRotation());
00217
00218
00219
00220
00221 SoComplexity * comp = new SoComplexity;
00222 comp->textureQuality.setValue((float)0.9);
00223 root->addChild(comp);
00224
00225 SoTexture3 * texture = new SoTexture3;
00226 texture->wrapR.setValue(SoTexture3::CLAMP);
00227 texture->wrapS.setValue(SoTexture3::CLAMP);
00228 texture->wrapT.setValue(SoTexture3::CLAMP);
00229
00230
00231
00232
00233 unsigned char * img = generateTexture(256,256,256);
00234 texture->images.setValue(SbVec3s(256,256,256), 1, img);
00235 root->addChild(texture);
00236
00237 SoMaterial * mat = new SoMaterial;
00238 mat->emissiveColor.setValue(1,1,1);
00239 root->addChild(mat);
00240
00241 SoTransformerDragger * dragger = new SoTransformerDragger;
00242 dragger->scaleFactor.setValue(5,5,5);
00243 dragger->addValueChangedCallback(draggerCB, NULL);
00244 root->addChild(dragger);
00245
00246 SoCoordinate3 * clippedCoords = new SoCoordinate3;
00247 clippedCoords->point.connectFrom((SoMFVec3f *)
00248 SoDB::getGlobalField("globalVerts"));
00249 root->addChild(clippedCoords);
00250 SoTextureCoordinate3 * clippedTCoords = new SoTextureCoordinate3;
00251 clippedTCoords->point.connectFrom((SoMFVec3f *)
00252 SoDB::getGlobalField("globalTVerts"));
00253 root->addChild(clippedTCoords);
00254 SoFaceSet * clippedFS = new SoFaceSet;
00255 clippedFS->numVertices.connectFrom((SoMFInt32 *)
00256 SoDB::getGlobalField("globalnv"));
00257 root->addChild(clippedFS);
00258
00259 SoCoordinate3 * planeCoords = new SoCoordinate3;
00260 planeCoords->point.connectFrom((SoMFVec3f *)
00261 SoDB::getGlobalField("planeVerts"));
00262 root->addChild(planeCoords);
00263 SoTextureCoordinate3 * planeTCoords = new SoTextureCoordinate3;
00264 planeTCoords->point.connectFrom((SoMFVec3f *)
00265 SoDB::getGlobalField("planeTVerts"));
00266 root->addChild(planeTCoords);
00267 SoFaceSet * planeFS = new SoFaceSet;
00268 root->addChild(planeFS);
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 }
00288
00289
00290
00291
00292 static const char scenegraph[] = "#Inventor V2.1 ascii\n"
00293 "Separator {\n"
00294 " DEF RedLight PointLight { location -10 -10 10 color 1 0 0 }\n"
00295 " DEF GreenLight PointLight { location -5 5 10 color 0 1 0 }\n"
00296 " DEF BlueLight PointLight { location 10 10 10 color 0 0 1 }\n"
00297 " Material { diffuseColor 0.5 0.5 0.5 specularColor 1 1 1 }\n"
00298 " Array {\n"
00299 " origin CENTER\n"
00300 " numElements1 3 separation1 5.5 0 0\n"
00301 " numElements2 3 separation2 0 5.5 0\n"
00302 "\n"
00303 " Sphere { radius 3 }\n"
00304 " }\n"
00305 "}\n";
00306
00307 void LightManip(SoSeparator * root)
00308 {
00309
00310 SoInput in;
00311 in.setBuffer((void *)scenegraph, std::strlen(scenegraph));
00312 SoSeparator * _root = SoDB::readAll( &in );
00313 root->addChild(_root);
00314 if ( root == NULL ) exit( 1 );
00315 root->ref();
00316
00317 const char * pointlightnames[3] = { "RedLight", "GreenLight", "BlueLight" };
00318 SoSearchAction sa;
00319
00320 for (int i = 0; i < 3; i++) {
00321 sa.setName( pointlightnames[i] );
00322 sa.setInterest( SoSearchAction::FIRST );
00323 sa.setSearchingAll( FALSE );
00324 sa.apply( root );
00325 SoPath * path = sa.getPath();
00326 if ( path == NULL) exit( 1 );
00327
00328 SoPointLightManip * manip = new SoPointLightManip;
00329 manip->replaceNode( path );
00330 }
00331
00332
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342 const int texturewidth = 128;
00343 const int textureheight = 128;
00344
00345
00346 double cr = 0.33;
00347 double ci = 0.43;
00348
00349
00350
00351 unsigned char bitmap[texturewidth*textureheight];
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 void
00364 julia(double crr, double cii, float zoom, int width, int height, int mult,
00365 unsigned char * bmp, int n)
00366 {
00367 double zr, zr_old, zi;
00368 int w;
00369
00370 for (int y=0; y<height/2; y++)
00371 for (int x=0; x<width; x++) {
00372 zr = ((double)(x)/(double)width)*zoom-zoom/2;
00373 zi = ((double)(y)/(double)height)*zoom-zoom/2;
00374 for (w = 0; (w < n) && (zr*zr+zi*zi)<n; w++) {
00375 zr_old = zr;
00376 zr = zr*zr - zi*zi + crr;
00377 zi = 2*zr_old*zi + cii;
00378 }
00379 bmp[y*width+x] = 255-w*mult;
00380 bmp[((height-y)*width)-(x+1)] = 255-w*mult;
00381 }
00382 }
00383
00384
00385
00386
00387
00388 SoTexture2 *
00389 texture()
00390 {
00391 SoTexture2 * texture = new SoTexture2;
00392 texture->image.setValue(SbVec2s(texturewidth, textureheight), 1, bitmap);
00393 texture->model = SoTexture2::MODULATE;
00394 texture->blendColor.setValue(1.0, 0.0, 0.0);
00395 return texture;
00396 }
00397
00398
00399 static void
00400 timersensorcallback(void * data, SoSensor *)
00401 {
00402 static SbBool direction = FALSE;
00403
00404 SoTexture2 * texnode = (SoTexture2*) data;
00405
00406 if (!direction) {
00407 cr -= 0.0005;
00408 ci += 0.0005;
00409 }
00410 else {
00411 cr += 0.0005;
00412 ci -= 0.0005;
00413 }
00414
00415 if (ci<0.30)
00416 direction = !direction;
00417 else if (ci>0.83)
00418 direction = !direction;
00419
00420 SbVec2s size;
00421 int nc;
00422 unsigned char * image = texnode->image.startEditing(size, nc);
00423
00424 julia(cr, ci, 2.5, size[0], size[1], 4, image, 64);
00425 texnode->image.finishEditing();
00426 }
00427
00428 void AnimationTexture(SoSeparator * root)
00429 {
00430
00431
00432 julia(cr, ci, 2.5, texturewidth, textureheight, 4, bitmap, 64);
00433
00434
00435 SoTexture2 * texnode = texture();
00436
00437
00438 SoShapeHints * hints = new SoShapeHints;
00439
00440 hints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
00441 hints->shapeType = SoShapeHints::SOLID;
00442
00443
00444 SoTimerSensor * texturetimer = new SoTimerSensor(timersensorcallback, texnode);
00445 texturetimer->setInterval(0.05);
00446 texturetimer->schedule();
00447
00448
00449 if ( root == NULL ) exit( 1 );
00450 root->ref();
00451
00452
00453
00454 root->addChild(hints);
00455 root->addChild(texnode);
00456 root->addChild(new SoCube);
00457
00458 }
00459