example for Infrared channel using multigen's model

New Message Reply Date view Thread view Subject view Author view

Sam Chu (c00chu00++at++nchc.gov.tw)
Tue, 17 Jun 1997 08:37:52 +0800 (CST)


For those who want to implement the Infrared Ray channel using MultiGen's
models may be have a interest in the following codes. The code is used
the program from Performer's Lab exercise as skeleton and added the code
segment from the articles written by Marcus Barnes in The MultiGen Newletter
Vol 3.1, 3.2 and 4.1.
Of course, you need a multigen's model with IR material value. and
compile with libpfflt_[io]go.so under /usr/lib/libpfdb

I still try to figure out how to display texture for some special
objects(trees)using this method. Maybe someone can give me a advise?
thanks.

/*--------------------------------------------------------------
 * irsim.c - Skeleton program for lab exersizes
 * Adding the code segment from the MultiGen Newletter
 * Vol 3-1, 3-2 and 4-1
 */

#include <Performer/pf.h>
#include <Performer/pfui.h>
#include <Performer/pfutil.h>
#include <Performer/pfdu.h>
#include <Performer/pfdb/pfflt.h>

#include <stdlib.h>
#include <stdio.h>

/*==================
 * Types
 *=================*/

typedef struct {
   void *arena;
   pfScene *pScene;
   pfDCS *pSceneDCS; /* DCS for trackball interface */
   pfPipeWindow *pPWindow;
   int winType;
   int inputType;
   pfChannel *pMainChannel;
   pfChannel *pIRChannel;
   float near, far;
   pfCoord startPos;
   pfiTDFXformer *pXformer;
   pfuMouse mouse;
   pfuEventStream events;
   int exitFlag;
   int litFlag;
   int txtFlag;
} SharedState;

/*========================
 * Prototypes
 *========================*/
void setupSharedState(void);
void setupWindow(void);
void openPipeWindowCB(pfPipeWindow *);
void setupSceneGraph(void);
void setupChannel(void);
void initViewPos(void);
void printBBoxSize(pfBox *);
float calcMaxSize(pfBox *);
void setupInputHandling(void);
void updateView(void);
void updateSim(void);
void processKeybdInput(void);
void showHelp(void);
void initInfraredChan(pfChannel *);
void InfraRedMaterials(fltSharedPalette *);
void SetEmissive(pfMaterial *, int);
void drawCB(pfChannel *, void*);
void changeStates(void);

/*=====================
 * Globals
 *====================*/
SharedState *pState;
int notifyLevel = PFNFY_WARN; /* Level of msgs printed */
char title[256];

/*=======================
 * main()
 *=======================*/
int main(int argc, char *argv[])
{
   pfPipe *pPipe;
    

   /****************************************************************
    * Initialize performer and shared info
    ****************************************************************/
   pfInit(); /* Init performer (pf) */
    
   pfNotifyLevel(notifyLevel);
   pState = (SharedState*)pfCalloc(1, sizeof(SharedState), pfGetSharedArena());
   setupSharedState();
   pfMultiprocess(PFMP_APP_CULL_DRAW);

   pfConfig(); /* fork? processes */
    
   pfiInit(); /* Init input processing (pfui) */
   pfuInitUtil(); /* Init utilities (pfutil) */

    
   /*********************************************
    * Set up simulation
    *********************************************/
   sprintf(title, "%s MOUSE: L=accel M=steer R=decel"
           " KEYS: <h> help", argv[0]);

   setupWindow(); /* Create & open a window */
   setupSceneGraph(); /* Build database */
   setupChannel(); /* Set up a view into database */
   setupInputHandling(); /* Prepare to handle input */
   pfChanTravFunc(pState->pMainChannel, PFTRAV_DRAW, drawCB);
   pfChanTravFunc(pState->pIRChannel, PFTRAV_DRAW, drawCB);

    
   /*********************************************
    * Simulation loop
    *********************************************/
   while ( !pState->exitFlag ) {
      updateSim(); /* Handle rest of info */
      pfSync(); /* Wait until next frame */
       
      updateView(); /* Collect time critical info */
      pfFrame(); /* Process/draw the frame */

   }

    
   /********************************************
    * Clean-up
    ********************************************/
   pfuExitUtil();
   pfuExitGUI();
   pfuExitInput();
   pfExit();
    
   return 0;
}

/*===============================
 * Shared Memory Functions
 *===============================*/
void setupSharedState(void)
{
   pState->arena = pfGetSharedArena();
   pState->winType = PFWIN_TYPE_X;
   pState->inputType = PFUINPUT_X;
   pState->near = 0.5f;
   pState->far = 10.0f;
   pState->litFlag = 1;
}

/*=============================
 * Window functions
 *============================*/

void setupWindow(void)
{
   pState->pPWindow = pfNewPWin(pfGetPipe(0));
   pfPWinName(pState->pPWindow, title);
   pfPWinType(pState->pPWindow, pState->winType);
   pfPWinOriginSize(pState->pPWindow, 0, 0, 1000, 800);
   pfPWinConfigFunc(pState->pPWindow, openPipeWindowCB);
   pfConfigPWin(pState->pPWindow);

   pfFrame();
}

/**** openPipeWindow(): callback to create window *********/
void openPipeWindowCB(pfPipeWindow *pw)
{
   pfOpenPWin(pw);
}

/**** Draw Process Callback ******/
void drawCB(pfChannel *chan, void *data)
{

   /* Make GL state changes in draw process */
   changeStates();

   /* You must asked to clear your own framebuffer */
   pfClearChan(chan);

   /* You must ask to draw your scene */
   pfDraw();

   (data);
}

void changeStates(void)
{
   static int lastLitFlag=1;
   static int lastTxtFlag=1;

   if ( pState->litFlag != lastLitFlag ) {
      if ( pState->litFlag ) {
         /* Enable lighting for lit objects */
         pfOverride(PFSTATE_ENLIGHTING, PF_OFF);
         pfEnable(PFEN_LIGHTING);
         printf("Enable lighting\n");
      } else {
         /* Disable lighting for all objects */
         pfOverride(PFSTATE_ENLIGHTING, PF_OFF);
         pfDisable(PFEN_LIGHTING);
         pfOverride(PFSTATE_ENLIGHTING, PF_ON);
         printf("Disable lighting\n");
      }
      lastLitFlag = pState->litFlag;
   }
   if ( pState->txtFlag != lastTxtFlag ) {
      if ( pState->txtFlag ) {
         /* Enable texture for texture objects */
         pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
         pfEnable(PFEN_TEXTURE);
         printf("Enable texture\n");
      } else {
         /* Disable texture for all objects */
         pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
         pfDisable(PFEN_TEXTURE);
         pfOverride(PFSTATE_ENTEXTURE, PF_ON);
         printf("Disable texture\n");
      }
      lastTxtFlag = pState->txtFlag;
   }
}

/*=============================
 * Scene graph functions
 *============================*/

void setupSceneGraph(void)
{
   pfNode *pModelRoot;
   pfLightSource *pSun;
   char *filename;
    
   pfFilePath("."
              ":../data"
              ":../pf_data"
              ":../pf_friends/town/orig/pfmodel"
              ":../pf_friends/town/orig/pftexture"
              ":../pf_friends/town/orig/pftown"
              ":/usr/share/Performer/data"
              ":/usr/share/Performer/friends/town/orig/pfmodel"
              ":/usr/share/Performer/friends/town/orig/pftexture"
              ":/usr/share/Performer/friends/town/orig/pftown"
              );
    
   pState->pScene = pfNewScene();
   pSun = pfNewLSource(); /* Create a light to see by */
   pfAddChild(pState->pScene, pSun);
   pState->pSceneDCS = pfNewDCS();
   pfAddChild(pState->pScene, pState->pSceneDCS);

   pfdConverterMode("flt", PFFLT_GSTATE_TABLES,2); /* IR */
   filename = "m48_ir1.flt";
   if ( (pModelRoot = pfdLoadFile_flt(filename)) == NULL ) {
      pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Failed to read %s\n", filename);
   }
   pfAddChild(pState->pSceneDCS, pModelRoot);

}

/*=============================
 * Channel/view functions
 *============================*/
void setupChannel(void)
{
        pfList *gsList;
        fltSharedPalette *palette;
        fltRenderMap *rendMap;

   
   /*** Create and connect channel to window & scene graph ****/
   pState->pMainChannel = pfNewChan(pfGetPipe(0));
   pfChanScene(pState->pMainChannel, pState->pScene);

   pState->pIRChannel = pfNewChan(pfGetPipe(0));
   pfChanScene(pState->pIRChannel, pState->pScene);

   /**** Set channel's viewing volume and position ****/
   initViewPos();
   pfChanFOV(pState->pMainChannel, 45.0f, -1.0f);
   pfChanViewport(pState->pMainChannel, 0.0f, 0.5f, 0.0f, 1.0f);
   pfChanNearFar(pState->pMainChannel, pState->near, pState->far);
   pfChanView(pState->pMainChannel, pState->startPos.xyz,
              pState->startPos.hpr);

   pfChanFOV(pState->pIRChannel, 45.0f, -1.0f);
   pfChanViewport(pState->pIRChannel, 0.5f, 1.0f, 0.0f, 1.0f);
   pfChanNearFar(pState->pIRChannel, pState->near, pState->far);
   pfChanView(pState->pIRChannel, pState->startPos.xyz,
              pState->startPos.hpr);

   /* for normal and IR Channel's shared object sutup*/
   palette = fltGetCurSharedPalette();
   rendMap = palette->rendMap;
   gsList = pfGet(rendMap->renditions, 0);
   pfChanGStateTable(pState->pMainChannel, gsList);
   gsList = pfGet(rendMap->renditions, 1);
   pfChanGStateTable(pState->pIRChannel, gsList);
   InfraRedMaterials(palette);

}

/**** initViewPos(): calculates starting view position ***********/
void initViewPos(void)
{
   pfBox sceneBBox;
   float goodViewDist;
   pfNode *pModelRoot;

   /**** Find size of scene *****/
   pfuTravCalcBBox(pState->pScene, &sceneBBox);
   printBBoxSize(&sceneBBox);

   /**** Calculate center of database ********/
   pfAddVec3(pState->startPos.xyz, sceneBBox.min, sceneBBox.max);
   pfScaleVec3(pState->startPos.xyz, 0.5f, pState->startPos.xyz);

   /**** Pull back for good view ****/
   goodViewDist = 1.3 * calcMaxSize(&sceneBBox);
   pState->far = 3.8 * goodViewDist;
   pState->startPos.xyz[PF_Y] -= goodViewDist;

   /**** Set direction of view ****/
   pfSetVec3(pState->startPos.hpr, 0.0f, 0.0f, 0.0f);
}

void printBBoxSize(pfBox *pb) /* Prints box size for debugging */
{
   pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "Bounding box of object is:\n");
   pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\tAxis: Minimum\tMaximum\n");
   pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t-------------------------\n");
   pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t X: %8.2f\t%8.2f\n",
            pb->min[PF_X], pb->max[PF_X]);
   pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t Y: %8.2f\t%8.2f\n",
            pb->min[PF_Y], pb->max[PF_Y]);
   pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\t\t Z: %8.2f\t%8.2f\n",
            pb->min[PF_Z], pb->max[PF_Z]);
   pfNotify(PFNFY_NOTICE, PFNFY_MORE, "\n");
}

float calcMaxSize(pfBox *pb) /**** calc length of longest dim ****/
{
   float result;
    
   result = pb->max[PF_X] - pb->min[PF_X];
   result = PF_MAX2(result, pb->max[PF_Y] - pb->min[PF_Y]);
   result = PF_MAX2(result, pb->max[PF_Z] - pb->min[PF_Z]);

   return result;
}

/*=====================================
 * Simulation/input functions
 *=====================================*/

void setupInputHandling(void)
{
   /**** Set the type of input processing. X or GL? ****/
   pfuInitInput(pState->pPWindow, pState->inputType);

   /**** Create a transformer ****/
   pState->pXformer = (pfiXformer *)pfiNewTDFXformer(pfGetSharedArena());

   /**** Set initial and reset position for xformer ****/
   pfiXformerCoord(pState->pXformer, &pState->startPos);

   /**** Xformer will get its input from buffers mouse & events ****/
   pfiXformerAutoInput(pState->pXformer, pState->pMainChannel,
                       &pState->mouse, &pState->events);
   pfiXformerNode(pState->pXformer, pState->pScene);
   pfiXformerResetCoord(pState->pXformer, &pState->startPos);

   /**** Xformer's results automatically change channels position ****/
   pfiXformerAutoPosition(pState->pXformer, pState->pMainChannel, pState->pSceneDCS);

   /**** Use TRACKBALL model ****/
   pfiSelectXformerModel(pState->pXformer, PFITDF_TRACKBALL);
}

void updateView(void) /**** Time sensitive updates ****/
{
   pfCoord view;
   
   pfuGetMouse(&pState->mouse); /* Record mouse position */
   pfiUpdateXformer(pState->pXformer); /* Update Xformer */
   pfiGetIXformCoord(pState->pXformer, &view);
   pfChanView(pState->pIRChannel, view.xyz, view.hpr);
}

void updateSim(void) /**** Costlier updates ****/
{
   pfuGetEvents(&pState->events); /* Read keyboard events */
   processKeybdInput(); /* Process these events */
}

void processKeybdInput(void)
{
   int i, j;
   int key, dev, val, numDevs;
   pfuEventStream *pEvents;

   pEvents = &pState->events;
   numDevs = pEvents->numDevs;

   for ( j=0; j < numDevs; ++j) {
      dev = pEvents->devQ[j];
      val = pEvents->devVal[j];

      if ( pEvents->devCount[dev] > 0 ) {
         switch ( dev ) {
             
          case PFUDEV_REDRAW:
            pEvents->devCount[dev] = 0;
            break;

          case PFUDEV_WINQUIT:
            pState->exitFlag = 1;
            pEvents->devCount[dev] = 0;
            break;

          case PFUDEV_KEYBD:
            for ( i=0; i < pEvents->numKeys; ++i ) {
                
               key = pEvents->keyQ[i];
               if ( pEvents->keyCount[key] ) {

                  switch ( key ) {
                   case 27: /* ESC key. Exits prog */
                     pState->exitFlag = 1;
                     break;

                   case 'R':
                   case 'r': /* Reset position */
                     pfiStopXformer(pState->pXformer);
                     pfiResetXformerPosition(pState->pXformer);
                     break;

                   case 'H':
                   case 'h':
                     showHelp();
                     break;

                   case 'L':
                   case 'l':
                     pState->litFlag = !pState->litFlag;
                     break;

                   case 'T':
                   case 't':
                     pState->txtFlag = !pState->txtFlag;
                     break;
                      
                   default:
                     break;
                  }
               }
            }
            pEvents->devCount[dev] = 0;
            break;
             
          default:
            break;
         }
      }
   }
   pEvents->numKeys = 0;
   pEvents->numDevs = 0;
}

void showHelp(void)
{
   system("xconfirm "
          " -h Help"
          " -icon info"
          " -t \"Esc Quit\""
          " -t \"r/R Reset position\""
          " -t \"h/H Help\""
          " -font \"-*-screen-bold-r-*-*-15-*-*-*-*-*-*-*\""
          " > /dev/null &");
}

static void
SetEmissive(pfMaterial *mtl, int keyValue)
{
        float red = 0.0f;
        float gre = 0.0f;
        float blu = 0.0f;

        printf("(SetEmissive) keyValue = %d\n", keyValue);
        switch (keyValue) { /* face IR Material index */
                case 1: /* white hot */
                        red = 1.0f;
                        gre = 1.0f;
                        blu = 1.0f;
                        break;
                case 2: /* red warm */
                        red = 0.7f;
                        gre = 0.1f;
                        blu = 0.1f;
                        break;
                case 3: /* blue cool */
                        red = 0.1f;
                        gre = 0.1f;
                        blu = 0.5f;
                        break;
                case 4: /* dark grey cold */
                        red = 0.1f;
                        gre = 0.1f;
                        blu = 0.1f;
                        break;
                case 100: /* Tank ir color */
                        red = 0.0f;
                        gre = 0.7f;
                        blu = 0.2f;
                        break;
                case 101: /* Tank ir color */
                        red = 0.8f;
                        gre = 0.3f;
                        blu = 0.4f;
                        break;
        }
        pfMtlColor(mtl, PFMTL_EMISSION, red, gre, blu);
}

static void
InfraRedMaterials(fltSharedPalette *palette)
{
        pfList *matList = palette->matList;
        int howMany = pfGetNum(matList);
        int which;

        for (which = 0; which < howMany; ++which) {
                fltSharedObj *obj = pfGet(matList, which);
                printf("which=%d\n", which);
                if (obj->key.attr == FLTA_IRMATERIAL) {
                        /*material mode is PFMTL_CMODE_COLOR */
                        pfMaterial *mtl = (pfMaterial *)obj->object;
                        SetEmissive(mtl, obj->key.value);
                }
        }
}
Sam Chu
National Center for High-Performance Computing
Scientific Visualization Lab Email: c00chu00++at++nchc.gov.tw
Tel: (886)35-776085 Ext 248 Fax : (886)35-773538
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
            Submissions: info-performer++at++sgi.com
        Admin. requests: info-performer-request++at++sgi.com


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:55:27 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.