static void
rib_camera(FILE *o, Lib3dsFile *f, Lib3dsMatrix M)
{
  Lib3dsNode *c;
  Lib3dsNode *t;
  const char *name=camera;

  ASSERT(f);
  if (!name) {
    if (f->cameras) {
      name=f->cameras->name;
    }
  }
  if (!name) {
    fprintf(stderr, "***ERROR*** No camera found!\n");
    return;
  }
  c=lib3ds_file_node_by_name(f, name, LIB3DS_CAMERA_NODE);
  t=lib3ds_file_node_by_name(f, name, LIB3DS_TARGET_NODE);
  if (!c || !t) {
    fprintf(stderr, "***ERROR*** Invalid camera/target!\n");
    return;
  }

  lib3ds_matrix_camera(M, c->data.camera.pos, t->data.target.pos, c->data.camera.roll);
  rib_concat_transform(o, M);
  fprintf(o, "Camera \"perspective\" \"float fov\" [%f]\n", c->data.camera.fov);
}
示例#2
0
static void
rib_lights(FILE *o, Lib3dsFile *f, Lib3dsMatrix M)
{
  Lib3dsLight *light;
  Lib3dsNode *l;
  Lib3dsNode *s;
  int i=1;

  for (light=f->lights; light; light=light->next) {
    l=lib3ds_file_node_by_name(f, light->name, LIB3DS_LIGHT_NODE);
    s=lib3ds_file_node_by_name(f, light->name, LIB3DS_SPOT_NODE);
    if (!l) {
      fprintf(stderr, "***ERROR*** Invalid light!\n");
      exit(1);
    }
    if (s) {
      Lib3dsVector pos,spot;
      lib3ds_vector_copy(pos, l->data.light.pos);
      lib3ds_vector_copy(spot, s->data.spot.pos);
      fprintf(o,
        "LightSource "
        "\"lib3dslight\" "
        "%d "
        "\"string lighttype\" [\"spot\"] "
        "\"point from\" [%f %f %f] "
        "\"point to\" [%f %f %f]\n",
        i,
        pos[0],
        pos[1],
        pos[2],
        spot[0],
        spot[1],
        spot[2]
      );
    }
    else {
      Lib3dsVector pos;
      lib3ds_vector_copy(pos, l->data.light.pos);
      fprintf(o,
        "LightSource "
        "\"pointlight\" "
        "%d "
        "\"from\" [%f %f %f]\n",
        i,
        pos[0],
        pos[1],
        pos[2]
      );
    }
    fprintf(o, "Illuminate %d 1\n", i);
    ++i;
  }
}
示例#3
0
/*!
 *
 */
static void
display(void)
{
  Lib3dsNode *c,*t;
  Lib3dsMatrix M;
  
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  if (!file) {
    return;
  }
  c=lib3ds_file_node_by_name(file, camera, LIB3DS_CAMERA_NODE);
  t=lib3ds_file_node_by_name(file, camera, LIB3DS_TARGET_NODE);
  if (!c || !t) {
    return;
  }

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective( c->data.camera.fov, 1.0*gl_width/gl_height, 100.0, 20000.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glRotatef(-90, 1.0,0,0);
  {
    GLfloat lightPos[] = {0.0f, -1.0f, 0.0f, 0.0f};
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
    glPushMatrix();
    glTranslatef(0,-10,0);
    glutSolidTeapot(10.0);
    glPopMatrix();
  }

  lib3ds_matrix_camera(M, c->data.camera.pos, t->data.target.pos, c->data.camera.roll);
  glMultMatrixf(&M[0][0]);

  {
    Lib3dsNode *p;
    for (p=file->nodes; p!=0; p=p->next) {
      render_node(p);
    }
  }

  if (!halt) {
    current_frame+=1.0;
    if (current_frame>file->frames) {
      current_frame=0;
    }
    lib3ds_file_eval(file, current_frame);
    glutSwapBuffers();
    glutPostRedisplay();
  }
}
示例#4
0
static void
light_update(Lib3dsLight *l)
{
  Lib3dsNode *ln, *sn;

  ln = lib3ds_file_node_by_name(file, l->name, LIB3DS_LIGHT_NODE);
  sn = lib3ds_file_node_by_name(file, l->name, LIB3DS_SPOT_NODE);

  if( ln != NULL ) {
    memcpy(l->color, ln->data.light.col, sizeof(Lib3dsRgb));
    memcpy(l->position, ln->data.light.pos, sizeof(Lib3dsVector));
  }

  if( sn != NULL )
    memcpy(l->spot, sn->data.spot.pos, sizeof(Lib3dsVector));
}
static void construct_hierarchy(Lib3dsFile *file, Scene *scene) {
	std::list<Object*> *list = scene->get_object_list();
	std::list<Object*>::iterator iter = list->begin();
	while(iter != list->end()) {
		Object *obj = *iter;
		Lib3dsNode *n = lib3ds_file_node_by_name(file, obj->name.c_str(), LIB3DS_OBJECT_NODE);
		if(!n) {
			iter++;
			continue;
		}

		// get parent
		if(n->parent) {
			obj->parent = scene->get_node(n->parent->name);
		}
		
		// get children
		Lib3dsNode *child = n->childs;
		while(child) {
			XFormNode *child_node = scene->get_node(child->name);
			if(child_node) {
				(*iter)->children.push_back(child_node);
			}
			child = child->next;
		}

		iter++;
	}
}
示例#6
0
static void
light_update(Lib3dsLight *l) {
	Lib3dsNode *ln, *sn;
	
	
	ln = lib3ds_file_node_by_name(file, l->name, LIB3DS_NODE_SPOTLIGHT);
	sn = lib3ds_file_node_by_name(file, l->name, LIB3DS_NODE_SPOTLIGHT_TARGET);
	
	
	if (ln != NULL) {
		Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)ln;
		memcpy(l->color, n->color, 3 * sizeof(float));
		memcpy(l->position, n->pos, 3 * sizeof(float));
	}
	
	
	if (sn != NULL) {
		Lib3dsTargetNode *n = (Lib3dsTargetNode*)sn;
		memcpy(l->target, n->pos, 3* sizeof(float));
	}
}
示例#7
0
文件: node.c 项目: GYengera/mrpt
/*!
 * \ingroup node
 */
Lib3dsBool
lib3ds_node_write(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io)
{
  Lib3dsChunk c;

  switch (node->type) {
    case LIB3DS_AMBIENT_NODE:
      c.chunk=LIB3DS_AMBIENT_NODE_TAG;
      break;
    case LIB3DS_OBJECT_NODE:
      c.chunk=LIB3DS_OBJECT_NODE_TAG;
      break;
    case LIB3DS_CAMERA_NODE:
      c.chunk=LIB3DS_CAMERA_NODE_TAG;
      break;
    case LIB3DS_TARGET_NODE:
      c.chunk=LIB3DS_TARGET_NODE_TAG;
      break;
    case LIB3DS_LIGHT_NODE:
      if (lib3ds_file_node_by_name(file, node->name, LIB3DS_SPOT_NODE)) {
        c.chunk=LIB3DS_SPOTLIGHT_NODE_TAG;
      }
      else {
        c.chunk=LIB3DS_LIGHT_NODE_TAG;
      }
      break;
    case LIB3DS_SPOT_NODE:
      c.chunk=LIB3DS_L_TARGET_NODE_TAG;
      break;
    default:
      return(LIB3DS_FALSE);
  }
  if (!lib3ds_chunk_write_start(&c,io)) {
    return(LIB3DS_FALSE);
  }

  { /*---- LIB3DS_NODE_ID ----*/
    Lib3dsChunk c;
    c.chunk=LIB3DS_NODE_ID;
    c.size=8;
    lib3ds_chunk_write(&c,io);
    lib3ds_io_write_intw(io, node->node_id);
  }

  { /*---- LIB3DS_NODE_HDR ----*/
    Lib3dsChunk c;
    c.chunk=LIB3DS_NODE_HDR;
    c.size=6+ 1+(Lib3dsDword)strlen(node->name) +2+2+2;
    lib3ds_chunk_write(&c,io);
    lib3ds_io_write_string(io, node->name);
    lib3ds_io_write_word(io, node->flags1);
    lib3ds_io_write_word(io, node->flags2);
    lib3ds_io_write_word(io, node->parent_id);
  }

  switch (c.chunk) {
    case LIB3DS_AMBIENT_NODE_TAG:
      { /*---- LIB3DS_COL_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_COL_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.ambient.col_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      break;
    case LIB3DS_OBJECT_NODE_TAG:
      { /*---- LIB3DS_PIVOT ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_PIVOT;
        c.size=18;
        lib3ds_chunk_write(&c,io);
        lib3ds_io_write_vector(io, node->data.object.pivot);
      }
      { /*---- LIB3DS_INSTANCE_NAME ----*/
        Lib3dsChunk c;
        const char *name;
        if (strlen(node->data.object.instance)) {
          name=node->data.object.instance;

          c.chunk=LIB3DS_INSTANCE_NAME;
          c.size=6+1+(Lib3dsDword)strlen(name);
          lib3ds_chunk_write(&c,io);
          lib3ds_io_write_string(io, name);
        }
      }
      {
        int i;
        for (i=0; i<3; ++i) {
          if ((fabs(node->data.object.bbox_min[i])>LIB3DS_EPSILON) ||
            (fabs(node->data.object.bbox_max[i])>LIB3DS_EPSILON)) {
            break;
          }
        }
        
        if (i<3) { /*---- LIB3DS_BOUNDBOX ----*/
          Lib3dsChunk c;
          c.chunk=LIB3DS_BOUNDBOX;
          c.size=30;
          lib3ds_chunk_write(&c,io);
          lib3ds_io_write_vector(io, node->data.object.bbox_min);
          lib3ds_io_write_vector(io, node->data.object.bbox_max);
        }
      }
      { /*---- LIB3DS_POS_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_POS_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.object.pos_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_ROT_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_ROT_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_quat_track_write(&node->data.object.rot_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_SCL_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_SCL_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.object.scl_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      if (node->data.object.hide_track.keyL) { /*---- LIB3DS_HIDE_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_HIDE_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_bool_track_write(&node->data.object.hide_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      if (fabs(node->data.object.morph_smooth)>LIB3DS_EPSILON){ /*---- LIB3DS_MORPH_SMOOTH ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_MORPH_SMOOTH;
        c.size=10;
        lib3ds_chunk_write(&c,io);
        lib3ds_io_write_float(io, node->data.object.morph_smooth);
      }
      break;
    case LIB3DS_CAMERA_NODE_TAG:
      { /*---- LIB3DS_POS_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_POS_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.camera.pos_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_FOV_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_FOV_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin1_track_write(&node->data.camera.fov_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_ROLL_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_ROLL_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin1_track_write(&node->data.camera.roll_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      break;
    case LIB3DS_TARGET_NODE_TAG:
      { /*---- LIB3DS_POS_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_POS_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.target.pos_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      break;
    case LIB3DS_LIGHT_NODE_TAG:
      { /*---- LIB3DS_POS_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_POS_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.light.pos_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_COL_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_COL_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.light.col_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      break;
    case LIB3DS_SPOTLIGHT_NODE_TAG:
      { /*---- LIB3DS_POS_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_POS_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.light.pos_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_COL_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_COL_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.light.col_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_HOT_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_HOT_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin1_track_write(&node->data.light.hotspot_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_FALL_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_FALL_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin1_track_write(&node->data.light.falloff_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      { /*---- LIB3DS_ROLL_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_ROLL_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin1_track_write(&node->data.light.roll_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      break;
    case LIB3DS_L_TARGET_NODE_TAG:
      { /*---- LIB3DS_POS_TRACK_TAG ----*/
        Lib3dsChunk c;
        c.chunk=LIB3DS_POS_TRACK_TAG;
        if (!lib3ds_chunk_write_start(&c,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_lin3_track_write(&node->data.spot.pos_track,io)) {
          return(LIB3DS_FALSE);
        }
        if (!lib3ds_chunk_write_end(&c,io)) {
          return(LIB3DS_FALSE);
        }
      }
      break;
    default:
      return(LIB3DS_FALSE);
  }

  if (!lib3ds_chunk_write_end(&c,io)) {
    return(LIB3DS_FALSE);
  }
  return(LIB3DS_TRUE);
}
示例#8
0
/*!
* Main display function; called whenever the scene needs to be redrawn.
*/
static void
display(void)
{
  Lib3dsNode *c,*t;
  Lib3dsFloat fov, roll;
  float near, far, dist;
  float *campos;
  float *tgt;
  Lib3dsMatrix M;
  Lib3dsCamera *cam;
  Lib3dsVector v;
  Lib3dsNode *p;

  if( file != NULL && file->background.solid.use )
    glClearColor(file->background.solid.col[0],
    file->background.solid.col[1],
    file->background.solid.col[2], 1.);

  /* TODO: fog */

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  if( anti_alias )
    glEnable(GL_POLYGON_SMOOTH);
  else
    glDisable(GL_POLYGON_SMOOTH);


  if (!file) {
    return;
  }

  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, file->ambient);

  c=lib3ds_file_node_by_name(file, camera, LIB3DS_CAMERA_NODE);
  t=lib3ds_file_node_by_name(file, camera, LIB3DS_TARGET_NODE);

  if( t != NULL )
    tgt = t->data.target.pos;

  if( c != NULL ) {
    fov = c->data.camera.fov;
    roll = c->data.camera.roll;
    campos = c->data.camera.pos;
  }

  if ((cam = lib3ds_file_camera_by_name(file, camera)) == NULL)
    return;

  near = cam->near_range;
  far = cam->far_range;

  if (c == NULL || t == NULL) {
    if( c == NULL ) {
      fov = cam->fov;
      roll = cam->roll;
      campos = cam->position;
    }
    if( t == NULL )
      tgt = cam->target;
  }

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  /* KLUDGE alert:  OpenGL can't handle a near clip plane of zero,
  * so if the camera's near plane is zero, we give it a small number.
  * In addition, many .3ds files I've seen have a far plane that's
  * much too close and the model gets clipped away.  I haven't found
  * a way to tell OpenGL not to clip the far plane, so we move it
  * further away.  A factor of 10 seems to make all the models I've
  * seen visible.
  */
  if( near <= 0. ) near = far * .001;

  gluPerspective( fov, 1.0*gl_width/gl_height, near, far);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glRotatef(-90, 1.0,0,0);

  /* User rotates the view about the target point */

  lib3ds_vector_sub(v, tgt, campos);
  dist = lib3ds_vector_length(v);

  glTranslatef(0.,dist, 0.);
  glRotatef(view_rotx, 1., 0., 0.);
  glRotatef(view_roty, 0., 1., 0.);
  glRotatef(view_rotz, 0., 0., 1.);
  glTranslatef(0.,-dist, 0.);

  lib3ds_matrix_camera(M, campos, tgt, roll);
  glMultMatrixf(&M[0][0]);

  /* Lights.  Set them from light nodes if possible.  If not, use the
  * light objects directly.
  */
  {
    static const GLfloat a[] = {0.0f, 0.0f, 0.0f, 1.0f};
    static GLfloat c[] = {1.0f, 1.0f, 1.0f, 1.0f};
    static GLfloat p[] = {0.0f, 0.0f, 0.0f, 1.0f};
    Lib3dsLight *l;

    int li=GL_LIGHT0;
    for (l=file->lights; l; l=l->next) {
      glEnable(li);

      light_update(l);

      c[0] = l->color[0];
      c[1] = l->color[1];
      c[2] = l->color[2];
      glLightfv(li, GL_AMBIENT, a);
      glLightfv(li, GL_DIFFUSE, c);
      glLightfv(li, GL_SPECULAR, c);

      p[0] = l->position[0];
      p[1] = l->position[1];
      p[2] = l->position[2];
      glLightfv(li, GL_POSITION, p);

      if (l->spot_light) {
        p[0] = l->spot[0] - l->position[0];
        p[1] = l->spot[1] - l->position[1];
        p[2] = l->spot[2] - l->position[2];
        glLightfv(li, GL_SPOT_DIRECTION, p);
      }
      ++li;
    }
  }




  if( show_object )
  {
    for (p=file->nodes; p!=0; p=p->next) {
      render_node(p);
    }
  }

  if( show_bounds )
    draw_bounds(tgt);

  if( show_cameras )
  {
    for( cam = file->cameras; cam != NULL; cam = cam->next )
    {
      lib3ds_matrix_camera(M, cam->position, cam->target, cam->roll);
      lib3ds_matrix_inv(M);

      glPushMatrix();
      glMultMatrixf(&M[0][0]);
      glScalef(size/20, size/20, size/20);
      glCallList(cameraList);
      glPopMatrix();
    }
  }

  if( show_lights )
  {
    Lib3dsLight *light;
    for( light = file->lights; light != NULL; light = light->next )
      draw_light(light->position, light->color);
    glMaterialfv(GL_FRONT, GL_EMISSION, black);
  }


  glutSwapBuffers();
}
static bool load_keyframes(Lib3dsFile *file, const char *name, Lib3dsNodeTypes type, XFormNode *node) {
	if(!name || !*name) return false;
	
	Lib3dsNode *n = lib3ds_file_node_by_name(file, name, type);
	if(!n) return false;

	switch(type) {
	case LIB3DS_OBJECT_NODE:
		{
			Lib3dsObjectData *obj = &n->data.object;
			std::vector<int> *frames = get_frames(obj);
			if(!frames) return false;

			for(int i=0; i<(int)frames->size(); i++) {
				lib3ds_node_eval(n, (float)(*frames)[i]);
					
				Vector3 pos = CONV_VEC3(obj->pos) - CONV_VEC3(obj->pivot);
				Quaternion rot = CONV_QUAT(obj->rot);
				Vector3 scl = CONV_VEC3(obj->scl);

				Keyframe key(PRS(pos, rot, scl), FRAME_TO_TIME((*frames)[i]));
				node->add_keyframe(key);
			}
		}
		break;

	case LIB3DS_LIGHT_NODE:
		{
			Lib3dsLightData *light = &n->data.light;
			std::vector<int> *frames = get_frames(light);
			if(!frames) return false;

			for(int i=0; i<(int)frames->size(); i++) {
				lib3ds_node_eval(n, (float)(*frames)[i]);

				Vector3 pos = CONV_VEC3(light->pos);

				Keyframe key(PRS(pos, Quaternion()), FRAME_TO_TIME((*frames)[i]));
				node->add_keyframe(key);
			}
		}
		break;

	case LIB3DS_CAMERA_NODE:
		{
			Lib3dsCameraData *cam = &n->data.camera;
			std::vector<int> *frames = get_frames(cam);
			if(!frames) return false;

			for(int i=0; i<(int)frames->size(); i++) {
				lib3ds_node_eval(n, (float)(*frames)[i]);

				Vector3 pos = CONV_VEC3(cam->pos);

				Keyframe key(PRS(pos, Quaternion()), FRAME_TO_TIME((*frames)[i]));
				node->add_keyframe(key);
			}
		}
		break;

		/*
	case LIB3DS_TARGET_NODE:
		{
			Lib3dsCameraData *targ = &n->data.target;
			std::vector<int> *frames = get_frames(targ);
			if(!frames) return false;

			for(int i=0; i<(int)frames->size(); i++) {
				lib3ds_node_eval(n, (float)(*frames)[i]);

				Vector3 pos = CONV_VEC3(targ->pos);

				Keyframe key(PRS(pos, Quaternion()), FRAME_TO_TIME((*frames)[i]));
				node->add_keyframe(key);
			}

		}
		break;
		*/

	default:
		break;
	}

	return true;
}
static bool load_objects(Lib3dsFile *file, Scene *scene) {
	// load meshes
	unsigned long poly_count = 0;
	Lib3dsMesh *m = file->meshes;
	while(m) {

		Lib3dsNode *node = lib3ds_file_node_by_name(file, m->name, LIB3DS_OBJECT_NODE);
		if(!node) {
			warning("object \"%s\" does not have a corresponding node!", m->name);
		}
		Vector3 node_pos = node ? CONV_VEC3(node->data.object.pos) : Vector3();
		Quaternion node_rot = node ? CONV_QUAT(node->data.object.rot) : Quaternion();
		Vector3 node_scl = node ? CONV_VEC3(node->data.object.scl) : Vector3(1,1,1);
		Vector3 pivot = node ? CONV_VEC3(node->data.object.pivot) : Vector3();

		// load the vertices
		Vertex *varray = new Vertex[m->points];
		Vertex *vptr = varray;
		for(int i=0; i<(int)m->points; i++) {
			vptr->pos = CONV_VEC3(m->pointL[i].pos) - node_pos;
			vptr->pos.transform(node_rot);
			
			if(m->texels) {
				vptr->tex[0] = vptr->tex[1] = CONV_TEXCOORD(m->texelL[i]);
			}
			
			vptr++;
		}
		
		if(m->faces) {
			poly_count += m->faces;
			// -------- object ---------
			Object *obj = new Object;
			obj->set_dynamic(false);

			obj->name = m->name;

			obj->set_position(node_pos - pivot);
			obj->set_rotation(node_rot);
			obj->set_scaling(node_scl);

			obj->set_pivot(pivot);
		
			// load the polygons
			Triangle *tarray = new Triangle[m->faces];
			Triangle *tptr = tarray;
			for(int i=0; i<(int)m->faces; i++) {
				*tptr = CONV_TRIANGLE(m->faceL[i]);
				tptr->normal = CONV_VEC3(m->faceL[i].normal);
				tptr->smoothing_group = m->faceL[i].smoothing;

				tptr++;
			}

			// set the geometry data to the object
			obj->get_mesh_ptr()->set_data(varray, m->points, tarray, m->faces);
			obj->get_mesh_ptr()->calculate_normals();
		
			delete [] tarray;

			// load the material
			load_material(file, m->faceL[0].material, obj->get_material_ptr());

			// load the keyframes (if any)
			if(load_keyframes(file, m->name, LIB3DS_OBJECT_NODE, obj)) {
				obj->set_position(Vector3());
				obj->set_rotation(Quaternion());
				obj->set_scaling(Vector3(1, 1, 1));
			}

			scene->add_object(obj);
			
		} else {
			// --------- curve ------------
			Curve *curve = new CatmullRomSplineCurve;
			curve->name = m->name;

			Vector3 offs = node_pos - pivot;
			
			for(int i=0; i<(int)m->points; i++) {
				curve->add_control_point(varray[i].pos + offs);
			}

			scene->add_curve(curve);
		}

		delete [] varray;


		m = m->next;
	}
	
	scene->set_poly_count(poly_count);
	return true;
}
示例#11
0
	void	x3ds_instance::display()
	{
		assert(m_def != NULL);

		if (m_def->m_file == NULL)
		{
			return;
		}

		//update_material();

		// save GL state
		glPushAttrib (GL_ALL_ATTRIB_BITS);	
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glMatrixMode(GL_PROJECTION);
		glPushMatrix();

		// apply gameSWF matrix

		rect bound;
		m_def->get_bound(&bound);

		matrix m = get_parent()->get_world_matrix();
		m.transform(&bound);

		// get viewport size
		GLint vp[4]; 
		glGetIntegerv(GL_VIEWPORT, vp); 
//		int vp_width = vp[2];
		int vp_height = vp[3];

		bound.twips_to_pixels();
		int w = (int) (bound.m_x_max - bound.m_x_min);
		int h = (int) (bound.m_y_max - bound.m_y_min);
		int x = (int) bound.m_x_min;
		int y = (int) bound.m_y_min;
		glViewport(x, vp_height - y - h, w, h);

		// set 3D params

		glClear(GL_DEPTH_BUFFER_BIT);
		glDepthFunc(GL_LEQUAL);
		glEnable(GL_DEPTH_TEST);
		glCullFace(GL_BACK);

		glEnable(GL_POLYGON_SMOOTH);
//		glEnable(GL_BLEND);
//		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glDisable(GL_BLEND);

		// set GL matrix to identity
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();

		assert(m_camera);

		Lib3dsNode* cnode = lib3ds_file_node_by_name(m_def->m_file, m_camera->name, LIB3DS_CAMERA_NODE);
		Lib3dsNode* tnode = lib3ds_file_node_by_name(m_def->m_file, m_camera->name, LIB3DS_TARGET_NODE);

		float* target = tnode ? tnode->data.target.pos : m_camera->target;

		float	view_angle;
		float roll;
		float* camera_pos;
		if (cnode)
		{
			view_angle = cnode->data.camera.fov;
			roll = cnode->data.camera.roll;
			camera_pos = cnode->data.camera.pos;
		}
		else
		{
			view_angle = m_camera->fov;
			roll = m_camera->roll;
			camera_pos = m_camera->position;
		}

		float ffar = m_camera->far_range;
		float nnear = m_camera->near_range <= 0 ? ffar * .001f : m_camera->near_range;

		float top = tan(view_angle * 0.5f) * nnear;
		float bottom = -top;
		float aspect = 1.3333f;	// 4/3 == width /height
		float left = aspect* bottom;
		float right = aspect * top;

		//	gluPerspective(fov, aspect, nnear, ffar) ==> glFrustum(left, right, bottom, top, nnear, ffar);
		//	fov * 0.5 = arctan ((top-bottom)*0.5 / near)
		//	Since bottom == -top for the symmetrical projection that gluPerspective() produces, then:
		//	top = tan(fov * 0.5) * near
		//	bottom = -top
		//	Note: fov must be in radians for the above formulae to work with the C math library. 
		//	If you have comnputer your fov in degrees (as in the call to gluPerspective()), 
		//	then calculate top as follows:
		//	top = tan(fov*3.14159/360.0) * near
		//	The left and right parameters are simply functions of the top, bottom, and aspect:
		//	left = aspect * bottom
		//	right = aspect * top
		glFrustum(left, right, bottom, top, nnear, ffar);

		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glRotatef(-90., 1.0, 0., 0.);

		// apply camera matrix
		Lib3dsMatrix cmatrix;
		lib3ds_matrix_camera(cmatrix, camera_pos, target, roll);
		glMultMatrixf(&cmatrix[0][0]);

		// apply light
		set_light();

		// draw 3D model

		for (Lib3dsNode* p = m_def->m_file->nodes; p != 0; p = p->next)
		{
			render_node(p);
		}

		// restore openGL state
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();
		glPopAttrib();
	}
示例#12
0
	// apply light
	// Set them from light nodes if possible.
	// If not, use the light objects directly.
	void	x3ds_instance::set_light()
	{
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, m_def->m_file->ambient);
		glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
		glShadeModel(GL_SMOOTH);

		Lib3dsLight* l = m_def->m_file->lights;
		for (int gl_light = GL_LIGHT0; gl_light <= GL_LIGHT7; gl_light++)
		{
			if (l)
			{
				glEnable(gl_light);

				// default we use light objects directly
				GLfloat color[4];
				color[0] = l->color[0];
				color[1] = l->color[1];
				color[2] = l->color[2];
				color[3] = 1;

				// default position
				GLfloat position[4];
				position[0] = l->position[0];
				position[1] = l->position[1];
				position[2] = l->position[2];
				position[3] = 1;

				// try light nodes if possible
				Lib3dsNode* ln = lib3ds_file_node_by_name(m_def->m_file, l->name, LIB3DS_LIGHT_NODE);
				if (ln)
				{
					color[0] = ln->data.light.col[0];
					color[1] = ln->data.light.col[1];
					color[2] = ln->data.light.col[2];
					position[0] = ln->data.light.pos[0];
					position[1] = ln->data.light.pos[1];
					position[2] = ln->data.light.pos[2];
				}

				// try spot nodes if possible
				Lib3dsNode* sn = lib3ds_file_node_by_name(m_def->m_file, l->name, LIB3DS_SPOT_NODE);
				if (sn)
				{
					l->spot[0] = sn->data.spot.pos[0];
					l->spot[1] = sn->data.spot.pos[1];
					l->spot[2] = sn->data.spot.pos[2];
				}

				static const GLfloat a[] = {0.0f, 0.0f, 0.0f, 1.0f};
				glLightfv(gl_light, GL_AMBIENT, a);
				glLightfv(gl_light, GL_DIFFUSE, color);
				glLightfv(gl_light, GL_SPECULAR, color);
				glLightfv(gl_light, GL_POSITION, position);
				glLightf(gl_light, GL_LINEAR_ATTENUATION, l->attenuation);
//				glLightf(gl_light, GL_CONSTANT_ATTENUATION, 0);
//				glLightf(gl_light, GL_QUADRATIC_ATTENUATION, 0);

				if (l->spot_light)
				{
					position[0] = l->spot[0];
					position[1] = l->spot[1];
					position[2] = l->spot[2];
					glLightfv(gl_light, GL_SPOT_DIRECTION, position);
					glLightf(gl_light, GL_SPOT_CUTOFF, l->fall_off);
					glLightf(gl_light, GL_SPOT_EXPONENT, 0);	// hack
				}

				l = l->next;
			}
			else
			{
				glDisable(gl_light);
			}
		}
		glEnable(GL_LIGHTING);
	}