diff old/simple_render/polygon.cpp @ 507:735f76483bb2

Reorganization..
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 12 Oct 2009 09:39:35 +0900
parents TaskManager/Test/simple_render/polygon.cpp@5c194c71eca8
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/old/simple_render/polygon.cpp	Mon Oct 12 09:39:35 2009 +0900
@@ -0,0 +1,954 @@
+#include <iostream>
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include <SDL_image.h>
+#include <libxml/parser.h>
+#include "polygon.h"
+#include "xml.h"
+#include "texture.h"
+#include "sys.h"
+#include "triangle.h"
+#include "vertex.h"
+#include "Span.h"
+#include "SpanC.h"
+#include "scene_graph_pack.h"
+using namespace std;
+
+//extern int decode(char *cont, char *file_name);
+extern int decode(char *cont, FILE *outfile);
+
+
+SDL_Surface* Polygon::texture_image;
+
+Polygon::Polygon()
+{
+  xyz[0] = 0;
+  xyz[1] = 0;
+  xyz[2] = 0;
+  xyz[3] = 1;
+  c_xyz[0] = 0;
+  c_xyz[1] = 0;
+  c_xyz[2] = 0;
+  c_xyz[3] = 1;
+  angle[0] = 0;
+  angle[1] = 0;
+  angle[2] = 0;
+  angle[3] = 1;
+  next = NULL;
+  child = NULL;
+  parent = NULL;
+  brother = NULL;
+  children = NULL;
+  lastChild = NULL;
+}
+
+
+
+void Polygon::tree_check()
+{
+  Polygon *t;
+  t = this;
+
+  while(t)
+    {
+      cout << "my_name : " << t->name << endl;
+      if(t->child != NULL)
+	{
+	  cout << "--move child : " << t->child->name << endl;
+	  t = t->child;
+	}
+      else if(t->brother != NULL)
+	{
+	  cout << "--move brother : " << t->brother->name << endl;
+	  t = t->brother;
+	}
+      else
+	{
+	  while(t)
+	    {
+	      if(t->brother != NULL)
+		{
+		  cout << "--move brother : " << t->brother->name << endl;
+		  t = t->brother;
+		  break;
+		}
+	      else
+		{
+		  if(t->parent)
+		    {
+		      cout << "--move parent : " << t->parent->name << endl;
+		    }
+		  t = t->parent;
+		}
+	    }
+	}
+    }
+}
+
+void Polygon::print_member()
+{
+  //int n;
+
+  cout << "size = " << size << endl;
+  cout << "name = " << name << endl;
+  cout << "parent_name = " << parent_name << endl;
+  /*
+  for(n=0; n<size*3; n+=3)
+    {
+      cout<<"coordinate = "<<data[n]<<" "<<data[n+1]<<" "<< data[n+2]<<endl;
+    }
+  */
+  /*
+  for(n=size*3; n<size*6; n+=3)
+    {
+      cout<<"narmal = "<<data[n]<<" "<<data[n+1]<<" "<<data[n+2]<<endl;
+    }
+  */
+  cout<<"c_xyz = "<<c_xyz[0]<<" "<<c_xyz[1]<<" "<<c_xyz[2]<<endl;
+  /*
+  for(n=size*6; n<size*9; n+=3)
+    {
+      cout<<"texture = "<<data[n]<<" "<<data[n+1]<<" "<<data[n+2]<<endl;
+    }
+  */
+  /*
+  for(n=0; n<size*3; n+=3)
+    {
+      cout<<"coordinate = "<<data[n]<<" "<<data[n+1]<<" "<<data[n+2]<<endl;
+      cout<<"normal = "<<data[n+size*3]<<" "<<data[n+size*3+1]<<" "<<data[n+size*3+2]<<endl;
+      cout<<"texture = "<<data[n+size*6]<<" "<<1-data[n+size*6+1]<<endl;
+    }
+  */
+  //cout << "image_name = " << image_name << endl;
+  if(parent != NULL)
+    {
+      cout << "parent->name = " << parent->name << endl;
+    }
+  if(child != NULL)
+    {
+      cout << "child->name = " << child->name << endl;
+    }
+}
+
+void Polygon::draw(SceneGraphPack *sgp)
+{
+  float xyz1[4],xyz2[4],xyz3[4];
+
+  /***SceneGraphUpdate***/
+  //sgp_update();
+  for (int i = 0; i < sgp->info.size; i++) {
+    SceneGraphNode node = sgp->node[i];
+
+    /***draw***/
+    int n,nt;
+    for(n=0,nt=0; n<node.size*3; n+=9,nt+=6) {
+      xyz1[0] = node.vertex[n];
+      xyz1[1] = node.vertex[n+1];
+      xyz1[2] = node.vertex[n+2]*-1;
+      xyz1[3] = 1;
+      xyz2[0] = node.vertex[n+3];
+      xyz2[1] = node.vertex[n+3+1];
+      xyz2[2] = node.vertex[n+3+2]*-1;
+      xyz2[3] = 1;
+      xyz3[0] = node.vertex[n+6];
+      xyz3[1] = node.vertex[n+6+1];
+      xyz3[2] = node.vertex[n+6+2]*-1;
+      xyz3[3] = 1;
+
+      rotate(xyz1, node.translation);
+      rotate(xyz2, node.translation);
+      rotate(xyz3, node.translation);
+
+      Vertex *ver1 = new Vertex(xyz1[0],xyz1[1],xyz1[2],node.texture[nt],node.texture[nt+1]);
+      Vertex *ver2 = new Vertex(xyz2[0],xyz2[1],xyz2[2],node.texture[nt+2],node.texture[nt+2+1]);
+      Vertex *ver3 = new Vertex(xyz3[0],xyz3[1],xyz3[2],node.texture[nt+4],node.texture[nt+4+1]);
+
+      Triangle *tri = new Triangle(ver1,ver2,ver3);
+      Span_c *span = new Span_c();
+      span->viewer = viewer;
+      span->p = this;
+      span->create_span(tri,texture_image);
+      delete ver1;
+      delete ver2;
+      delete ver3;
+      delete tri;
+      delete span;
+    }
+  }
+}
+
+
+void Polygon::draw(PolygonPack *pp)
+{
+  for(int n=0; n<pp->info.size; n++)
+    {
+      Vertex *ver1 = new Vertex(pp->tri[n].ver1.x,pp->tri[n].ver1.y,pp->tri[n].ver1.z,pp->tri[n].ver1.tex_x,pp->tri[n].ver1.tex_y);
+      Vertex *ver2 = new Vertex(pp->tri[n].ver2.x,pp->tri[n].ver2.y,pp->tri[n].ver2.z,pp->tri[n].ver2.tex_x,pp->tri[n].ver2.tex_y);
+      Vertex *ver3 = new Vertex(pp->tri[n].ver3.x,pp->tri[n].ver3.y,pp->tri[n].ver3.z,pp->tri[n].ver3.tex_x,pp->tri[n].ver3.tex_y);
+
+      Triangle *tri = new Triangle(ver1,ver2,ver3);
+      Span_c *span = new Span_c();
+      span->viewer = viewer;
+      span->p = this;
+      span->create_span(tri,texture_image);
+      delete ver1;
+      delete ver2;
+      delete ver3;
+      delete tri;
+      delete span;
+    }
+}
+
+void Polygon::draw(SpanPack *sp)
+{
+    Span *span;
+
+    for (int n = 0; n < sp->info.size; n++) {
+	span = &sp->span[n];
+
+	int x = span->x;
+	int y = span->y;
+	float z = span->start_z;
+	int end = span->length_x;
+	float zpos = span->end_z;
+	float tex1 = span->tex_x1;
+	float tex2 = span->tex_x2;
+	float tey1 = span->tex_y1;
+	float tey2 = span->tex_y2;
+	Uint32 rgb;
+	int tex_xpos;
+	int tex_ypos;
+	int tex_zpos;
+	float tex_x, tex_y, tex_z;
+
+	if (end == 1) {
+	    tex_xpos = (int)((span->tex_height-1) * tex1);
+	    tex_ypos = (int)((span->tex_width-1) * tey1);
+	    tex_zpos = (int)z;
+	    rgb = get_rgb(tex_xpos, tex_ypos);
+	    viewer->write_pixel(x, y, zpos, rgb);
+	} else {
+	    for (int j = 0; j < end; j++) {
+		tex_x = tex1*(end-1-j)/(end-1) + tex2*j/(end-1);
+		tex_y = tey1*(end-1-j)/(end-1) + tey2*j/(end-1);
+		tex_z = z*(end-1-j)/(end-1) + zpos*j/(end-1);
+		if (tex_x > 1) tex_x = 1;
+		if (tex_y > 1) tex_y = 1;
+		tex_xpos = (int)((span->tex_height-1) * tex_x);
+		tex_ypos = (int)((span->tex_width-1) * tex_y);
+		rgb = get_rgb(tex_xpos,tex_ypos);
+		viewer->write_pixel(j + x, y, tex_z, rgb);
+	    }
+	}
+    }
+}
+
+void
+Polygon::draw(SpanPackList *ss)
+{
+    SpanPack *spanPack;
+    Span *span;
+
+    //for (int i = 0; i < ss->length; i++) {
+    for (int i = 0; i < 10; i++) {
+	spanPack = &ss->packs[i];
+
+	for(int n = 0; n < spanPack->info.size; n++) {
+	    span = &spanPack->span[n];
+
+	    int end    = span->length_x;
+	    Uint32 rgb;
+	    float tex1 = span->tex_x1;
+	    float tex2 = span->tex_x2;
+	    float tey1 = span->tex_y1;
+	    float tey2 = span->tex_y2;
+	    int tex_xpos;
+	    int tex_ypos;
+	    int tex_zpos;
+	    int x = span->x;
+	    int y = span->y;
+	    float z = span->start_z;
+	    float zpos = span->end_z;
+	    float tex_x,tex_y,tex_z;
+      
+	    if(end == 1) {
+		//printf("end == 1\n");
+		//printf("tex_x:%f tex_y:%f\n",tex1,tex2);
+		//if(tex1 > 1) tex1 = 1;
+		//if(tey1 > 1) tey1 = 1;
+		tex_xpos = (int)((span->tex_height-1) * tex1);
+		tex_ypos = (int)((span->tex_width-1) * tey1);
+		tex_zpos = (int)z;
+		//printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);
+		//printf("image->h:%d tex_x:%f\n",(int)span->tex_height,tex1);
+		rgb = get_rgb(tex_xpos,tex_ypos);
+		viewer->write_pixel(x,y,zpos,rgb);
+	    }else {
+		//printf("end != 1\n");
+		for(int j = 0; j < end; j++) {
+		    tex_x = tex1*(end-1-j)/(end-1) + tex2*j/(end-1);
+		    tex_y = tey1*(end-1-j)/(end-1) + tey2*j/(end-1);
+		    tex_z = z*(end-1-j)/(end-1) + zpos*j/(end-1);
+		    if(tex_x > 1) tex_x = 1;
+		    if(tex_y > 1) tex_y = 1;
+		    tex_xpos = (int)((span->tex_height-1) * tex_x);
+		    tex_ypos = (int)((span->tex_width-1) * tex_y);
+		    //printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);
+		    //printf("z:%f zpos:%f tex_z:%f\n",z,zpos,tex_z);
+		    //printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+		    rgb = get_rgb(tex_xpos,tex_ypos);
+		    viewer->write_pixel(j+x,y,tex_z,rgb);
+		}
+	    }
+	}
+    }
+}
+
+
+/*
+void Polygon::create_scene_graph_pack()
+{
+  //SceneGraphPack *sgp = new SceneGraphPack;
+  sgp = new SceneGraphPack;
+  int i = 0;
+  int nnpn = -1;
+
+  Polygon *t;
+  t = this;
+
+  while(t)
+    {
+      //SceneGraphNode node;
+      sgp->node[i].size = t->size;
+      int d,tex;
+      for(d=0,tex=0; d<t->size*3; d+=3,tex+=2)
+	{
+	  sgp->node[i].vertex[d] = t->data[d];
+	  sgp->node[i].vertex[d+1] = t->data[d+1];
+	  sgp->node[i].vertex[d+2] = t->data[d+2];
+	  sgp->node[i].texture[tex] = t->data[d+t->size*6];
+	  sgp->node[i].texture[tex+1] = t->data[d+t->size*6+1];
+	}
+
+      sgp->node[i].obj_pos[0] = 0;
+      sgp->node[i].obj_pos[1] = 0;
+      sgp->node[i].obj_pos[2] = 0;
+      sgp->node[i].obj_pos[3] = 1;
+      sgp->node[i].angle[0] = 0;
+      sgp->node[i].angle[1] = 0;
+      sgp->node[i].angle[2] = 0;
+      sgp->node[i].angle[3] = 1;
+
+      for(int tm=0; tm<16; tm++)
+        {
+          sgp->node[i].translation[tm] = 0;
+        }
+      sgp->node[i].id = 0;
+      sgp->node[i].move = 0;
+      sgp->node[i].interaction = 0;
+      sgp->node[i].pn = nnpn;
+
+      if(t->child != NULL)
+	{
+	  nnpn = i;
+	  t = t->child;
+	}
+      else if(t->brother != NULL)
+	{
+	  nnpn = sgp->node[i].pn;
+	  t = t->brother;
+	}
+      else
+	{
+	  while(t)
+	    {
+	      if(t->brother != NULL)
+		{
+		  t = t->brother;
+		  break;
+		}
+	      else
+		{
+		  if(t->parent == NULL)
+		    {
+		      t = NULL;
+		      break;
+		    }
+		  nnpn = sgp->node[nnpn].pn;
+		  t = t->parent;
+		}
+	    }
+	}
+      //printf("sgp->node[%d].pn = %d\n", i, sgp->node[i].pn);
+      i++;
+    }
+  sgp->info.size = i;
+
+  
+  //for(int s=0; s<i; s++)
+  //{
+  //printf("sgp.node[%d].pn = %d\n",s,sgp.node[s].pn);
+  //}
+  
+  //delete sgp;
+}
+*/
+
+
+void Polygon::add_next()
+{
+  Polygon *p;
+  p = new Polygon;
+
+  next = p;
+}
+
+
+void Polygon::create_tree()
+{
+  Polygon *list;
+  Polygon *check_list;
+  Polygon *p;
+  Polygon *bros;
+
+  check_list = this;
+
+  for(list=this; list; list=list->next)
+    {
+      if(xmlStrcmp((xmlChar *)list->parent_name, (xmlChar *)"NULL"))
+	{
+	  p = this;
+	  while(p)
+	    {
+	      if(!xmlStrcmp((xmlChar *)p->name,(xmlChar *)list->parent_name))
+		{
+		  list->parent = p;
+		  if(p->child == NULL)
+		    {
+		      p->child = list;
+		    }
+		  else
+		    {
+		      bros = p->child;
+		      while(bros->brother != NULL)
+			{
+			  bros = bros->brother;
+			}
+		      bros->brother = list;
+		    }		  
+		  break;
+		}
+	      p = p->next;
+	    }
+	}
+    }
+}
+
+/*
+void Polygon::create_scene_graph_pack()
+{
+  SceneGraphPack sgp;
+  int i = 0;
+  int nnpn = -1;
+
+  Polygon *t;
+  t = this;
+  while(t)
+    {
+      //t->draw();
+      SceneGraphNode node;
+      node.obj_pos[0] = 0;
+      node.obj_pos[1] = 0;
+      node.obj_pos[2] = 0;
+      node.obj_pos[3] = 1;
+      for(int tm=0; tm<16; tm++)
+	{
+	  node.translation[tm] = 0;
+	}
+      node.id = 0;
+      node.move = 0;
+      node.interaction = 0;
+      for(int a=0; a<10; a++)
+	{
+	  node.op[a] = -1;
+	}
+      node.pn = nnpn;
+      int p = 0;
+
+      if(t->child != NULL)
+        {
+          //glPushMatrix();
+	  //node.op[p] = PUSH;
+	  //nnpn = i;
+          t = t->child;
+        }
+      else if(t->brother != NULL)
+        {
+          //glPopMatrix();
+          //glPushMatrix();
+	  //node.op[p] = SHIFT;
+	  //nnpn = node.pn;
+          t = t->brother;
+        }
+      else
+	{
+          while(t)
+            {
+              if(t->brother != NULL)
+                {
+                  //glPopMatrix();
+                  //glPushMatrix();
+		  //node.op[p] = SHIFT;
+                  t = t->brother;
+                  break;
+                }
+              else
+                {
+                  t = t->parent;
+                  if(t)
+                    {
+                      //glPopMatrix();
+		      //node.op[p] = POP;
+		      //nnpn = sgp.node[nnpn].pn; 
+		      p++;
+                    }
+                }
+            }
+        }
+      sgp.node[i] = node; 
+      i++;
+    }
+
+  sgp.info.size = i;
+
+  for(int s=0; s<4; s++)
+    {
+      for(int a=0; sgp.node[s].op[a]!=-1; a++)
+	{
+	  printf("sgp.node[%d].op[%d] = %d\n",s, a, sgp.node[s].op[a]);
+	}
+      //printf("sgp.node[%d].pn = %d\n",s,sgp.node[s].pn);
+    }
+}
+*/
+
+
+
+void Polygon::pickup_coordinate(char *cont)
+{
+  for(int n=0; n<size*3; n+=3)
+    {
+      cont = pickup_float(cont, data+n);
+      cont = pickup_float(cont, data+n+1);
+      cont = pickup_float(cont, data+n+2);
+      
+      if (cont == NULL)
+	{
+	  cout << "Analyzing obj data failed coordinate\n";
+	}
+    }
+}
+
+void Polygon::pickup_normal(char *cont)
+{
+  for(int n=size*3;n<size*6;n+=3)
+    {
+      cont = pickup_float(cont,data+n);
+      cont = pickup_float(cont,data+n+1);
+      cont = pickup_float(cont,data+n+2);
+      
+      if (cont == NULL)
+	{
+	  cout << "Analyzing obj data failed normal\n";
+	}
+    }
+}
+
+void Polygon::pickup_model(char *cont)
+{
+  cont = pickup_float(cont,c_xyz);
+  cont = pickup_float(cont,c_xyz+1);
+  cont = pickup_float(cont,c_xyz+2);
+  
+  if (cont == NULL)
+    {
+      cout << "Analyzing obj data failed model\n";
+    }
+}
+
+void Polygon::pickup_texture(char *cont)
+{
+  for(int n=size*6; n<size*9; n+=3)
+    {
+      cont = pickup_float(cont,data+n);
+      cont = pickup_float(cont,data+n+1);
+      data[n+2] = 1.0;
+      
+      if (cont == NULL)
+	{
+	  cout << "Analyzing obj data failed texture\n";
+	}
+    }
+}
+
+char *get_pixel(int tx, int ty, SDL_Surface *texture_image)
+{
+  return (char*)texture_image->pixels+(texture_image->format->BytesPerPixel*((texture_image->w)*ty+tx));
+}
+
+unsigned my_ntohl(unsigned u) {
+  //     rr gg bb 00
+  //           rr
+  //     bb gg rr
+  //unsigned u1 =   ((u&0xff)<<24) +
+  //         ((u&0xff00)<<8) +
+  //         ((u&0xff0000)>>8) +
+  //         ((u&0xff000000)>>24);
+  unsigned u1;
+  unsigned b = (u&0xff000000)>>24;
+  unsigned g = (u&0xff0000)>>16;
+  unsigned r = (u&0xff00)>>8;
+  u1 = r + (g<<8) + (b<<16);
+  //printf("pixel %x->%x\n",u,u1);
+  return u1;
+}
+
+Uint32 Polygon::get_rgb(int tx, int ty)
+{
+  SDL_PixelFormat *fmt;
+  //Uint32 temp, pixel;
+  Uint8 red, green, blue;
+  
+  fmt = texture_image->format;
+
+  if (tx<0) tx = 0;
+  if (texture_image->w-1< tx) tx = texture_image->w-1 ;
+  if (ty<0) ty = 0;
+  if (texture_image->h-1< ty) ty = texture_image->h-1 ;
+
+
+
+  //SDL_LockSurface(texture_image);
+  char *p = get_pixel(tx,ty,texture_image);
+#if 0
+  pixel = my_ntohl(*(Uint32*)p);
+  //printf("pixel = %d\n", pixel);
+  //printf("pixel %x bpp = %d ",p, fmt->BytesPerPixel);
+  //SDL_UnlockSurface(texture_image);
+  
+  temp = pixel&fmt->Rmask;
+  temp = temp>>fmt->Rshift;
+  temp = temp<<fmt->Rloss;
+  red = (Uint8)temp;
+  
+  temp = pixel&fmt->Gmask;
+  temp = temp>>fmt->Gshift;
+  temp = temp<<fmt->Gloss;
+  green = (Uint8)temp;
+  
+  temp = pixel&fmt->Bmask;
+  temp = temp>>fmt->Bshift;
+  temp = temp<<fmt->Bloss;
+  blue = (Uint8)temp;
+#endif
+  blue  = (Uint8) p[0];
+  green = (Uint8) p[1];
+  red   = (Uint8) p[2];
+	  
+  //printf("tx = %d ty = %d ", tx,ty); 
+  //printf("pixel color =>  R: %d,  G: %d,  B: %d\n", red, green, blue);
+
+  SDL_PixelFormat *pf;
+  pf = viewer->screen->format;
+
+  //cout << SDL_MapRGB(pf, red, green, blue) << endl;
+  return SDL_MapRGB(pf, red, green, blue);
+}
+
+
+/*
+ * surface nodeからポリゴンの情報を読み出す 再帰しない
+ */
+void Polygon::get_data(xmlNodePtr cur)
+{
+  char *cont;
+  //char *image_name;
+
+  for(;cur;cur=cur->next)
+    {
+      if(!xmlStrcmp(cur->name,(xmlChar*)"coordinate"))
+        {
+          cont = (char *)xmlNodeGetContent(cur);
+	  pickup_coordinate(cont);
+        }
+      else if(!xmlStrcmp(cur->name,(xmlChar*)"normal"))
+        {
+          cont = (char *)xmlNodeGetContent(cur);
+	  pickup_normal(cont);
+        }
+      else if(!xmlStrcmp(cur->name,(xmlChar*)"model"))
+        {
+          cont = (char *)xmlNodeGetContent(cur);
+	  pickup_model(cont);
+        }
+      else if(!xmlStrcmp(cur->name,(xmlChar*)"texture"))
+        {
+          cont = (char *)xmlNodeGetContent(cur);
+	  pickup_texture(cont);
+	}
+      else if(!xmlStrcmp(cur->name,(xmlChar*)"image"))
+        {
+	  char image_name[20] = "/tmp/image_XXXXXX";
+	  int fd = mkstemp(image_name);
+	  FILE *outfile = fdopen(fd, "wb");
+	  if(NULL == outfile)
+	    {
+	      cout << "error open file\n";
+	    }
+          cont = (char *)xmlNodeGetContent(cur);
+          //decode(cont, image_name);
+	  decode(cont, outfile);
+	  fclose(outfile);
+
+	  texture_image = IMG_Load(image_name);
+
+	  //load_texture(image_name);
+	  if(unlink(image_name))
+	    {
+	      cout << "unlink error\n";
+	    }
+        }
+    }
+}
+
+
+/*
+ * ノードを受け取って、そこからポリゴンを生成
+ * リークしてない? data上書きしちゃだめ
+ */
+void Polygon::create_data(xmlNodePtr cur)
+{
+  size = atoi((char *)xmlGetProp(cur,(xmlChar *)"size"));
+  name = (char *)xmlGetProp(cur,(xmlChar *)"name");
+  parent_name = (char *)xmlGetProp(cur,(xmlChar *)"parent");
+  next = NULL;
+
+  data = new float[size*3*3];
+
+  get_data(cur->children);
+}
+
+/*
+ * xmlをオープンして、Surfaceノードからポリゴンを作る
+ *
+ */
+void Polygon::set_data(char *file_name)
+{
+  xmlDocPtr doc;
+  xmlNodePtr cur;
+  Polygon *tmp;
+
+  doc = xmlParseFile(file_name);
+
+  cur = xmlDocGetRootElement(doc);
+
+  xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");
+
+  tmp = this;
+
+  for (cur=cur->children; cur; cur=cur->next)
+    {
+      if (!xmlStrcmp(cur->name,(xmlChar*)"surface"))
+        {
+	  tmp->create_data(cur);
+	  if(cur->next->next)
+	    {
+	      tmp->add_next();
+	      tmp = tmp->next;
+	    }
+        }
+    }
+
+  create_tree();
+  //tree_check();
+  //create_scene_graph_pack();
+
+  xmlFreeDoc(doc);
+
+  /*
+  for(int s=0; s<sgp->info.size; s++)
+    {
+      printf("sgp->node[%d].pn = %d\n",s,sgp->node[s].pn);
+    }
+  */
+  //delete sgp;
+}
+
+void Polygon::delete_data()
+{
+  Polygon *n,*m;
+
+  n = this;
+  delete [] n->data;
+
+  if(next)
+    {
+      for(n = this->next; n; n=m)
+	{
+	  m = n->next;
+	  delete [] n->data;
+	  delete n;
+	}
+    }
+}
+
+
+
+/* construct polygon from xml.  */
+/*
+Polygon::Polygon(char *xmlfile)
+{
+  Polygon();
+  xmlDocPtr doc;
+  xmlNodePtr cur;
+  Polygon *tmp;
+
+  doc = xmlParseFile(file_name);
+
+  cur = xmlDocGetRootElement(doc);
+
+  xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");
+
+  tmp = this;
+
+  for (cur=cur->children; cur; cur=cur->next)
+    {
+      if ( xmlStrcmp(cur->name,(xmlChar*)"surface")!=0 )
+	  continue;
+
+      if ( xmlStrcmp(cur->parent ))
+      tmp->create_data(cur);
+      if(cur->next->next)
+        {
+	  tmp->add_next();
+	  tmp = tmp->next;
+	}
+    }
+
+  create_tree();
+  //tree_check();
+  //create_scene_graph_pack();
+
+  xmlFreeDoc(doc);
+}
+*/
+
+/* construct polygon from xmlNode.  */
+Polygon::Polygon(xmlNodePtr surface)
+{
+#if 1
+  xyz[0] = 0;
+  xyz[1] = 0;
+  xyz[2] = 0;
+  xyz[3] = 1;
+  c_xyz[0] = 0;
+  c_xyz[1] = 0;
+  c_xyz[2] = 0;
+  c_xyz[3] = 1;
+  angle[0] = 0;
+  angle[1] = 0;
+  angle[2] = 0;
+  angle[3] = 1;
+  next = NULL;
+  child = NULL;
+  parent = NULL;
+  brother = NULL;
+  children = NULL;
+  lastChild = NULL;
+#else
+  /* これ使うにはどうすればいいの?  */
+  this->Polygon();
+#endif
+  size = atoi((char *)xmlGetProp(surface,(xmlChar *)"size"));
+  name = (char *)xmlGetProp(surface,(xmlChar *)"name");
+  parent_name = (char *)xmlGetProp(surface,(xmlChar *)"parent");
+  next = NULL;
+
+  data = new float[size*3*3];
+
+  get_data(surface->children);
+}
+
+/* XMLファイルからポリゴンを作成  */
+Polygon *Polygon::createFromXMLfile(char *xmlfile)
+{
+  xmlDocPtr doc;
+  xmlNodePtr cur;
+  Polygon *root=NULL, *tmp, *parent;
+
+  /* パース DOM生成 */
+  doc = xmlParseFile(xmlfile);
+  cur = xmlDocGetRootElement(doc);
+
+  /* ??  */
+  xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");
+
+  /* XMLのノードを一つずつ解析  */
+  for (cur=cur->children; cur; cur=cur->next)
+    {
+      /* 扱うのはsurfaceオンリー  */
+      if ( xmlStrcmp(cur->name,(xmlChar*)"surface")!=0 )
+	  continue;
+
+      /* ポリゴン生成  */
+      tmp = new Polygon(cur);
+      if( tmp->parent_name==NULL || 0==strcmp(tmp->parent_name, "NULL"))
+	  /* このsurfaceがroot  */
+	  root = tmp;
+      else
+        {
+	  /* 親はこのsurfaceより前に定義されているものとする (していい?)  */
+	  parent = root->searchPolygon(tmp->parent_name);
+	  parent->addChild( tmp );
+	}
+    }
+
+  xmlFreeDoc(doc);
+  return root;
+}
+
+/* 子供を追加  */
+Polygon *Polygon::addChild(Polygon *child)
+{
+  Polygon *tmp;
+
+  /* childrenのリストの最後に加える */
+  if (this->lastChild != NULL) {
+      tmp = this->lastChild;
+      tmp->next = child;
+  }
+
+  this->lastChild = child;
+
+  return child;
+}
+
+/* thisの子や子孫にnameのものが存在すればそいつを返す なければNULL.  */
+Polygon *Polygon::searchPolygon(char *name)
+{
+  Polygon *tmp, *result;
+
+  /* 本人か  */
+  if( 0==strcmp(this->name, name) ) return this;
+
+  /* 子供から再帰的に探す  */
+  for( tmp=this->children; tmp; tmp=tmp->next )
+    {
+      if( (result=tmp->searchPolygon(name))!=NULL )
+	return result;
+    }
+
+  /* 無かったら NULL.  */
+  return NULL;
+}
+