Ejemplo n.º 1
0
	VertexMapper::VertexMapper(SubMesh* subMesh, BufferAccess access)
	{
		ErrorFlags flags(ErrorFlag_ThrowException, true);

		VertexBuffer* buffer = nullptr;
		switch (subMesh->GetAnimationType())
		{
			case AnimationType_Skeletal:
			{
				SkeletalMesh* skeletalMesh = static_cast<SkeletalMesh*>(subMesh);
				buffer = skeletalMesh->GetVertexBuffer();
				break;
			}

			case AnimationType_Static:
			{
				StaticMesh* staticMesh = static_cast<StaticMesh*>(subMesh);
				buffer = staticMesh->GetVertexBuffer();
				break;
			}
		}

		if (!buffer)
		{
			NazaraInternalError("Animation type not handled (0x" + String::Number(subMesh->GetAnimationType(), 16) + ')');
		}

		m_mapper.Map(buffer, access);
	}
void ClusterTreeWidgetItem::setRenderable(MeshCluster* c)
{

	list<StaticMesh*> meshes = c->getMeshes();
	list<StaticMesh*>::iterator it;

	for(it = meshes.begin(); it != meshes.end(); it++)
	{
		StaticMesh* m = *it;
		TriangleMeshTreeWidgetItem* item = new TriangleMeshTreeWidgetItem(TriangleMeshItem);

		// Setup supported render modes
		int modes = 0;
		size_t n_pn;
		modes |= Mesh;
		modes |= Wireframe;

		item->setName(m->Name());
		item->setNumFaces(m->getNumberOfFaces());
		item->setNumVertices(m->getNumberOfVertices());
		item->setRenderable(m);

		addChild(item);
	}

	m_renderable = c;

}
Ejemplo n.º 3
0
StaticMesh* GraphicsEngineImp::CreateStaticMesh(string filename, D3DXVECTOR3 pos, Material* material)
{
	StaticMesh* mesh = new StaticMesh(pos, filename);

	// if it is in memory dont put it on another thread.
	if(!this->useLoadingThread && GetResourceManager()->HasMeshStripsResource(filename.c_str()))
	{
		bool success = mesh->LoadFromFile(filename);
		if(success)
		{
			this->dx->CreateStaticMesh(mesh);
		}


		MaloW::Array<MeshStrip*>* strips = mesh->GetStrips();
		for(unsigned int i = 0; i < strips->size(); i++)
		{
			strips->get(i)->SetMaterial(material);
			
			if(i+1 < strips->size())
			{
				material = new Material(material);
			}
		}
	}
	else
	{
		LoadMeshEvent* re = new LoadMeshEvent(filename, mesh, NULL, material);
		this->PutEvent(re);
	}

	return mesh;
}
Ejemplo n.º 4
0
void XmlSceneParser::Parse (const ParseNode& decl, StaticMesh& node, Node& parent, SceneContext& context)
{
  try
  {
      //предварительный разбор
      
    StaticMeshDeclPtr node_decl = impl->PrepareStaticMesh (decl);

      //настройка узла

    node.SetMeshName (node_decl->source.c_str ());

    //set bound box only if either min or max value is present, otherwise leave infinite bound box
    if (node_decl->min_bound.state || node_decl->max_bound.state)
    {
      bound_volumes::aaboxf box;
    
      if (node_decl->min_bound.state) box.set_minimum (node_decl->min_bound.value);
      if (node_decl->max_bound.state) box.set_maximum (node_decl->max_bound.value);

      node.SetBoundBox (box);
    }

      //разбор родительских параметров
    
    Parse (decl, static_cast<Entity&> (node), parent, context);
  }
  catch (xtl::exception& e)
  {
    e.touch ("scene_graph::XmlSceneParser::Parse(const ParseNode&,StaticMesh&,Node&,SceneContext&)");
    throw;
  }
}
Ejemplo n.º 5
0
void ConstructQuadMesh(StaticMesh& mesh)
{
    Vertex tempVertex;
    std::vector<Vertex> quadVertices;

    tempVertex.position = Vector3(-1, -1, 0);
    tempVertex.uv = Vector2(0, 0);
    quadVertices.push_back(tempVertex);

    tempVertex.position = Vector3(-1, 1, 0);
    tempVertex.uv = Vector2(0, 1);
    quadVertices.push_back(tempVertex);

    tempVertex.position = Vector3(1, -1, 0);
    tempVertex.uv = Vector2(1, 0);
    quadVertices.push_back(tempVertex);

    tempVertex.position = Vector3(1, 1, 0);
    tempVertex.uv = Vector2(1, 1);
    quadVertices.push_back(tempVertex);
    
    std::vector<GLuint> quadIndices;
    quadIndices.push_back(0);
    quadIndices.push_back(2);
    quadIndices.push_back(1);

    quadIndices.push_back(1);
    quadIndices.push_back(2);
    quadIndices.push_back(3);

    mesh.BufferData(quadVertices, quadIndices);
}
Ejemplo n.º 6
0
	void Mesh::Transform(const Matrix4f& matrix)
	{
		#if NAZARA_UTILITY_SAFE
		if (!m_impl)
		{
			NazaraError("Mesh not created");
			return;
		}

		if (m_impl->animationType != AnimationType_Static)
		{
			NazaraError("Mesh must be static");
			return;
		}
		#endif

		if (matrix.IsIdentity())
			return;

		for (SubMesh* subMesh : m_impl->subMeshes)
		{
			StaticMesh* staticMesh = static_cast<StaticMesh*>(subMesh);

			BufferMapper<VertexBuffer> mapper(staticMesh->GetVertexBuffer(), BufferAccess_ReadWrite);
			MeshVertex* vertices = static_cast<MeshVertex*>(mapper.GetPointer());

			Boxf aabb(vertices->position.x, vertices->position.y, vertices->position.z, 0.f, 0.f, 0.f);

			unsigned int vertexCount = staticMesh->GetVertexCount();
			for (unsigned int i = 0; i < vertexCount; ++i)
			{
				vertices->position = matrix.Transform(vertices->position);
				aabb.ExtendTo(vertices->position);

				vertices++;
			}

			staticMesh->SetAABB(aabb);
		}

		// Il ne faut pas oublier d'invalider notre AABB
		m_impl->aabbUpdated = false;
	}
Ejemplo n.º 7
0
	void Mesh::Recenter()
	{
		#if NAZARA_UTILITY_SAFE
		if (!m_impl)
		{
			NazaraError("Mesh not created");
			return;
		}

		if (m_impl->animationType != AnimationType_Static)
		{
			NazaraError("Mesh must be static");
			return;
		}
		#endif

		// Le centre de notre mesh est le centre de l'AABB *globale*
		Vector3f center = GetAABB().GetCenter();

		for (SubMesh* subMesh : m_impl->subMeshes)
		{
			StaticMesh* staticMesh = static_cast<StaticMesh*>(subMesh);

			BufferMapper<VertexBuffer> mapper(staticMesh->GetVertexBuffer(), BufferAccess_ReadWrite);
			MeshVertex* vertices = static_cast<MeshVertex*>(mapper.GetPointer());

			unsigned int vertexCount = staticMesh->GetVertexCount();
			for (unsigned int i = 0; i < vertexCount; ++i)
			{
				vertices->position -= center;
				vertices++;
			}

			// l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé
			Boxf aabb = staticMesh->GetAABB();
			aabb.Translate(-center);

			staticMesh->SetAABB(aabb);
		}

		// Il ne faut pas oublier d'invalider notre AABB
		m_impl->aabbUpdated = false;
	}
Ejemplo n.º 8
0
StaticMesh* GraphicsEngineImp::CreateStaticMesh(string filename, D3DXVECTOR3 pos, const char* billboardFilePath, float distanceToSwapToBillboard)
{
	StaticMesh* mesh = new StaticMesh(pos, filename, billboardFilePath, distanceToSwapToBillboard);
	
	// if it is in memory dont put it on another thread.
	if(!this->useLoadingThread && GetResourceManager()->HasMeshStripsResource(filename.c_str()))
	{
		bool success = mesh->LoadFromFile(filename);
		if(success)
		{
			this->dx->CreateStaticMesh(mesh);
		}
	}
	else
	{
		LoadMeshEvent* re = new LoadMeshEvent(filename, mesh, NULL, NULL);
		this->PutEvent(re);
	}

	return mesh;
}
Ejemplo n.º 9
0
void test()
{
	GraphicsEngine* ge = GetGraphicsEngine();

	// Example of GE useage
	GraphicsEngine* eng = GetGraphicsEngine();
	eng->GetCamera()->setPosition(D3DXVECTOR3(0, 15, -15.6f));
	eng->GetCamera()->LookAt(D3DXVECTOR3(30, 10, 10));
	StaticMesh* testBall = eng->CreateStaticMesh("Media/Ball.obj", D3DXVECTOR3(8, 15, 8));
	StaticMesh* testCylinder = eng->CreateStaticMesh("Media/Cylinder.obj", D3DXVECTOR3(10, 10, 10));
	StaticMesh* bth = eng->CreateStaticMesh("Media/bth.obj", D3DXVECTOR3(5, 20, 15));
	
	AnimatedMesh* flag = eng->CreateAnimatedMesh("Media/FlagRed.ani",  D3DXVECTOR3(8, 15, 8));
	flag->LoopSeamless();

	AnimatedMesh* flagb = eng->CreateAnimatedMesh("Media/FlagBlue.ani",  D3DXVECTOR3(10, 15, 8));
	flagb->LoopSeamless();
	
	StaticMesh* flag1 = eng->CreateStaticMesh("Media/FlagBlue1.obj", D3DXVECTOR3(12, 15, 8));
	StaticMesh* flag2 = eng->CreateStaticMesh("Media/FlagBlue2.obj", D3DXVECTOR3(14, 15, 8));
	StaticMesh* flag3 = eng->CreateStaticMesh("Media/FlagBlue3.obj", D3DXVECTOR3(16, 15, 8));
	StaticMesh* flag4 = eng->CreateStaticMesh("Media/FlagBlue4.obj", D3DXVECTOR3(18, 15, 8));
	StaticMesh* flag5 = eng->CreateStaticMesh("Media/FlagBlue5.obj", D3DXVECTOR3(20, 15, 8));

	StaticMesh* ball1 = eng->CreateStaticMesh("Media/Ball1.obj", D3DXVECTOR3(12, 30, 8));
	StaticMesh* ball2 = eng->CreateStaticMesh("Media/Ball2.obj", D3DXVECTOR3(14, 30, 8));
	StaticMesh* ball3 = eng->CreateStaticMesh("Media/Ball3.obj", D3DXVECTOR3(16, 30, 8));
	StaticMesh* ball4 = eng->CreateStaticMesh("Media/Ball4.obj", D3DXVECTOR3(18, 30, 8));
	
	//StaticMesh* wlmap = eng->CreateStaticMesh("Media/WarlockMap.obj", D3DXVECTOR3(100, 4, 8));
	//StaticMesh* hb = eng->CreateStaticMesh("Media/HardenedBall.obj", D3DXVECTOR3(12, 15, 12));

	bth->Scale(0.1f);
	Light* testLight = eng->CreateLight(D3DXVECTOR3(15, 30, 15));
	testLight->SetLookAt(testBall->GetPosition());
	
	//testBall->SetSpecialColor(RED_COLOR);
	//testCylinder->SetSpecialColor(GREEN_COLOR);
	
	//AnimatedMesh* ani = eng->CreateAnimatedMesh("Media/AniTest.ani", D3DXVECTOR3(12, 16, 12));
	//ani->LoopNormal();
	//ani->LoopSeamless();

	
	SoundEngine* seng = eng->GetSoundEngine();
	SoundEffect* se1 = seng->LoadSoundEffect("Media/Sounds/SoundEffects/ball_vs_ball.mp3", false);
	//SoundEffect* se2 = seng->LoadSoundEffect("Media/Sounds/SoundEffects/ball_vs_wall.mp3", false);
	//SoundSong* ss1 = seng->LoadSong("Media/Sounds/Songs/america_fuck_yeah.mp3", true);
	seng->SetMasterVolume(0.5f);
	//ss1->Play();
	
	
	//eng->LoadingScreen("Media/LoadingScreen/LoadingScreenBG.png", "Media/LoadingScreen/LoadingScreenPB.png");			// going to LoadingScreen to load the above meshes
	//eng->LoadingScreen("Media/LoadingScreen/LoadingScreenBG.png", "Media/LoadingScreen/LoadingScreenPB.png", 0.0f, 1.0f, 1.0f, 1.0f);
	
	eng->LoadingScreen("Media/LoadingScreen/StartScreen.png", "", 0.0f, 1.0f, 1.0f, 1.0f);
	Text* text = eng->CreateText("Lol ", D3DXVECTOR2(500, 500), 1.0f, "Media/Fonts/1");
	
	//Image* testImg = eng->CreateImage(D3DXVECTOR2(50, 50), D3DXVECTOR2(500, 75), "Media/PowerBall.png");
	
	//testLight->SetPosition(testBall->GetPosition() + D3DXVECTOR3(0, 5, 0));
	//testLight->SetLookAt(testLight->GetPosition() - D3DXVECTOR3(0, 5, 0));
	//Light* testLight2 = eng->CreateLight(D3DXVECTOR3(3, 20, 3));
	

	CamRecording* camRec = new CamRecording(2000, true);	// How many milliseconds between each way point
	camRec->Init(eng->GetCamera());
	
	/*camRec->AddCameraWaypoint(D3DXVECTOR3(0, 0, 0), D3DXVECTOR3(8, 16, 8));
	camRec->AddCameraWaypoint(D3DXVECTOR3(0, 30, 0), D3DXVECTOR3(8, 16, 8));
	camRec->AddCameraWaypoint(D3DXVECTOR3(30, 30, 30), D3DXVECTOR3(8, 16, 8));
	camRec->AddCameraWaypoint(D3DXVECTOR3(-20, 20, 30), D3DXVECTOR3(8, 16, 8));
	camRec->AddCameraWaypoint(D3DXVECTOR3(0, 50, 0), D3DXVECTOR3(8, 16, 8));
	camRec->AddCameraWaypoint(D3DXVECTOR3(0, 20, 0), D3DXVECTOR3(8, 16, 8));*/
	//camRec->Load(CIRCLE_AROUND);
	camRec->CircleAround(true, 50, 1000, 0, D3DXVECTOR3(30, 50, 0), D3DXVECTOR3(0,0,30));
	
	bool sw = true;
	float size = 1.0f;

	bool go = true;
		
	while(eng->isRunning() && go)	// Returns true as long as ESC hasnt been pressed, if it's pressed the game engine will shut down itself (to be changed)
	{
		float diff = eng->Update();	// Updates camera etc, does NOT render the frame, another process is doing that, so diff should be very low.

		text->SetText("Distance to Lava: " + MaloW::convertNrToString(eng->GetCamera()->getPosition().y - eng->GetLavaHeightAt(eng->GetCamera()->getPosition().x, eng->GetCamera()->getPosition().z)));

		//testBall->Rotate(D3DXVECTOR3(2*PI, 0, 0) * (diff/1000.0f)); // Divide diff by 1000 to get seconds since diff is in milliseconds.
		testBall->RotateAxis(D3DXVECTOR3(2, 0, 0),  2* PI * (diff/1000.0f)); // Divide diff by 1000 to get seconds since diff is in milliseconds.
		CursorControl cc;

		if(eng->GetKeyListener()->IsPressed('W'))
			eng->GetCamera()->moveForward(diff);
		if(eng->GetKeyListener()->IsPressed(VK_RETURN))	// For keys other than the main-chars you use the VK_ Enums, rightclick on VK_RETURN and "Go to definition" to find the list of all keys
			cc.SetVisibility(true);
		if(eng->GetKeyListener()->IsPressed('A'))
			eng->GetCamera()->moveLeft(diff);
		if(eng->GetKeyListener()->IsPressed('S'))	
			eng->GetCamera()->moveBackward(diff);
		if(eng->GetKeyListener()->IsPressed('D'))	
			eng->GetCamera()->moveRight(diff);

		if(eng->GetKeyListener()->IsPressed(VK_ESCAPE))
			go = false;

		if(eng->GetKeyListener()->IsPressed(VK_BACK))
		{
			if(sw)
			{
				//se1->Play();
				text->DeleteFromEnd(1);
			}
			sw = false;
		}
		else
			sw = true;
		
		if(eng->GetKeyListener()->IsClicked(1))
		{
			size += diff * 0.001f;
			text->SetSize(size);
			//ss1->SetVolume(0.5f);
			text->AppendText("LoL ");
			//ss1->Play();
		}
		//else
			//se1->Play();

		if(eng->GetKeyListener()->IsClicked(2))
		{
			testBall->UseInvisibilityEffect(true);
		}
		else 
			testBall->UseInvisibilityEffect(false);
		
		if(eng->GetKeyListener()->IsPressed('G'))	
		{
			//ani->LoopNormal();
			flag->LoopNormal();
			flagb->LoopNormal();
			eng->GetEngineParameters().FXAAQuality = 4;
			ge->GetEngineParameters().FXAAQuality = 4;
			//camRec->Play();						// Play to start moving the camera along the path
		}
		camRec->Update(diff);					// update needed to move the camera when play is initialized.
	
		if(eng->GetKeyListener()->IsPressed('V'))	
		{
			//ani->NoLooping();
			flag->NoLooping();
			flagb->NoLooping();
		}
		if(eng->GetKeyListener()->IsPressed('B'))	
		{
			//ani->LoopSeamless();
			flag->LoopSeamless();
			flagb->LoopSeamless();
			eng->GetEngineParameters().FXAAQuality = 0;
			//ge->GetEngineParameters().FXAAQuality = 0;
			for(int i = 0; i < 200; i++)
			{
				//se1->Play();
			}
		}
		
	}
	// Delete camera recording
	delete camRec;
}
Ejemplo n.º 10
0
void DxManager::CalculateCulling()
{
	D3DXMATRIX view = this->camera->GetViewMatrix();
	D3DXMATRIX proj = this->camera->GetProjectionMatrix();

	/*
	float zMinimum = -proj._43 / proj._33;
	float r = this->params.FarClip / (this->params.FarClip - zMinimum);
	proj._33 = r;
	proj._43 = -r * zMinimum;
	*/

	D3DXMATRIX VP;
	D3DXMatrixMultiply(&VP, &view, &proj);


	// Calculate near plane of frustum.
	FrustrumPlanes[0].a = VP._14 + VP._13;
	FrustrumPlanes[0].b = VP._24 + VP._23;
	FrustrumPlanes[0].c = VP._34 + VP._33;
	FrustrumPlanes[0].d = VP._44 + VP._43;
	D3DXPlaneNormalize(&FrustrumPlanes[0], &FrustrumPlanes[0]);

	// Calculate far plane of frustum.
	FrustrumPlanes[1].a = VP._14 - VP._13; 
	FrustrumPlanes[1].b = VP._24 - VP._23;
	FrustrumPlanes[1].c = VP._34 - VP._33;
	FrustrumPlanes[1].d = VP._44 - VP._43;
	D3DXPlaneNormalize(&FrustrumPlanes[1], &FrustrumPlanes[1]);

	// Calculate left plane of frustum.
	FrustrumPlanes[2].a = VP._14 + VP._11; 
	FrustrumPlanes[2].b = VP._24 + VP._21;
	FrustrumPlanes[2].c = VP._34 + VP._31;
	FrustrumPlanes[2].d = VP._44 + VP._41;
	D3DXPlaneNormalize(&FrustrumPlanes[2], &FrustrumPlanes[2]);

	// Calculate right plane of frustum.
	FrustrumPlanes[3].a = VP._14 - VP._11; 
	FrustrumPlanes[3].b = VP._24 - VP._21;
	FrustrumPlanes[3].c = VP._34 - VP._31;
	FrustrumPlanes[3].d = VP._44 - VP._41;
	D3DXPlaneNormalize(&FrustrumPlanes[3], &FrustrumPlanes[3]);

	// Calculate top plane of frustum.
	FrustrumPlanes[4].a = VP._14 - VP._12; 
	FrustrumPlanes[4].b = VP._24 - VP._22;
	FrustrumPlanes[4].c = VP._34 - VP._32;
	FrustrumPlanes[4].d = VP._44 - VP._42;
	D3DXPlaneNormalize(&FrustrumPlanes[4], &FrustrumPlanes[4]);

	// Calculate bottom plane of frustum.
	FrustrumPlanes[5].a = VP._14 + VP._12;
	FrustrumPlanes[5].b = VP._24 + VP._22;
	FrustrumPlanes[5].c = VP._34 + VP._32;
	FrustrumPlanes[5].d = VP._44 + VP._42;
	D3DXPlaneNormalize(&FrustrumPlanes[5], &FrustrumPlanes[5]);
	
	//Terrain
	for(int i = 0; i < this->terrains.size(); i++)
	{
		Terrain* terr = this->terrains.get(i);

		float scale = max(terr->GetScale().x, max(terr->GetScale().y, terr->GetScale().z));
		if(pe.FrustrumVsSphere(this->FrustrumPlanes, terr->GetBoundingSphere(), terr->GetWorldMatrix(), scale))
		{
			terr->SetCulled(false);
		}
		else
		{
			terr->SetCulled(true);
		}
	}

	//Static meshes
	for(int i = 0; i < this->objects.size(); i++)
	{
		StaticMesh* ms = this->objects.get(i);
		MaloW::Array<MeshStrip*>* strips = ms->GetStrips();
		for(int u = 0; u < strips->size(); u++)
		{
			MeshStrip* s = strips->get(u);
			float scale = max(ms->GetScaling().x, max(ms->GetScaling().y, ms->GetScaling().z));
			if(pe.FrustrumVsSphere(this->FrustrumPlanes, s->GetBoundingSphere(), ms->GetWorldMatrix(), scale))
			{
				s->SetCulled(false);
			}
			else
			{
				s->SetCulled(true);
			}
		}
	}

	//Animated meshes
	for(int i = 0; i < this->animations.size(); i++)
	{
		AnimatedMesh* ms = this->animations.get(i);
		MeshStrip* s = ms->GetStrips()->get(0);

		float scale = max(ms->GetScaling().x, max(ms->GetScaling().y, ms->GetScaling().z));
		if(pe.FrustrumVsSphere(this->FrustrumPlanes, s->GetBoundingSphere(), ms->GetWorldMatrix(), scale))
		{
			s->SetCulled(false);
		}
		else
		{
			s->SetCulled(true);
		}
	}
}
Ejemplo n.º 11
0
//! Loads and returns a static model from a file.
StaticModel* ModelImporter::LoadStaticModel(string filename)
{
	// Is the model already loaded?
	if(mStaticModelMap.find(filename) != mStaticModelMap.end())
		return mStaticModelMap[filename];

	Assimp::Importer importer;
	mFilename =	filename;
	StaticModel* model = NULL;

	// Important! Makes sure that if the angle between two face normals is > 80 they are not smoothed together.
	// Since the angle between a cubes face normals is 90 the lighting looks very bad if we don't specify this.
	importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f);	
	importer.SetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 1);
	importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE);

	// Load scene from the file.
	const aiScene* scene = importer.ReadFile(filename, 
		aiProcess_CalcTangentSpace		| 
		aiProcess_Triangulate			| 
		aiProcess_GenSmoothNormals		|
		aiProcess_SplitLargeMeshes		|
		aiProcess_ConvertToLeftHanded	|
		aiProcess_SortByPType);

	// Successfully loaded the scene.
	if(scene)
	{
		// Create the model that is getting filled out.
		model = new StaticModel();

		// Loop through all meshes.
		for(int i = 0; i < scene->mNumMeshes; i++)
		{
			aiMesh* assimpMesh = scene->mMeshes[i];
			vector<Vertex>	vertices;
			vector<UINT>	indices;

			// Add vertices to the vertex list.
			for(int i = 0; i < assimpMesh->mNumVertices; i++) 
			{
				aiVector3D v = assimpMesh->mVertices[i];
				aiVector3D n = assimpMesh->mNormals[i];
				aiVector3D t = aiVector3D(0, 0, 0);
				if(assimpMesh->HasTextureCoords(0))
					t = assimpMesh->mTextureCoords[0][i];

				n = n.Normalize();
				Vertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 0, t.x, t.y);
				vertices.push_back(vertex);
			}

			// Add indices to the index list.
			for(int i = 0; i < assimpMesh->mNumFaces; i++) 
				for(int j = 0; j < assimpMesh->mFaces[i].mNumIndices; j++) 
					indices.push_back(assimpMesh->mFaces[i].mIndices[j]);

			// Get the path to the texture in the directory.
			aiString path;
			aiMaterial* material = scene->mMaterials[assimpMesh->mMaterialIndex];
			material->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path);
			FindValidPath(&path);

			// Extract all the ambient, diffuse and specular colors.
			aiColor4D ambient, diffuse, specular;
			material->Get(AI_MATKEY_COLOR_AMBIENT, ambient);
			material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
			material->Get(AI_MATKEY_COLOR_SPECULAR, specular);

			// Create the mesh and its primitive.
			StaticMesh* mesh = new StaticMesh();
			Primitive* primitive = new Primitive(GlobalApp::GetD3DDevice(), vertices, indices);
			mesh->SetPrimitive(primitive);
			mesh->SetVertices(vertices);
			mesh->SetIndices(indices);
			mPrimtiveFactory->AddPrimitive(path.C_Str(), primitive);

			// Any texture?
			if(_stricmp(path.C_Str(), "") != 0)
				mesh->LoadTexture(path.C_Str());

			// Any normal map?
			aiString nmap;
			material->Get(AI_MATKEY_TEXTURE_HEIGHT(0), nmap);
			FindValidPath(&nmap);
			if(_stricmp(nmap.C_Str(), "") != 0)	
				mesh->SetNormalMap(GlobalApp::GetGraphics()->LoadTexture(nmap.C_Str()));

			// [NOTE] The material is set to white.
			mesh->SetMaterial(Material(Colors::White)); // Was  before [NOTE]

			model->SetFilename(filename);

			// Add the mesh to the model.
			model->AddMesh(mesh);
		}

		// Add to the model map and return it.
		mStaticModelMap[filename] = model;
		return mStaticModelMap[filename];
	}
	else {
		char buffer[246];
		sprintf(buffer, "Error loading model: %s", filename.c_str());
		MessageBox(0, buffer, "Error!", 0);
		mStaticModelMap[filename] = LoadStaticModel("models/box.obj");
		return mStaticModelMap[filename];
	}
}