Ejemplo n.º 1
0
Material::Material()
{
		ambient(1,1,1,1);
	diffuse(1,1,1,1);
	emissive(1,1,1,1);
	specular(1,1,1,1);
	m_shininess = 100;
	m_texture = -1;
	m_pTextureFilename = 0;
}
Ejemplo n.º 2
0
void SetOpenGlDefaultMaterial()
{
    glm::vec4 ambient( 0.2, 0.2, 0.2, 1.0 );
    glm::vec4 specular( 0.0, 0.0, 0.0, 1.0 );
    glm::vec4 emissive( 0.0, 0.0, 0.0, 1.0 );
    glm::vec4 diffuse( 0.0, 0.0, 0.0, 1.0 );
    GLint shininess_value = 0;

    glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
    glMateriali ( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value );
    glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, &emissive.x );
    glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.x );
    glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT,  &ambient.x );
    glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE,  &diffuse.x );

}
Ejemplo n.º 3
0
VType *CopyMesh(INDICES &indices, LptaSkin::ID &skinId, const aiScene *scene, MANAGERS &managers)
{
    VType *vertices = new VType();
    vector<LptaSkin::ID> skinIds;
    for (unsigned int matIdx = 0; matIdx < scene->mNumMaterials; ++matIdx) {
        aiMaterial *mat = scene->mMaterials[matIdx];
        aiColor4D diffuse(0.0f, 0.0f, 0.0f, 0.0f);
        aiColor4D ambient(0.0f, 0.0f, 0.0f, 0.0f);
        aiColor4D specular(0.0f, 0.0f, 0.0f, 0.0f);
        aiColor4D emissive(0.0f, 0.0f, 0.0f, 0.0f);
        float specularPower = 0.0f;

        mat->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
        mat->Get(AI_MATKEY_COLOR_AMBIENT, ambient);
        mat->Get(AI_MATKEY_COLOR_SPECULAR, specular);
        mat->Get(AI_MATKEY_COLOR_EMISSIVE, emissive);
        mat->Get(AI_MATKEY_SHININESS, specularPower);

        aiGetMaterialColor(mat, AI_MATKEY_COLOR_EMISSIVE, &emissive);

        LptaMaterial::ID materialId = managers.material.AddOrRetrieveMaterial(
            LptaColor(diffuse.r, diffuse.g, diffuse.b, diffuse.a),
            LptaColor(ambient.r, ambient.g, ambient.b, diffuse.a),
            LptaColor(specular.r, specular.g, specular.b, specular.a),
            LptaColor(emissive.r, emissive.g, emissive.b, emissive.a),
            specularPower
        );
        
        LptaSkin::TEXTURE_IDS textureIds;
        // only diffuse texture is supported for now
        for (unsigned int texIdx = 0; texIdx < mat->GetTextureCount(aiTextureType_DIFFUSE) && texIdx < LptaSkin::MAX_TEXTURES; ++texIdx) {
            aiString filepath;
            mat->GetTexture(aiTextureType_DIFFUSE, texIdx, &filepath);
            LptaTexture::ID textureId = managers.texture.AddOrRetrieveTexture(filepath.C_Str());
            textureIds.push_back(textureId);
        }
        LptaSkin::ID skinId = managers.skin.AddSkin(materialId, textureIds, false);
        skinIds.push_back(skinId);
    }
    for (unsigned int meshIdx = 0; meshIdx < scene->mNumMeshes; ++meshIdx) {
        const aiMesh *mesh = scene->mMeshes[meshIdx];

        CopyAlgorithm::Copy(*vertices, indices, *mesh, vertices->GetNumVertices());
        skinId = skinIds.at(mesh->mMaterialIndex);
    }
    return vertices;
}
Ejemplo n.º 4
0
void SurfacePropertiesCS::parsePhong( TiXmlElement* techniqueRoot )
{
   // create a material
   float power = 2;
   if ( techniqueRoot->FirstChildElement( "shininess" ) )
   {
      const char* valStr = techniqueRoot->FirstChildElement( "shininess" )->FirstChildElement( "float" )->GetText();
      sscanf_s( valStr, "%f", &power );
   }

   Color ambient( 0.7f, 0.7f, 0.7f, 1 );
   if ( techniqueRoot->FirstChildElement( "ambient" ) )
   {
      const char* valStr = techniqueRoot->FirstChildElement( "ambient" )->FirstChildElement( "color" )->GetText();
      sscanf_s( valStr, "%f %f %f %f", &ambient.r, &ambient.g, &ambient.b, &ambient.a );
   }

   Color diffuse( 0.7f, 0.7f, 0.7f, 1 );
   if ( techniqueRoot->FirstChildElement( "diffuse" ) )
   {
      const char* valStr = techniqueRoot->FirstChildElement( "diffuse" )->FirstChildElement( "color" )->GetText();
      sscanf_s( valStr, "%f %f %f %f", &diffuse.r, &diffuse.g, &diffuse.b, &diffuse.a );
   }

   Color specular( 0.9f, 0.9f, 0.9f, 1 );
   if ( techniqueRoot->FirstChildElement( "specular" ) )
   {
      const char* valStr = techniqueRoot->FirstChildElement( "specular" )->FirstChildElement( "color" )->GetText();
      sscanf_s( valStr, "%f %f %f %f", &specular.r, &specular.g, &specular.b, &specular.a );
   }

   Color emissive( 0, 0, 0 );
   if ( techniqueRoot->FirstChildElement( "emission" ) )
   {
      const char* valStr = techniqueRoot->FirstChildElement( "emission" )->FirstChildElement( "color" )->GetText();
      sscanf_s( valStr, "%f %f %f %f", &emissive.r, &emissive.g, &emissive.b, &emissive.a );
   }

   m_surfaceProperties = new SurfaceProperties( ambient, diffuse, specular, emissive, power );
}
Ejemplo n.º 5
0
bool Model::LoadAssimp(const char *filename)
{
	Assimp::Importer importer;

	// remove unused data
	importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, 
		aiComponent_COLORS | aiComponent_LIGHTS | aiComponent_CAMERAS);

	// max triangles and vertices per mesh, splits above this threshold
	importer.SetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, INT_MAX);
	importer.SetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT, 0xfffe); // avoid the primitive restart index

	// remove points and lines
	importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_POINT | aiPrimitiveType_LINE);

	const aiScene *scene = importer.ReadFile(filename,
		aiProcess_CalcTangentSpace |
		aiProcess_JoinIdenticalVertices |
		aiProcess_Triangulate |
		aiProcess_RemoveComponent |
		aiProcess_GenSmoothNormals |
		aiProcess_SplitLargeMeshes |
		aiProcess_ValidateDataStructure |
		//aiProcess_ImproveCacheLocality | // handled by optimizePostTransform()
		aiProcess_RemoveRedundantMaterials |
		aiProcess_SortByPType |
		aiProcess_FindInvalidData |
		aiProcess_GenUVCoords |
		aiProcess_TransformUVCoords |
		aiProcess_OptimizeMeshes |
		aiProcess_OptimizeGraph);

	if (scene == nullptr)
		return false;

	if (scene->HasTextures())
	{
		// embedded textures...
	}

	if (scene->HasAnimations())
	{
		// todo
	}

	m_Header.materialCount = scene->mNumMaterials;
	m_pMaterial = new Material [m_Header.materialCount];
	memset(m_pMaterial, 0, sizeof(Material) * m_Header.materialCount);
	for (unsigned int materialIndex = 0; materialIndex < scene->mNumMaterials; materialIndex++)
	{
		const aiMaterial *srcMat = scene->mMaterials[materialIndex];
		Material *dstMat = m_pMaterial + materialIndex;

		aiColor3D diffuse(1.0f, 1.0f, 1.0f);
		aiColor3D specular(1.0f, 1.0f, 1.0f);
		aiColor3D ambient(1.0f, 1.0f, 1.0f);
		aiColor3D emissive(0.0f, 0.0f, 0.0f);
		aiColor3D transparent(1.0f, 1.0f, 1.0f);
		float opacity = 1.0f;
		float shininess = 0.0f;
		float specularStrength = 1.0f;
		aiString texDiffusePath;
		aiString texSpecularPath;
		aiString texEmissivePath;
		aiString texNormalPath;
		aiString texLightmapPath;
		aiString texReflectionPath;
		srcMat->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
		srcMat->Get(AI_MATKEY_COLOR_SPECULAR, specular);
		srcMat->Get(AI_MATKEY_COLOR_AMBIENT, ambient);
		srcMat->Get(AI_MATKEY_COLOR_EMISSIVE, emissive);
		srcMat->Get(AI_MATKEY_COLOR_TRANSPARENT, transparent);
		srcMat->Get(AI_MATKEY_OPACITY, opacity);
		srcMat->Get(AI_MATKEY_SHININESS, shininess);
		srcMat->Get(AI_MATKEY_SHININESS_STRENGTH, specularStrength);
		srcMat->Get(AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0), texDiffusePath);
		srcMat->Get(AI_MATKEY_TEXTURE(aiTextureType_SPECULAR, 0), texSpecularPath);
		srcMat->Get(AI_MATKEY_TEXTURE(aiTextureType_EMISSIVE, 0), texEmissivePath);
		srcMat->Get(AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0), texNormalPath);
		srcMat->Get(AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0), texLightmapPath);
		srcMat->Get(AI_MATKEY_TEXTURE(aiTextureType_REFLECTION, 0), texReflectionPath);

		dstMat->diffuse = Vector3(diffuse.r, diffuse.g, diffuse.b);
		dstMat->specular = Vector3(specular.r, specular.g, specular.b);
		dstMat->ambient = Vector3(ambient.r, ambient.g, ambient.b);
		dstMat->emissive = Vector3(emissive.r, emissive.g, emissive.b);
		dstMat->transparent = Vector3(transparent.r, transparent.g, transparent.b);
		dstMat->opacity = opacity;
		dstMat->shininess = shininess;
		dstMat->specularStrength = specularStrength;

		char *pRem = nullptr;

		strncpy_s(dstMat->texDiffusePath, "models/", Material::maxTexPath - 1);
		strncat_s(dstMat->texDiffusePath, texDiffusePath.C_Str(), Material::maxTexPath - 1);
		pRem = strrchr(dstMat->texDiffusePath, '.');
		while (pRem != nullptr && *pRem != 0) *(pRem++) = 0; // remove extension

		strncpy_s(dstMat->texSpecularPath, "models/", Material::maxTexPath - 1);
		strncat_s(dstMat->texSpecularPath, texSpecularPath.C_Str(), Material::maxTexPath - 1);
		pRem = strrchr(dstMat->texSpecularPath, '.');
		while (pRem != nullptr && *pRem != 0) *(pRem++) = 0; // remove extension

		strncpy_s(dstMat->texEmissivePath, "models/", Material::maxTexPath - 1);
		strncat_s(dstMat->texEmissivePath, texEmissivePath.C_Str(), Material::maxTexPath - 1);
		pRem = strrchr(dstMat->texEmissivePath, '.');
		while (pRem != nullptr && *pRem != 0) *(pRem++) = 0; // remove extension

		strncpy_s(dstMat->texNormalPath, "models/", Material::maxTexPath - 1);
		strncat_s(dstMat->texNormalPath, texNormalPath.C_Str(), Material::maxTexPath - 1);
		pRem = strrchr(dstMat->texNormalPath, '.');
		while (pRem != nullptr && *pRem != 0) *(pRem++) = 0; // remove extension

		strncpy_s(dstMat->texLightmapPath, "models/", Material::maxTexPath - 1);
		strncat_s(dstMat->texLightmapPath, texLightmapPath.C_Str(), Material::maxTexPath - 1);
		pRem = strrchr(dstMat->texLightmapPath, '.');
		while (pRem != nullptr && *pRem != 0) *(pRem++) = 0; // remove extension

		strncpy_s(dstMat->texReflectionPath, "models/", Material::maxTexPath - 1);
		strncat_s(dstMat->texReflectionPath, texReflectionPath.C_Str(), Material::maxTexPath - 1);
		pRem = strrchr(dstMat->texReflectionPath, '.');
		while (pRem != nullptr && *pRem != 0) *(pRem++) = 0; // remove extension

		aiString matName;
		srcMat->Get(AI_MATKEY_NAME, matName);
		strncpy_s(dstMat->name, matName.C_Str(), Material::maxMaterialName - 1);
	}

	m_Header.meshCount = scene->mNumMeshes;
	m_pMesh = new Mesh [m_Header.meshCount];
	memset(m_pMesh, 0, sizeof(Mesh) * m_Header.meshCount);
	// first pass, count everything
	for (unsigned int meshIndex = 0; meshIndex < scene->mNumMeshes; meshIndex++)
	{
		const aiMesh *srcMesh = scene->mMeshes[meshIndex];
		Mesh *dstMesh = m_pMesh + meshIndex;

		assert(srcMesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE);

		dstMesh->materialIndex = srcMesh->mMaterialIndex;

		// just store everything as float. Can quantize in Model::optimize()
		dstMesh->attribsEnabled |= attrib_mask_position;
		dstMesh->attrib[attrib_position].offset = dstMesh->vertexStride;
		dstMesh->attrib[attrib_position].normalized = 0;
		dstMesh->attrib[attrib_position].components = 3;
		dstMesh->attrib[attrib_position].format = attrib_format_float;
		dstMesh->vertexStride += sizeof(float) * 3;

		dstMesh->attribsEnabled |= attrib_mask_texcoord0;
		dstMesh->attrib[attrib_texcoord0].offset = dstMesh->vertexStride;
		dstMesh->attrib[attrib_texcoord0].normalized = 0;
		dstMesh->attrib[attrib_texcoord0].components = 2;
		dstMesh->attrib[attrib_texcoord0].format = attrib_format_float;
		dstMesh->vertexStride += sizeof(float) * 2;

		dstMesh->attribsEnabled |= attrib_mask_normal;
		dstMesh->attrib[attrib_normal].offset = dstMesh->vertexStride;
		dstMesh->attrib[attrib_normal].normalized = 0;
		dstMesh->attrib[attrib_normal].components = 3;
		dstMesh->attrib[attrib_normal].format = attrib_format_float;
		dstMesh->vertexStride += sizeof(float) * 3;

		dstMesh->attribsEnabled |= attrib_mask_tangent;
		dstMesh->attrib[attrib_tangent].offset = dstMesh->vertexStride;
		dstMesh->attrib[attrib_tangent].normalized = 0;
		dstMesh->attrib[attrib_tangent].components = 3;
		dstMesh->attrib[attrib_tangent].format = attrib_format_float;
		dstMesh->vertexStride += sizeof(float) * 3;

		dstMesh->attribsEnabled |= attrib_mask_bitangent;
		dstMesh->attrib[attrib_bitangent].offset = dstMesh->vertexStride;
		dstMesh->attrib[attrib_bitangent].normalized = 0;
		dstMesh->attrib[attrib_bitangent].components = 3;
		dstMesh->attrib[attrib_bitangent].format = attrib_format_float;
		dstMesh->vertexStride += sizeof(float) * 3;

		// depth-only
		dstMesh->attribsEnabledDepth |= attrib_mask_position;
		dstMesh->attribDepth[attrib_position].offset = dstMesh->vertexStrideDepth;
		dstMesh->attribDepth[attrib_position].normalized = 0;
		dstMesh->attribDepth[attrib_position].components = 3;
		dstMesh->attribDepth[attrib_position].format = attrib_format_float;
		dstMesh->vertexStrideDepth += sizeof(float) * 3;

		// color rendering
		dstMesh->vertexDataByteOffset = m_Header.vertexDataByteSize;
		dstMesh->vertexCount = srcMesh->mNumVertices;

		dstMesh->indexDataByteOffset = m_Header.indexDataByteSize;
		dstMesh->indexCount = srcMesh->mNumFaces * 3;

		m_Header.vertexDataByteSize += dstMesh->vertexStride * dstMesh->vertexCount;
		m_Header.indexDataByteSize += sizeof(uint16_t) * dstMesh->indexCount;

		// depth-only rendering
		dstMesh->vertexDataByteOffsetDepth = m_Header.vertexDataByteSizeDepth;
		dstMesh->vertexCountDepth = srcMesh->mNumVertices;

		m_Header.vertexDataByteSizeDepth += dstMesh->vertexStrideDepth * dstMesh->vertexCountDepth;
	}
	// allocate storage
	m_pVertexData = new unsigned char [m_Header.vertexDataByteSize];
	m_pIndexData = new unsigned char [m_Header.indexDataByteSize];
	m_pVertexDataDepth = new unsigned char [m_Header.vertexDataByteSizeDepth];
	m_pIndexDataDepth = new unsigned char [m_Header.indexDataByteSize];
	// second pass, fill in vertex and index data
	for (unsigned int meshIndex = 0; meshIndex < scene->mNumMeshes; meshIndex++)
	{
		const aiMesh *srcMesh = scene->mMeshes[meshIndex];
		Mesh *dstMesh = m_pMesh + meshIndex;

		float *dstPos = (float*)(m_pVertexData + dstMesh->vertexDataByteOffset + dstMesh->attrib[attrib_position].offset);
		float *dstTexcoord0 = (float*)(m_pVertexData + dstMesh->vertexDataByteOffset + dstMesh->attrib[attrib_texcoord0].offset);
		float *dstNormal = (float*)(m_pVertexData + dstMesh->vertexDataByteOffset + dstMesh->attrib[attrib_normal].offset);
		float *dstTangent = (float*)(m_pVertexData + dstMesh->vertexDataByteOffset + dstMesh->attrib[attrib_tangent].offset);
		float *dstBitangent = (float*)(m_pVertexData + dstMesh->vertexDataByteOffset + dstMesh->attrib[attrib_bitangent].offset);

		float *dstPosDepth = (float*)(m_pVertexDataDepth + dstMesh->vertexDataByteOffsetDepth + dstMesh->attribDepth[attrib_position].offset);

		for (unsigned int v = 0; v < dstMesh->vertexCount; v++)
		{
			if (srcMesh->mVertices)
			{
				dstPos[0] = srcMesh->mVertices[v].x;
				dstPos[1] = srcMesh->mVertices[v].y;
				dstPos[2] = srcMesh->mVertices[v].z;

				dstPosDepth[0] = srcMesh->mVertices[v].x;
				dstPosDepth[1] = srcMesh->mVertices[v].y;
				dstPosDepth[2] = srcMesh->mVertices[v].z;
			}
			else
			{
				// no position? That's kind of bad.
				assert(0);
			}
			dstPos = (float*)((unsigned char*)dstPos + dstMesh->vertexStride);
			dstPosDepth = (float*)((unsigned char*)dstPosDepth + dstMesh->vertexStrideDepth);

			if (srcMesh->mTextureCoords[0])
			{
				dstTexcoord0[0] = srcMesh->mTextureCoords[0][v].x;
				dstTexcoord0[1] = srcMesh->mTextureCoords[0][v].y;
			}
			else
			{
				dstTexcoord0[0] = 0.0f;
				dstTexcoord0[1] = 0.0f;
			}
			dstTexcoord0 = (float*)((unsigned char*)dstTexcoord0 + dstMesh->vertexStride);

			if (srcMesh->mNormals)
			{
				dstNormal[0] = srcMesh->mNormals[v].x;
				dstNormal[1] = srcMesh->mNormals[v].y;
				dstNormal[2] = srcMesh->mNormals[v].z;
			}
			else
			{
				// Assimp should generate normals if they are missing, according to the postprocessing flag specified on load,
				// so we should never get here.
				assert(0);
			}
			dstNormal = (float*)((unsigned char*)dstNormal + dstMesh->vertexStride);

			if (srcMesh->mTangents)
			{
				dstTangent[0] = srcMesh->mTangents[v].x;
				dstTangent[1] = srcMesh->mTangents[v].y;
				dstTangent[2] = srcMesh->mTangents[v].z;
			}
			else
			{
				// TODO: generate tangents/bitangents if missing
				dstTangent[0] = 1.0f;
				dstTangent[1] = 0.0f;
				dstTangent[2] = 0.0f;
			}
			dstTangent = (float*)((unsigned char*)dstTangent + dstMesh->vertexStride);

			if (srcMesh->mBitangents)
			{
				dstBitangent[0] = srcMesh->mBitangents[v].x;
				dstBitangent[1] = srcMesh->mBitangents[v].y;
				dstBitangent[2] = srcMesh->mBitangents[v].z;
			}
			else
			{
				// TODO: generate tangents/bitangents if missing
				dstBitangent[0] = 0.0f;
				dstBitangent[1] = 1.0f;
				dstBitangent[2] = 0.0f;
			}
			dstBitangent = (float*)((unsigned char*)dstBitangent + dstMesh->vertexStride);
		}

		uint16_t *dstIndex = (uint16_t*)(m_pIndexData + dstMesh->indexDataByteOffset);
		uint16_t *dstIndexDepth = (uint16_t*)(m_pIndexDataDepth + dstMesh->indexDataByteOffset);
		for (unsigned int f = 0; f < srcMesh->mNumFaces; f++)
		{
			assert(srcMesh->mFaces[f].mNumIndices == 3);

			*dstIndex++ = srcMesh->mFaces[f].mIndices[0];
			*dstIndex++ = srcMesh->mFaces[f].mIndices[1];
			*dstIndex++ = srcMesh->mFaces[f].mIndices[2];

			*dstIndexDepth++ = srcMesh->mFaces[f].mIndices[0];
			*dstIndexDepth++ = srcMesh->mFaces[f].mIndices[1];
			*dstIndexDepth++ = srcMesh->mFaces[f].mIndices[2];
		}
	}

	ComputeAllBoundingBoxes();

	return true;
}
Ejemplo n.º 6
0
Ray SceneObject::emit(bool isUniformOrigin , bool isUniformDir) const
{
	Ray ray;
	
	if(!areaValues.size())
	{
		ray.direction = vec3f(0, 0, 0);
		ray.directionProb = 1;
		ray.color = vec3f(0, 0, 0);
		return ray;
	}

	if (isUniformOrigin)
	{
		float rnd = RandGenerator::genFloat()*totalArea;
		unsigned index = (lower_bound(areaValues.begin(), areaValues.end(), rnd)-areaValues.begin());
		if(index >= areaValues.size())
			index = areaValues.size() - 1; 
		ray.contactObject = (SceneObject*)this;
		ray.contactObjectTriangleID = index;
		ray.origin = genRandTrianglePosition(ray.contactObjectTriangleID);
		ray.originProb = weight / totalArea;
	}
	else
	{
		float rnd = RandGenerator::genFloat()*totalEnergy;
		unsigned index = (lower_bound(energyDensity.begin(), energyDensity.end(), rnd)-energyDensity.begin());
		if(index >= energyDensity.size())
			index = energyDensity.size() - 1; 
		ray.contactObject = (SceneObject*)this;
		ray.contactObjectTriangleID = index;
		ray.origin = genRandTrianglePosition(ray.contactObjectTriangleID);

		float prob;
		if (index == 0)
			prob = energyDensity[index] / totalEnergy;
		else
			prob = (energyDensity[index] - energyDensity[index - 1]) / totalEnergy;
		ray.originProb = weight * prob / areaValues[index];
	}

	UniformSphericalSampler uniformSphericalSampler;
	CosineSphericalSampler cosineSphericalSampler;

	LocalFrame lf = ray.contactObject->getAutoGenWorldLocalFrame(ray.contactObjectTriangleID, ray.origin);

	if (isUniformDir)
		ray.direction = uniformSphericalSampler.genSample(lf);
	else
		ray.direction = cosineSphericalSampler.genSample(lf);

	if(ray.getContactNormal().dot(ray.direction) < 0)
		ray.direction = -ray.direction;

	ray.insideObject = scene->findInsideObject(ray, ray.contactObject);

	ray.current_tid = scene->getContactTreeTid(ray);
	ray.color = ray.getBSDF(ray);
	if(!emissive())
		ray.color = vec3f(1, 1, 1);

	if (isUniformDir)
		ray.directionProb = uniformSphericalSampler.getProbDensity(lf , ray.direction) * 2.f;
	else
		ray.directionProb = cosineSphericalSampler.getProbDensity(lf, ray.direction);

	ray.directionSampleType = ray.originSampleType = Ray::RANDOM;

	if(!scene->usingGPU())
	{
		Scene::ObjSourceInformation osi;
		NoSelfIntersectionCondition condition(scene, ray);
		float dist = scene->intersect(ray, osi, &condition);
		if(dist > 0)
		{
			ray.intersectDist = dist;
			ray.intersectObject = scene->objects[osi.objID];
			ray.intersectObjectTriangleID = osi.triangleID;
		}
	}
	return ray;
}
Ejemplo n.º 7
0
Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
                                            const Ogre::String &name, const Ogre::String &group,
                                            const Nif::NiTexturingProperty *texprop,
                                            const Nif::NiMaterialProperty *matprop,
                                            const Nif::NiAlphaProperty *alphaprop,
                                            const Nif::NiVertexColorProperty *vertprop,
                                            const Nif::NiZBufferProperty *zprop,
                                            const Nif::NiSpecularProperty *specprop,
                                            const Nif::NiWireframeProperty *wireprop,
                                            const Nif::NiStencilProperty *stencilprop,
                                            bool &needTangents, bool particleMaterial)
{
    Ogre::MaterialManager &matMgr = Ogre::MaterialManager::getSingleton();
    Ogre::MaterialPtr material = matMgr.getByName(name);
    if(!material.isNull())
        return name;

    Ogre::Vector3 ambient(1.0f);
    Ogre::Vector3 diffuse(1.0f);
    Ogre::Vector3 specular(0.0f);
    Ogre::Vector3 emissive(0.0f);
    float glossiness = 0.0f;
    float alpha = 1.0f;
    int alphaFlags = 0;
    int alphaTest = 0;
    int vertMode = 2;
    //int lightMode = 1;
    int depthFlags = 3;
    // Default should be 1, but Bloodmoon's models are broken
    int specFlags = 0;
    int wireFlags = 0;
    int drawMode = 1;
    Ogre::String texName[7];

    bool vertexColour = (shapedata->colors.size() != 0);

    // Texture
    if(texprop)
    {
        for(int i = 0;i < 7;i++)
        {
            if(!texprop->textures[i].inUse)
                continue;
            if(texprop->textures[i].texture.empty())
            {
                warn("Texture layer "+Ogre::StringConverter::toString(i)+" is in use but empty in "+name);
                continue;
            }

            const Nif::NiSourceTexture *st = texprop->textures[i].texture.getPtr();
            if(st->external)
                texName[i] = Misc::ResourceHelpers::correctTexturePath(st->filename);
            else
                warn("Found internal texture, ignoring.");
        }

        Nif::ControllerPtr ctrls = texprop->controller;
        while(!ctrls.empty())
        {
            if (ctrls->recType != Nif::RC_NiFlipController) // Handled in ogrenifloader
                warn("Unhandled texture controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    // Alpha modifiers
    if(alphaprop)
    {
        alphaFlags = alphaprop->flags;
        alphaTest = alphaprop->data.threshold;

        Nif::ControllerPtr ctrls = alphaprop->controller;
        while(!ctrls.empty())
        {
            warn("Unhandled alpha controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    // Vertex color handling
    if(vertprop)
    {
        vertMode = vertprop->data.vertmode;
        // FIXME: Handle lightmode?
        //lightMode = vertprop->data.lightmode;

        Nif::ControllerPtr ctrls = vertprop->controller;
        while(!ctrls.empty())
        {
            warn("Unhandled vertex color controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    if(zprop)
    {
        depthFlags = zprop->flags;
        // Depth function???

        Nif::ControllerPtr ctrls = zprop->controller;
        while(!ctrls.empty())
        {
            warn("Unhandled depth controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    if(specprop)
    {
        specFlags = specprop->flags;

        Nif::ControllerPtr ctrls = specprop->controller;
        while(!ctrls.empty())
        {
            warn("Unhandled specular controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    if(wireprop)
    {
        wireFlags = wireprop->flags;

        Nif::ControllerPtr ctrls = wireprop->controller;
        while(!ctrls.empty())
        {
            warn("Unhandled wireframe controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    if(stencilprop)
    {
        drawMode = stencilprop->data.drawMode;
        if (stencilprop->data.enabled)
            warn("Unhandled stencil test in "+name);

        Nif::ControllerPtr ctrls = stencilprop->controller;
        while(!ctrls.empty())
        {
            warn("Unhandled stencil controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    // Material
    if(matprop)
    {
        ambient = matprop->data.ambient;
        diffuse = matprop->data.diffuse;
        specular = matprop->data.specular;
        emissive = matprop->data.emissive;
        glossiness = matprop->data.glossiness;
        alpha = matprop->data.alpha;

        Nif::ControllerPtr ctrls = matprop->controller;
        while(!ctrls.empty())
        {
            if (ctrls->recType != Nif::RC_NiAlphaController && ctrls->recType != Nif::RC_NiMaterialColorController)
                warn("Unhandled material controller "+ctrls->recName+" in "+name);
            ctrls = ctrls->next;
        }
    }

    if (particleMaterial)
    {
        alpha = 1.f; // Apparently ignored, might be overridden by particle vertex colors?
    }

    {
        // Generate a hash out of all properties that can affect the material.
        size_t h = 0;
        boost::hash_combine(h, ambient.x);
        boost::hash_combine(h, ambient.y);
        boost::hash_combine(h, ambient.z);
        boost::hash_combine(h, diffuse.x);
        boost::hash_combine(h, diffuse.y);
        boost::hash_combine(h, diffuse.z);
        boost::hash_combine(h, alpha);
        boost::hash_combine(h, specular.x);
        boost::hash_combine(h, specular.y);
        boost::hash_combine(h, specular.z);
        boost::hash_combine(h, glossiness);
        boost::hash_combine(h, emissive.x);
        boost::hash_combine(h, emissive.y);
        boost::hash_combine(h, emissive.z);
        for(int i = 0;i < 7;i++)
        {
            if(!texName[i].empty())
            {
                boost::hash_combine(h, texName[i]);
                boost::hash_combine(h, texprop->textures[i].clamp);
                boost::hash_combine(h, texprop->textures[i].uvSet);
            }
        }
        boost::hash_combine(h, drawMode);
        boost::hash_combine(h, vertexColour);
        boost::hash_combine(h, alphaFlags);
        boost::hash_combine(h, alphaTest);
        boost::hash_combine(h, vertMode);
        boost::hash_combine(h, depthFlags);
        boost::hash_combine(h, specFlags);
        boost::hash_combine(h, wireFlags);

        std::map<size_t,std::string>::iterator itr = sMaterialMap.find(h);
        if (itr != sMaterialMap.end())
        {
            // a suitable material exists already - use it
            sh::MaterialInstance* instance = sh::Factory::getInstance().getMaterialInstance(itr->second);
            needTangents = !sh::retrieveValue<sh::StringValue>(instance->getProperty("normalMap"), instance).get().empty();
            return itr->second;
        }
        // not found, create a new one
        sMaterialMap.insert(std::make_pair(h, name));
    }

    // No existing material like this. Create a new one.
    sh::MaterialInstance *instance = sh::Factory::getInstance().createMaterialInstance(name, "openmw_objects_base");
    if(vertMode == 0 || !vertexColour)
    {
        instance->setProperty("ambient", sh::makeProperty(new sh::Vector4(ambient.x, ambient.y, ambient.z, 1)));
        instance->setProperty("diffuse", sh::makeProperty(new sh::Vector4(diffuse.x, diffuse.y, diffuse.z, alpha)));
        instance->setProperty("emissive", sh::makeProperty(new sh::Vector4(emissive.x, emissive.y, emissive.z, 1)));
        instance->setProperty("vertmode", sh::makeProperty(new sh::StringValue("0")));
    }
    else if(vertMode == 1)
    {
        instance->setProperty("ambient", sh::makeProperty(new sh::Vector4(ambient.x, ambient.y, ambient.z, 1)));
        instance->setProperty("diffuse", sh::makeProperty(new sh::Vector4(diffuse.x, diffuse.y, diffuse.z, alpha)));
        instance->setProperty("emissive", sh::makeProperty(new sh::StringValue("vertexcolour")));
        instance->setProperty("vertmode", sh::makeProperty(new sh::StringValue("1")));
    }
    else if(vertMode == 2)
    {
        instance->setProperty("ambient", sh::makeProperty(new sh::StringValue("vertexcolour")));
        instance->setProperty("diffuse", sh::makeProperty(new sh::StringValue("vertexcolour")));
        instance->setProperty("emissive", sh::makeProperty(new sh::Vector4(emissive.x, emissive.y, emissive.z, 1)));
        instance->setProperty("vertmode", sh::makeProperty(new sh::StringValue("2")));
    }
    else
        std::cerr<< "Unhandled vertex mode: "<<vertMode <<std::endl;

    if(specFlags)
    {
        instance->setProperty("specular", sh::makeProperty(
            new sh::Vector4(specular.x, specular.y, specular.z, glossiness)));
    }

    if(wireFlags)
    {
        instance->setProperty("polygon_mode", sh::makeProperty(new sh::StringValue("wireframe")));
    }

    if (drawMode == 1)
        instance->setProperty("cullmode", sh::makeProperty(new sh::StringValue("clockwise")));
    else if (drawMode == 2)
        instance->setProperty("cullmode", sh::makeProperty(new sh::StringValue("anticlockwise")));
    else if (drawMode == 3)
        instance->setProperty("cullmode", sh::makeProperty(new sh::StringValue("none")));

    instance->setProperty("diffuseMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BaseTexture]));
    instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture]));
    instance->setProperty("detailMap", sh::makeProperty(texName[Nif::NiTexturingProperty::DetailTexture]));
    instance->setProperty("emissiveMap", sh::makeProperty(texName[Nif::NiTexturingProperty::GlowTexture]));
    instance->setProperty("darkMap", sh::makeProperty(texName[Nif::NiTexturingProperty::DarkTexture]));
    if (!texName[Nif::NiTexturingProperty::BaseTexture].empty())
    {
        instance->setProperty("use_diffuse_map", sh::makeProperty(new sh::BooleanValue(true)));
        setTextureProperties(instance, "diffuseMap", texprop->textures[Nif::NiTexturingProperty::BaseTexture]);
    }
    if (!texName[Nif::NiTexturingProperty::GlowTexture].empty())
    {
        instance->setProperty("use_emissive_map", sh::makeProperty(new sh::BooleanValue(true)));
        setTextureProperties(instance, "emissiveMap", texprop->textures[Nif::NiTexturingProperty::GlowTexture]);
    }
    if (!texName[Nif::NiTexturingProperty::DetailTexture].empty())
    {
        instance->setProperty("use_detail_map", sh::makeProperty(new sh::BooleanValue(true)));
        setTextureProperties(instance, "detailMap", texprop->textures[Nif::NiTexturingProperty::DetailTexture]);
    }
    if (!texName[Nif::NiTexturingProperty::DarkTexture].empty())
    {
        instance->setProperty("use_dark_map", sh::makeProperty(new sh::BooleanValue(true)));
        setTextureProperties(instance, "darkMap", texprop->textures[Nif::NiTexturingProperty::DarkTexture]);
    }

    bool useParallax = !texName[Nif::NiTexturingProperty::BumpTexture].empty()
            && texName[Nif::NiTexturingProperty::BumpTexture].find("_nh.") != std::string::npos;
    instance->setProperty("use_parallax", sh::makeProperty(new sh::BooleanValue(useParallax)));

    for(int i = 0;i < 7;i++)
    {
        if(i == Nif::NiTexturingProperty::BaseTexture ||
           i == Nif::NiTexturingProperty::DetailTexture ||
           i == Nif::NiTexturingProperty::DarkTexture ||
           i == Nif::NiTexturingProperty::BumpTexture ||
           i == Nif::NiTexturingProperty::GlowTexture)
            continue;
        if(!texName[i].empty())
            warn("Ignored texture "+texName[i]+" on layer "+Ogre::StringConverter::toString(i) + " in " + name);
    }

    if (vertexColour)
        instance->setProperty("has_vertex_colour", sh::makeProperty(new sh::BooleanValue(true)));

    // Override alpha flags based on our override list (transparency-overrides.cfg)
    if ((alphaFlags&1) && !texName[0].empty())
    {
        NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName[0]);
        if (result.first)
        {
            alphaFlags = (1<<9) | (6<<10); /* alpha_rejection enabled, greater_equal */
            alphaTest = result.second;
            depthFlags = (1<<0) | (1<<1); // depth_write on, depth_check on
        }
    }

    // Add transparency if NiAlphaProperty was present
    if((alphaFlags&1))
    {
        std::string blend_mode;
        blend_mode += getBlendFactor((alphaFlags>>1)&0xf);
        blend_mode += " ";
        blend_mode += getBlendFactor((alphaFlags>>5)&0xf);
        instance->setProperty("scene_blend", sh::makeProperty(new sh::StringValue(blend_mode)));
    }
Ejemplo n.º 8
0
// Convert DirectX mesh to osg::Geode
osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh,
                                               bool flipTexture, float creaseAngle,
                                               const osgDB::ReaderWriter::Options * options) const
{
    const DX::MeshMaterialList* meshMaterial = mesh.getMeshMaterialList();
    if (!meshMaterial)
        return NULL;

    const DX::MeshNormals* meshNormals = mesh.getMeshNormals();
    if (!meshNormals) {
        mesh.generateNormals(creaseAngle);
        meshNormals = mesh.getMeshNormals();
    }
    //std::cerr << "normals=" << meshNormals << std::endl;
    if (!meshNormals)
        return NULL;

    const DX::MeshTextureCoords* meshTexCoords = mesh.getMeshTextureCoords();
    //std::cerr << "texcoord=" << meshTexCoords << std::endl;
    if (!meshTexCoords)
        return NULL;

    /*
     * - MeshMaterialList contains a list of Material and a per-face
     *   information with Material is to be applied to which face.
     * - Mesh contains a list of Vertices and a per-face information
     *   which vertices (three or four) belong to this face.
     * - MeshNormals contains a list of Normals and a per-face information
     *   which normal is used by which vertex.
     * - MeshTextureCoords contains a list of per-vertex texture coordinates.
     *
     * - Uses left-hand CS with Y-up, Z-into
     *   obj_x -> osg_x
     *   obj_y -> osg_z
     *   obj_z -> osg_y
     *
     * - Polys are CW oriented
     */
    std::vector<osg::Geometry*> geomList;

    // Texture-for-Image map
    std::map<std::string, osg::Texture2D*> texForImage;
    
    unsigned int i;
    for (i = 0; i < meshMaterial->material.size(); i++) {

        //std::cerr << "material " << i << std::endl;

        const DX::Material& mtl = meshMaterial->material[i];
        osg::StateSet* state = new osg::StateSet;

        // Material
        osg::Material* material = new osg::Material;
        state->setAttributeAndModes(material);

        float alpha = mtl.faceColor.alpha;
        osg::Vec4 ambient(mtl.faceColor.red,
                          mtl.faceColor.green,
                          mtl.faceColor.blue,
                          alpha);
        material->setAmbient(osg::Material::FRONT, ambient);
        material->setDiffuse(osg::Material::FRONT, ambient);

        material->setShininess(osg::Material::FRONT, mtl.power);

        osg::Vec4 specular(mtl.specularColor.red,
                           mtl.specularColor.green,
                           mtl.specularColor.blue, alpha);
        material->setSpecular(osg::Material::FRONT, specular);

        osg::Vec4 emissive(mtl.emissiveColor.red,
                           mtl.emissiveColor.green,
                           mtl.emissiveColor.blue, alpha);
        material->setEmission(osg::Material::FRONT, emissive);

        // Transparency? Set render hint & blending
        if (alpha < 1.0f) {
            state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
            state->setMode(GL_BLEND, osg::StateAttribute::ON);
        }
        else
            state->setMode(GL_BLEND, osg::StateAttribute::OFF);

        unsigned int textureCount = mtl.texture.size();
        for (unsigned int j = 0; j < textureCount; j++) {

            //std::cerr << "texture " << j << std::endl;

            // Share image/texture pairs
            osg::Texture2D* texture = texForImage[mtl.texture[j]];
            if (!texture) {
                osg::Image* image = osgDB::readImageFile(mtl.texture[j],options);
                if (!image)
                    continue;

                // Texture
                texture = new osg::Texture2D;
                texForImage[mtl.texture[j]] = texture;

                texture->setImage(image);
                texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
                texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
            }
            state->setTextureAttributeAndModes(j, texture);
        }

        // Geometry
        osg::Geometry* geom = new osg::Geometry;
        geomList.push_back(geom);

        geom->setStateSet(state);

        // Arrays to hold vertices, normals, and texcoords.
        geom->setVertexArray(new osg::Vec3Array);
        geom->setNormalArray(new osg::Vec3Array);
        geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
        if (textureCount) {
            // All texture units share the same array
            osg::Vec2Array* texCoords = new osg::Vec2Array;
            for (unsigned int j = 0; j < textureCount; j++)
                geom->setTexCoordArray(j, texCoords);
        }

        geom->addPrimitiveSet(new osg::DrawArrayLengths(osg::PrimitiveSet::POLYGON));
    }

    const std::vector<DX::MeshFace> & faces = mesh.getFaces();
    if (faces.size() != meshMaterial->faceIndices.size())
    {
        osg::notify(osg::FATAL)<<"Error: internal error in DirectX .x loader,"<<std::endl;
        osg::notify(osg::FATAL)<<"       mesh->faces.size() == meshMaterial->faceIndices.size()"<<std::endl;
        return NULL;
    }

    // Add faces to Geometry
    for (i = 0; i < meshMaterial->faceIndices.size(); i++) {

        // Geometry for Material
        unsigned int mi = meshMaterial->faceIndices[i];
        osg::Geometry* geom = geomList[mi];

        // #pts of this face
        unsigned int np = faces[i].size();
        ((osg::DrawArrayLengths*) geom->getPrimitiveSet(0))->push_back(np);

        if (np != meshNormals->faceNormals[i].size())
        {
            osg::notify(osg::WARN)<<"DirectX loader: Error, error in normal list."<<std::endl;
        }

        osg::Vec3Array* vertexArray = (osg::Vec3Array*) geom->getVertexArray();
        osg::Vec3Array* normalArray = (osg::Vec3Array*) geom->getNormalArray();
        osg::Vec2Array* texCoordArray = (osg::Vec2Array*) geom->getTexCoordArray(0);

        // Add vertices, normals, texcoords
        for (unsigned int j = 0; j < np; j++) {

            // Convert CW to CCW order
            unsigned int jj = (j > 0 ? np - j : j);

            // Vertices
            unsigned int vi = faces[i][jj];
            if (vertexArray) {
                // Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup
                const DX::Vector & v = mesh.getVertices()[vi];
                vertexArray->push_back(osg::Vec3(v.x,v.z,v.y));
            }

            // Normals
            unsigned int ni = meshNormals->faceNormals[i][jj];
            if (normalArray) {
                // Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup
                const DX::Vector& n = meshNormals->normals[ni];
                normalArray->push_back(osg::Vec3(n.x,n.z,n.y));
            }

            // TexCoords
            if (texCoordArray) {
                const DX::Coords2d& tc = (*meshTexCoords)[vi];
                osg::Vec2 uv;
                if (flipTexture)
                    uv.set(tc.u, 1.0f - tc.v); // Image is upside down
                else
                    uv.set(tc.u, tc.v);
                texCoordArray->push_back(uv);
            }
        }
    }

    // Add non-empty nodes to Geode
    osg::Geode* geode = new osg::Geode;
    for (i = 0; i < geomList.size(); i++) {
        osg::Geometry* geom = geomList[i];
        if (((osg::Vec3Array*) geom->getVertexArray())->size())
            geode->addDrawable(geom);
    }

    // Back-face culling
    osg::StateSet* state = new osg::StateSet;
    geode->setStateSet(state);

    osg::CullFace* cullFace = new osg::CullFace;
    cullFace->setMode(osg::CullFace::BACK);
    state->setAttributeAndModes(cullFace);

    return geode;
}
Ejemplo n.º 9
0
		static bool load(std::shared_ptr<CookingTask> cookingTask)
		{
			if (!cookingTask->dataSet->loadMaterials)
				return true;
			auto tid = Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PushTask("MaterialLoader : loading " + cookingTask->dataSet->filePath.getShortFileName());
			if (!cookingTask->assimpScene->HasMaterials())
			{
				Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PopTask(tid);
				return true;
			}

			if (cookingTask->assimpScene->mNumMaterials <= 1)
			{
				return true;
			}

			for (unsigned int materialIndex = 1; materialIndex < cookingTask->assimpScene->mNumMaterials; ++materialIndex)
			{
				auto &aiMat = cookingTask->assimpScene->mMaterials[materialIndex];

				aiColor4D diffuse(1.0f,1.0f,1.0f,1.0f);
				aiColor4D ambient(1.0f, 1.0f, 1.0f, 1.0f);
				aiColor4D emissive(1.0f, 1.0f, 1.0f, 1.0f);
				aiColor4D reflective(1.0f, 1.0f, 1.0f, 1.0f);
				aiColor4D specular(1.0f, 1.0f, 1.0f, 1.0f);

				aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_DIFFUSE, &diffuse);
				aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_AMBIENT, &ambient);
				aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_EMISSIVE, &emissive);
				aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_REFLECTIVE, &reflective);
				aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_SPECULAR, &specular);

				aiString diffuseTexPath;
				aiString ambientTexPath;
				aiString emissiveTexPath;
				aiString reflexionTexPath;
				aiString specularTexPath;
				aiString normalTexPath;
				aiString bumpTexPath;

				aiMat->GetTexture(aiTextureType_DIFFUSE, 0, &diffuseTexPath);
				aiMat->GetTexture(aiTextureType_AMBIENT, 0, &ambientTexPath);
				aiMat->GetTexture(aiTextureType_EMISSIVE, 0, &emissiveTexPath);
				aiMat->GetTexture(aiTextureType_REFLECTION, 0, &reflexionTexPath);
				aiMat->GetTexture(aiTextureType_SPECULAR, 0, &specularTexPath);
				aiMat->GetTexture(aiTextureType_NORMALS, 0, &normalTexPath);
				aiMat->Get(AI_MATKEY_TEXTURE_HEIGHT(0), bumpTexPath);

				auto material = std::make_shared<MaterialData>();

				material->diffuse = AssimpLoader::aiColorToGlm(diffuse);
				material->ambient = AssimpLoader::aiColorToGlm(ambient);
				material->emissive = AssimpLoader::aiColorToGlm(emissive);
				material->reflective = AssimpLoader::aiColorToGlm(reflective);
				material->specular = AssimpLoader::aiColorToGlm(specular);

				material->diffuseTexPath = diffuseTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(diffuseTexPath) : "";
				material->ambientTexPath = ambientTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(ambientTexPath) : "";
				material->emissiveTexPath = emissiveTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(emissiveTexPath) : "";
				material->reflectiveTexPath = reflexionTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(reflexionTexPath) : "";
				material->specularTexPath = specularTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(specularTexPath) : "";
				material->normalTexPath = normalTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(normalTexPath) : "";
				material->bumpTexPath = bumpTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(bumpTexPath) : "";

				cookingTask->texturesPath.insert(material->diffuseTexPath);
				cookingTask->texturesPath.insert(material->ambientTexPath);
				cookingTask->texturesPath.insert(material->emissiveTexPath);
				cookingTask->texturesPath.insert(material->reflectiveTexPath);
				cookingTask->texturesPath.insert(material->specularTexPath);
				cookingTask->texturesPath.insert(material->normalTexPath);
				cookingTask->texturesPath.insert(material->bumpTexPath);

				AssimpLoader::replaceExtension(material->diffuseTexPath, ".dds");
				AssimpLoader::replaceExtension(material->ambientTexPath, ".dds");
				AssimpLoader::replaceExtension(material->emissiveTexPath, ".dds");
				AssimpLoader::replaceExtension(material->reflectiveTexPath, ".dds");
				AssimpLoader::replaceExtension(material->specularTexPath, ".dds");
				AssimpLoader::replaceExtension(material->normalTexPath, ".dds");
				AssimpLoader::replaceExtension(material->bumpTexPath, ".dds");

				cookingTask->materials.push_back(material);
            }

			if (cookingTask->materials.size() == 0)
			{
				Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PopTask(tid);
				std::cerr << "MaterialLoader : Materials has not been loaded" << std::endl;
				return false;
			}
			Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PopTask(tid);
			return true;
		}