コード例 #1
0
static void
point_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) {
    Lib3dsChunk c;
    int i;

    c.chunk = CHK_POINT_ARRAY;
    c.size = 8 + 12 * mesh->nvertices;
    lib3ds_chunk_write(&c, io);

    lib3ds_io_write_word(io, (uint16_t) mesh->nvertices);

    if (lib3ds_matrix_det(mesh->matrix) >= 0.0f) {
        for (i = 0; i < mesh->nvertices; ++i) {
            lib3ds_io_write_vector(io, mesh->vertices[i]);
        }
    } else {
        /* Flip X coordinate of vertices if mesh matrix
           has negative determinant */
        float inv_matrix[4][4], M[4][4];
        float tmp[3];

        lib3ds_matrix_copy(inv_matrix, mesh->matrix);
        lib3ds_matrix_inv(inv_matrix);
        lib3ds_matrix_copy(M, mesh->matrix);
        lib3ds_matrix_scale(M, -1.0f, 1.0f, 1.0f);
        lib3ds_matrix_mult(M, M, inv_matrix);

        for (i = 0; i < mesh->nvertices; ++i) {
            lib3ds_vector_transform(tmp, M, mesh->vertices[i]);
            lib3ds_io_write_vector(io, tmp);
        }
    }
}
コード例 #2
0
void draw3DSNode(Lib3dsNode *node)
{
   Lib3dsNode *n;
   for(n=node->childs;n!=NULL;n=n->next)
      draw3DSNode(n);
   if(node->type==LIB3DS_OBJECT_NODE) {
      int i;
      Lib3dsMesh *mesh=NULL;
      Lib3dsVector *normals=NULL;
      Lib3dsMatrix M;
      if(strcmp(node->name,"$$$DUMMY")==0)
         return;
      mesh=lib3ds_file_mesh_by_name(file,node->name);
      if(!mesh)
         return;
      /* apply mesh transformation */
      lib3ds_matrix_copy(M,mesh->matrix);
      lib3ds_matrix_inv(M);
      glMultMatrixf(&M[0][0]);
      /* calculate normals */
      normals=malloc(3*sizeof(Lib3dsVector)*mesh->faces);
      lib3ds_mesh_calculate_normals(mesh,normals);
      for(i=0;i<mesh->faces;i++) {
         Lib3dsFace *face=&mesh->faceL[i];
         Lib3dsMaterial *mat=NULL;
         /* materials */
         if(face->material[0])
            mat=lib3ds_file_material_by_name(file,face->material);
         if(mat) {
            float shine;
            glMaterialfv(GL_FRONT,GL_AMBIENT,mat->ambient);
            glMaterialfv(GL_FRONT,GL_DIFFUSE,mat->diffuse);
            glMaterialfv(GL_FRONT,GL_SPECULAR,mat->specular);
            shine=pow(2.0,10.0*mat->shininess);
            if(shine>128.0)
               shine=128.0;
            glMaterialf(GL_FRONT,GL_SHININESS,shine);
         } else {
            static GLfloat amb[4]={0.2,0.2,0.2,1.0};
            static GLfloat diff[4]={0.8,0.8,0.8,1.0};
            static GLfloat spec[4]={0.0,0.0,0.0,1.0};
            glMaterialfv(GL_FRONT,GL_AMBIENT,amb);
            glMaterialfv(GL_FRONT,GL_DIFFUSE,diff);
            glMaterialfv(GL_FRONT,GL_SPECULAR,spec);
         }
         /* vertices */
         srelBegin(GL_TRIANGLES);
         srelNormal3fv(normals[3*i]);
         srelVertex3fv(mesh->pointL[face->points[0]].pos);
         srelNormal3fv(normals[3*i+1]);
         srelVertex3fv(mesh->pointL[face->points[1]].pos);
         srelNormal3fv(normals[3*i+2]);
         srelVertex3fv(mesh->pointL[face->points[2]].pos);
         srelEnd();
      }
      free(normals);
   }
}
コード例 #3
0
ファイル: mesh.c プロジェクト: mcu786/my_OpenPilot_mods
static Lib3dsBool
point_array_write(Lib3dsMesh *mesh, Lib3dsIo *io)
{
  Lib3dsChunk c;
  unsigned i;

  if (!mesh->points || !mesh->pointL) {
    return(LIB3DS_TRUE);
  }
  ASSERT(mesh->points<0x10000);
  c.chunk=LIB3DS_POINT_ARRAY;
  c.size=8+12*mesh->points;
  lib3ds_chunk_write(&c, io);
  
  lib3ds_io_write_word(io, (Lib3dsWord)mesh->points);

  if (lib3ds_matrix_det(mesh->matrix) >= 0.0f) {
    for (i=0; i<mesh->points; ++i) {
      lib3ds_io_write_vector(io, mesh->pointL[i].pos);
    }
  }
  else {
    /* Flip X coordinate of vertices if mesh matrix 
       has negative determinant */
    Lib3dsMatrix inv_matrix, M;
    Lib3dsVector tmp;

    lib3ds_matrix_copy(inv_matrix, mesh->matrix);
    lib3ds_matrix_inv(inv_matrix);
    lib3ds_matrix_copy(M, mesh->matrix);
    lib3ds_matrix_scale_xyz(M, -1.0f, 1.0f, 1.0f);
    lib3ds_matrix_mult(M, inv_matrix);

    for (i=0; i<mesh->points; ++i) {
      lib3ds_vector_transform(tmp, M, mesh->pointL[i].pos);
      lib3ds_io_write_vector(io, tmp);
    }
  }

  return(LIB3DS_TRUE);
}
コード例 #4
0
ファイル: gameswf_3ds_inst.cpp プロジェクト: CneoC/shinzui
	void x3ds_instance::create_mesh_list(Lib3dsMesh* mesh)
	{
		Lib3dsVector* normalL = (Lib3dsVector*) malloc(3 * sizeof(Lib3dsVector) * mesh->faces);
		Lib3dsMatrix m;
		lib3ds_matrix_copy(m, mesh->matrix);
		lib3ds_matrix_inv(m);
		glMultMatrixf(&m[0][0]);

		lib3ds_mesh_calculate_normals(mesh, normalL);

		Lib3dsMaterial* prev_mat = NULL;
		for (Uint32 p = 0; p < mesh->faces; ++p)
		{
			Lib3dsFace* f = &mesh->faceL[p];
			Lib3dsMaterial* mat = f->material[0] ? 
				lib3ds_file_material_by_name(m_def->m_file, f->material) : NULL;

			if (prev_mat != mat)
			{
				set_material(mat);
			}

			glBegin(GL_TRIANGLES);
			glNormal3fv(f->normal);
			for (int i = 0; i < 3; ++i)
			{
				glNormal3fv(normalL[3 * p + i]);
				if (mesh->texelL)
				{
					bind_material(mat, mesh->texelL[f->points[i]][1], mesh->texelL[f->points[i]][0]);
				}
				glVertex3fv(mesh->pointL[f->points[i]].pos);
			}
			glEnd();
			glDisable(GL_TEXTURE_2D);
		}

		free(normalL);
	}
コード例 #5
0
ファイル: file.c プロジェクト: NickDaniil/structured
static void
file_bounding_box_of_nodes_impl(Lib3dsNode *node, Lib3dsFile *file, Lib3dsBool include_meshes, 
                                Lib3dsBool include_cameras, Lib3dsBool include_lights, 
                                Lib3dsVector bmin, Lib3dsVector bmax)
{
  switch (node->type)
  {
    case LIB3DS_OBJECT_NODE:
      if (include_meshes) {
        Lib3dsMesh *mesh;

        mesh = lib3ds_file_mesh_by_name(file, node->data.object.instance);
        if (!mesh)
          mesh = lib3ds_file_mesh_by_name(file, node->name);
        if (mesh) {
          Lib3dsMatrix inv_matrix, M;
          Lib3dsVector v;
          unsigned i;

          lib3ds_matrix_copy(inv_matrix, mesh->matrix);
          lib3ds_matrix_inv(inv_matrix);
          lib3ds_matrix_copy(M, node->matrix);
          lib3ds_matrix_translate_xyz(M, -node->data.object.pivot[0], -node->data.object.pivot[1], -node->data.object.pivot[2]);
          lib3ds_matrix_mult(M, inv_matrix);

          for (i=0; i<mesh->points; ++i) {
            lib3ds_vector_transform(v, M, mesh->pointL[i].pos);
            lib3ds_vector_min(bmin, v);
            lib3ds_vector_max(bmax, v);
          }
        }
      }
      break;
   /*
    case LIB3DS_CAMERA_NODE:
    case LIB3DS_TARGET_NODE:
      if (include_cameras) {
        Lib3dsVector z,v;
        lib3ds_vector_zero(z);
        lib3ds_vector_transform(v, node->matrix, z);
        lib3ds_vector_min(bmin, v);
        lib3ds_vector_max(bmax, v);
      }
      break;

    case LIB3DS_LIGHT_NODE:
    case LIB3DS_SPOT_NODE:
      if (include_lights) {
        Lib3dsVector z,v;
        lib3ds_vector_zero(z);
        lib3ds_vector_transform(v, node->matrix, z);
        lib3ds_vector_min(bmin, v);
        lib3ds_vector_max(bmax, v);
      }
      break;
    */
  }
  {
    Lib3dsNode *p=node->childs;
    while (p) {
      file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax);
      p=p->next;
    }
  }
}
コード例 #6
0
ファイル: mesh.c プロジェクト: mcu786/my_OpenPilot_mods
/*!
 * \ingroup mesh
 */
Lib3dsBool
lib3ds_mesh_read(Lib3dsMesh *mesh, Lib3dsIo *io)
{
  Lib3dsChunk c;
  Lib3dsWord chunk;

  if (!lib3ds_chunk_read_start(&c, LIB3DS_N_TRI_OBJECT, io)) {
    return(LIB3DS_FALSE);
  }

  while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
    switch (chunk) {
      case LIB3DS_MESH_MATRIX:
        {
          int i,j;
          
          lib3ds_matrix_identity(mesh->matrix);
          for (i=0; i<4; i++) {
            for (j=0; j<3; j++) {
              mesh->matrix[i][j]=lib3ds_io_read_float(io);
            }
          }
        }
        break;
      case LIB3DS_MESH_COLOR:
        {
          mesh->color=lib3ds_io_read_byte(io);
        }
        break;
      case LIB3DS_POINT_ARRAY:
        {
          unsigned i,j;
          unsigned points;
          
          lib3ds_mesh_free_point_list(mesh);
          points=lib3ds_io_read_word(io);
          if (points) {
            if (!lib3ds_mesh_new_point_list(mesh, points)) {
              LIB3DS_ERROR_LOG;
              return(LIB3DS_FALSE);
            }
            for (i=0; i<mesh->points; ++i) {
              for (j=0; j<3; ++j) {
                mesh->pointL[i].pos[j]=lib3ds_io_read_float(io);
              }
            }
            ASSERT((!mesh->flags) || (mesh->points==mesh->flags));
            ASSERT((!mesh->texels) || (mesh->points==mesh->texels));
          }
        }
        break;
      case LIB3DS_POINT_FLAG_ARRAY:
        {
          unsigned i;
          unsigned flags;
          
          lib3ds_mesh_free_flag_list(mesh);
          flags=lib3ds_io_read_word(io);
          if (flags) {
            if (!lib3ds_mesh_new_flag_list(mesh, flags)) {
              LIB3DS_ERROR_LOG;
              return(LIB3DS_FALSE);
            }
            for (i=0; i<mesh->flags; ++i) {
              mesh->flagL[i]=lib3ds_io_read_word(io);
            }
            ASSERT((!mesh->points) || (mesh->flags==mesh->points));
            ASSERT((!mesh->texels) || (mesh->flags==mesh->texels));
          }
        }
        break;
      case LIB3DS_FACE_ARRAY:
        {
          lib3ds_chunk_read_reset(&c, io);
          if (!face_array_read(mesh, io)) {
            return(LIB3DS_FALSE);
          }
        }
        break;
      case LIB3DS_MESH_TEXTURE_INFO:
        {
          int i,j;

          for (i=0; i<2; ++i) {
            mesh->map_data.tile[i]=lib3ds_io_read_float(io);
          }
          for (i=0; i<3; ++i) {
            mesh->map_data.pos[i]=lib3ds_io_read_float(io);
          }
          mesh->map_data.scale=lib3ds_io_read_float(io);

          lib3ds_matrix_identity(mesh->map_data.matrix);
          for (i=0; i<4; i++) {
            for (j=0; j<3; j++) {
              mesh->map_data.matrix[i][j]=lib3ds_io_read_float(io);
            }
          }
          for (i=0; i<2; ++i) {
            mesh->map_data.planar_size[i]=lib3ds_io_read_float(io);
          }
          mesh->map_data.cylinder_height=lib3ds_io_read_float(io);
        }
        break;
      case LIB3DS_TEX_VERTS:
        {
          unsigned i;
          unsigned texels;
          
          lib3ds_mesh_free_texel_list(mesh);
          texels=lib3ds_io_read_word(io);
          if (texels) {
            if (!lib3ds_mesh_new_texel_list(mesh, texels)) {
              LIB3DS_ERROR_LOG;
              return(LIB3DS_FALSE);
            }
            for (i=0; i<mesh->texels; ++i) {
              mesh->texelL[i][0]=lib3ds_io_read_float(io);
              mesh->texelL[i][1]=lib3ds_io_read_float(io);
            }
            ASSERT((!mesh->points) || (mesh->texels==mesh->points));
            ASSERT((!mesh->flags) || (mesh->texels==mesh->flags));
          }
        }
        break;
      default:
        lib3ds_chunk_unknown(chunk);
    }
  }
  {
    unsigned j;

    for (j=0; j<mesh->faces; ++j) {
      ASSERT(mesh->faceL[j].points[0]<mesh->points);
      ASSERT(mesh->faceL[j].points[1]<mesh->points);
      ASSERT(mesh->faceL[j].points[2]<mesh->points);
      lib3ds_vector_normal(
        mesh->faceL[j].normal,
        mesh->pointL[mesh->faceL[j].points[0]].pos,
        mesh->pointL[mesh->faceL[j].points[1]].pos,
        mesh->pointL[mesh->faceL[j].points[2]].pos
      );
    }
  }

  if (lib3ds_matrix_det(mesh->matrix) < 0.0)
  {
    /* Flip X coordinate of vertices if mesh matrix 
       has negative determinant */
    Lib3dsMatrix inv_matrix, M;
    Lib3dsVector tmp;
    unsigned i;

    lib3ds_matrix_copy(inv_matrix, mesh->matrix);
    lib3ds_matrix_inv(inv_matrix);

    lib3ds_matrix_copy(M, mesh->matrix);
    lib3ds_matrix_scale_xyz(M, -1.0f, 1.0f, 1.0f);
    lib3ds_matrix_mult(M, inv_matrix);

    for (i=0; i<mesh->points; ++i) {
      lib3ds_vector_transform(tmp, M, mesh->pointL[i].pos);
      lib3ds_vector_copy(mesh->pointL[i].pos, tmp);
    }
  }

  lib3ds_chunk_read_end(&c, io);

  return(LIB3DS_TRUE);
}
コード例 #7
0
static void
create_node(Lib3dsFile *f, Lib3dsNode *node, FILE *o)
{
  Lib3dsMesh *mesh;
  
  if ((node->type==LIB3DS_OBJECT_NODE) && (strcmp(node->name,"$$$DUMMY")!=0)) {
    mesh=lib3ds_file_mesh_by_name(f, node->name);
    ASSERT(mesh);
    if (mesh) {
      Lib3dsObjectData *d=&node->data.object;

      fprintf(o, "\n\n##\n## Object: %s\n##\n", node->name);
      fprintf(o, "AttributeBegin\n");

      {
        Lib3dsMatrix N,M,X;
        lib3ds_matrix_copy(N, node->matrix);
        lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]);
        lib3ds_matrix_copy(M, mesh->matrix);
        lib3ds_matrix_inv(M);
        lib3ds_matrix_mul(X,N,M);
        rib_concat_transform(o, X);
      }
      {
        unsigned p;
	int i, j;
        Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces);
        lib3ds_mesh_calculate_normals(mesh, normalL);
	Lib3dsMaterial *lastmat = NULL;

	int nalloc = 256, nfaces = 0;
	float *P = (float *)malloc(nalloc*9*sizeof(float));
	float *N = (float *)malloc(nalloc*9*sizeof(float));
	float *uv = (float *)malloc(nalloc*6*sizeof(float));

        for (p=0; p<mesh->faces; ++p) {
          Lib3dsFace *face=&mesh->faceL[p];
          Lib3dsMaterial *mat=lib3ds_file_material_by_name(f, face->material);
          if (mat && mat != lastmat) {
	      char *Kdmap = NULL, *Omap = NULL;

	      flushpp(o, P, N, uv, nfaces);
	      nfaces = 0;
	      lastmat = mat;

	      if (mat->texture1_map.name[0]) {
		  Kdmap = GetTexture(o, mat->texture1_map.name, mat->texture1_mask.name, 0);
		  char *scale = malloc(strlen(Kdmap)+20);
		  strcpy(scale, Kdmap);
		  strcat(scale, "-scale");
		  fprintf(o, "Texture \"%s\" \"color\" \"scale\" \"texture tex1\" \"%s\" "
			  "\"color tex2\" [.8 .8 .8]\n", scale, Kdmap);
		  Kdmap = scale;
	      }
	      if (mat->opacity_map.name[0])
		  Omap = GetTexture(o, mat->opacity_map.name, mat->opacity_mask.name, 0);

	      char *bumpScale = NULL;
	      if (mat->bump_map.name[0]) {
		  char *Bmap = GetTexture(o, mat->bump_map.name, mat->bump_mask.name, 1);
		  bumpScale = malloc(strlen(Bmap)+20);
		  strcpy(bumpScale, Bmap);
		  strcat(bumpScale, "-scale");
		  fprintf(o, "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" \"%s\" "
			  "\"float tex2\" [.05]\n", bumpScale, Bmap);
	      }

	      fprintf(o, "Material \"uber\" ");
	      if (Kdmap) fprintf(o, "\"texture Kd\" \"%s\" ", Kdmap);
	      else       fprintf(o, "\"color Kd\" [%f %f %f] ",
				 mat->diffuse[0], mat->diffuse[1], mat->diffuse[2]);
	      if (Omap) fprintf(o, "\"texture opacity\" \"%s\" ", Omap);
	      else      fprintf(o, "\"color opacity\" [%f %f %f] ",
				1.f - mat->transparency,
				1.f - mat->transparency,
				1.f - mat->transparency);
	      fprintf(o, "\"color Ks\" [%f %f %f] "
		      "\"float roughness\" [%f] ",
		      mat->specular[0]*mat->shin_strength,
		      mat->specular[1]*mat->shin_strength,
		      mat->specular[2]*mat->shin_strength,
		      mat->shininess
		      );
//CO	      dumptex(o, "tex2", &mat->texture2_map); 
//CO	      dumptex(o, "tex2mask", &mat->texture2_mask);
//CO	      dumptex(o, "specular", &mat->specular_map); 
//CO	      dumptex(o, "specularmask", &mat->specular_mask);
//CO	      dumptex(o, "shininess", &mat->shininess_map); 
//CO	      dumptex(o, "shininessmask", &mat->shininess_mask);
//CO	      dumptex(o, "reflection", &mat->reflection_map); 
//CO	      dumptex(o, "reflectionmask", &mat->reflection_mask);
	      fprintf(o, "\n");

	      if (bumpScale)
		  fprintf(o, "\"float bumpmap\" \"%s\"\n", bumpScale);
          }
	  if (nfaces+1 == nalloc) {
	      nalloc *= 2;
	      P = (float *)realloc(P, nalloc*9*sizeof(float));
	      N = (float *)realloc(N, nalloc*9*sizeof(float));
	      uv = (float *)realloc(uv, nalloc*6*sizeof(float));
	  }

	  for (i = 0; i < 3; ++i) {
	      for (j = 0; j < 3; ++j) {
		  P[9*nfaces+3*i+j] = mesh->pointL[face->points[i]].pos[j];
		  N[9*nfaces+3*i+j] = normalL[3*p+i][j];
		  if (j != 2 && mesh->texelL) 
		      uv[6*nfaces+2*i+j] = mesh->texelL[face->points[i]][j];
	      }
	      if (!mesh->texelL) {
		  uv[6*nfaces+0] = 0;
		  uv[6*nfaces+1] = 0;
		  uv[6*nfaces+2] = 0;
		  uv[6*nfaces+3] = 1;
		  uv[6*nfaces+4] = 1;
		  uv[6*nfaces+5] = 0;
	      }
	  }
	  ++nfaces;
	}

	flushpp(o, P, N, uv, nfaces);
	free(P);
	free(N);
	free(uv);
        free(normalL);
      }
      nTextures = 0;
      fprintf(o, "AttributeEnd\n");
    }
  }
  {
    Lib3dsNode *n;
    for (n=node->childs; n; n=n->next) {
      create_node(f,n,o);
    }
  }
}
コード例 #8
0
    /*!
     * See \ref Loader3ds::loadFromFileToOneMesh
     */
    dcollide::Mesh* Loader3dsInternal::loadFromFileToOneMesh(const char* fileName, TextureInformation* textureInformation) {
        // AB:
        // we cannot load texture information here, because we are merging all
        // meshes into a single one.
        // -> adjusting the texels may still be possible, however if the model
        //    uses > 1 texture, we can't change that.

        mData->mProxy2Transformation.clear();
        mData->mProxy2TextureInformation.clear();
        if (!fileName) {
            throw dcollide::NullPointerException("fileName");
        }

        mFile = lib3ds_file_load(fileName);
        if (!mFile) {
            std::cout << dc_funcinfo << "unable to load " << fileName << std::endl;
            return 0;
        }

        // AB: some files don't store nodes and just want exactly one node per mesh.
        //     atm we don't support that.
        if (!mFile->nodes) {
            std::cout << dc_funcinfo << "File " << fileName << " does not contain any nodes. mesh-only files not supported currently." << std::endl;
            lib3ds_file_free(mFile);
            mFile = 0;
            return 0;
        }

        // 3ds stores several frames, we want the first
        lib3ds_file_eval(mFile, 0);

        std::list<Lib3dsNode*> nodes;
        Lib3dsNode* node = mFile->nodes;
        while (node) {
            nodes.push_back(node);
            node = node->next;
        }

        bool texelLoadError = false;
        std::vector<dcollide::Vector3> texels;
        std::vector<dcollide::Vertex*> vertices;
        std::vector<dcollide::Triangle*> triangles;
        std::vector<int> indices;
        while (!nodes.empty()) {
            Lib3dsNode* node = nodes.front();
            nodes.pop_front();

            for (Lib3dsNode* n = node->childs; n; n = n->next) {
                nodes.push_back(n);
            }

            // node->type can be object, light, camera, ...
            // -> only object nodes are relevant to us
            if (node->type != LIB3DS_OBJECT_NODE) {
                continue;
            }

            if (strcmp(node->name, "$$$DUMMY") == 0) {
                // AB: nodes with this name are only transformation nodes, i.e. they
                // don't have a mesh, only a matrix.
                continue;
            }

            unsigned int pointOffset = vertices.size();

            Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(mFile, node->name);
            Lib3dsMatrix origMeshMatrix;
            lib3ds_matrix_copy(origMeshMatrix, mesh->matrix);
            lib3ds_matrix_inv(origMeshMatrix); // 3ds stores inverted mesh matrix
            dcollide::Matrix meshMatrix(&origMeshMatrix[0][0]);
            dcollide::Matrix nodeMatrix(&node->matrix[0][0]);

            Lib3dsObjectData* data = &node->data.object;
            nodeMatrix.translate(dcollide::Vector3(-data->pivot[0], -data->pivot[1], -data->pivot[2]));

            dcollide::Matrix matrix = nodeMatrix;
            matrix.multiply(&meshMatrix);

            for (unsigned int i = 0; i < mesh->points; i++) {
                Lib3dsPoint* p = &mesh->pointL[i];
                dcollide::Vector3 pos;
                matrix.transform(&pos, dcollide::Vector3(
                            p->pos[0],
                            p->pos[1],
                            p->pos[2]
                            ));
                vertices.push_back(new dcollide::Vertex(pos));
            }

            for (unsigned int i = 0; i < mesh->faces; i++) {
                Lib3dsFace* f = &mesh->faceL[i];
                indices.push_back(f->points[0] + pointOffset);
                indices.push_back(f->points[1] + pointOffset);
                indices.push_back(f->points[2] + pointOffset);
            }

            if (textureInformation) {
                TextureInformation t = loadTextureInformation(node);
                const std::vector<dcollide::Vector3>& nodeTexels = t.getTexels();
                if (mesh->texelL && nodeTexels.size() != mesh->texels) {
                    dcollide::warning() << "texturing problem in " << fileName;
                    dcollide::warning() << "invalid texel count loaded: have=" << nodeTexels.size() << " expected=" << mesh->texels;
                    dcollide::warning() << "adding dummy texels...";
                    for (unsigned int i = 0; i < mesh->texels; i++) {
                        texels.push_back(dcollide::Vector3(0.0, 0.0, 0.0));
                    }
//                    texelLoadError = true;
                } else {
                    for (unsigned int i = 0; i < nodeTexels.size(); i++) {
                        texels.push_back(nodeTexels[i]);
                    }
                }
            }
        }

        if (textureInformation) {
            if (!texelLoadError) {
                textureInformation->setTextured(true);
                textureInformation->setTextureFileName("deformable.tga");
                textureInformation->setTexels(texels);
            } else {
                textureInformation->setTextured(false);
            }
        }

        lib3ds_file_free(mFile);
        mFile = 0;

        dcollide::Mesh* mesh = new dcollide::Mesh(vertices, indices);
        return mesh;
    }
コード例 #9
0
    /*!
     * \internal
     *
     * \return A new mesh object containing the mesh in \p node, or NULL if no such
     * mesh can be found.
     */
    dcollide::Shape* Loader3dsInternal::createShape(Lib3dsNode* node, Lib3dsMatrix* translateRotateMatrix) {
        if (!node) {
            return 0;
        }
        if (node->type != LIB3DS_OBJECT_NODE) {
            return 0;
        }
        if (strcmp(node->name, "$$$DUMMY") == 0) {
            // AB: nodes with this name are only transformation nodes, i.e. they
            // don't have a mesh, only a matrix.
            return 0;
        }
        Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(mFile, node->name);
        if (!mesh) {
            std::cout << "Cannot find mesh " << node->name << " in 3ds file" << std::endl;
            return 0;
        }
        if (mesh->faces < 1) {
            std::cerr << "No faces in mesh " << node->name << std::endl;
            return 0;
        }
        if (mesh->points < 3) {
            std::cerr << "Less than 3 points in mesh " << node->name << std::endl;
            return 0;
        }

        Lib3dsMatrix origMeshMatrix;
        lib3ds_matrix_copy(origMeshMatrix, mesh->matrix);
        lib3ds_matrix_inv(origMeshMatrix); // 3ds stores inverted mesh matrix
        dcollide::Matrix meshMatrix(&origMeshMatrix[0][0]);


        // AB: Ogre does not apply "scale" values to child nodes, lib3ds does.
        //     so to display the model correctly we remove the scale completely
        //     (we integrate it directly into the vertices).
        //     to do this:
        //       let M:=the lib3ds matrix the point is normally transformed by
        //              (i.e. including the parent-node matrix)
        //       let M':=the matrix d-collide will use (i.e.
        //               translation+rotation only, no scale)
        //     then for every vertex v the correct transformed position p is:
        //       Mv=p
        //     we search for a vertex v' so that:
        //       M'v'=p
        //     since we have M and v (and thus p) and M' we can do this like
        //     this:
        //       v'=(M'^-1)p
        //     which equals:
        //       v'=(M'^-1)Mv

        dcollide::Matrix nodeMatrix(&node->matrix[0][0]); // M
        Lib3dsMatrix invertedTranslateRotate3ds;
        lib3ds_matrix_copy(invertedTranslateRotate3ds, *translateRotateMatrix);
        lib3ds_matrix_inv(invertedTranslateRotate3ds);
        dcollide::Matrix invertedTranslateRotate(&invertedTranslateRotate3ds[0][0]); // M'^-1
        dcollide::Matrix removeScaleMatrix(invertedTranslateRotate);
        removeScaleMatrix.multiply(&nodeMatrix);

        Lib3dsObjectData* data = &node->data.object;
        std::vector<dcollide::Vertex*> vertices(mesh->points);
        for (unsigned int i = 0; i < mesh->points; i++) {
            Lib3dsPoint* p = &mesh->pointL[i];
            dcollide::Vector3 meshPos;
            meshMatrix.transform(&meshPos, dcollide::Vector3(
                        p->pos[0] - data->pivot[0],
                        p->pos[1] - data->pivot[1],
                        p->pos[2] - data->pivot[2]));

            dcollide::Vector3 pos;
            removeScaleMatrix.transform(&pos, meshPos);

            vertices[i] = new dcollide::Vertex(pos);
        }

        std::vector<int> indices(mesh->faces * 3);
        for (unsigned int i = 0; i < mesh->faces; i++) {
            Lib3dsFace* f = &mesh->faceL[i];
            indices[i * 3 + 0] = f->points[0];
            indices[i * 3 + 1] = f->points[1];
            indices[i * 3 + 2] = f->points[2];
        }

        dcollide::Mesh* newMesh = new dcollide::Mesh(vertices, indices);

        return newMesh;
    }
コード例 #10
0
ファイル: MK_Models.cpp プロジェクト: miguel28/WatchDog
// this code is rewritten from player.c example that came with lib3ds
// what it does is render a node from our model
void Model::renderNode(Lib3dsNode *node)
{
	ASSERT(file); //this is for debugging
	{
		Lib3dsNode *tmp;
		for(tmp = node->childs;tmp != 0;tmp = tmp->next)
			renderNode(tmp); //render all child nodes of this note
	}
	if(node->type == LIB3DS_OBJECT_NODE) //check wheter the node is a 3ds node
	{
		
		if(! node->user.d) //Wheter we have a list or not, if not we're gonna create one
		{
			
			Lib3dsMesh *mesh = lib3ds_file_mesh_by_name(file, node->name); //get all the meshes of the current node
			ASSERT(mesh); //for debugging in case we don't have a mesh
			if(! mesh)
				return;
			node->user.d = glGenLists(1); //alocate memory for one list
			/////////////////////////////////////////////////////////////	
			if(glGetError() != GL_NO_ERROR)
			{
				cout << "ERROR!\n";
				exit(0);
			}
			/////////////////////////////////////////////////////////////	
			glNewList(node->user.d, GL_COMPILE); //here we create our list
			{
				unsigned p;
				Lib3dsVector *normals;
				normals = static_cast<float(*)[3]> (std::malloc (3*sizeof(Lib3dsVector)*mesh->faces)); //alocate memory for our normals
				{
					Lib3dsMatrix m;
					lib3ds_matrix_copy(m, mesh->matrix); //copy the matrix of the mesh in our temporary matrix
					lib3ds_matrix_inv(m);
					glMultMatrixf(&m[0][0]); //adjust our current matrix to the matrix of the mesh
				}
				lib3ds_mesh_calculate_normals(mesh, normals); //calculate the normals of the mesh
				int j = 0;
				for(p = 0;p < mesh->faces;p++)
				{
					Lib3dsFace *f = &mesh->faceL[p];
					Lib3dsMaterial *mat=0;
					if(f->material[0]) //if the face of the mesh has material properties
						mat = lib3ds_file_material_by_name(file, f->material); //read material properties from file
					if(mat) //if we have material
					{
						static GLfloat ambient[4] = { 0.0, 0.0, 0.0, 1.0 };
						glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); // Ambient color
						glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); //diffuse color
						glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); //specular color
						float shine;
						shine = pow(2, 10.0 * mat->shininess);
						if(shine > 128.0)
							shine = 128.0;
						glMaterialf(GL_FRONT, GL_SHININESS, shine);
					}
					else // if we do not have material properties, we have to set them manually
					{
						GLfloat diff[4] = { 0.75, 0.75, 0.75, 1.0 }; // color: white/grey
						GLfloat amb[4] = { 0.25, 0.25, 0.25, 1.0 }; //color: black/dark gray
						GLfloat spec[4] = { 0.0, 0.0, 0.0, 1.0 }; //color: completly black
						glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
						glMaterialfv(GL_FRONT, GL_AMBIENT, amb);
						glMaterialfv(GL_FRONT, GL_AMBIENT, spec);
					}
					{
						if(mesh->texels)
						{
							glBindTexture(GL_TEXTURE_2D, textureIndices.at(j));
							j++;
						}
						glBegin(GL_TRIANGLES);
						for(int i = 0;i < 3;i++)
						{
							glNormal3fv(normals[3*p+i]); //set normal vector of that point
							if(mesh->texels)
								glTexCoord2f(mesh->texelL[f->points[i]][0], mesh->texelL[f->points[i]][1]);
							glVertex3fv(mesh->pointL[f->points[i]].pos); //Draw the damn triangle
						}
						glEnd();
					}
				}
				free(normals); //free up memory
			}
			glEndList(); // end of list
		}
		if(node->user.d) // if we have created a link list(with glNewList)
		{
			Lib3dsObjectData *tmpdat;
			glPushMatrix(); //save transformation values
			tmpdat = &node->data.object; // get the position data
			glMultMatrixf(&node->matrix[0][0]); //adjust matrix according to the node
			glTranslatef(-tmpdat->pivot[0], -tmpdat->pivot[1], -tmpdat->pivot[2]); //move to the right place;
			glCallList(node->user.d); //render node
			glPopMatrix(); //return transformation original values
		}
	}	 
}
コード例 #11
0
ファイル: Object_3DS.cpp プロジェクト: OpenGelo/Map2DFusion
void Object_3DS::renderNode(Lib3dsNode *node)
{
#ifdef HAS_LIB3DS
    for (Lib3dsNode* p=node->childs; p!=0; p=p->next)
      renderNode(p);

    if (node->type == LIB3DS_OBJECT_NODE)
      {
        if (strcmp(node->name,"$$$DUMMY")==0)
      return;

        if (!node->user.d)
      {
        Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(file, node->name);
        if (!mesh)
          return;
        MSG_INFO("Rendering node %s",node->name);
        MSG_INFO("Face number: %d",mesh->faces);
//        return ;
        node->user.d = glGenLists(1);
        glNewList(node->user.d, GL_COMPILE);

        Lib3dsVector *normalL = new Lib3dsVector[3*mesh->faces];

        Lib3dsMatrix M;
        lib3ds_matrix_copy(M, mesh->matrix);
        lib3ds_matrix_inv(M);
        glMultMatrixf(&M[0][0]);

        lib3ds_mesh_calculate_normals(mesh, normalL);

        for (unsigned int p=0; p<mesh->faces; ++p)
          {
            Lib3dsFace *f=&mesh->faceL[p];
            Lib3dsMaterial *mat=0;
            if (f->material[0])
          mat=lib3ds_file_material_by_name(file, f->material);

            if (mat)
          {
            static GLfloat a[4]={0,0,0,1};
            float s;
            glMaterialfv(GL_FRONT, GL_AMBIENT, a);
            glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);
            glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);
            s = pow(2, 10.0*mat->shininess);
            if (s>128.0)
              s=128.0;
            glMaterialf(GL_FRONT, GL_SHININESS, s);
          }
            else
          {
            Lib3dsRgba a={0.2, 0.2, 0.2, 1.0};
            Lib3dsRgba d={0.8, 0.8, 0.8, 1.0};
            Lib3dsRgba s={0.0, 0.0, 0.0, 1.0};
            glMaterialfv(GL_FRONT, GL_AMBIENT, a);
            glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
            glMaterialfv(GL_FRONT, GL_SPECULAR, s);
          }

            glBegin(GL_TRIANGLES);
            glNormal3fv(f->normal);
            for (int i=0; i<3; ++i)
          {
            glNormal3fv(normalL[3*p+i]);
            glVertex3fv(mesh->pointL[f->points[i]].pos);
          }
            glEnd();
          }

        delete[] normalL;

        glEndList();
      }

        if (node->user.d)
      {
        glPushMatrix();
        Lib3dsObjectData* d = &node->data.object;
        glMultMatrixf(&node->matrix[0][0]);
        glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]);
        glCallList(node->user.d);
        glPopMatrix();
      }
      }
#endif
}
コード例 #12
0
ファイル: 3dsplay.c プロジェクト: gdh1995/GhostFace
/*!
* 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();
}
コード例 #13
0
ファイル: m3ds.cpp プロジェクト: anirul/3DStereo
void m3ds::render_node(Lib3dsNode* node) {
	assert(m_file);
	{
		Lib3dsNode* p;
		for (p = node->childs; p != 0; p = p->next)
			render_node(p);
	}
	if (node->type == LIB3DS_OBJECT_NODE) {
		if (!strcmp(node->name, "$$$DUMMY")) return;
		if (!node->user.d) {
			Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(m_file, node->name);
			assert(mesh);
			if (!mesh)
				return;
			node->user.d = glGenLists(1);
			glNewList(node->user.d, GL_COMPILE);
			{
				unsigned int p;
				Lib3dsVector* normalL = new Lib3dsVector[3 * mesh->faces];
				{
					Lib3dsMatrix M;
					lib3ds_matrix_copy(M, mesh->matrix);
					lib3ds_matrix_inv(M);
					glMultMatrixf(&M[0][0]);
				}
				lib3ds_mesh_calculate_normals(mesh, normalL);

				for (p = 0; p < mesh->faces; ++p) {
					Lib3dsFace* f = &mesh->faceL[p];
					Lib3dsMaterial* mat = 0;
					if (f->material[0]) {
						mat = lib3ds_file_material_by_name(m_file, f->material);
						if (mat->texture1_map.name[0]) {
							std::string str = mat->texture1_map.name;
							std::map<std::string, texture*>::iterator ite;
							ite = texlib::instance()->find(str);
							if (ite == texlib::instance()->end()) {
								texture* pt = NULL;
								char str2[512];
								memset(str2, 0, 512);
								sprintf(str2, "%s%s", s_prefix, str.c_str());
								char* ext = &str2[strlen(str2) - 3];
								ext[0] = tolower(ext[0]);
								ext[1] = tolower(ext[1]);
								ext[2] = tolower(ext[2]);
								if (!strcmp(ext, "tga")) {
									tga_tex* tex = new tga_tex(str2);
									if (tex->get_tex_id() != -1) {
										pt = tex;
										texlib::instance()->insert(texlib::value_type(str, pt));
									}
								} else if (!strcmp(ext, "bmp")) {
									bmp_tex* tex = new bmp_tex(str2);
									if (tex->get_tex_id() != -1) {
										pt = tex;
										texlib::instance()->insert(texlib::value_type(str, pt));
									}
								} else if (!strcmp(ext, "pcx")) {
									pcx_tex* tex = new pcx_tex(str2);
									if (tex->get_tex_id() != -1) {
										pt = tex;
										texlib::instance()->insert(texlib::value_type(str, pt));
									}
								} else {
									ext[0] = 't';
									ext[1] = 'g';
									ext[2] = 'a';
									tga_tex* tex = new tga_tex(str2);
//									str = str2;
									if (tex->get_tex_id() != -1) {
										pt = tex;
									} else {
										pt = texlib::instance()->operator[]("default.tga");
									}
									texlib::instance()->insert(texlib::value_type(str, pt));
								}
								glBindTexture(GL_TEXTURE_2D, (pt) ? pt->get_tex_id() :
									((*texlib::instance())["default.tga"])->get_tex_id());
							} else {
								glBindTexture(GL_TEXTURE_2D, (ite->second)->get_tex_id());
							}
						}	
					}
					if (mat) {
						static GLfloat a[4] = {0.0f, 0.0f, 0.0f, 1.0f};
						float s;
						glMaterialfv(GL_FRONT, GL_AMBIENT, a);
						glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);
						glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);
						s = pow(2.0f, 10.0f * mat->shininess);
						if (s > 128.0) s = 128.0;
						glMaterialf(GL_FRONT, GL_SHININESS, s);
					} else {
						Lib3dsRgba a = {0.2f, 0.2f, 0.2f, 1.0f};
						Lib3dsRgba d = {0.8f, 0.8f, 0.8f, 1.0f};
						Lib3dsRgba s = {0.0f, 0.0f, 0.0f, 1.0f};
						glMaterialfv(GL_FRONT, GL_AMBIENT, a);
						glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
						glMaterialfv(GL_FRONT, GL_SPECULAR, s);
					}
					glBegin(GL_TRIANGLES);
						glNormal3fv(f->normal);
						for (int i = 0; i < 3; ++i) {
							assert(mesh);
							if (mesh->texelL)
								glTexCoord2fv(mesh->texelL[f->points[i]]);
							glNormal3fv(normalL[3 * p + i]);
							glVertex3fv(mesh->pointL[f->points[i]].pos);
						}
					glEnd();
				}
				delete [] normalL;
			}
			glEndList();
		}
		if (node->user.d) {
			Lib3dsObjectData* d;
			glPushMatrix();
			d = &node->data.object;
			glMultMatrixf(&node->matrix[0][0]);
			glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]);
			glCallList(node->user.d);
			glPopMatrix();
		}
	}
}
コード例 #14
0
void
lib3ds_mesh_read(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) {
    Lib3dsChunk c;
    uint16_t chunk;

    lib3ds_chunk_read_start(&c, CHK_N_TRI_OBJECT, io);

    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
        switch (chunk) {
            case CHK_MESH_MATRIX: {
                int i, j;

                lib3ds_matrix_identity(mesh->matrix);
                for (i = 0; i < 4; i++) {
                    for (j = 0; j < 3; j++) {
                        mesh->matrix[i][j] = lib3ds_io_read_float(io);
                    }
                }
                break;
            }

            case CHK_MESH_COLOR: {
                mesh->color = lib3ds_io_read_byte(io);
                break;
            }

            case CHK_POINT_ARRAY: {
                int i;
                uint16_t nvertices = lib3ds_io_read_word(io);
                lib3ds_mesh_resize_vertices(mesh, nvertices, mesh->texcos != NULL, mesh->vflags != NULL);
                for (i = 0; i < mesh->nvertices; ++i) {
                    lib3ds_io_read_vector(io, mesh->vertices[i]);
                }
                break;
            }

            case CHK_POINT_FLAG_ARRAY: {
                int i;
                uint16_t nflags = lib3ds_io_read_word(io);
                uint16_t nvertices = (mesh->nvertices >= nflags)? mesh->nvertices : nflags;
                lib3ds_mesh_resize_vertices(mesh, nvertices, mesh->texcos != NULL, 1);
                for (i = 0; i < nflags; ++i) {
                    mesh->vflags[i] = lib3ds_io_read_word(io);
                }
                break;
            }

            case CHK_FACE_ARRAY: {
                lib3ds_chunk_read_reset(&c, io);
                face_array_read(file, mesh, io);
                break;
            }

            case CHK_MESH_TEXTURE_INFO: {
                int i, j;

                //FIXME: mesh->map_type = lib3ds_io_read_word(io);

                for (i = 0; i < 2; ++i) {
                    mesh->map_tile[i] = lib3ds_io_read_float(io);
                }
                for (i = 0; i < 3; ++i) {
                    mesh->map_pos[i] = lib3ds_io_read_float(io);
                }
                mesh->map_scale = lib3ds_io_read_float(io);

                lib3ds_matrix_identity(mesh->map_matrix);
                for (i = 0; i < 4; i++) {
                    for (j = 0; j < 3; j++) {
                        mesh->map_matrix[i][j] = lib3ds_io_read_float(io);
                    }
                }
                for (i = 0; i < 2; ++i) {
                    mesh->map_planar_size[i] = lib3ds_io_read_float(io);
                }
                mesh->map_cylinder_height = lib3ds_io_read_float(io);
                break;
            }

            case CHK_TEX_VERTS: {
                int i;
                uint16_t ntexcos = lib3ds_io_read_word(io);
                uint16_t nvertices = (mesh->nvertices >= ntexcos)? mesh->nvertices : ntexcos;;
                if (!mesh->texcos) {
                    lib3ds_mesh_resize_vertices(mesh, nvertices, 1, mesh->vflags != NULL);
                }
                for (i = 0; i < ntexcos; ++i) {
                    mesh->texcos[i][0] = lib3ds_io_read_float(io);
                    mesh->texcos[i][1] = lib3ds_io_read_float(io);
                }
                break;
            }

            default:
                lib3ds_chunk_unknown(chunk, io);
        }
    }

    if (lib3ds_matrix_det(mesh->matrix) < 0.0) {
        /* Flip X coordinate of vertices if mesh matrix
           has negative determinant */
        float inv_matrix[4][4], M[4][4];
        float tmp[3];
        int i;

        lib3ds_matrix_copy(inv_matrix, mesh->matrix);
        lib3ds_matrix_inv(inv_matrix);

        lib3ds_matrix_copy(M, mesh->matrix);
        lib3ds_matrix_scale(M, -1.0f, 1.0f, 1.0f);
        lib3ds_matrix_mult(M, M, inv_matrix);

        for (i = 0; i < mesh->nvertices; ++i) {
            lib3ds_vector_transform(tmp, M, mesh->vertices[i]);
            lib3ds_vector_copy(mesh->vertices[i], tmp);
        }
    }

    lib3ds_chunk_read_end(&c, io);
}
コード例 #15
0
ファイル: 3dsplay.c プロジェクト: kasicass/frustum
/*!
 *
 */
static void
render_node(Lib3dsNode *node)
{
  ASSERT(file);

  {
    Lib3dsNode *p;
    for (p=node->childs; p!=0; p=p->next) {
      render_node(p);
    }
  }
  if (node->type==LIB3DS_OBJECT_NODE) {
    if (strcmp(node->name,"$$$DUMMY")==0) {
      return;
    }

    if (!node->user.d) {
      Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(file, node->name);
      ASSERT(mesh);
      if (!mesh) {
        return;
      }

      node->user.d=glGenLists(1);
      glNewList(node->user.d, GL_COMPILE);

      {
        unsigned p;
        Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces);

        {
          Lib3dsMatrix M;
          lib3ds_matrix_copy(M, mesh->matrix);
          lib3ds_matrix_inv(M);
          glMultMatrixf(&M[0][0]);
        }
        lib3ds_mesh_calculate_normals(mesh, normalL);

        for (p=0; p<mesh->faces; ++p) {
          Lib3dsFace *f=&mesh->faceL[p];
          Lib3dsMaterial *mat=0;
          if (f->material[0]) {
            mat=lib3ds_file_material_by_name(file, f->material);
          }
          if (mat) {
            float s[1];
            s[0]=1.0;
            glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient);
            glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);
            glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);
            glMaterialf(GL_FRONT, GL_SHININESS, 11.0-0.2*mat->shininess);
          }
          else {
            Lib3dsRgba a={0.2, 0.2, 0.2, 1.0};
            Lib3dsRgba d={0.8, 0.8, 0.8, 1.0};
            Lib3dsRgba s={0.0, 0.0, 0.0, 1.0};
            glMaterialfv(GL_FRONT, GL_AMBIENT, a);
            glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
            glMaterialfv(GL_FRONT, GL_SPECULAR, s);
          }
          {
            int i;
            glBegin(GL_TRIANGLES);
              glNormal3fv(f->normal);
              for (i=0; i<3; ++i) {
                glNormal3fv(normalL[3*p+i]);
                glVertex3fv(mesh->pointL[f->points[i]].pos);
              }
            glEnd();
          }
        }

        free(normalL);
      }

      glEndList();
    }

    if (node->user.d) {
      Lib3dsObjectData *d;

      glPushMatrix();
      d=&node->data.object;
      glMultMatrixf(&node->matrix[0][0]);
      glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]);
      glCallList(node->user.d);
      /*glutSolidSphere(50.0, 20,20);*/
      glPopMatrix();
    }
  }
}
コード例 #16
0
ファイル: 3dsply.cpp プロジェクト: OS2World/LIB-Lib3ds
/*!
* Render node recursively, first children, then parent.
* Each node receives its own OpenGL display list.
*/
static void
render_node(Lib3dsNode *node) {
	assert(file);
	
	
	{
		Lib3dsNode *p;
		for (p = node->childs; p != 0; p = p->next) {
			render_node(p);
		}
	}
	if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
		int index;
		Lib3dsMesh *mesh;
		Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
		
		
		if (strcmp(node->name, "$$$DUMMY") == 0) {
			return;
		}
		
		
		index = lib3ds_file_mesh_by_name(file, n->instance_name);
		if (index < 0)
			index = lib3ds_file_mesh_by_name(file, node->name);
		if (index < 0) {
			return;
		}
		mesh = file->meshes[index];
		
		
		if (!mesh->user_id) {
			assert(mesh);
			
			
			mesh->user_id = glGenLists(1);
			glNewList(mesh->user_id, GL_COMPILE);
			
			
			{
				int p;
				float (*normalL)[3] = (float(*)[3])malloc(3 * 3 * sizeof(float) * mesh->nfaces);
				Lib3dsMaterial *oldmat = (Lib3dsMaterial *) - 1;
				{
					float M[4][4];
					lib3ds_matrix_copy(M, mesh->matrix);
					lib3ds_matrix_inv(M);
					glMultMatrixf(&M[0][0]);
				}
				lib3ds_mesh_calculate_vertex_normals(mesh, normalL);
				
				
				for (p = 0; p < mesh->nfaces; ++p) {
					Lib3dsMaterial *mat = 0;
#ifdef USE_SDL
					Player_texture *pt = NULL;
					int tex_mode = 0;
#endif
					if (mesh->faces[p].material > 0) {
						mat = file->materials[mesh->faces[p].material];
					}
					
					
					if (mat != oldmat) {
						if (mat) {
							if (mat->two_sided)
								glDisable(GL_CULL_FACE);
							else
								glEnable(GL_CULL_FACE);
							
							
							glDisable(GL_CULL_FACE);
							
							
							/* Texturing added by Gernot < *****@*****.** > */
							
							
							if (mat->texture1_map.name[0]) { /* texture map? */
								Lib3dsTextureMap *tex = &mat->texture1_map;
								if (!tex->user_ptr) { /* no player texture yet? */
									char texname[1024];
									pt = (Player_texture*)malloc(sizeof(*pt));
									tex->user_ptr = pt;
									//snprintf(texname, sizeof(texname), "%s/%s", datapath, tex->name);
									strcpy(texname, datapath);
									strcat(texname, "/");
									strcat(texname, tex->name);
#ifdef DEBUG
									printf("Loading texture map, name %s\n", texname);
#endif /* DEBUG */
#ifdef USE_SDL
#ifdef USE_SDL_IMG_load
									pt->bitmap = IMG_load(texname);
#else
									pt->bitmap = IMG_Load(texname);
#endif /* IMG_Load */
									
									
#else /* USE_SDL */
									pt->bitmap = NULL;
									fputs("3dsplayer: Warning: No image loading support, skipping texture.\n", stderr);
#endif /* USE_SDL */
									if (pt->bitmap) { /* could image be loaded ? */
																		/* this OpenGL texupload code is incomplete format-wise!
																		* to make it complete, examine SDL_surface->format and
																		* tell us @lib3ds.sf.net about your improvements :-)
										*/
										int upload_format = GL_RED; /* safe choice, shows errors */
#ifdef USE_SDL
										int bytespp = pt->bitmap->format->BytesPerPixel;
										void *pixel = NULL;
										glGenTextures(1, &pt->tex_id);
#ifdef DEBUG
										printf("Uploading texture to OpenGL, id %d, at %d bytepp\n",
											pt->tex_id, bytespp);
#endif /* DEBUG */
										if (pt->bitmap->format->palette) {
											pixel = convert_to_RGB_Surface(pt->bitmap);
											upload_format = GL_RGBA;
										} else {
											pixel = pt->bitmap->pixels;
											/* e.g. this could also be a color palette */
											if (bytespp == 1) upload_format = GL_LUMINANCE;
											else if (bytespp == 3) upload_format = GL_RGB;
											else if (bytespp == 4) upload_format = GL_RGBA;
										}
										glBindTexture(GL_TEXTURE_2D, pt->tex_id);
										glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
											TEX_XSIZE, TEX_YSIZE, 0,
											GL_RGBA, GL_UNSIGNED_BYTE, NULL);
										glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
										glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
										glTexParameteri(GL_TEXTURE_2D,
											GL_TEXTURE_MAG_FILTER, GL_LINEAR);
										glTexParameteri(GL_TEXTURE_2D,
											GL_TEXTURE_MIN_FILTER, GL_LINEAR);
										glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
										glTexSubImage2D(GL_TEXTURE_2D,
											0, 0, 0, pt->bitmap->w, pt->bitmap->h,
											upload_format, GL_UNSIGNED_BYTE, pixel);
										pt->scale_x = (float)pt->bitmap->w / (float)TEX_XSIZE;
										pt->scale_y = (float)pt->bitmap->h / (float)TEX_YSIZE;
#endif /* USE_SDL */
										pt->valid = 1;
									} else {
										fprintf(stderr,
											"Load of texture %s did not succeed "
											"(format not supported !)\n",
											texname);
										pt->valid = 0;
									}
								} else {
									pt = (Player_texture *)tex->user_ptr;
								}
								tex_mode = pt->valid;
							} else {
								tex_mode = 0;
							}
							
							
							{
								float a[4], d[4], s[4];
								int i;
								for (i=0; i<3; ++i) {
									a[i] = mat->ambient[i];
									d[i] = mat->diffuse[i];
									s[i] = mat->specular[i];
								}
								a[3] = d[3] = s[3] = 1.0f;
								
								glMaterialfv(GL_FRONT, GL_AMBIENT, a);
								glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
								glMaterialfv(GL_FRONT, GL_SPECULAR, s);
							}
							glMaterialf(GL_FRONT, GL_SHININESS, pow(2, 10.0*mat->shininess));
 } else {
	 static const float a[4] = {0.7, 0.7, 0.7, 1.0};
	 static const float d[4] = {0.7, 0.7, 0.7, 1.0};
	 static const float s[4] = {1.0, 1.0, 1.0, 1.0};
	 glMaterialfv(GL_FRONT, GL_AMBIENT, a);
	 glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
	 glMaterialfv(GL_FRONT, GL_SPECULAR, s);
	 glMaterialf(GL_FRONT, GL_SHININESS, pow(2, 10.0*0.5));
 }
 oldmat = mat;
 }
 
 
 else if (mat != NULL && mat->texture1_map.name[0]) {
	 Lib3dsTextureMap *tex = &mat->texture1_map;
	 if (tex != NULL && tex->user_ptr != NULL) {
		 pt = (Player_texture *)tex->user_ptr;
		 tex_mode = pt->valid;
	 }
 }
 
 
 
 
 {
	 int i;
	 
#ifndef USE_GL10
	 if (tex_mode) {
		 //printf("Binding texture %d\n", pt->tex_id);
		 glEnable(GL_TEXTURE_2D);
		 glBindTexture(GL_TEXTURE_2D, pt->tex_id);
	 }
#endif	 
	 
#if 0
	 {
		 float v1[3], n[3], v2[3];
		 glBegin(GL_LINES);
		 for (i = 0; i < 3; ++i) {
			 lib3ds_vector_copy(v1, mesh->vertices[f->points[i]]);
			 glVertex3fv(v1);
			 lib3ds_vector_copy(n, normalL[3*p+i]);
			 lib3ds_vector_scalar(n, 10.f);
			 lib3ds_vector_add(v2, v1, n);
			 glVertex3fv(v2);
		 }
		 glEnd();
	 }
#endif
	 
	 
	 glBegin(GL_TRIANGLES);
	 for (i = 0; i < 3; ++i) {
		 glNormal3fv(normalL[3*p+i]);
		 
		 
		 if (tex_mode) {
			 glTexCoord2f(
				 mesh->texcos[mesh->faces[p].index[i]][1]*pt->scale_x,
				 pt->scale_y - mesh->texcos[mesh->faces[p].index[i]][0]*pt->scale_y);
		 }
		 
		 
		 glVertex3fv(mesh->vertices[mesh->faces[p].index[i]]);
	 }
	 glEnd();
	 
	 
	 if (tex_mode)
		 glDisable(GL_TEXTURE_2D);
 }
 }
 
 
 free(normalL);
 }
 
 
 glEndList();
 }
 
 
 if (mesh->user_id) {
	 glPushMatrix();
	 glMultMatrixf(&node->matrix[0][0]);
	 glTranslatef(-n->pivot[0], -n->pivot[1], -n->pivot[2]);
	 glCallList(mesh->user_id);
	 /* glutSolidSphere(50.0, 20,20); */
	 glPopMatrix();
	 if (flush)
		 glFlush();
 }
 }
}
コード例 #17
0
ファイル: 3ds2rib.c プロジェクト: Neoniet/upspring
static void
create_node(Lib3dsFile *f, Lib3dsNode *node, FILE *o)
{
  Lib3dsMesh *mesh;
  
  if ((node->type==LIB3DS_OBJECT_NODE) && (strcmp(node->name,"$$$DUMMY")!=0)) {
    mesh=lib3ds_file_mesh_by_name(f, node->name);
    ASSERT(mesh);
    if (mesh) {
      Lib3dsObjectData *d=&node->data.object;
      
      fprintf(o, "AttributeBegin\n");
      fprintf(o, "Surface \"matte\" \"Kd\" [0.75]\n");
      fprintf(o, "Color 1 1 1\n");

      {
        Lib3dsMatrix N,M,X;
        lib3ds_matrix_copy(N, node->matrix);
        lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]);
        lib3ds_matrix_copy(M, mesh->matrix);
        lib3ds_matrix_inv(M);
        lib3ds_matrix_mul(X,N,M);
        rib_concat_transform(o, X);
      }
      {
        unsigned p;
        Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces);
        lib3ds_mesh_calculate_normals(mesh, normalL);
        
        for (p=0; p<mesh->faces; ++p) {
          Lib3dsFace *face=&mesh->faceL[p];
          Lib3dsMaterial *mat=lib3ds_file_material_by_name(f, face->material);
          if (mat) {
            fprintf(o, "Color [%f %f %f]\n",
              mat->diffuse[0],
              mat->diffuse[1],
              mat->diffuse[2]
            );
            fprintf(o,
              "Surface "
              "\"lib3dsmaterial\" "
              "\"color specularcolor\" [%f %f %f] "
              "\"float shininess \" [%f] "
              "\"float shin_stength \" [%f] "
              "\n",
              mat->specular[0],
              mat->specular[1],
              mat->specular[2],
              mat->shininess,
              mat->shin_strength
            );
          }
          fprintf(o, "Polygon \"P\" [%f %f %f %f %f %f %f %f %f] ",
            mesh->pointL[face->points[0]].pos[0],
            mesh->pointL[face->points[0]].pos[1],
            mesh->pointL[face->points[0]].pos[2],
            mesh->pointL[face->points[1]].pos[0],
            mesh->pointL[face->points[1]].pos[1],
            mesh->pointL[face->points[1]].pos[2],
            mesh->pointL[face->points[2]].pos[0],
            mesh->pointL[face->points[2]].pos[1],
            mesh->pointL[face->points[2]].pos[2] 
          );

          fprintf(o, "\"N\" [%f %f %f %f %f %f %f %f %f] ",
            normalL[3*p+0][0],
            normalL[3*p+0][1],
            normalL[3*p+0][2],
            normalL[3*p+1][0],
            normalL[3*p+1][1],
            normalL[3*p+1][2],
            normalL[3*p+2][0],
            normalL[3*p+2][1],
            normalL[3*p+2][2]
          );
        }

        free(normalL);
      }
      fprintf(o, "AttributeEnd\n");
    }
  }
  {
    Lib3dsNode *n;
    for (n=node->childs; n; n=n->next) {
      create_node(f,n,o);
    }
  }
}
コード例 #18
0
ファイル: 3ds2obj.c プロジェクト: jiangguang5201314/ZNginx
void write_mesh(FILE *o, Lib3dsFile *f, Lib3dsMeshInstanceNode *node) {
    float (*orig_vertices)[3];
    int export_texcos;
    int export_normals;
    int i, j;
    Lib3dsMesh *mesh;
        
    mesh = lib3ds_file_mesh_for_node(f, (Lib3dsNode*)node);
    if (!mesh || !mesh->vertices) return;

    fprintf(o, "# object %s\n", node->base.name);
    fprintf(o, "g %s\n", node->instance_name[0]? node->instance_name : node->base.name);

    orig_vertices = (float(*)[3])malloc(sizeof(float) * 3 * mesh->nvertices);
    memcpy(orig_vertices, mesh->vertices, sizeof(float) * 3 * mesh->nvertices);
     {
         float inv_matrix[4][4], M[4][4];
         float tmp[3];
         int i;
 
         lib3ds_matrix_copy(M, node->base.matrix);
         lib3ds_matrix_translate(M, -node->pivot[0], -node->pivot[1], -node->pivot[2]);
         lib3ds_matrix_copy(inv_matrix, mesh->matrix);
         lib3ds_matrix_inv(inv_matrix);
         lib3ds_matrix_mult(M, M, inv_matrix);
 
         for (i = 0; i < mesh->nvertices; ++i) {
             lib3ds_vector_transform(tmp, M, mesh->vertices[i]);
             lib3ds_vector_copy(mesh->vertices[i], tmp);
         }
     }

    export_texcos = (mesh->texcos != 0);
    export_normals = (mesh->faces != 0);

    for (i = 0; i < mesh->nvertices; ++i) {
        fprintf(o, "v %f %f %f\n", mesh->vertices[i][0], 
                                   mesh->vertices[i][1], 
                                   mesh->vertices[i][2]);
    }
    fprintf(o, "# %d vertices\n", mesh->nvertices);

    if (export_texcos) {
        for (i = 0; i < mesh->nvertices; ++i) {
            fprintf(o, "vt %f %f\n", mesh->texcos[i][0], 
                                     mesh->texcos[i][1]);
        }
        fprintf(o, "# %d texture vertices\n", mesh->nvertices);
    }

    if (export_normals) {
        float (*normals)[3] = (float(*)[3])malloc(sizeof(float) * 9 * mesh->nfaces);
        lib3ds_mesh_calculate_vertex_normals(mesh, normals);
        for (i = 0; i < 3 * mesh->nfaces; ++i) {
            fprintf(o, "vn %f %f %f\n", normals[i][0],
                                        normals[i][1],
                                        normals[i][2]);
        }
        free(normals);  
        fprintf(o, "# %d normals\n", 3 * mesh->nfaces);
    }

    {
        int mat_index = -1;
        for (i = 0; i < mesh->nfaces; ++i) {
            if (mat_index != mesh->faces[i].material) {
                mat_index = mesh->faces[i].material;
                if (mat_index != -1) {
                    fprintf(o, "usemtl %s\n", f->materials[mat_index]->name);
                }
            }

            fprintf(o, "f ");
            for (j = 0; j < 3; ++j) {
                fprintf(o, "%d", mesh->faces[i].index[j] + max_vertices + 1);
                if (export_texcos) {
                    fprintf(o, "/%d", mesh->faces[i].index[j] + max_texcos + 1);
                } else if (export_normals) {
                    fprintf(o, "/");
                }
                if (export_normals) {
                    fprintf(o, "/%d", 3 * i + j + max_normals + 1);
                }
                if (j < 3) {
                    fprintf(o, " ");
                }
            }
            fprintf(o, "\n");
        }
    }

    max_vertices += mesh->nvertices;
    if (export_texcos) 
        max_texcos += mesh->nvertices;
    if (export_normals) 
        max_normals += 3 * mesh->nfaces;
    
    memcpy(mesh->vertices, orig_vertices, sizeof(float) * 3 * mesh->nvertices);
    free(orig_vertices);
}
コード例 #19
0
ファイル: lib3ds_file.c プロジェクト: 0871087123/lib3ds
static void
file_bounding_box_of_nodes_impl(Lib3dsNode *node, Lib3dsFile *file, 
                                int include_meshes, int include_cameras, int include_lights,
                                float bmin[3], float bmax[3], float matrix[4][4]) {
    switch (node->type) {
        case LIB3DS_NODE_MESH_INSTANCE:
            if (include_meshes) {
                int index;
                Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;

                index = lib3ds_file_mesh_by_name(file, n->instance_name);
                if (index < 0)
                    index = lib3ds_file_mesh_by_name(file, node->name);
                if (index >= 0) {
                    Lib3dsMesh *mesh;
                    float inv_matrix[4][4], M[4][4];
                    float v[3];
                    int i;

                    mesh = file->meshes[index];
                    lib3ds_matrix_copy(inv_matrix, mesh->matrix);
                    lib3ds_matrix_inv(inv_matrix);
                    lib3ds_matrix_mult(M, matrix, node->matrix);
                    lib3ds_matrix_translate(M, -n->pivot[0], -n->pivot[1], -n->pivot[2]);
                    lib3ds_matrix_mult(M, M, inv_matrix);

                    for (i = 0; i < mesh->nvertices; ++i) {
                        lib3ds_vector_transform(v, M, mesh->vertices[i]);
                        lib3ds_vector_min(bmin, v);
                        lib3ds_vector_max(bmax, v);
                    }
                }
            }
            break;

        case LIB3DS_NODE_CAMERA:
        case LIB3DS_NODE_CAMERA_TARGET:
            if (include_cameras) {
                float z[3], v[3];
                float M[4][4];
                lib3ds_matrix_mult(M, matrix, node->matrix);
                lib3ds_vector_zero(z);
                lib3ds_vector_transform(v, M, z);
                lib3ds_vector_min(bmin, v);
                lib3ds_vector_max(bmax, v);
            }
            break;

        case LIB3DS_NODE_OMNILIGHT:
        case LIB3DS_NODE_SPOTLIGHT:
        case LIB3DS_NODE_SPOTLIGHT_TARGET:
            if (include_lights) {
                float z[3], v[3];
                float M[4][4];
                lib3ds_matrix_mult(M, matrix, node->matrix);
                lib3ds_vector_zero(z);
                lib3ds_vector_transform(v, M, z);
                lib3ds_vector_min(bmin, v);
                lib3ds_vector_max(bmax, v);
            }
            break;
    }
    {
        Lib3dsNode *p = node->childs;
        while (p) {
            file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax, matrix);
            p = p->next;
        }
    }
}
コード例 #20
0
ファイル: 3dsplay.c プロジェクト: gdh1995/GhostFace
/*!
* Render node recursively, first children, then parent.
* Each node receives its own OpenGL display list.
*/
static void
render_node(Lib3dsNode *node)
{
  ASSERT(file);

  {
    Lib3dsNode *p;
    for (p=node->childs; p!=0; p=p->next) {
      render_node(p);
    }
  }
  if (node->type==LIB3DS_OBJECT_NODE) {
    Lib3dsMesh *mesh;

    if (strcmp(node->name,"$$$DUMMY")==0) {
      return;
    }

    mesh = lib3ds_file_mesh_by_name(file, node->data.object.morph);
    if( mesh == NULL )
      mesh = lib3ds_file_mesh_by_name(file, node->name);

    if (!mesh->user.d) {
      ASSERT(mesh);
      if (!mesh) {
        return;
      }

      mesh->user.d=glGenLists(1);
      glNewList(mesh->user.d, GL_COMPILE);

      {
        unsigned p;
        Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces);
        Lib3dsMaterial *oldmat = (Lib3dsMaterial *)-1;
        {
          Lib3dsMatrix M;
          lib3ds_matrix_copy(M, mesh->matrix);
          lib3ds_matrix_inv(M);
          glMultMatrixf(&M[0][0]);
        }
        lib3ds_mesh_calculate_normals(mesh, normalL);

        for (p=0; p<mesh->faces; ++p) {
          Lib3dsFace *f=&mesh->faceL[p];
          Lib3dsMaterial *mat=0;
#ifdef	USE_SDL
          Player_texture *pt = NULL;
          int tex_mode = 0;
#endif
          if (f->material[0]) {
            mat=lib3ds_file_material_by_name(file, f->material);
          }

          if( mat != oldmat ) {
            if (mat) {
              if( mat->two_sided )
                glDisable(GL_CULL_FACE);
              else
                glEnable(GL_CULL_FACE);

              glDisable(GL_CULL_FACE);

              /* Texturing added by Gernot < *****@*****.** > */

              if (mat->texture1_map.name[0]) {		/* texture map? */
                Lib3dsTextureMap *tex = &mat->texture1_map;
                if (!tex->user.p) {		/* no player texture yet? */
                  char texname[1024];
                  pt = malloc(sizeof(*pt));
                  tex->user.p = pt;
                  //snprintf(texname, sizeof(texname), "%s/%s", datapath, tex->name);
                  strcpy(texname, datapath);
                  strcat(texname, "/");
                  strcat(texname, tex->name);
#ifdef	DEBUG
                  printf("Loading texture map, name %s\n", texname);
#endif	/* DEBUG */
#ifdef	USE_SDL
#ifdef  USE_SDL_IMG_load
                  pt->bitmap = IMG_load(texname);
#else
                  pt->bitmap = IMG_Load(texname);
#endif /* IMG_Load */

#else /* USE_SDL */
                  pt->bitmap = NULL;
                  fputs("3dsplayer: Warning: No image loading support, skipping texture.\n", stderr);
#endif /* USE_SDL */
                  if (pt->bitmap) {	/* could image be loaded ? */
                    /* this OpenGL texupload code is incomplete format-wise!
                    * to make it complete, examine SDL_surface->format and
                    * tell us @lib3ds.sf.net about your improvements :-)
                    */
                    int upload_format = GL_RED; /* safe choice, shows errors */
#ifdef USE_SDL
                    int bytespp = pt->bitmap->format->BytesPerPixel;
                    void *pixel = NULL;
                    glGenTextures(1, &pt->tex_id);
#ifdef	DEBUG
                    printf("Uploading texture to OpenGL, id %d, at %d bytepp\n",
                      pt->tex_id, bytespp);
#endif	/* DEBUG */
                    if (pt->bitmap->format->palette) {
                      pixel = convert_to_RGB_Surface(pt->bitmap);
                      upload_format = GL_RGBA;
                    }
                    else {
                      pixel = pt->bitmap->pixels;
                      /* e.g. this could also be a color palette */
                      if (bytespp == 1) upload_format = GL_LUMINANCE;
                      else if (bytespp == 3) upload_format = GL_RGB;
                      else if (bytespp == 4) upload_format = GL_RGBA;
                    }
                    glBindTexture(GL_TEXTURE_2D, pt->tex_id);
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                      TEX_XSIZE, TEX_YSIZE, 0,
                      GL_RGBA, GL_UNSIGNED_BYTE, NULL);
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
                    glTexParameteri(GL_TEXTURE_2D,
                      GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                    glTexParameteri(GL_TEXTURE_2D,
                      GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                    glTexSubImage2D(GL_TEXTURE_2D,
                      0, 0, 0, pt->bitmap->w, pt->bitmap->h,
                      upload_format, GL_UNSIGNED_BYTE, pixel);
                    pt->scale_x = (float)pt->bitmap->w/(float)TEX_XSIZE;
                    pt->scale_y = (float)pt->bitmap->h/(float)TEX_YSIZE;
#endif /* USE_SDL */
                    pt->valid = 1;
                  }
                  else {
                    fprintf(stderr,
                      "Load of texture %s did not succeed "
                      "(format not supported !)\n",
                      texname);
                    pt->valid = 0;
                  }
                }
                else {
                  pt = (Player_texture *)tex->user.p;
                }
                tex_mode = pt->valid;
              }
              else {
                tex_mode = 0;
              }
              glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient);
              glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);
              glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);
              glMaterialf(GL_FRONT, GL_SHININESS, pow(2, 10.0*mat->shininess));
            }
            else {
              static const Lib3dsRgba a={0.7, 0.7, 0.7, 1.0};
              static const Lib3dsRgba d={0.7, 0.7, 0.7, 1.0};
              static const Lib3dsRgba s={1.0, 1.0, 1.0, 1.0};
              glMaterialfv(GL_FRONT, GL_AMBIENT, a);
              glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
              glMaterialfv(GL_FRONT, GL_SPECULAR, s);
              glMaterialf(GL_FRONT, GL_SHININESS, pow(2, 10.0*0.5));
            }
            oldmat = mat;
          }

          else if (mat != NULL && mat->texture1_map.name[0]) {
            Lib3dsTextureMap *tex = &mat->texture1_map;
            if (tex != NULL && tex->user.p != NULL) {
              pt = (Player_texture *)tex->user.p;
              tex_mode = pt->valid;
            }
          }


          {
            int i;

            if (tex_mode) {
              //printf("Binding texture %d\n", pt->tex_id);
              glEnable(GL_TEXTURE_2D);
              glBindTexture(GL_TEXTURE_2D, pt->tex_id);
            }

            glBegin(GL_TRIANGLES);
            glNormal3fv(f->normal);
            for (i=0; i<3; ++i) {
              glNormal3fv(normalL[3*p+i]);

              if (tex_mode) {
                glTexCoord2f(mesh->texelL[f->points[i]][1]*pt->scale_x,
                  pt->scale_y - mesh->texelL[f->points[i]][0]*pt->scale_y);
              }

              glVertex3fv(mesh->pointL[f->points[i]].pos);
            }
            glEnd();

            if (tex_mode)
              glDisable(GL_TEXTURE_2D);
          }
        }

        free(normalL);
      }

      glEndList();
    }

    if (mesh->user.d) {
      Lib3dsObjectData *d;

      glPushMatrix();
      d=&node->data.object;
      glMultMatrixf(&node->matrix[0][0]);
      glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]);
      glCallList(mesh->user.d);
      /* glutSolidSphere(50.0, 20,20); */
      glPopMatrix();
      if( flush )
        glFlush();
    }
  }
}
コード例 #21
0
std::vector<CL_Lib3dsMesh> CL_Lib3dsFile::export_meshes(Lib3dsNode *node)
{
	if (node == 0)
	{
		lib3ds_file_eval(file, 0.0f);
		node = file->nodes;
	}

	std::vector<CL_Lib3dsMesh> meshes;
	for (; node; node = node->next)
	{
		if (node->type == LIB3DS_NODE_MESH_INSTANCE)
		{
			Lib3dsMeshInstanceNode *instance_node = (Lib3dsMeshInstanceNode *) node;
			Lib3dsMesh *mesh = lib3ds_file_mesh_for_node(file, (Lib3dsNode*)node);
			if (mesh && mesh->vertices)
			{
				float inv_matrix[4][4], M[4][4];
				lib3ds_matrix_copy(M, instance_node->base.matrix);
				lib3ds_matrix_translate(M, -instance_node->pivot[0], -instance_node->pivot[1], -instance_node->pivot[2]);
				lib3ds_matrix_copy(inv_matrix, mesh->matrix);
				lib3ds_matrix_inv(inv_matrix);
				lib3ds_matrix_mult(M, M, inv_matrix);

				std::vector<CL_Vec3f> positions;
				for (int i = 0; i < mesh->nvertices; ++i)
				{
					float position[3];
					lib3ds_vector_transform(position, M, mesh->vertices[i]);
					positions.push_back(CL_Vec3f(position[0], position[1], position[2]));
				}

				std::vector<CL_Vec2f> texcoords;
				if (mesh->texcos)
				{
					for (int i = 0; i < mesh->nvertices; ++i)
					{
						float tx = mesh->texcos[i][0];
						float ty = mesh->texcos[i][1];
						texcoords.push_back(CL_Vec2f(tx, ty));
					}
				}

				std::vector<CL_Vec3f> normals;
				if (mesh->faces && mesh->nfaces > 0)
				{
			        float (*normals_array)[3] = (float(*)[3])malloc(sizeof(float) * 9 * mesh->nfaces);
					lib3ds_mesh_calculate_vertex_normals(mesh, normals_array);
					for (int i = 0; i < 3 * mesh->nfaces; ++i)
					{
						normals.push_back(CL_Vec3f(normals_array[i][0], normals_array[i][1], normals_array[i][2]));
					}
					free(normals_array);
				}

				CL_Lib3dsMesh mesh_object;
				for (int i = 0; i < mesh->nfaces; ++i)
				{
					int material_index = mesh->faces[i].material;
					mesh_object.face_materials.push_back(material_index);

					for (int j = 0; j < 3; ++j)
					{
						int vertex_index = mesh->faces[i].index[j];
						mesh_object.positions.push_back(positions[vertex_index]);
						if (!texcoords.empty())
							mesh_object.texcooords.push_back(texcoords[vertex_index]);
						if (!normals.empty())
							mesh_object.normals.push_back(normals[i*3+j]);
					}
				}

				meshes.push_back(mesh_object);
			}

			if (node->childs)
			{
				std::vector<CL_Lib3dsMesh> child_meshes = export_meshes(node->childs);
				meshes.insert(meshes.end(), child_meshes.begin(), child_meshes.end());
			}
		}
	}

	return meshes;
}