Chapter Overview
| >Chapter Introduction - Exercise 1 >Chapter Introduction - Exercise 2 >Chapter Basics - Exercise 1 >Chapter Basics - Exercise 2 >Chapter Node Cores - Exercise 1 |
The appropriate configure command has to be executed in your OpenSG folder
./configure --enable-glut --enable-jpg --enable-tif --enable-pngif you are compiling an a PowerPC architecture you might need to add
--with-compiler=g++
After configure has finished you need to call
make optif you omit opt, you will build the debug version. If any errors occur during compilation check if you have installed all corresponding devel packages for the image libraries (and read again the installation section - maybe you missed something)
Check the Makefile : the first line (without comments) says
LIBTYPE ?= dbgadjust this to 'opt', if you compiled the optimized version.
Enter the directory your_opensg_folder/Tutorials and call
makeBefore you execute the compiled binaries you should make sure if you have adjusted your library path (see Installation) unless you installed a rpm package or the window binaries (where this is done automatically)
The result is simpy the same. The order of the commands seem to have no impact on the result. If you understand how these methods work it becomes obvious. The setTranslate command for instance will overwrite the appropriate three entries in a matrix that define the translation but will leave all others untouched. The same is with the setRotate command. The matrix is the same in both ways.
This would have not been the case if we multiplied a transform and a rotation matrix, however that is not what we have done here, but what might have been confusing you!
You need to alter the createScenegraph method in the following way
NodePtr createScenegraph(int argc, char **argv){ // the scene must be created here //first we create a group root node which all loaded //files will be attached to NodePtr root = Node::create(); beginEditCP(root); root->setCore(Group::create()); endEditCP(root); //we assume that all given parameters are filename for (int i = 1;i < argc; i++){ NodePtr n = SceneFileHandler::the().read(argv[i]); //we check the result if (n != NullFC){ // add the loaded node to the root beginEditCP(root); root->addChild(n); endEditCP(root); }else cout << "Loading the specified file (" << argv[i] << ") was not possible!" << endl; } return root; }
Notice that you need to change the interface of this method as you need to pass the arguments from the command line. This implies that you also change one line in the main method from
scene = createScenegraph();
to scene = createScenegraph(argc, argv);
Instead of loading just a single file and returning that node we node create one root node which will be parent to all loaded files. In a loop we load all given files and add them to the root node. Notice that our loop begins with one and not zero, as the very first argument is always the program name. Also note that you have to provide the complete relative path to the source files.
The eyes are named FACESET_Eyes. The geometry node with this names stores both eyes in a single core. In order to copy the whole woman with her eyes we first need to extend the checkName function. We previously have hardcoded the search string "FACESET_Woman" as the node's name this function is looking for. Of course this is not very good programming - so we add another parameter which will carry the search string. Change the function head from
NodePtr checkName(NodePtr n)
to
NodePtr checkName(NodePtr n, std::string search)
next replace the string "FACESET_Woman" in the function body with the new variable search like this
if (getName(n) == search)
the conversion to std::string is of course no longer needed.
Now in the createScenegraph() function locate the line that says
NodePtr womanGeometry = checkName(w_high);
which is found directly after the root node is created. As we have changed the interface of the checkName() function, you need to add the new parameter which will be the hard coded string we just removed. The new line is
NodePtr womanGeometryGeometry = checkName(w_high, "FACESET_Woman");
Don't forget to adjust the path right at the beginning of the createScenegraph() function when loading the models (if you place your file somewhere else than in the progs folder).
Well, now our checkName() function is able to find any node with a given name. We can get the geometry core containing the eyes by invoking a new search. Add the following code right below the code where we call checkNames() with "FACESET_Woman"
// now we extract the eye geometry NodePtr womanEyes = checkName(w_high, "FACESET_Eyes"); GeometryPtr eyesGeo = GeometryPtr::dcast(womanEyesGeometry->getCore());
Now scroll some lines down and add the next block of code below the lines where the material for "geo" is set.
beginEditCP(eyesGeo, Geometry::MaterialFieldMask);
eyesGeo->setMaterial(mat);
endEditCP(eyesGeo, Geometry::MaterialFieldMask);
Next, place this block after the "woman" Node is created (again, just a few lines below)
NodePtr womanEyes = Node::create();
beginEditCP(womanEyes);
womanEyes->setCore(eyesGeo);
endEditCP(womanEyes);
Finally locate the line where the ctNode is edited (somewhere near the end of the createScenegraph() function) and add this line somewhere between the begin- and endEditCP commands.
ctNode->addChild(womanEyes);
Now compile and execute! Well, the eyes are still not there, but if you have a closer look at the stomach you can find the eyes. It seems that the transformation is missing - what actually makes sense, as we have copied the geometry only. So it is now up to you to locate and clone the transformation...
Missing solutions and even more execrises may come in the feature. You are welcome to contribute ;-)
Next Chapter : Appendix B - OpenSG with QT
1.4.3