⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mesh.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * The 3D Studio File Format Library * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net> * All rights reserved. * * This program is  free  software;  you can redistribute it and/or modify it * under the terms of the  GNU Lesser General Public License  as published by  * the  Free Software Foundation;  either version 2.1 of the License,  or (at  * your option) any later version. * * This  program  is  distributed in  the  hope that it will  be useful,  but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public   * License for more details. * * You should  have received  a copy of the GNU Lesser General Public License * along with  this program;  if not, write to the  Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: mesh.cpp 5453 2006-08-21 15:07:31Z robert $ */#define LIB3DS_EXPORT#include "mesh.h"#include "readwrite.h"#include "chunk.h"#include "vector.h"#include "matrix.h"#include <stdlib.h>#include <string.h>#include <math.h>#include "config.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endif/*! * \defgroup mesh Meshes * * \author J.E. Hoffmann <je-h@gmx.net> */static Lib3dsBoolface_array_read(Lib3dsMesh *mesh, FILE *f){  Lib3dsChunk c;  Lib3dsWord chunk;  int i;  int faces;  if (!lib3ds_chunk_read_start(&c, LIB3DS_FACE_ARRAY, f)) {    return(LIB3DS_FALSE);  }  lib3ds_mesh_free_face_list(mesh);    faces=lib3ds_word_read(f);  if (faces) {    if (!lib3ds_mesh_new_face_list(mesh, faces)) {      LIB3DS_ERROR_LOG;      return(LIB3DS_FALSE);    }    for (i=0; i<faces; ++i) {      strcpy(mesh->faceL[i].material, "");      mesh->faceL[i].points[0]=lib3ds_word_read(f);      mesh->faceL[i].points[1]=lib3ds_word_read(f);      mesh->faceL[i].points[2]=lib3ds_word_read(f);      mesh->faceL[i].flags=lib3ds_word_read(f);    }    lib3ds_chunk_read_tell(&c, f);    while ((chunk=lib3ds_chunk_read_next(&c, f))!=0) {      switch (chunk) {        case LIB3DS_SMOOTH_GROUP:          {            unsigned i;            for (i=0; i<mesh->faces; ++i) {              mesh->faceL[i].smoothing=lib3ds_dword_read(f);            }          }          break;        case LIB3DS_MSH_MAT_GROUP:          {            char name[64];            unsigned faces;            unsigned i;            unsigned index;            if (!lib3ds_string_read(name, 64, f)) {              return(LIB3DS_FALSE);            }            faces=lib3ds_word_read(f);            for (i=0; i<faces; ++i) {              index=lib3ds_word_read(f);              ASSERT(index<mesh->faces);              strcpy(mesh->faceL[index].material, name);            }          }          break;        case LIB3DS_MSH_BOXMAP:          {            char name[64];            if (!lib3ds_string_read(name, 64, f)) {              return(LIB3DS_FALSE);            }            strcpy(mesh->box_map.front, name);            if (!lib3ds_string_read(name, 64, f)) {              return(LIB3DS_FALSE);            }            strcpy(mesh->box_map.back, name);            if (!lib3ds_string_read(name, 64, f)) {              return(LIB3DS_FALSE);            }            strcpy(mesh->box_map.left, name);            if (!lib3ds_string_read(name, 64, f)) {              return(LIB3DS_FALSE);            }            strcpy(mesh->box_map.right, name);            if (!lib3ds_string_read(name, 64, f)) {              return(LIB3DS_FALSE);            }            strcpy(mesh->box_map.top, name);            if (!lib3ds_string_read(name, 64, f)) {              return(LIB3DS_FALSE);            }            strcpy(mesh->box_map.bottom, name);          }          break;        default:          lib3ds_chunk_unknown(chunk);      }    }      }  lib3ds_chunk_read_end(&c, f);  return(LIB3DS_TRUE);}/*! * \ingroup mesh */Lib3dsMesh*lib3ds_mesh_new(const char *name){  Lib3dsMesh *mesh;  ASSERT(name);  ASSERT(strlen(name)<64);    mesh=(Lib3dsMesh*)calloc(sizeof(Lib3dsMesh), 1);  if (!mesh) {    return(0);  }  strcpy(mesh->name, name);  lib3ds_matrix_identity(mesh->matrix);  mesh->map_data.maptype=LIB3DS_MAP_NONE;  return(mesh);}/*! * \ingroup mesh */voidlib3ds_mesh_free(Lib3dsMesh *mesh){  lib3ds_mesh_free_point_list(mesh);  lib3ds_mesh_free_flag_list(mesh);  lib3ds_mesh_free_texel_list(mesh);  lib3ds_mesh_free_face_list(mesh);  memset(mesh, 0, sizeof(Lib3dsMesh));  free(mesh);}/*! * \ingroup mesh */Lib3dsBoollib3ds_mesh_new_point_list(Lib3dsMesh *mesh, Lib3dsDword points){  ASSERT(mesh);  if (mesh->pointL) {    ASSERT(mesh->points);    lib3ds_mesh_free_point_list(mesh);  }  ASSERT(!mesh->pointL && !mesh->points);  mesh->points=0;  mesh->pointL=(Lib3dsPoint*)calloc(sizeof(Lib3dsPoint)*points,1);  if (!mesh->pointL) {    LIB3DS_ERROR_LOG;    return(LIB3DS_FALSE);  }  mesh->points=points;  return(LIB3DS_TRUE);}/*! * \ingroup mesh */voidlib3ds_mesh_free_point_list(Lib3dsMesh *mesh){  ASSERT(mesh);  if (mesh->pointL) {    ASSERT(mesh->points);    free(mesh->pointL);    mesh->pointL=0;    mesh->points=0;  }  else {    ASSERT(!mesh->points);  }}/*! * \ingroup mesh */Lib3dsBoollib3ds_mesh_new_flag_list(Lib3dsMesh *mesh, Lib3dsDword flags){  ASSERT(mesh);  if (mesh->flagL) {    ASSERT(mesh->flags);    lib3ds_mesh_free_flag_list(mesh);  }  ASSERT(!mesh->flagL && !mesh->flags);  mesh->flags=0;  mesh->flagL=(Lib3dsWord*)calloc(sizeof(Lib3dsWord)*flags,1);  if (!mesh->flagL) {    LIB3DS_ERROR_LOG;    return(LIB3DS_FALSE);  }  mesh->flags=flags;  return(LIB3DS_TRUE);}/*! * \ingroup mesh */voidlib3ds_mesh_free_flag_list(Lib3dsMesh *mesh){  ASSERT(mesh);  if (mesh->flagL) {    ASSERT(mesh->flags);    free(mesh->flagL);    mesh->flagL=0;    mesh->flags=0;  }  else {    ASSERT(!mesh->flags);  }}/*! * \ingroup mesh */Lib3dsBoollib3ds_mesh_new_texel_list(Lib3dsMesh *mesh, Lib3dsDword texels){  ASSERT(mesh);  if (mesh->texelL) {    ASSERT(mesh->texels);    lib3ds_mesh_free_texel_list(mesh);  }  ASSERT(!mesh->texelL && !mesh->texels);  mesh->texels=0;  mesh->texelL=(Lib3dsTexel*) calloc(sizeof(Lib3dsTexel)*texels,1);  if (!mesh->texelL) {    LIB3DS_ERROR_LOG;    return(LIB3DS_FALSE);  }  mesh->texels=texels;  return(LIB3DS_TRUE);}/*! * \ingroup mesh */voidlib3ds_mesh_free_texel_list(Lib3dsMesh *mesh){  ASSERT(mesh);  if (mesh->texelL) {    ASSERT(mesh->texels);    free(mesh->texelL);    mesh->texelL=0;    mesh->texels=0;  }  else {    ASSERT(!mesh->texels);  }}/*! * \ingroup mesh */Lib3dsBoollib3ds_mesh_new_face_list(Lib3dsMesh *mesh, Lib3dsDword faces){  ASSERT(mesh);  if (mesh->faceL) {    ASSERT(mesh->faces);    lib3ds_mesh_free_face_list(mesh);  }  ASSERT(!mesh->faceL && !mesh->faces);  mesh->faces=0;  mesh->faceL=(Lib3dsFace*)calloc(sizeof(Lib3dsFace)*faces,1);  if (!mesh->faceL) {    LIB3DS_ERROR_LOG;    return(LIB3DS_FALSE);  }  mesh->faces=faces;  return(LIB3DS_TRUE);}/*! * \ingroup mesh */voidlib3ds_mesh_free_face_list(Lib3dsMesh *mesh){  ASSERT(mesh);  if (mesh->faceL) {    ASSERT(mesh->faces);    free(mesh->faceL);    mesh->faceL=0;    mesh->faces=0;  }  else {    ASSERT(!mesh->faces);  }}typedef struct _Lib3dsFaces Lib3dsFaces; struct _Lib3dsFaces {  Lib3dsFaces *next;  Lib3dsFace *face;};/*! * \ingroup mesh */voidlib3ds_mesh_bounding_box(Lib3dsMesh *mesh, Lib3dsVector min, Lib3dsVector max){  unsigned i,j;  Lib3dsFloat v;  if (!mesh->points) {    lib3ds_vector_zero(min);    lib3ds_vector_zero(max);    return;  }   lib3ds_vector_copy(min, mesh->pointL[0].pos);  lib3ds_vector_copy(max, mesh->pointL[0].pos);  for (i=1; i<mesh->points; ++i) {    for (j=0; j<3; ++j) {      v=mesh->pointL[i].pos[j];      if (v<min[j]) {        min[j]=v;      }      if (v>max[j]) {        max[j]=v;      }    }  };}/*! * Calculates the vertex normals corresponding to the smoothing group * settings for each face of a mesh. * * \param mesh      A pointer to the mesh to calculate the normals for. * \param normalL   A pointer to a buffer to store the calculated *                  normals. The buffer must have the size: *                  3*sizeof(Lib3dsVector)*mesh->faces.  * * To allocate the normal buffer do for example the following: * \code *  Lib3dsVector *normalL = malloc(3*sizeof(Lib3dsVector)*mesh->faces); * \endcode * * To access the normal of the i-th vertex of the j-th face do the  * following: * \code *   normalL[3*j+i] * \endcode */voidlib3ds_mesh_calculate_normals(Lib3dsMesh *mesh, Lib3dsVector *normalL){  Lib3dsFaces **fl;   Lib3dsFaces *fa;   unsigned i,j,k;  if (!mesh->faces) {    return;  }  fl=(Lib3dsFaces**)calloc(sizeof(Lib3dsFaces*),mesh->points);  ASSERT(fl);  fa=(Lib3dsFaces*)calloc(sizeof(Lib3dsFaces),3*mesh->faces);  ASSERT(fa);  k=0;  for (i=0; i<mesh->faces; ++i) {    Lib3dsFace *f=&mesh->faceL[i];    for (j=0; j<3; ++j) {      Lib3dsFaces* l=&fa[k++];      ASSERT(f->points[j]<mesh->points);      l->face=f;      l->next=fl[f->points[j]];      fl[f->points[j]]=l;    }  }    for (i=0; i<mesh->faces; ++i) {    Lib3dsFace *f=&mesh->faceL[i];    for (j=0; j<3; ++j) {      Lib3dsVector n,N[32];      Lib3dsFaces *p;      int k,l;      int found;      ASSERT(f->points[j]<mesh->points);      if (f->smoothing) {        lib3ds_vector_zero(n);        k=0;        for (p=fl[f->points[j]]; p; p=p->next) {          found=0;          for (l=0; l<k; ++l) {            if (fabs(lib3ds_vector_dot(N[l], p->face->normal)-1.0)<1e-5) {              found=1;              break;            }          }          if (!found) {            if (f->smoothing & p->face->smoothing) {              lib3ds_vector_add(n,n, p->face->normal);              lib3ds_vector_copy(N[k], p->face->normal);              ++k;            }          }        }      }       else {        lib3ds_vector_copy(n, f->normal);      }      lib3ds_vector_normalize(n);      lib3ds_vector_copy(normalL[3*i+j], n);    }  }  free(fa);  free(fl);}/*! * This function prints data associated with the specified mesh such as * vertex and point lists. * * \param mesh  Points to a mesh that you wish to view the data for. *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -