示例#1
0
int CsceneRender::loadAssimpModel(const string & modelFile, const bool wireFrame)
{      
    // Import model file
    const aiScene* scene = importer.ReadFile( modelFile,
        aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType);
      
    if ( !scene ) // If the import failed, report it
    {
        std::cout << importer.GetErrorString() << std::endl;
        return -1;
    }
    else //if scene != NULL, import suceed, so associates the scene to the model List
    {
        //Sets modelList
        glutSetWindow(winId);
        glNewList(modelList, GL_COMPILE);      
        
        //Draw the model, only polygon faces, filled with orange
        glColor3f(5.,3.,0.);            
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        this->recursiveAssimpRender(scene, scene->mRootNode);
        
        //if wireFrame, redraw the model but only the polygon line borders in black
        if (wireFrame) 
        {
            glColor4f(0.,0.,0.,0.1);            
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            this->recursiveAssimpRender(scene, scene->mRootNode);
        }

        
        glEndList();
        glFinish(); //finish all openGL work      
        
        // We're done. Everything will be cleaned up by the importer destructor
        std::cout << "Model loaded successfully by Assimp::Importer";
        std::cout << " (Version: " << aiGetVersionMajor() << "." << aiGetVersionMinor() << ")" << std::endl;
        return 1;
    }
}
示例#2
0
// ------------------------------------------------------------------------------------------------
PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool binary)
: filename(_filename)
, endl("\n")
{
    // make sure that all formatting happens using the standard, C locale and not the user's current locale
    const std::locale& l = std::locale("C");
    mOutput.imbue(l);

    unsigned int faces = 0u, vertices = 0u, components = 0u;
    for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
        const aiMesh& m = *pScene->mMeshes[i];
        faces += m.mNumFaces;
        vertices += m.mNumVertices;

        if (m.HasNormals()) {
            components |= PLY_EXPORT_HAS_NORMALS;
        }
        if (m.HasTangentsAndBitangents()) {
            components |= PLY_EXPORT_HAS_TANGENTS_BITANGENTS;
        }
        for (unsigned int t = 0; m.HasTextureCoords(t); ++t) {
            components |= PLY_EXPORT_HAS_TEXCOORDS << t;
        }
        for (unsigned int t = 0; m.HasVertexColors(t); ++t) {
            components |= PLY_EXPORT_HAS_COLORS << t;
        }
    }

    mOutput << "ply" << endl;
    if (binary) {
#if (defined AI_BUILD_BIG_ENDIAN)
        mOutput << "format binary_big_endian 1.0" << endl;
#else
        mOutput << "format binary_little_endian 1.0" << endl;
#endif
    }
    else {
        mOutput << "format ascii 1.0" << endl;
    }
    mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v"
        << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
        << aiGetVersionRevision() << ")" << endl;

    mOutput << "element vertex " << vertices << endl;
    mOutput << "property float x" << endl;
    mOutput << "property float y" << endl;
    mOutput << "property float z" << endl;

    if(components & PLY_EXPORT_HAS_NORMALS) {
        mOutput << "property float nx" << endl;
        mOutput << "property float ny" << endl;
        mOutput << "property float nz" << endl;
    }

    // write texcoords first, just in case an importer does not support tangents
    // bitangents and just skips over the rest of the line upon encountering
    // unknown fields (Ply leaves pretty much every vertex component open,
    // but in reality most importers only know about vertex positions, normals
    // and texture coordinates).
    for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
        if (!c) {
            mOutput << "property float s" << endl;
            mOutput << "property float t" << endl;
        }
        else {
            mOutput << "property float s" << c << endl;
            mOutput << "property float t" << c << endl;
        }
    }

    for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) {
        if (!c) {
            mOutput << "property float r" << endl;
            mOutput << "property float g" << endl;
            mOutput << "property float b" << endl;
            mOutput << "property float a" << endl;
        }
        else {
            mOutput << "property float r" << c << endl;
            mOutput << "property float g" << c << endl;
            mOutput << "property float b" << c << endl;
            mOutput << "property float a" << c << endl;
        }
    }

    if(components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) {
        mOutput << "property float tx" << endl;
        mOutput << "property float ty" << endl;
        mOutput << "property float tz" << endl;
        mOutput << "property float bx" << endl;
        mOutput << "property float by" << endl;
        mOutput << "property float bz" << endl;
    }

    mOutput << "element face " << faces << endl;

    // uchar seems to be the most common type for the number of indices per polygon and int seems to be most common for the vertex indices.
    // For instance, MeshLab fails to load meshes in which both types are uint. Houdini seems to have problems as well.
    // Obviously, using uchar will not work for meshes with polygons with more than 255 indices, but how realistic is this case?
    mOutput << "property list uchar int vertex_index" << endl;

    mOutput << "end_header" << endl;

    for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
        if (binary) {
            WriteMeshVertsBinary(pScene->mMeshes[i], components);
        }
        else {
            WriteMeshVerts(pScene->mMeshes[i], components);
        }
    }
    for (unsigned int i = 0, ofs = 0; i < pScene->mNumMeshes; ++i) {
        if (binary) {
            WriteMeshIndicesBinary(pScene->mMeshes[i], ofs);
        }
        else {
            WriteMeshIndices(pScene->mMeshes[i], ofs);
        }
        ofs += pScene->mMeshes[i]->mNumVertices;
    }
}
示例#3
0
// ------------------------------------------------------------------------------
// Application entry point
int main (int argc, char* argv[])
{
	if (argc <= 1)	{
		printf("assimp: No command specified. Use \'assimp help\' for a detailed command list\n");
		return 0;
	}

	// assimp version
	// Display version information
	if (! strcmp(argv[1], "version")) {
		const unsigned int flags = aiGetCompileFlags();
		printf(AICMD_MSG_ABOUT,
			aiGetVersionMajor(),
			aiGetVersionMinor(),
			(flags & ASSIMP_CFLAGS_DEBUG ?			"-debug "   : ""),
			(flags & ASSIMP_CFLAGS_NOBOOST ?		"-noboost " : ""),
			(flags & ASSIMP_CFLAGS_SHARED ?			"-shared "  : ""),
			(flags & ASSIMP_CFLAGS_SINGLETHREADED ? "-st "      : ""),
			(flags & ASSIMP_CFLAGS_STLPORT ?		"-stlport " : ""),
			aiGetVersionRevision());

		return 0;
	}

	// assimp help
	// Display some basic help (--help and -h work as well 
	// because people could try them intuitively)
	if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
		printf("%s",AICMD_MSG_HELP);
		return 0;
	}

	// assimp cmpdump
	// Compare two mini model dumps (regression suite) 
	if (! strcmp(argv[1], "cmpdump")) {
		return Assimp_CompareDump (&argv[2],argc-2);
	}

	// construct global importer and exporter instances
	Assimp::Importer imp;
	imp.SetPropertyBool("GLOB_MEASURE_TIME",true);
	globalImporter = &imp;

#ifndef ASSIMP_BUILD_NO_EXPORT
	// 
	Assimp::Exporter exp;
	globalExporter = &exp;
#endif

	// assimp listext
	// List all file extensions supported by Assimp
	if (! strcmp(argv[1], "listext")) {
		aiString s;
		imp.GetExtensionList(s);

		printf("%s\n",s.data);
		return 0;
	}

#ifndef ASSIMP_BUILD_NO_EXPORT
	// assimp listexport
	// List all export file formats supported by Assimp (not the file extensions, just the format identifiers!)
	if (! strcmp(argv[1], "listexport")) {
		aiString s;
		
		for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) {
			const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
			s.Append( e->id );
			if (i!=end-1) {
				s.Append("\n");
			}
		}

		printf("%s\n",s.data);
		return 0;
	}


	// assimp exportinfo
	// stat an export format
	if (! strcmp(argv[1], "exportinfo")) {
		aiString s;

		if (argc<3) {
			printf("Expected file format id\n");
			return -11;
		}

		for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) {
			const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
			if (!strcmp(e->id,argv[2])) {
				printf("%s\n%s\n%s\n",e->id,e->fileExtension,e->description);
				return 0;
			}
		}
		
		printf("Unknown file format id: \'%s\'\n",argv[2]);
		return -12;
	}

	// assimp export
	// Export a model to a file
	if (! strcmp(argv[1], "export")) {
		return Assimp_Export (&argv[2],argc-2);
	}

#endif

	// assimp knowext
	// Check whether a particular file extension is known by us, return 0 on success
	if (! strcmp(argv[1], "knowext")) {
		if (argc<3) {
			printf("Expected file extension");
			return -10;
		}
		const bool b = imp.IsExtensionSupported(argv[2]);
		printf("File extension \'%s\'  is %sknown\n",argv[2],(b?"":"not "));
		return b?0:-1;
	}

	// assimp info
	// Print basic model statistics
	if (! strcmp(argv[1], "info")) {
		return Assimp_Info ((const char**)&argv[2],argc-2);
	}

	// assimp dump 
	// Dump a model to a file 
	if (! strcmp(argv[1], "dump")) {
		return Assimp_Dump (&argv[2],argc-2);
	}

	// assimp extract 
	// Extract an embedded texture from a file
	if (! strcmp(argv[1], "extract")) {
		return Assimp_Extract (&argv[2],argc-2);
	}

	// assimp testbatchload
	// Used by /test/other/streamload.py to load a list of files
	// using the same importer instance to check for incompatible
	// importers.
	if (! strcmp(argv[1], "testbatchload")) {
		return Assimp_TestBatchLoad (&argv[2],argc-2);
	}

	printf("Unrecognized command. Use \'assimp help\' for a detailed command list\n");
	return 1;
}
示例#4
0
// -----------------------------------------------------------------------------------
// Write a text model dump
void WriteDump(const aiScene* scene, FILE* out, const char* src, const char* cmd, bool shortened)
{
	time_t tt = ::time(NULL);
	tm* p     = ::gmtime(&tt);

	std::string c = cmd;
	std::string::size_type s; 

	// https://sourceforge.net/tracker/?func=detail&aid=3167364&group_id=226462&atid=1067632
	// -- not allowed in XML comments
	while((s = c.find("--")) != std::string::npos) {
		c[s] = '?';
	}
	aiString name;

	// write header
	fprintf(out,
		"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
		"<ASSIMP format_id=\"1\">\n\n"

		"<!-- XML Model dump produced by assimp dump\n"
		"  Library version: %i.%i.%i\n"
		"  Source: %s\n"
		"  Command line: %s\n"
		"  %s\n"
		"-->"
		" \n\n"
		"<Scene flags=\"%i\" postprocessing=\"%i\">\n",
		
		aiGetVersionMajor(),aiGetVersionMinor(),aiGetVersionRevision(),src,c.c_str(),asctime(p),
		scene->mFlags,
		0 /*globalImporter->GetEffectivePostProcessing()*/);

	// write the node graph
	WriteNode(scene->mRootNode, out, 0);

#if 0
		// write cameras
	for (unsigned int i = 0; i < scene->mNumCameras;++i) {
		aiCamera* cam  = scene->mCameras[i];
		ConvertName(name,cam->mName);

		// camera header
		fprintf(out,"\t<Camera parent=\"%s\">\n"
			"\t\t<Vector3 name=\"up\"        > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"lookat\"    > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"pos\"       > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Float   name=\"fov\"       > %f </Float>\n"
			"\t\t<Float   name=\"aspect\"    > %f </Float>\n"
			"\t\t<Float   name=\"near_clip\" > %f </Float>\n"
			"\t\t<Float   name=\"far_clip\"  > %f </Float>\n"
			"\t</Camera>\n",
			name.data,
			cam->mUp.x,cam->mUp.y,cam->mUp.z,
			cam->mLookAt.x,cam->mLookAt.y,cam->mLookAt.z,
			cam->mPosition.x,cam->mPosition.y,cam->mPosition.z,
			cam->mHorizontalFOV,cam->mAspect,cam->mClipPlaneNear,cam->mClipPlaneFar,i);
	}

	// write lights
	for (unsigned int i = 0; i < scene->mNumLights;++i) {
		aiLight* l  = scene->mLights[i];
		ConvertName(name,l->mName);

		// light header
		fprintf(out,"\t<Light parent=\"%s\"> type=\"%s\"\n"
			"\t\t<Vector3 name=\"diffuse\"   > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"specular\"  > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"ambient\"   > %0 8f %0 8f %0 8f </Vector3>\n",
			name.data,
			(l->mType == aiLightSource_DIRECTIONAL ? "directional" :
			(l->mType == aiLightSource_POINT ? "point" : "spot" )),
			l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b,
			l->mColorSpecular.r,l->mColorSpecular.g,l->mColorSpecular.b,
			l->mColorAmbient.r, l->mColorAmbient.g, l->mColorAmbient.b);

		if (l->mType != aiLightSource_DIRECTIONAL) {
			fprintf(out,
				"\t\t<Vector3 name=\"pos\"       > %0 8f %0 8f %0 8f </Vector3>\n"
				"\t\t<Float   name=\"atten_cst\" > %f </Float>\n"
				"\t\t<Float   name=\"atten_lin\" > %f </Float>\n"
				"\t\t<Float   name=\"atten_sqr\" > %f </Float>\n",
				l->mPosition.x,l->mPosition.y,l->mPosition.z,
				l->mAttenuationConstant,l->mAttenuationLinear,l->mAttenuationQuadratic);
		}

		if (l->mType != aiLightSource_POINT) {
			fprintf(out,
				"\t\t<Vector3 name=\"lookat\"    > %0 8f %0 8f %0 8f </Vector3>\n",
				l->mDirection.x,l->mDirection.y,l->mDirection.z);
		}

		if (l->mType == aiLightSource_SPOT) {
			fprintf(out,
				"\t\t<Float   name=\"cone_out\" > %f </Float>\n"
				"\t\t<Float   name=\"cone_inn\" > %f </Float>\n",
				l->mAngleOuterCone,l->mAngleInnerCone);
		}
		fprintf(out,"\t</Light>\n");
	}
#endif

	// write textures
	if (scene->mNumTextures) {
		fprintf(out,"<TextureList num=\"%i\">\n",scene->mNumTextures);
		for (unsigned int i = 0; i < scene->mNumTextures;++i) {
			aiTexture* tex  = scene->mTextures[i];
			bool compressed = (tex->mHeight == 0);

			// mesh header
			fprintf(out,"\t<Texture width=\"%i\" height=\"%i\" compressed=\"%s\"> \n",
				(compressed ? -1 : tex->mWidth),(compressed ? -1 : tex->mHeight),
				(compressed ? "true" : "false"));

			if (compressed) {
				fprintf(out,"\t\t<Data length=\"%i\"> \n",tex->mWidth);

				if (!shortened) {
					for (unsigned int n = 0; n < tex->mWidth;++n) {
						fprintf(out,"\t\t\t%2x",reinterpret_cast<uint8_t*>(tex->pcData)[n]);
						if (n && !(n % 50)) {
							fprintf(out,"\n");
						}
					}
				}
			}
			else if (!shortened){
				fprintf(out,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4);

				// const unsigned int width = (unsigned int)log10((double)std::max(tex->mHeight,tex->mWidth))+1;
				for (unsigned int y = 0; y < tex->mHeight;++y) {
					for (unsigned int x = 0; x < tex->mWidth;++x) {
						aiTexel* tx = tex->pcData + y*tex->mWidth+x;
						unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a;
						fprintf(out,"\t\t\t%2x %2x %2x %2x",r,g,b,a);

						// group by four for readibility
						if (0 == (x+y*tex->mWidth) % 4)
							fprintf(out,"\n");
					}
				}
			}
			fprintf(out,"\t\t</Data>\n\t</Texture>\n");
		}
		fprintf(out,"</TextureList>\n");
	}

	// write materials
	if (scene->mNumMaterials) {
		fprintf(out,"<MaterialList num=\"%i\">\n",scene->mNumMaterials);
		for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
			const aiMaterial* mat = scene->mMaterials[i];

			fprintf(out,"\t<Material>\n");
			fprintf(out,"\t\t<MatPropertyList  num=\"%i\">\n",mat->mNumProperties);
			for (unsigned int n = 0; n < mat->mNumProperties;++n) {

				const aiMaterialProperty* prop = mat->mProperties[n];
				const char* sz = "";
				if (prop->mType == aiPTI_Float) {
					sz = "float";
				}
				else if (prop->mType == aiPTI_Integer) {
					sz = "integer";
				}
				else if (prop->mType == aiPTI_String) {
					sz = "string";
				}
				else if (prop->mType == aiPTI_Buffer) {
					sz = "binary_buffer";
				}

				fprintf(out,"\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%i\"",
					prop->mKey.data, sz,
					::TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex);

				if (prop->mType == aiPTI_Float) {
					fprintf(out," size=\"%i\">\n\t\t\t\t",
						static_cast<int>(prop->mDataLength/sizeof(float)));

					for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p) {
						fprintf(out,"%f ",*((float*)(prop->mData+p*sizeof(float))));
					}
				}
				else if (prop->mType == aiPTI_Integer) {
					fprintf(out," size=\"%i\">\n\t\t\t\t",
						static_cast<int>(prop->mDataLength/sizeof(int)));

					for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p) {
						fprintf(out,"%i ",*((int*)(prop->mData+p*sizeof(int))));
					}
				}
				else if (prop->mType == aiPTI_Buffer) {
					fprintf(out," size=\"%i\">\n\t\t\t\t",
						static_cast<int>(prop->mDataLength));

					for (unsigned int p = 0; p < prop->mDataLength;++p) {
						fprintf(out,"%2x ",prop->mData[p]);
						if (p && 0 == p%30) {
							fprintf(out,"\n\t\t\t\t");
						}
					}
				}
				else if (prop->mType == aiPTI_String) {
					fprintf(out,">\n\t\t\t\"%s\"",prop->mData+4 /* skip length */);
				}
				fprintf(out,"\n\t\t\t</MatProperty>\n");
			}
			fprintf(out,"\t\t</MatPropertyList>\n");
			fprintf(out,"\t</Material>\n");
		}
		fprintf(out,"</MaterialList>\n");
	}

	// write animations
	if (scene->mNumAnimations) {
		fprintf(out,"<AnimationList num=\"%i\">\n",scene->mNumAnimations);
		for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
			aiAnimation* anim = scene->mAnimations[i];

			// anim header
			ConvertName(name,anim->mName);
			fprintf(out,"\t<Animation name=\"%s\" duration=\"%e\" tick_cnt=\"%e\">\n",
				name.data, anim->mDuration, anim->mTicksPerSecond);

			// write bone animation channels
			if (anim->mNumChannels) {
				fprintf(out,"\t\t<NodeAnimList num=\"%i\">\n",anim->mNumChannels);
				for (unsigned int n = 0; n < anim->mNumChannels;++n) {
					aiNodeAnim* nd = anim->mChannels[n];

					// node anim header
					ConvertName(name,nd->mNodeName);
					fprintf(out,"\t\t\t<NodeAnim node=\"%s\">\n",name.data);

					if (!shortened) {
						// write position keys
						if (nd->mNumPositionKeys) {
							fprintf(out,"\t\t\t\t<PositionKeyList num=\"%i\">\n",nd->mNumPositionKeys);
							for (unsigned int a = 0; a < nd->mNumPositionKeys;++a) {
								aiVectorKey* vc = nd->mPositionKeys+a;
								fprintf(out,"\t\t\t\t\t<PositionKey time=\"%e\">\n"
									"\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</PositionKey>\n",
									vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
							}
							fprintf(out,"\t\t\t\t</PositionKeyList>\n");
						}

						// write scaling keys
						if (nd->mNumScalingKeys) {
							fprintf(out,"\t\t\t\t<ScalingKeyList num=\"%i\">\n",nd->mNumScalingKeys);
							for (unsigned int a = 0; a < nd->mNumScalingKeys;++a) {
								aiVectorKey* vc = nd->mScalingKeys+a;
								fprintf(out,"\t\t\t\t\t<ScalingKey time=\"%e\">\n"
									"\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</ScalingKey>\n",
									vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
							}
							fprintf(out,"\t\t\t\t</ScalingKeyList>\n");
						}

						// write rotation keys
						if (nd->mNumRotationKeys) {
							fprintf(out,"\t\t\t\t<RotationKeyList num=\"%i\">\n",nd->mNumRotationKeys);
							for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) {
								aiQuatKey* vc = nd->mRotationKeys+a;
								fprintf(out,"\t\t\t\t\t<RotationKey time=\"%e\">\n"
									"\t\t\t\t\t\t%0 8f %0 8f %0 8f %0 8f\n\t\t\t\t\t</RotationKey>\n",
									vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,vc->mValue.w);
							}
							fprintf(out,"\t\t\t\t</RotationKeyList>\n");
						}
					}
					fprintf(out,"\t\t\t</NodeAnim>\n");
				}
				fprintf(out,"\t\t</NodeAnimList>\n");
			}
			fprintf(out,"\t</Animation>\n");
		}
		fprintf(out,"</AnimationList>\n");
	}

	// write meshes
	if (scene->mNumMeshes) {
		fprintf(out,"<MeshList num=\"%i\">\n",scene->mNumMeshes);
		for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
			aiMesh* mesh = scene->mMeshes[i];
			// const unsigned int width = (unsigned int)log10((double)mesh->mNumVertices)+1;

			// mesh header
			fprintf(out,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n",
				(mesh->mPrimitiveTypes & aiPrimitiveType_POINT    ? "points"    : ""),
				(mesh->mPrimitiveTypes & aiPrimitiveType_LINE     ? "lines"     : ""),
				(mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE ? "triangles" : ""),
				(mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON  ? "polygons"  : ""),
				mesh->mMaterialIndex);

			// bones
			if (mesh->mNumBones) {
				fprintf(out,"\t\t<BoneList num=\"%i\">\n",mesh->mNumBones);

				for (unsigned int n = 0; n < mesh->mNumBones;++n) {
					aiBone* bone = mesh->mBones[n];

					ConvertName(name,bone->mName);
					// bone header
					fprintf(out,"\t\t\t<Bone name=\"%s\">\n"
						"\t\t\t\t<Matrix4> \n"
						"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
						"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
						"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
						"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
						"\t\t\t\t</Matrix4> \n",
						name.data,
						bone->mOffsetMatrix.a1,bone->mOffsetMatrix.a2,bone->mOffsetMatrix.a3,bone->mOffsetMatrix.a4,
						bone->mOffsetMatrix.b1,bone->mOffsetMatrix.b2,bone->mOffsetMatrix.b3,bone->mOffsetMatrix.b4,
						bone->mOffsetMatrix.c1,bone->mOffsetMatrix.c2,bone->mOffsetMatrix.c3,bone->mOffsetMatrix.c4,
						bone->mOffsetMatrix.d1,bone->mOffsetMatrix.d2,bone->mOffsetMatrix.d3,bone->mOffsetMatrix.d4);

					if (!shortened && bone->mNumWeights) {
						fprintf(out,"\t\t\t\t<WeightList num=\"%i\">\n",bone->mNumWeights);

						// bone weights
						for (unsigned int a = 0; a < bone->mNumWeights;++a) {
							aiVertexWeight* wght = bone->mWeights+a;

							fprintf(out,"\t\t\t\t\t<Weight index=\"%i\">\n\t\t\t\t\t\t%f\n\t\t\t\t\t</Weight>\n",
								wght->mVertexId,wght->mWeight);
						}
						fprintf(out,"\t\t\t\t</WeightList>\n");
					}
					fprintf(out,"\t\t\t</Bone>\n");
				}
				fprintf(out,"\t\t</BoneList>\n");
			}

			// faces
			if (!shortened && mesh->mNumFaces) {
				fprintf(out,"\t\t<FaceList num=\"%i\">\n",mesh->mNumFaces);
				for (unsigned int n = 0; n < mesh->mNumFaces; ++n) {
					aiFace& f = mesh->mFaces[n];
					fprintf(out,"\t\t\t<Face num=\"%i\">\n"
						"\t\t\t\t",f.mNumIndices);

					for (unsigned int j = 0; j < f.mNumIndices;++j)
						fprintf(out,"%i ",f.mIndices[j]);

					fprintf(out,"\n\t\t\t</Face>\n");
				}
				fprintf(out,"\t\t</FaceList>\n");
			}

			// vertex positions
			if (mesh->HasPositions()) {
				fprintf(out,"\t\t<Positions num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
				if (!shortened) {
					for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
						fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
							mesh->mVertices[n].x,
							mesh->mVertices[n].y,
							mesh->mVertices[n].z);
					}
				}
				fprintf(out,"\t\t</Positions>\n");
			}

			// vertex normals
			if (mesh->HasNormals()) {
				fprintf(out,"\t\t<Normals num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
				if (!shortened) {
					for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
						fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
							mesh->mNormals[n].x,
							mesh->mNormals[n].y,
							mesh->mNormals[n].z);
					}
				}
				else {
				}
				fprintf(out,"\t\t</Normals>\n");
			}

			// vertex tangents and bitangents
			if (mesh->HasTangentsAndBitangents()) {
				fprintf(out,"\t\t<Tangents num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
				if (!shortened) {
					for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
						fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
							mesh->mTangents[n].x,
							mesh->mTangents[n].y,
							mesh->mTangents[n].z);
					}
				}
				fprintf(out,"\t\t</Tangents>\n");

				fprintf(out,"\t\t<Bitangents num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
				if (!shortened) {
					for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
						fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
							mesh->mBitangents[n].x,
							mesh->mBitangents[n].y,
							mesh->mBitangents[n].z);
					}
				}
				fprintf(out,"\t\t</Bitangents>\n");
			}

			// texture coordinates
			for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
				if (!mesh->mTextureCoords[a])
					break;

				fprintf(out,"\t\t<TextureCoords num=\"%i\" set=\"%i\" num_components=\"%i\"> \n",mesh->mNumVertices,
					a,mesh->mNumUVComponents[a]);
				
				if (!shortened) {
					if (mesh->mNumUVComponents[a] == 3) {
						for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
							fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
								mesh->mTextureCoords[a][n].x,
								mesh->mTextureCoords[a][n].y,
								mesh->mTextureCoords[a][n].z);
						}
					}
					else {
						for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
							fprintf(out,"\t\t%0 8f %0 8f\n",
								mesh->mTextureCoords[a][n].x,
								mesh->mTextureCoords[a][n].y);
						}
					}
				}
				fprintf(out,"\t\t</TextureCoords>\n");
			}

			// vertex colors
			for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
				if (!mesh->mColors[a])
					break;
				fprintf(out,"\t\t<Colors num=\"%i\" set=\"%i\" num_components=\"4\"> \n",mesh->mNumVertices,a);
				if (!shortened) {
					for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
						fprintf(out,"\t\t%0 8f %0 8f %0 8f %0 8f\n",
							mesh->mColors[a][n].r,
							mesh->mColors[a][n].g,
							mesh->mColors[a][n].b,
							mesh->mColors[a][n].a);
					}
				}
				fprintf(out,"\t\t</Color>\n");
			}
			fprintf(out,"\t</Mesh>\n");
		}
		fprintf(out,"</MeshList>\n");
	}
	fprintf(out,"</Scene>\n</ASSIMP>");
}
示例#5
0
// -----------------------------------------------------------------------------------
// Write a text model dump
void WriteDump(const aiScene* scene, FILE* out, const char* src, const char* cmd, bool shortened)
{
	time_t tt = ::time(NULL);
	tm* p     = ::gmtime(&tt);

	aiString name;

	// write header
	::fprintf(out,
		"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
		"<ASSIMP >\n\n"

		"<!-- XML Model dump produced by assimp dump\n"
		"  Library version: %i.%i.%i\n"
		"  Source: %s\n"
		"  Command line: %s\n"
		"  %s\n"
		"-->"
		" \n\n"
		"<Scene NumberOfMeshes=\"%i\" NumberOfMaterials=\"%i\" NumberOfTextures=\"%i\" NumberOfCameras=\"%i\" NumberOfLights=\"%i\" NumberOfAnimations=\"%i\">\n",
		
		aiGetVersionMajor(),aiGetVersionMinor(),aiGetVersionRevision(),src,cmd,::asctime(p),
		scene->mNumMeshes, scene->mNumMaterials,scene->mNumTextures,
		scene->mNumCameras,scene->mNumLights,scene->mNumAnimations);

	// write the node graph
	WriteNode(scene->mRootNode, out, 1);

		// write cameras
	for (unsigned int i = 0; i < scene->mNumCameras;++i) {
		aiCamera* cam  = scene->mCameras[i];
		ConvertName(name,cam->mName);

		// camera header
		::fprintf(out,"\t<Camera parent=\"%s\">\n"
			"\t\t<Vector3 name=\"up\"        > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"lookat\"    > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"pos\"       > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Float   name=\"fov\"       > %f </Float>\n"
			"\t\t<Float   name=\"aspect\"    > %f </Float>\n"
			"\t\t<Float   name=\"near_clip\" > %f </Float>\n"
			"\t\t<Float   name=\"far_clip\"  > %f </Float>\n"
			"\t</Camera>\n",
			name.data,
			cam->mUp.x,cam->mUp.y,cam->mUp.z,
			cam->mLookAt.x,cam->mLookAt.y,cam->mLookAt.z,
			cam->mPosition.x,cam->mPosition.y,cam->mPosition.z,
			cam->mHorizontalFOV,cam->mAspect,cam->mClipPlaneNear,cam->mClipPlaneFar,i);
	}

	// write lights
	for (unsigned int i = 0; i < scene->mNumLights;++i) {
		aiLight* l  = scene->mLights[i];
		ConvertName(name,l->mName);

		// light header
		::fprintf(out,"\t<Light parent=\"%s\"> type=\"%s\"\n"
			"\t\t<Vector3 name=\"diffuse\"   > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"specular\"  > %0 8f %0 8f %0 8f </Vector3>\n"
			"\t\t<Vector3 name=\"ambient\"   > %0 8f %0 8f %0 8f </Vector3>\n",
			name.data,
			(l->mType == aiLightSource_DIRECTIONAL ? "directional" :
			(l->mType == aiLightSource_POINT ? "point" : "spot" )),
			l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b,
			l->mColorSpecular.r,l->mColorSpecular.g,l->mColorSpecular.b,
			l->mColorAmbient.r, l->mColorAmbient.g, l->mColorAmbient.b);

		if (l->mType != aiLightSource_DIRECTIONAL) {
			::fprintf(out,
				"\t\t<Vector3 name=\"pos\"       > %0 8f %0 8f %0 8f </Vector3>\n"
				"\t\t<Float   name=\"atten_cst\" > %f </Float>\n"
				"\t\t<Float   name=\"atten_lin\" > %f </Float>\n"
				"\t\t<Float   name=\"atten_sqr\" > %f </Float>\n",
				l->mPosition.x,l->mPosition.y,l->mPosition.z,
				l->mAttenuationConstant,l->mAttenuationLinear,l->mAttenuationQuadratic);
		}

		if (l->mType != aiLightSource_POINT) {
			::fprintf(out,
				"\t\t<Vector3 name=\"lookat\"    > %0 8f %0 8f %0 8f </Vector3>\n",
				l->mDirection.x,l->mDirection.y,l->mDirection.z);
		}

		if (l->mType == aiLightSource_SPOT) {
			::fprintf(out,
				"\t\t<Float   name=\"cone_out\" > %f </Float>\n"
				"\t\t<Float   name=\"cone_inn\" > %f </Float>\n",
				l->mAngleOuterCone,l->mAngleInnerCone);
		}
		::fprintf(out,"\t</Light>\n");
	}

	// write textures
	for (unsigned int i = 0; i < scene->mNumTextures;++i) {
		aiTexture* tex  = scene->mTextures[i];
		bool compressed = (tex->mHeight == 0);

		// mesh header
		::fprintf(out,"\t<Texture> \n"
			"\t\t<Integer   name=\"width\"      > %i </Integer>\n",
			"\t\t<Integer   name=\"height\"     > %i </Integer>\n",
			"\t\t<Boolean   name=\"compressed\" > %s </Boolean>\n",
			(compressed ? -1 : tex->mWidth),(compressed ? -1 : tex->mHeight),
			(compressed ? "true" : "false"));

		if (compressed) {
			::fprintf(out,"\t\t<Data length=\"%i\"> %i \n",tex->mWidth);

			if (!shortened) {
				for (unsigned int n = 0; n < tex->mWidth;++n) {
					::fprintf(out,"\t\t\t%2x",tex->pcData[n]);
					if (n && !(n % 50))
						::fprintf(out,"\n");
				}
			}
		}
		else if (!shortened){
			::fprintf(out,"\t\t<Data length=\"%i\"> %i \n",tex->mWidth*tex->mHeight*4);

			const unsigned int width = (unsigned int)log10((double)std::max(tex->mHeight,tex->mWidth))+1;
			for (unsigned int y = 0; y < tex->mHeight;++y) {
				for (unsigned int x = 0; x < tex->mWidth;++x) {
					aiTexel* tx = tex->pcData + y*tex->mWidth+x;
					unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a;
					::fprintf(out,"\t\t\t%2x %2x %2x %2x",r,g,b,a);

					// group by four for readibility
					if (0 == (x+y*tex->mWidth) % 4)
						::fprintf(out,"\n");
				}
			}
		}
		::fprintf(out,"\t\t</Data>\n\t</Texture>\n");
	}

	// write materials
	for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
		const aiMaterial* mat = scene->mMaterials[i];

		::fprintf(out,
			"\t<Material  NumberOfProperties=\"%i\">\n",mat->mNumProperties);

		for (unsigned int n = 0; n < mat->mNumProperties;++n) {
			const aiMaterialProperty* prop = mat->mProperties[n];

			const char* sz = "";
			if (prop->mType == aiPTI_Float) 
				sz = "float";
			else if (prop->mType == aiPTI_Integer) 
				sz = "integer";
			else if (prop->mType == aiPTI_String) 
				sz = "string";
			else if (prop->mType == aiPTI_Buffer) 
				sz = "binary_buffer";

			::fprintf(out,
				"\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%i\"",
				prop->mKey.data, sz,
				TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex);

			if (prop->mType == aiPTI_Float) {
				::fprintf(out,
				" size=\"%i\">\n\t\t\t",
				prop->mDataLength/sizeof(float));
				
				for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p)
					::fprintf(out,"%f ",*((float*)(prop->mData+p*sizeof(float))));
			}
			else if (prop->mType == aiPTI_Integer) {
				::fprintf(out,
				" size=\"%i\">\n\t\t\t",
				prop->mDataLength/sizeof(int));

				for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p)
					::fprintf(out,"%i ",*((int*)(prop->mData+p*sizeof(int))));
			}
			else if (prop->mType == aiPTI_Buffer) {
				::fprintf(out,
				" size=\"%i\">\n\t\t\t",
				prop->mDataLength);
				
				for (unsigned int p = 0; p < prop->mDataLength;++p) {
					::fprintf(out,"%2x ",prop->mData[p]);
					if (p && 0 == p%30)
						::fprintf(out,"\n\t\t\t");
				}
			}
			else if (prop->mType == aiPTI_String) {
				::fprintf(out,">\n\t\t\t\"%s\"",prop->mData+4 /* skip length */);
			}
			::fprintf(out,"\n\t\t</MatProperty>\n");
		}
		::fprintf(out,"\t</Material>\n");
	}

	// write animations
	for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
		aiAnimation* anim = scene->mAnimations[i];

		// anim header
		ConvertName(name,anim->mName);
		::fprintf(out,"\t<Animation name=\"%s\">\n"
			"\t\t<Integer name=\"num_chan\" > %i </Integer>\n"
			"\t\t<Float   name=\"duration\" > %e </Float>\n"
			"\t\t<Float   name=\"tick_cnt\" > %e </Float>\n",
			name.data, anim->mNumChannels,anim->mDuration, anim->mTicksPerSecond);

		// write bone animation channels
		for (unsigned int n = 0; n < anim->mNumChannels;++n) {
			aiNodeAnim* nd = anim->mChannels[n];

			// node anim header
			ConvertName(name,nd->mNodeName);
			::fprintf(out,"\t\t<Channel node=\"%s\">\n"
				"\t\t\t<Integer name=\"num_pos_keys\" > %i </Integer>\n"
				"\t\t\t<Integer name=\"num_scl_keys\" > %i </Integer>\n"
				"\t\t\t<Integer name=\"num_rot_keys\" > %i </Integer>\n",
				name.data,nd->mNumPositionKeys,nd->mNumScalingKeys,nd->mNumRotationKeys);

			if (!shortened) {
				// write position keys
				for (unsigned int a = 0; a < nd->mNumPositionKeys;++a) {
					aiVectorKey* vc = nd->mPositionKeys+a;
					::fprintf(out,"\t\t\t<PositionKey time=\"%e\">\n"
						"\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t</PositionKey>\n",
						vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,a);
				}

				// write scaling keys
				for (unsigned int a = 0; a < nd->mNumScalingKeys;++a) {
					aiVectorKey* vc = nd->mScalingKeys+a;
					::fprintf(out,"\t\t\t<ScalingKey time=\"%e\">\n"
						"\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t</ScalingKey>\n",
						vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,a);
				}

				// write rotation keys
				for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) {
					aiQuatKey* vc = nd->mRotationKeys+a;
					::fprintf(out,"\t\t\t<RotationKey time=\"%e\">\n"
						"\t\t\t\t%0 8f %0 8f %0 8f %0 8f\n\t\t\t</RotationKey>\n",
						vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,vc->mValue.w,a);
				}
			}
			::fprintf(out,"\t\t</Channel>\n",n);
		}
		::fprintf(out,"\t</Animation>\n",i);
	}

	// write meshes
	for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
		aiMesh* mesh = scene->mMeshes[i];
		const unsigned int width = (unsigned int)log10((double)mesh->mNumVertices)+1;

		// mesh header
		::fprintf(out,"\t<Mesh types=\"%s %s %s %s\">\n"
			"\t\t<Integer name=\"num_verts\" > %i </Integer>\n"
			"\t\t<Integer name=\"num_faces\" > %i </Integer>\n",
			(mesh->mPrimitiveTypes & aiPrimitiveType_POINT    ? "points"    : ""),
			(mesh->mPrimitiveTypes & aiPrimitiveType_LINE     ? "lines"     : ""),
			(mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE ? "triangles" : ""),
			(mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON  ? "polygons"  : ""),
			mesh->mNumVertices,mesh->mNumFaces);

		// bones
		for (unsigned int n = 0; n < mesh->mNumBones;++n) {
			aiBone* bone = mesh->mBones[n];

			ConvertName(name,bone->mName);
			// bone header
			::fprintf(out,"\t\t<Bone name=\"%s\">\n"
				"\t\t\t<Matrix4 name=\"offset\" > \n"
				"\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
				"\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
				"\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
				"\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
				"\t\t\t</Matrix4> \n"
				"\t\t\t<Integer name=\"num_weights\" > %i </Integer>\n",
				name.data,
				bone->mOffsetMatrix.a1,bone->mOffsetMatrix.a2,bone->mOffsetMatrix.a3,bone->mOffsetMatrix.a4,
				bone->mOffsetMatrix.b1,bone->mOffsetMatrix.b2,bone->mOffsetMatrix.b3,bone->mOffsetMatrix.b4,
				bone->mOffsetMatrix.c1,bone->mOffsetMatrix.c2,bone->mOffsetMatrix.c3,bone->mOffsetMatrix.c4,
				bone->mOffsetMatrix.d1,bone->mOffsetMatrix.d2,bone->mOffsetMatrix.d3,bone->mOffsetMatrix.d4,
				bone->mNumWeights);

			if (!shortened) {
				// bone weights
				for (unsigned int a = 0; a < bone->mNumWeights;++a) {
					aiVertexWeight* wght = bone->mWeights+a;

					::fprintf(out,"\t\t\t<VertexWeight index=\"%i\">\n\t\t\t\t%f\n\t\t\t</VertexWeight>\n",
						wght->mVertexId,wght->mWeight);
				}
			}
			::fprintf(out,"\t\t</Bone>\n",n);
		}

		// faces
		if (!shortened) {
			for (unsigned int n = 0; n < mesh->mNumFaces; ++n) {
				aiFace& f = mesh->mFaces[n];
				::fprintf(out,"\t\t<Face num_indices=\"%i\">\n"
					"\t\t\t",f.mNumIndices);

				for (unsigned int j = 0; j < f.mNumIndices;++j)
					::fprintf(out,"%i ",f.mIndices[j]);

				::fprintf(out,"\n\t\t</Face>\n");
			}
		}

		// vertex positions
		if (mesh->HasPositions()) {
			::fprintf(out,"\t\t<Positions> \n");
			if (!shortened) {
				for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
					::fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
						mesh->mVertices[n].x,
						mesh->mVertices[n].y,
						mesh->mVertices[n].z);
				}
			}
			else {
			}
			::fprintf(out,"\t\t</Positions>\n");
		}

		// vertex normals
		if (mesh->HasNormals()) {
			::fprintf(out,"\t\t<Normals> \n");
			if (!shortened) {
				for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
					::fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
						mesh->mNormals[n].x,
						mesh->mNormals[n].y,
						mesh->mNormals[n].z);
				}
			}
			else {
			}
			::fprintf(out,"\t\t</Normals>\n");
		}

		// vertex tangents and bitangents
		if (mesh->HasTangentsAndBitangents()) {
			::fprintf(out,"\t\t<Tangents> \n");
			if (!shortened) {
				for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
					::fprintf(out,"\t\t%0 8f %0 8f %0 8f \t %0 8f %0 8f %0 8f\n",
						mesh->mTangents[n].x,
						mesh->mTangents[n].y,
						mesh->mTangents[n].z,
						mesh->mBitangents[n].x,
						mesh->mBitangents[n].y,
						mesh->mBitangents[n].z);
				}
			}
			else {
			}
			::fprintf(out,"\t\t</Tangents>\n");
		}

		// texture coordinates
		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
			if (!mesh->mTextureCoords[a])
				break;

			::fprintf(out,"\t\t<TextureCoords set=\"%i\" num_components=\"%i\"> \n",a,mesh->mNumUVComponents[a]);
			if (!shortened) {
				for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
					::fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
						mesh->mTextureCoords[a][n].x,
						mesh->mTextureCoords[a][n].y,
						mesh->mTextureCoords[a][n].z);
				}
			}
			else {
			}
			::fprintf(out,"\t\t</TextureCoords>\n");
		}

		// vertex colors
		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
			if (!mesh->mColors[a])
				break;
			//::fprintf(out,"\t\t<Colors set=\"%i\"> \n",a);
			if (!shortened) {
				for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
					::fprintf(out,"\t\t%0 8f %0 8f %0 8f %0 8f\n",
						mesh->mColors[a][n].r,
						mesh->mColors[a][n].g,
						mesh->mColors[a][n].b,
						mesh->mColors[a][n].a);
				}
			}
			else {
			}
			::fprintf(out,"\t\t</Color>\n");
		}
		::fprintf(out,"\t</Mesh>\n");
	}
	::fprintf(out,"</Scene>\n</ASSIMP>");
}
示例#6
0
// -----------------------------------------------------------------------------------
// Write a binary model dump
void WriteBinaryDump(const aiScene* scene, FILE* out, const char* src, const char* cmd, 
	bool shortened, bool compressed, ImportData& imp)
{
	time_t tt = ::time(NULL);
	tm* p     = ::gmtime(&tt);

	// header
	::fprintf(out,"ASSIMP.binary-dump.%s.",::asctime(p));
	// == 45 bytes

	WriteInteger(aiGetVersionMajor(),out);
	WriteInteger(aiGetVersionMinor(),out);
	WriteInteger(aiGetVersionRevision(),out);
	WriteInteger(aiGetCompileFlags(),out);
	WriteShort(shortened,out);
	WriteShort(compressed,out);
	// ==  20 bytes

	char buff[256]; 
	::strncpy(buff,src,256);
	::fwrite(buff,256,1,out);

	::strncpy(buff,cmd,128);
	::fwrite(buff,128,1,out);

	// leave 41 bytes free for future extensions
	::memset(buff,0xcd,41);
	::fwrite(buff,32,1,out);
	// == 435 bytes

	// ==== total header size: 500 bytes
	// Up to here the data is uncompressed. For compressed files, the rest
	// is compressed using standard DEFLATE from zlib.
	
	// basic scene information
	WriteInteger(scene->mFlags,out);
	WriteInteger(scene->mNumAnimations,out);
	WriteInteger(scene->mNumTextures,out);
	WriteInteger(scene->mNumMaterials,out);
	WriteInteger(scene->mNumCameras,out);
	WriteInteger(scene->mNumLights,out);
	WriteInteger(scene->mNumMeshes,out);

	// write node graph
	WriteBinaryNode(scene->mRootNode,out);

	// write materials
	for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
		const aiMaterial* mat = scene->mMaterials[i];

		WriteMagic("#MA",out);
		WriteInteger(mat->mNumProperties,out);

		for (unsigned int a = 0; a < mat->mNumProperties;++a) {
			const aiMaterialProperty* prop = mat->mProperties[a];
			
			WriteMagic("#MP",out);
			WriteAiString(prop->mKey,out);
			WriteInteger(prop->mSemantic,out);
			WriteInteger(prop->mIndex,out);

			WriteInteger(prop->mDataLength,out);
			::fwrite(prop->mData,prop->mDataLength,1,out);
		}
	}

	// write cameras
	for (unsigned int i = 0; i < scene->mNumCameras;++i) {
		const aiCamera* cam = scene->mCameras[i];

		WriteMagic("#CA",out);
		WriteAiString(cam->mName,out);
		WriteVec3(cam->mPosition,out);
		WriteVec3(cam->mLookAt,out);
		WriteVec3(cam->mUp,out);
		WriteFloat(cam->mClipPlaneNear,out);
		WriteFloat(cam->mClipPlaneFar,out);
		WriteFloat(cam->mHorizontalFOV,out);
		WriteFloat(cam->mAspect,out);
	}

	// write lights
	for (unsigned int i = 0; i < scene->mNumLights;++i) {
		const aiLight* l = scene->mLights[i];

		WriteMagic("#LI",out);
		WriteAiString(l->mName,out);
		WriteInteger(l->mType,out);

		WriteVec3((const aiVector3D&)l->mColorDiffuse,out);
		WriteVec3((const aiVector3D&)l->mColorSpecular,out);
		WriteVec3((const aiVector3D&)l->mColorAmbient,out);

		if (l->mType != aiLightSource_DIRECTIONAL) { 
			WriteVec3(l->mPosition,out);
			WriteFloat(l->mAttenuationLinear,out);
			WriteFloat(l->mAttenuationConstant,out);
			WriteFloat(l->mAttenuationQuadratic,out);
		}

		if (l->mType != aiLightSource_POINT) {
			WriteVec3(l->mDirection,out);
		}

		if (l->mType == aiLightSource_SPOT) {
			WriteFloat(l->mAttenuationConstant,out);
			WriteFloat(l->mAttenuationQuadratic,out);
		}
	}

	// write all animations
	for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
		const aiAnimation* anim = scene->mAnimations[i];
		
		WriteMagic("#AN",out);
		WriteAiString (anim->mName,out);
		WriteDouble (anim->mTicksPerSecond,out);
		WriteDouble (anim->mDuration,out);
		WriteInteger(anim->mNumChannels,out);

		for (unsigned int a = 0; a < anim->mNumChannels;++a) {
			const aiNodeAnim* nd = anim->mChannels[a];

			WriteMagic("#NA",out);
			WriteAiString(nd->mNodeName,out);
			WriteInteger(nd->mPreState,out);
			WriteInteger(nd->mPostState,out);
			WriteInteger(nd->mNumPositionKeys,out);
			WriteInteger(nd->mNumRotationKeys,out);
			WriteInteger(nd->mNumScalingKeys,out);

			if (nd->mPositionKeys) {
				if (shortened) {
					WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys,out);

				} // else write as usual
				else ::fwrite(nd->mPositionKeys,sizeof(aiVectorKey),nd->mNumPositionKeys,out);
			}
			if (nd->mRotationKeys) {
				if (shortened) {
					WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys,out);

				} // else write as usual
				else ::fwrite(nd->mRotationKeys,sizeof(aiQuatKey),nd->mNumRotationKeys,out);
			}
			if (nd->mScalingKeys) {
				if (shortened) {
					WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys,out);

				} // else write as usual
				else ::fwrite(nd->mScalingKeys,sizeof(aiVectorKey),nd->mNumScalingKeys,out);
			}
		}
	}

	// write all meshes
	for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
		const aiMesh* mesh = scene->mMeshes[i];

		WriteMagic("#ME",out);
		WriteInteger(mesh->mPrimitiveTypes,out);
		WriteInteger(mesh->mNumBones,out);
		WriteInteger(mesh->mNumFaces,out);
		WriteInteger(mesh->mNumVertices,out);

		// write bones
		if (mesh->mNumBones) {
			for (unsigned int a = 0; a < mesh->mNumBones;++a) {
				const aiBone* b = mesh->mBones[a];

				WriteMagic("#BN",out);
				WriteAiString(b->mName,out);
				WriteMat4x4(b->mOffsetMatrix,out);
				WriteInteger(b->mNumWeights,out);

				// for the moment we write dumb min/max values for the bones, too.
				// maybe I'll add a better, hash-like solution later
				if (shortened) {
					WriteBounds(b->mWeights,b->mNumWeights,out);
				} // else write as usual
				else ::fwrite(b->mWeights,sizeof(aiVertexWeight),b->mNumWeights,out);
			}
		}

		// write faces. There are no floating-point calculations involved
		// in these, so we can write a simple hash over the face data
		// to the dump file. We generate a single 32 Bit hash for 512 faces
		// using Assimp's standard hashing function.
		if (shortened) {
			unsigned int processed = 0;
			for (unsigned int job;job = std::min(mesh->mNumFaces-processed,512u);processed += job) {

				unsigned int hash = 0;
				for (unsigned int a = 0; a < job;++a) {

					const aiFace& f = mesh->mFaces[processed+a];
					hash = SuperFastHash((const char*)&f.mNumIndices,sizeof(unsigned int),hash);
					hash = SuperFastHash((const char*) f.mIndices,f.mNumIndices*sizeof(unsigned int),hash);
				}
				WriteInteger(hash,out);
			}
		}
		else // else write as usual
		{
			for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
				const aiFace& f = mesh->mFaces[i];

				WriteInteger(f.mNumIndices,out);
				for (unsigned int a = 0; a < f.mNumIndices;++a)
					WriteInteger(f.mIndices[a],out);
			}
		}

		// first of all, write bits for all existent vertex components
		unsigned int c = 0;
		if (mesh->mVertices) 
			c |= 1;
		if (mesh->mNormals)
			c |= 2;
		if (mesh->mTangents && mesh->mBitangents) 
			c |= 4;
		for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
			if (!mesh->mTextureCoords[n])break;
			c |= (8 << n);
		}
		for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
			if (!mesh->mColors[n])break;
			c |= (16 << n);
		}
		WriteInteger(c,out);
		
		aiVector3D minVec, maxVec;
		if (mesh->mVertices) {
			if (shortened) {
				WriteBounds(mesh->mVertices,mesh->mNumVertices,out);
			} // else write as usual
			else ::fwrite(mesh->mVertices,12*mesh->mNumVertices,1,out);
		}
		if (mesh->mNormals) {
			if (shortened) {
				WriteBounds(mesh->mNormals,mesh->mNumVertices,out);
			} // else write as usual
			else ::fwrite(mesh->mNormals,12*mesh->mNumVertices,1,out);
		}
		if (mesh->mTangents && mesh->mBitangents) {
			if (shortened) {
				WriteBounds(mesh->mTangents,mesh->mNumVertices,out);
				WriteBounds(mesh->mBitangents,mesh->mNumVertices,out);
			} // else write as usual
			else {
				::fwrite(mesh->mTangents,12*mesh->mNumVertices,1,out);
				::fwrite(mesh->mBitangents,12*mesh->mNumVertices,1,out);
			}
		}
		for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
			if (!mesh->mTextureCoords[n])break;

			// write number of UV components
			WriteInteger(mesh->mNumUVComponents[n],out);

			if (shortened) {
				WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices,out);
			} // else write as usual
			else ::fwrite(mesh->mTextureCoords[n],12*mesh->mNumVertices,1,out);
		}
		for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
			if (!mesh->mColors[n])
				break;

			if (shortened) {
				WriteBounds(mesh->mColors[n],mesh->mNumVertices,out);
			} // else write as usual
			else ::fwrite(mesh->mColors[n],16*mesh->mNumVertices,1,out);
		}
	}
}
示例#7
0
TEST_F( utVersion, aiGetVersionMajorTest ) {
    EXPECT_EQ( aiGetVersionMajor(), 4U );
}