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

#include "VidAv.h"

#define SPEED 5.0f
#define VA_SPEED 0.10f
#define RADtoDEG (180/M_PI)


/*****  LocalVidAv is used to reference the local video avatar     ****/
/*****  Xpos, Ypos, Zpos, Yrot are position and rotation variables ****/
/*****			       for the local video avatar          ****/
/*****  LocalVidAvDir & LocalVidAvBase are used when initializing  ****/
/*****			       the local video avatar              ****/
 
int LocalVidAv; 
float Xpos, Ypos, Zpos, Yrot;

char LocalVidAvDir[256], LocalVidAvBase[256];

void updateVidAvPOS(float prevtime); /*** user-defined function which ***/
			             /*** calculates local avatar     ***/
				     /*** position		      ***/
void ogl_init_fn(void);
void drawframe(void);
void update_funct(void);

void drawplane();  
void drawrow();  
void drawfloor();  
void navigate(void);


 
void main(int argc,char **argv)
{
   
   va_PreInit();   /*** does avatar initialization, must be   ****/
		   /*** called before CAVEInit();             ****/
   
   /***  va_InitLocalAvatar initializes the local avatar, must ****/
   /***  be called after va_PreInit(); and before CAVEInit();  ****/
   
   sprintf(LocalVidAvDir, "%s", "/nfs/avatars");
   sprintf(LocalVidAvBase, "%s", "joe2");
   LocalVidAv=va_InitLocalAvatar(LocalVidAvDir, LocalVidAvBase);
   
   CAVEInit();
   CAVEInitApplication(ogl_init_fn,0);
   CAVEDisplay(drawframe,0);
   CAVEFrameFunction(update_funct, 0);
 
   while(!CAVEgetbutton(CAVE_ESCKEY))
    {
      navigate();
      sginap(1);  /* Make this loop run about 100 iterations/second */
    }
   CAVEExit();
}


/* initialize the graphics  */
void ogl_init_fn()
{
    
    glClearColor(0.0, 0.0, 0.0, 0.0);
   
    /***  va_InitTex initializes avatar's texture mapping  ***/
    
    va_InitTex();
    
    /***  this next call is the only difference between the local avatars   ***/
    /***  only version and the version that has both local and remote       ***/
    /***  avatars.  technically it isn't even really needed.  if networking ***/
    /***  is not enabled (in your .caverc) then remote avatars will not be  ***/
    /***  used, but if networking is enabled, this call will prevent them   ***/
    /***  from being updated and drawn.  but if networking is enabled, be   ***/
    /***  aware that remote avatars will still be loaded.                   ***/

    va_DisableRemoteAvatars();
   
}

            
void drawframe(void)
{
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);  
  
  glPushMatrix();
    CAVENavTransform();
  
      drawfloor();
	  
      va_DrawAllAvatars();  /*** draws all enabled avatars ***/
	  
  glPopMatrix(); 
  

}


void update_funct(void)
{
    static int OnFlag=1, UpdateFlag=1;
    float t=*CAVETime;
    static float prevtime=*CAVETime;
    static Button1Val, Button2Val, Button3Val;
    static float LocalAvatarScale=1.0;
    
   if (CAVEBUTTON1 && (CAVEBUTTON1!=Button1Val)) printf("Local avatars are enabled: %d\n", va_LocalAvatarIsEnabled(LocalVidAv));
   
   if (CAVEBUTTON2 && (CAVEBUTTON2!=Button2Val)) 
    {
	OnFlag=(OnFlag+1)%2;
	printf("OnFlag: %d\n", OnFlag);
	if (OnFlag) va_EnableLocalAvatar(LocalVidAv);
	else va_DisableLocalAvatar(LocalVidAv);
    }
    
    if (CAVEBUTTON3 && (CAVEBUTTON3!=Button3Val)) 
    {
	UpdateFlag=(UpdateFlag+1)%2;
	printf("UpdateFlag: %d\n", UpdateFlag);
    }
    
    Button1Val=CAVEBUTTON1;
    Button2Val=CAVEBUTTON2;
    Button3Val=CAVEBUTTON3;
    
    /*** if the specified local avatar has been loaded, is enabled ***/
    /*** and UpdateFlag is true, the user-defined function is      ***/
    /*** called and va_UpdateLocalAvatar updates the specified     ***/
    /*** avatar with its new position, etc.			   ***/
    /*** even if the avatar's position hasn't changed, the user's  ***/
    /*** position may have, so va_UpdateLocalAvatar should be     ***/
    /*** called whenever the avatar is enabled			   ***/

    if (CAVEgetbutton(CAVE_MINUSKEY)) 
    {
	LocalAvatarScale-=.1;
	if (LocalAvatarScale<0.0) LocalAvatarScale=0.0;
	va_SetLocalAvatarScale(LocalVidAv, LocalAvatarScale);
    }
    
    if (CAVEgetbutton(CAVE_EQUALKEY)) 
    {
	LocalAvatarScale+=.1;
	va_SetLocalAvatarScale(LocalVidAv, LocalAvatarScale);
    }
    
    if (va_LocalAvatarIsLoaded(LocalVidAv) && va_LocalAvatarIsEnabled(LocalVidAv) )
    {
      if(UpdateFlag) updateVidAvPOS(prevtime);
      va_UpdateLocalAvatar(LocalVidAv, Xpos, Ypos, Zpos, Yrot);
    }

    /*** va_UpdateAllAvatars updates all avatars appropriately ***/
    
    va_UpdateAllAvatars();
    
    prevtime=t;
}


void updateVidAvPOS(float prevtime)
{
    static float theta=0.0;
    float R=8.0;
    float dt,t;

    t = *CAVETime;
    dt = t - prevtime;
    
    Xpos= cos(theta) * R;
    Zpos=-sin(theta) * R;
    Yrot=(theta*RADtoDEG);
    theta+= VA_SPEED * dt;
    if (theta> (2*M_PI)) theta-=(2*M_PI);
    
}


void navigate(void)
{
    float jx=CAVE_JOYSTICK_X,jy=CAVE_JOYSTICK_Y,dt,t;
    static float prevtime = 0;
    t = *CAVETime;
    dt = t - prevtime;
    prevtime = t;
    if (fabs(jy)>0.2)
    {
    float wandFront[3];
    CAVEGetVector(CAVE_WAND_FRONT,wandFront);
    CAVENavTranslate(wandFront[0]*jy*SPEED*dt, 0.0,
		    wandFront[2]*jy*SPEED*dt);
    }
    if (fabs(jx)>0.2)
	CAVENavRot(-jx*90.0f*dt,'y');
}


void drawplane()
{
	
   const  float	point1[3] = {-0.5, 0., -0.5};
   const  float	point2[3] = {0.5, 0., -0.5}; 
   const  float	point3[3] = {0.5, 0., 0.5};
   const  float	point4[3] = {-0.5, 0., 0.5}; 

   const  float normal[3] = {0., 1., 0}; 

   glBegin(GL_POLYGON);
     glNormal3fv(normal); 
     glVertex3fv(point4);
     glNormal3fv(normal); 
     glVertex3fv(point3);
     glNormal3fv(normal);
     glVertex3fv(point2);
     glNormal3fv(normal);
     glVertex3fv(point1);
   glEnd();
   				
}

void drawrow(void)
{
     glPushMatrix();
	glColor4f(1,0,0, 1);
	glTranslatef(-15, 0, 0);
	glScalef(10, 1., 10);
	drawplane();
    glPopMatrix();
    glPushMatrix();
	glColor4f(0,1,0, 1);
	glTranslatef(-5, 0, 0);
	glScalef(10, 1., 10);
	drawplane();
    glPopMatrix();
    glPushMatrix();
	glColor4f(0,0,1, 1);
	glTranslatef(5, 0, 0);
	glScalef(10, 1., 10);
	drawplane();
    glPopMatrix();
    glPushMatrix();
	glColor4f(1,1,0, 1);
	glTranslatef(15, 0, 0);
	glScalef(10, 1., 10);
	drawplane();
    glPopMatrix();   
}

void drawfloor(void)
{
      glPushMatrix();
	glTranslatef(0, 0, -15); 
	drawrow(); 
      glPopMatrix();
      glPushMatrix();
	glTranslatef(0, 0, -5);
	glRotatef(180, 0, 1, 0); 
	drawrow(); 
      glPopMatrix();
      glPushMatrix();
	glTranslatef(0, 0, 5); 
	drawrow(); 
      glPopMatrix();
      glPushMatrix();
	glTranslatef(0, 0, 15); 
	glRotatef(180, 0, 1, 0);
	drawrow(); 
      glPopMatrix();
}


Back to VideoAvatar