예제 #1
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);
   }
}
예제 #2
0
Lib3dsMesh* 
lib3ds_file_mesh_for_node(Lib3dsFile *file, Lib3dsNode *node) {
    int index;
    Lib3dsMeshInstanceNode *n;

    if (node->type != LIB3DS_NODE_MESH_INSTANCE)
        return NULL;
    n = (Lib3dsMeshInstanceNode*)node;

    index = lib3ds_file_mesh_by_name(file, node->name);

    return (index >= 0)? file->meshes[index] : NULL;
}
예제 #3
0
	void x3ds_instance::render_node(Lib3dsNode* node)
	{
		for (Lib3dsNode* p = node->childs; p != 0; p = p->next)
		{
			render_node(p);
		}

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

			Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(m_def->m_file, node->data.object.morph);
			if (mesh == NULL)
			{
				mesh = lib3ds_file_mesh_by_name(m_def->m_file, node->name);
			}
			assert(mesh);
			
			// build mesh list
			if (node->user.i == 0)
			{
				node->user.i = glGenLists(1);
				glNewList(node->user.i, GL_COMPILE);
				create_mesh_list(mesh);
				glEndList();
			}

			// exec mesh list
			glPushMatrix();
			Lib3dsObjectData* d = &node->data.object;
			glMultMatrixf(&node->matrix[0][0]);
			glTranslatef( - d->pivot[0], - d->pivot[1], - d->pivot[2]);
			glCallList(node->user.i);
			glPopMatrix();
		}
	}
SkeletalObject::SkeletalObject(const char* filename)
{

	m_TotalFaces = 0;
	m_model = lib3ds_file_load(filename);
	// If loading the model failed, we throw an exception
	if(!m_model)
	{
		cout << ("Unable to load ", filename);
	}
	Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(m_model,"filename");


}
예제 #5
0
    TextureInformation Loader3dsInternal::loadTextureInformation(Lib3dsNode* node) {
        if (!node) {
            return TextureInformation();
        }
        if (node->type != LIB3DS_OBJECT_NODE) {
            return TextureInformation();
        }
        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 TextureInformation();
        }
        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 TextureInformation();
        }
        if (mesh->faces < 1) {
            std::cerr << "No faces in mesh " << node->name << std::endl;
            return TextureInformation();
        }

        if (mesh->texelL == 0) {
            // mesh not textured.
            return TextureInformation();
        }

        if (mesh->texels != mesh->points) {
            std::cerr << "ERROR: mesh->texels != mesh->points, with non-NULL mesh->texelL" << std::endl;
            return TextureInformation();
        }

        if (mesh->faceL[0].material[0] == 0) {
            return TextureInformation();
        }

        // AB: at this point we assume that the mesh uses a single material
        // only. see checkUniqueMeshMaterial()
        Lib3dsMaterial* mat = lib3ds_file_material_by_name(mFile, mesh->faceL[0].material);

        TextureInformation textureInformation;
        textureInformation.setTextured(true);
        std::vector<dcollide::Vector3> texels;
        texels.reserve(mesh->texels);
        dcollide::Matrix textureMatrix;
        Lib3dsTextureMap* t = &mat->texture1_map;
        if (t->scale[0] && t->scale[1]) {
            // AB: see boson's bobmfloader/loaders/loader-3ds.cpp for details
            //     (remark: yes, I have permission to relicense to BSD!)
            textureMatrix.translate((dcollide::real)((1.0 - t->scale[0]) / 2.0),
                                    (dcollide::real)((1.0 - t->scale[1]) / 2.0),
                                    (dcollide::real) 0.0);
            textureMatrix.scale(t->scale[0], t->scale[1], 1.0);
        }
        if (t->rotation != 0.0) {
            textureMatrix.rotate(-t->rotation, 0.0, 0.0, 1.0);
        }
        textureMatrix.translate(-t->offset[0], -t->offset[1], 0.0);
        textureMatrix.translate(mesh->map_data.pos[0], mesh->map_data.pos[1], mesh->map_data.pos[2]);
        float scale = mesh->map_data.scale;
        if (scale != 0.0) {
            textureMatrix.scale(scale, scale, 1.0);
        }

        dcollide::Vector3 tmp1;
        dcollide::Vector3 tmp2;
        for (unsigned int i = 0; i < mesh->texels; i++) {
            tmp1.set((dcollide::real)(mesh->texelL[i])[0], (dcollide::real)(mesh->texelL[i])[1], (dcollide::real)0.0);
            textureMatrix.transform(&tmp2, tmp1);
            texels.push_back(tmp2);
        }
        textureInformation.setTexels(texels);

        textureInformation.setTextureFileName(mat->texture1_map.name);

        return textureInformation;
    }
예제 #6
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;
    }
예제 #7
0
// 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
		}
	}	 
}
예제 #8
0
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
}
예제 #9
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();
    }
  }
}
예제 #10
0
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;
    }
  }
}
예제 #11
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();
		}
	}
}
예제 #12
0
/*!
* 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();
 }
 }
}
예제 #13
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);
    }
  }
}
예제 #14
0
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;
        }
    }
}
예제 #15
0
// Create meshes from the 3ds File
void GLC_3dsToWorld::createMeshes(GLC_StructOccurence* pProduct, Lib3dsNode* pFatherNode)
{
	GLC_StructOccurence* pChildProduct= NULL;
	Lib3dsMesh *pMesh= NULL;

	if (pFatherNode->type == LIB3DS_OBJECT_NODE)
	{
		//qDebug() << "Node type LIB3DS_OBJECT_NODE is named : " << QString(pFatherNode->name);
		//qDebug() << "Node Matrix :";
		//qDebug() << GLC_Matrix4x4(&(pFatherNode->matrix[0][0])).toString();

		// Check if the node is a mesh or dummy
		if (!(strcmp(pFatherNode->name,"$$$DUMMY")==0))
		{
	    	pMesh = lib3ds_file_mesh_by_name(m_pLib3dsFile, pFatherNode->name);
		    if( pMesh != NULL )
		    {
		    	GLC_3DRep representation(create3DRep(pMesh));
		    	// Test if there is vertex in the mesh
		    	if (0 != representation.vertexCount())
		    	{
		    		m_LoadedMeshes.insert(representation.name());
			    	// Load node matrix
			    	GLC_Matrix4x4 nodeMat(&(pFatherNode->matrix[0][0]));
					// The mesh matrix to inverse
			    	GLC_Matrix4x4 matInv(&(pMesh->matrix[0][0]));
					matInv.invert();
					// Get the node pivot
					Lib3dsObjectData *pObjectData;
					pObjectData= &pFatherNode->data.object;
					GLC_Matrix4x4 trans(-pObjectData->pivot[0], -pObjectData->pivot[1], -pObjectData->pivot[2]);
					// Compute the part matrix
					nodeMat= nodeMat * trans * matInv; // I don't know why...
					nodeMat.optimise();
					// move the part by the matrix
					pProduct->addChild((new GLC_StructInstance(new GLC_3DRep(representation)))->move(nodeMat));
		    	}
		    	else
		    	{
		    		// the instance will be deleted, check material usage
		    		QSet<GLC_Material*> meshMaterials= representation.materialSet();
		    		QSet<GLC_Material*>::const_iterator iMat= meshMaterials.constBegin();
		    		while (iMat != meshMaterials.constEnd())
		    		{
		    			if ((*iMat)->numberOfUsage() == 1)
		    			{
		    				m_Materials.remove((*iMat)->name());
		    			}
		    			++iMat;
		    		}
		    	}
		    }
		} // End If DUMMY
	}
	else return;
	// If there is a child, create a child product
	if (NULL != pFatherNode->childs)
	{
		pChildProduct= new GLC_StructOccurence();
		pProduct->addChild(pChildProduct);

		pChildProduct->setName(QString("Product") + QString::number(pFatherNode->node_id));

		//pChildProduct->move(GLC_Matrix4x4(&(pFatherNode->matrix[0][0])));

		// Create Childs meshes if exists
		for (Lib3dsNode* pNode= pFatherNode->childs; pNode!=0; pNode= pNode->next)
		{
			createMeshes(pChildProduct, pNode);
		}
	}


}
예제 #16
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;
    }
예제 #17
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);
    }
  }
}
예제 #18
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();
    }
  }
}