ISimpleMesh* CResourceFactory::createSimpleMesh(
		const std::string& name,
		u32 sortcode,
		u32 vertexFormat,
		void* vertices,
		void* indices,
		u32 vertexCount,
		u32 vertexStride,
		u32 indiceCount,
		const math::SAxisAlignedBox& aabb,
		bool bit32Index,
		E_MEMORY_USAGE usage)
	{
		IMeshBuffer* buffer = createMeshBuffer(usage, vertices, indices, vertexCount, indiceCount, vertexStride, bit32Index);
		if (!buffer)
		{
			GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str());
			return nullptr;
		}

		CSimpleMesh* mesh = new CSimpleMesh(name, sortcode, aabb, 
			vertexFormat,
			buffer);

		if (!mesh)
		{
			GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str());
			buffer->drop();
			return nullptr;
		}

		return mesh;
	}
//! reads a mesh sections and creates a mesh from it
IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader)
{
	SAnimatedMesh* animatedmesh = new SAnimatedMesh();
	SMesh* mesh = new SMesh();

	animatedmesh->addMesh(mesh);
	mesh->drop();

	core::stringc bbSectionName = "boundingBox";
	core::stringc bufferSectionName = "buffer";
	core::stringc meshSectionName = "mesh";

	if (!reader->isEmptyElement())
	while(reader->read())
	{
		if (reader->getNodeType() == io::EXN_ELEMENT)
		{
			const wchar_t* nodeName = reader->getNodeName();
			if (bbSectionName == nodeName)
			{
				// inside a bounding box, ignore it for now because
				// we are calculating this anyway ourselves later.
			}
			else
			if (bufferSectionName == nodeName)
			{
				// we've got a mesh buffer

				IMeshBuffer* buffer = readMeshBuffer(reader);
				if (buffer)
				{
					mesh->addMeshBuffer(buffer);
					buffer->drop();
				}
			}
			else
				skipSection(reader, true); // unknown section

		} // end if node type is element
		else
		if (reader->getNodeType() == io::EXN_ELEMENT_END)
		{
			if (meshSectionName == reader->getNodeName())
			{
				// end of mesh section reached, cancel out
				break;
			}
		}
	} // end while reader->read();

	mesh->recalculateBoundingBox();
	animatedmesh->recalculateBoundingBox();

	return animatedmesh;
}
	IModelMesh* CResourceFactory::createModelMesh(
		const std::string& name,
		u32 sortcode,
		u32 vertexFormat,
		void* vertices,
		void* indices,
		u32 vertexCount,
		u32 vertexStride,
		u32 indiceCount,
		const math::SAxisAlignedBox& aabb,
		bool bit32Index,
		const std::vector<IModelMesh::SModelSubset>& subsets,
		E_MEMORY_USAGE usage)
	{
		IMeshBuffer* buffer = createMeshBuffer(usage, vertices, indices, vertexCount, indiceCount, vertexStride, bit32Index);
		if (!buffer)
		{
			GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str());
			return nullptr;
		}

		if (subsets.size() < 1)
		{
			GF_PRINT_CONSOLE_INFO("FAIL:The mesh ('%s') create failed!. The subsets count must be greater than 1.\n", name.c_str());
			return nullptr;
		}

		CModelMesh* mesh = new CModelMesh(name, sortcode, aabb, vertexFormat,
			subsets, buffer);
		if (!mesh)
		{
			GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str());
			buffer->drop();
			return nullptr;
		}

		return mesh;
	}
	IBillboardCollectionMesh* CResourceFactory::createBillboardCollectionMesh(
		const std::string& name,
		u32 sortcode,
		const math::SAxisAlignedBox& aabb,
		bool alterable,
		u32 maxNum,
		const std::vector<SBillboard>& billboards)
	{
		IMeshBuffer* buffer = nullptr;
		if (alterable)
		{
			if (billboards.size() > maxNum)
			{
				GF_PRINT_CONSOLE_INFO("Billboard buffer creation failed."
					"billboards' number exceeds the maxNum.\n");

				return nullptr;
			}

			void* vertices = nullptr;
			if (!billboards.empty())
				vertices = (void*)&billboards[0];

			buffer = createMeshBuffer(EMU_DYNAMIC, nullptr, nullptr, maxNum, 0,
				sizeof(SBillboard), true);

			buffer->setVertexData(vertices, billboards.size());
		}
		else 
		{
			// create a static buffer.
			// use the size of billboards as the maxNum. just ignore the 'maxNum' 
			maxNum = billboards.size();
			if (maxNum == 0)
			{
				GF_PRINT_CONSOLE_INFO("billboards cannot be empty when creating a "
					"billboard mesh");
				return nullptr;
			}
			
			buffer = createMeshBuffer(EMU_STATIC, (void*)&billboards[0],
				nullptr, billboards.size(), 0, sizeof(SBillboard), true);
		}

		if (!buffer)
		{
			GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str());
			return nullptr;
		}

		CBillboardCollectionMesh* mesh = new CBillboardCollectionMesh(name, sortcode, aabb,
			maxNum, alterable, billboards, buffer);

		if (!mesh)
		{
			GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str());
			buffer->drop();
			return nullptr;
		}

		return mesh;

	}