Trasparencias

Anuncio
Toolkits – RVA
Solución 4:
/********************************************************
*
* Este programa permite visualizar ficheros iv (vrml)
*
********************************************************/
//Según el sistema operativo en el que compilemos el código
//utilizaremos una librería de componentes u otra
#ifdef WIN32
//WINDOWS
#include <Inventor/Win/SoWin.h>
#include <Inventor/Win/viewers/SoWinExaminerViewer.h>
#else
//LINUX
#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/viewers/SoXtExaminerViewer.h>
#endif
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/draggers/SoTrackballDragger.h>
#include <Inventor/draggers/SoTranslate1Dragger.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/events/SoKeyboardEvent.h>
#include <Inventor/sensors/SoTimerSensor.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/engines/SoCalculator.h>
//Constantes
#define FPS 1.0f/25.0f //Frames por segundo
//Esta función es llamada cuando se produce un evento
//de teclado
void keyCallBack (void *userData, SoEventCallback *eventoTeclado)
{
const SoEvent *event = eventoTeclado->getEvent ();
Toolkits – RVA
//Se selecciona un dragger según la tecla que se pulse
if ((SO_KEY_PRESS_EVENT (event, Q))||(SO_KEY_PRESS_EVENT (event,
ESCAPE)))
exit(0);
else if (SO_KEY_PRESS_EVENT (event, N))
((SoSwitch *)userData)->whichChild=-1;
else if (SO_KEY_PRESS_EVENT (event, R))
((SoSwitch *)userData)->whichChild=0;
else if (SO_KEY_PRESS_EVENT (event, T))
((SoSwitch *)userData)->whichChild=1;
eventoTeclado->setHandled ();
}
//Esta función es llamada para realizar cada renderizado
void renderCallback (void *userData, SoSensor * sensor)
{
#ifdef WIN32
//WINDOWS
SoWinExaminerViewer * viewer=(SoWinExaminerViewer *) userData;
#else
//LINUX
SoXtExaminerViewer * viewer=(SoXtExaminerViewer *) userData;
#endif
viewer->render();
}
//MAIN
int main(int argc, char ** argv)
{
SoInput * LeeFich;
//Inicialización de la librería de componentes
#ifdef WIN32
//WINDOWS
HWND mainwin = SoWin::init(argc, argv, argv[0]);
if (mainwin==NULL) exit (1);
SoWinExaminerViewer *viewer = new SoWinExaminerViewer(mainwin);
#else
//LINUX
Widget mainwin = SoXt::init(argc, argv, argv[0]);
if (mainwin==NULL) exit (1);
SoXtExaminerViewer *viewer = new SoXtExaminerViewer(mainwin);
#endif
//Comprobamos el número de argumentos
if (argc != 2)
Toolkits – RVA
{
fprintf (stderr, " Uso: %s nombre_fichero.iv\n", argv[0]);
exit(1);
}
else
{
printf ("Abriendo %s\n", argv[1]);
LeeFich = new SoInput();
if (!LeeFich->openFile (argv[1]))
{
perror (argv[1]);
exit (-1);
}
//Comprobamos que es un fichero válido
if (!LeeFich->isValidFile ())
{
fprintf (stderr, "No puedo cargar este formato de datos\n");
exit (-1);
}
}
//Creamos el nodo raíz
SoSeparator * root = new SoSeparator;
root->ref();
//De este separador colgará la escena que se carga de
//fichero, así como las cámaras y luces encargadas de
//mostrarla
SoSeparator *s_fich= new SoSeparator;
//Introducimos la cámara que renderiza los datos del
//fichero.
SoPerspectiveCamera *cam = new SoPerspectiveCamera();
SoDirectionalLight *light= new SoDirectionalLight();
s_fich->addChild(cam);
s_fich->addChild(light);
//Esta es la transformación a la que se ven sometidos
//los datos del fichero
SoTransform *t_fich = new SoTransform;
s_fich->addChild(t_fich);
//Colgamos el fichero del nodo s_fich
SoSeparator *fich=SoDB::readAll (LeeFich);
Toolkits – RVA
s_fich->addChild (fich);
root->addChild (s_fich);
//Colocamos la camara de modo que pueda ver toda la escena
cam->viewAll(fich,viewer->getViewportRegion());
//Cerramos el fichero
LeeFich->closeFile ();
//De este separador colgarán los dragger encargados
//de mover la escena.
SoSeparator *s_drag= new SoSeparator;
//Introducimos una nueva cámara. Esta cámara pintará
//los draggers siempre en la misma posición
SoPerspectiveCamera *o_cam = new SoPerspectiveCamera();
SoDirectionalLight *o_light= new SoDirectionalLight();
o_cam->position = SbVec3f(0, 0, 10);
o_cam->nearDistance=8;
o_cam->farDistance=50;
s_drag->addChild(o_cam);
s_drag->addChild(o_light);
//Colgamos del árbol los draggers que nos permitirán
//modificar la escena
SoSwitch *ss_drag=new SoSwitch ();
SoTrackballDragger *rot_drag= new SoTrackballDragger;
SoTranslate1Dragger *tras_drag = new SoTranslate1Dragger;
ss_drag->addChild(rot_drag);
ss_drag->addChild(tras_drag);
ss_drag->whichChild=0;
s_drag->addChild(ss_drag);
root->addChild(s_drag);
//Creamos un evento asociado con cualquier tecla
SoEventCallback *eventoTeclado =new SoEventCallback;
eventoTeclado->addEventCallback (SoKeyboardEvent::getClassTypeId (),
keyCallBack,
ss_drag);
root->addChild (eventoTeclado);
Toolkits – RVA
//Una vez construida la escena conectamos los draggers
//con la transformación de la escena
SoCalculator *tras_mot = new SoCalculator;
tras_mot->ref();
tras_mot->expression= SbString("oA = A * B[2]/5");
tras_mot->A.connectFrom(&tras_drag->translation);
tras_mot->B.connectFrom(&cam->position);
t_fich->rotation.connectFrom(&rot_drag->rotation);
t_fich->translation.connectFrom(&tras_mot->oA);
//Creamos un sensor encargado del render
SoTimerSensor* rendertimer = new SoTimerSensor(renderCallback,(void
*)viewer);
rendertimer->setInterval(FPS);
rendertimer->schedule();
//Se le indica al visualizador que escena debe renderizar
viewer->setSceneGraph(root);
viewer->setAutoRedraw(FALSE); //Obligamos a que el renderizado sea bajo
peticion
viewer->show ();
//En este bucle se tratan los eventos.
#ifdef WIN32
SoWin::mainLoop();
#else
SoXt::mainLoop();
#endif
// Liberamos los recursos que hemos utilizado
delete viewer;
root->unref();
tras_mot->unref();
return 0;
}
Descargar