view Renderer/Test/viewer_2.cc @ 1292:90efd2aac2cb draft

add matrix test and debug light vector
author Yutaka_Kinjyo <yutaka@cr.ie.u-ryukyu.ac.jp>
date Fri, 02 Dec 2011 12:27:51 +0900
parents d95b10b711ad
children
line wrap: on
line source

/*
  viewer.cc を、xmlファイルのsurface nameをわざわざ書き出さなくても
  良いように改良しました。
  ただxmlファイル内のsurface name行をプログラム内で抜き出せるようにしただけ

  使い方:
  ./viewer_2 -sg (読み込みたいxmlファイル名)
  
*/
#include <math.h>
#include <stdlib.h>
#include "SceneGraphRoot.h"
#include "MainLoop.h"
#include "viewer.h"

// prototype
static void object_move_rotation(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h);
static void object_collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree);
static void object_move_translation(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h);

/*
  getStrFromFile関数
  指定したテキストファイル内から,
  ある文字列(searchStartStr)とある文字列(searchEndStr)の間の文字列を抜き出す.
  抜き出した文字列の数を返す.
  char **date に抜き出した文字列を二次元配列のポインタを渡す.
  中でmallocしてるから、使い終わったら free(date)しないとダメかも
  reallocとかでfree()しなくて良い方法も教えて下さい.
*/
static int getStrFromFile( char **date, const char *fname, const char *searchStartStr, const char *searchEndStr );

int light_sysswitch = 1;
int light_num = 4;

void LightSysSwitch(Viewer *sgroot) {
  if (light_sysswitch == 1) {
    sgroot->OnLightSysSwitch();
  } else if (light_sysswitch == 0) {
    sgroot->OffLightSysSwitch();
  }
}


static void
object_move_rotation(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
{
  SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_;
  Pad *pad = sgroot->getController();
  if (pad->circle.isPush()) {
    node->set_move_collision(object_move_translation, object_collision);
  }
  if (pad->left.isHold()) {
    node->angle[1] += 10;
  } else if (pad->right.isHold()) {
    node->angle[1] -= 10;
  }
  if (pad->up.isHold()) {
    node->angle[0] += 10;
  } else if (pad->down.isHold()) {
    node->angle[0] -= 10;
  }
}

static void
object_move_translation(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
{
  SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_;
  Pad *pad = sgroot->getController();

  if (pad->circle.isPush()) {
    node->set_move_collision(object_move_rotation, object_collision);
  }

  if (pad->left.isHold()) {
    node->xyz[0] -= 10;
  } else if (pad->right.isHold()) {
    node->xyz[0] += 10;
  }
  if (pad->up.isHold()) {
    node->xyz[1] -= 10;
  } else if (pad->down.isHold()) {
    node->xyz[1] += 10;
  }
}


static void
object_collision(SceneGraphPtr node, void *sgroot_, int screen_w, 
	       int screen_h,  SceneGraphPtr tree)
{
//     if (node->xyz[1] > screen_h - object_radius) {
// 		node->xyz[1] = screen_h - object_radius;

// 		vy *= e;
// 		if (vy > -g && vy < 0) {
// 			vy = 0.0;
// 			node->set_move_collision(object_move_idle, object_collision_idle);
// 		}
//     }
}

char *xmlfile;
#define MAX_ROOT 100
char *parts[MAX_ROOT ];
int parts_cnt;

MainLoopPtr 
viewer::init(Viewer *sgroot, int screen_w, int screen_h)
{

  LightSysSwitch(sgroot);

  SceneGraphPtr object;

  for (int i = 0; i < light_num; i++) {
    SceneGraphPtr light = sgroot->getLight(i);
    sgroot->OnLightSwitch(i);
    light->xyz[0] = screen_w / 2;
    light->xyz[1] = screen_h / 2;
    light->xyz[2] = 100;
  }

  // 固定した値で srandom すると、毎回同じ、random() 列が生成される
  // random な値が欲しいなら、man random に方法が書いてあります。
  srandom(100);

  object = sgroot->createSceneGraph();
  object->set_move_collision(object_move_rotation, object_collision);

  object->xyz[0] = screen_w/2;
  object->xyz[1] = screen_h/2;
  object->xyz[2] = 30.0f;

  
  // [128]ってのは取得する文字列の十分な大きさ。
  char *getStrDate[128];
  
  char	*fn   = xmlfile;           // 読み込みたいテキストファイル     
  const char	*sStr = "surface name=\""; // この文字列の直後の文字列を取得する
  const char	*eStr = "\" size=";	   // この文字列の直前までの文字列を抜き取る

  sgroot->createFromXMLfile(fn);

  if (parts_cnt>0) {
      for( int i = 0; i < parts_cnt; i ++ ){
	object->addChild( sgroot->createSceneGraph( parts[i] ) );
      }
      sgroot->setSceneData(object);
  } else {
      int num = getStrFromFile( getStrDate, fn, sStr, eStr );

      for( int i = 0; i < num; i ++ ){
	object->addChild( sgroot->createSceneGraph( getStrDate[i] ) );
      }
      sgroot->setSceneData(object);

      for( int i = 0; i < num; i ++ ){
	free(  getStrDate[i]  );
      }

  }
  

  return sgroot;
}

extern Application *
application() {
    return new viewer();
}

const char *usr_help_str = "Usage: ./test_nogl [OPTION]\n";

extern int init(TaskManager *manager, int argc, char *argv[]);
extern void task_initialize();
static void TMend(TaskManager *manager);

int
TMmain(TaskManager *manager, int argc, char *argv[])
{
  task_initialize();
  manager->set_TMend(TMend);


  for(int i=0;i<argc;i++) {
    if (strcmp(argv[i],"-sg") == 0 && i+1<=argc) {
      xmlfile = argv[i+1];
    }
    else if (strcmp(argv[i],"-name") == 0 && i+1<=argc) {
      parts[parts_cnt++] = argv[i+1];
    }
    else if (strcmp(argv[i],"-lightsys") == 0 && i+1<=argc) {
      if (strcmp(argv[i],"on") == 0) {
	light_sysswitch = 1;
      } else if (strcmp(argv[i],"off") == 0) {
	light_sysswitch = 0;
      }
    } else if (strcmp(argv[i],"-lightnum") == 0 && i+1<=argc) {
      light_num = atoi(argv[i+1]);
    }
  }
  return init(manager, argc, argv);

}

void
TMend(TaskManager *manager)
{
    printf("test_nogl end\n");
}


int getStrFromFile( char **getStrDate, const char *fname, const char *searchStartStr, const char *searchEndStr )
{
  const int BUFSIZE = 256;

  // [100]ってのは取得する文字列の十分な大きさ。
  // ここも動的に確保したいケド、良い方法がわからん。
  //  char *getStrDate[100]; 
  int num = 0;

  FILE *fp;
  //  const char *fname = "xml_file/car/kart_cp.xml"; // 読み込みたいファイル名

  char buf[BUFSIZE]; // 一行読み込み
  //const char *searchStartStr = "surface name=\""; // この文字列の直後の文字列を取得する
  //const char *searchEndStr = "\" size="; // この文字列の直前までの文字列を抜き取る

  fp = fopen( fname, "r" );
  if ( fp ==NULL ){
    printf("fileNameError\n");
    return 0;
  }

  // ファイルの終端まで一行読み込みをループする
  while( feof(fp) == 0 ){

    fgets( buf, BUFSIZE, fp );

    char *p1 = strstr( buf, searchStartStr ); // 文字列検索。
                                              // 見つけた位置のポインタを返す
                                              // 見つけれなかったらNULLを返す

    if( p1 != NULL ){
      int p1Len = strlen(p1);
      char *p2 = strstr( p1, searchEndStr );
      int p2Len = strlen(p2); //

      // 余分なsearchEndStr以降の文字列を切り捨てるため空白文字(改行文字だっけ?'\0'ってなんだっけ)
      p1[p1Len - p2Len] = '\0'; 

      int searchStartStrLen = strlen(searchStartStr);
      
      // +searchStartStrLenで最初の余分な文字列をカウントしないようにする
      int lenNum = strlen(p1 + searchStartStrLen);

      // 動的にメモリ確保したい。なんかオカしいってのはわかるケド、良い方法が思いつかん
      getStrDate[num] =  (char*)malloc(sizeof(char)*lenNum);
      
      strcpy(getStrDate[num], p1+searchStartStrLen); 

      num ++;
    }
  }

  fclose( fp );

  // 確認:抜き出した文字列の数
  printf("num = %d\n",num);

  // 確認:抜き出した文字列
  for( int i = 0; i < num; i ++ ){
    printf("getStrDate[%d] = %s\n", i, getStrDate[i]);
  }

  return num;
}

/* end */