Browse Source

Added resource pools to resource manager, assets can now be loaded into the global resource pool or custom resource pools, added support for resource pool linking in SceneEntityInstance, added support for resource pool browsing to AssetBrowser, changed material selector to use resource pools via AssetBrowser, added UI for linking material files as resource pools to the current entity, added a tree scene view to the entity editor.

Ivan Safrin 12 years ago
parent
commit
869709885e
44 changed files with 1177 additions and 383 deletions
  1. 1 4
      Core/Contents/Include/PolyEntity.h
  2. 3 2
      Core/Contents/Include/PolyGLSLShaderModule.h
  3. 12 9
      Core/Contents/Include/PolyMaterialManager.h
  4. 3 2
      Core/Contents/Include/PolyModule.h
  5. 54 52
      Core/Contents/Include/PolyResourceManager.h
  6. 13 2
      Core/Contents/Include/PolySceneEntityInstance.h
  7. 8 2
      Core/Contents/Include/PolySceneMesh.h
  8. 1 1
      Core/Contents/Source/PolyCamera.cpp
  9. 0 1
      Core/Contents/Source/PolyCoreServices.cpp
  10. 1 9
      Core/Contents/Source/PolyEntity.cpp
  11. 8 8
      Core/Contents/Source/PolyGLSLShaderModule.cpp
  12. 43 28
      Core/Contents/Source/PolyMaterialManager.cpp
  13. 226 141
      Core/Contents/Source/PolyResourceManager.cpp
  14. 76 7
      Core/Contents/Source/PolySceneEntityInstance.cpp
  15. 19 5
      Core/Contents/Source/PolySceneMesh.cpp
  16. 3 3
      IDE/Assets/ide_icons.ai
  17. 3 3
      IDE/Assets/ui_theme_light.ai
  18. 6 0
      IDE/Build/Mac OS X/Polycode.xcodeproj/project.pbxproj
  19. 2 1
      IDE/Contents/Include/EntityEditorPropertyView.h
  20. 45 0
      IDE/Contents/Include/EntityEditorSettingsView.h
  21. 16 0
      IDE/Contents/Include/PolycodeEntityEditor.h
  22. 3 1
      IDE/Contents/Include/PolycodeFrame.h
  23. 8 5
      IDE/Contents/Include/PolycodeMaterialEditor.h
  24. 90 21
      IDE/Contents/Include/PolycodeProps.h
  25. 20 3
      IDE/Contents/Include/TextureBrowser.h
  26. BIN
      IDE/Contents/Resources/Images/browserIcons/material_resource_icon.png
  27. BIN
      IDE/Contents/Resources/Images/browserIcons/materials_icon.png
  28. BIN
      IDE/Contents/Resources/Images/entityEditor/shade_full.png
  29. BIN
      IDE/Contents/Resources/Images/entityEditor/shade_solid.png
  30. BIN
      IDE/Contents/Resources/Images/entityEditor/shade_wire.png
  31. BIN
      IDE/Contents/Resources/ImagesRetina/browserIcons/material_resource_icon.png
  32. BIN
      IDE/Contents/Resources/ImagesRetina/browserIcons/materials_icon.png
  33. BIN
      IDE/Contents/Resources/ImagesRetina/entityEditor/shade_full.png
  34. BIN
      IDE/Contents/Resources/ImagesRetina/entityEditor/shade_solid.png
  35. BIN
      IDE/Contents/Resources/ImagesRetina/entityEditor/shade_wire.png
  36. 5 1
      IDE/Contents/Source/EntityEditorPropertyView.cpp
  37. 46 0
      IDE/Contents/Source/EntityEditorSettingsView.cpp
  38. 90 4
      IDE/Contents/Source/PolycodeEntityEditor.cpp
  39. 11 0
      IDE/Contents/Source/PolycodeFrame.cpp
  40. 1 1
      IDE/Contents/Source/PolycodeIDEApp.cpp
  41. 32 31
      IDE/Contents/Source/PolycodeMaterialEditor.cpp
  42. 2 2
      IDE/Contents/Source/PolycodeMeshEditor.cpp
  43. 229 26
      IDE/Contents/Source/PolycodeProps.cpp
  44. 97 8
      IDE/Contents/Source/TextureBrowser.cpp

+ 1 - 4
Core/Contents/Include/PolyEntity.h

@@ -593,10 +593,7 @@ namespace Polycode {
 			*/
 			bool backfaceCulled;	
 		
-			/**
-			* If this flag is set to true, the entity will render in wireframe. 
-			*/							
-			bool renderWireframe;
+
 
 			/**
 			* The entity's color.

+ 3 - 2
Core/Contents/Include/PolyGLSLShaderModule.h

@@ -30,6 +30,7 @@ namespace Polycode {
 	class ProgramParam;
 	class GLSLShader;
 	class ShaderProgram;
+    class ResourcePool;
 
 	class _PolyExport GLSLShaderModule : public PolycodeShaderModule {
 		public:
@@ -40,8 +41,8 @@ namespace Polycode {
 			ShaderProgram* createProgramFromFile(const String& extension, const String& fullPath);
 			void reloadPrograms();
 			String getShaderType();
-			Shader *createShader(TiXmlNode *node);
-			Shader *createShader(String name, String vpName, String fpName);
+			Shader *createShader(ResourcePool *resourcePool, TiXmlNode *node);
+			Shader *createShader(ResourcePool *resourcePool, String name, String vpName, String fpName);
 			bool applyShaderMaterial(Renderer *renderer, Material *material, ShaderBinding *localOptions, unsigned int shaderIndex);	
 			void clearShader();
 		

+ 12 - 9
Core/Contents/Include/PolyMaterialManager.h

@@ -39,6 +39,7 @@ namespace Polycode {
 	class Shader;
 	class String;
 	class ShaderProgram;
+    class ResourcePool;
 	
 	/**
 	* Manages loading and reloading of materials, textures and shaders. This class should be only accessed from the CoreServices singleton.
@@ -57,7 +58,7 @@ namespace Polycode {
 			Texture *createTexture(int width, int height, char *imageData, bool clamp=false, bool createMipmaps = true, int type=Image::IMAGE_RGBA);
 			Texture *createNewTexture(int width, int height, bool clamp=false, bool createMipmaps = true, int type=Image::IMAGE_RGBA);
 			Texture *createTextureFromImage(Image *image, bool clamp=false, bool createMipmaps = true);
-			Texture *createTextureFromFile(const String& fileName, bool clamp=false, bool createMipmaps = true);
+			Texture *createTextureFromFile(const String& fileName, bool clamp=false, bool createMipmaps = true, ResourcePool *resourcePool = NULL);
 			void deleteTexture(Texture *texture);
 		
 			void reloadTextures();
@@ -72,22 +73,24 @@ namespace Polycode {
 			
 			ShaderProgram *createProgramFromFile(String programPath);
 			
+            void loadMaterialLibraryIntoPool(ResourcePool *pool, const String &materialFile);
+        
 			// cubemaps
 		
 			Cubemap *cubemapFromXMLNode(TiXmlNode *node);
 		
 			// materials
-			Material *materialFromXMLNode(TiXmlNode *node);
+			Material *materialFromXMLNode(ResourcePool *resourcePool, TiXmlNode *node);
 			
-			Material *createMaterial(String materialName, String shaderName);
+			Material *createMaterial(ResourcePool *resourcePool, String materialName, String shaderName);
 			
-			Shader *setShaderFromXMLNode(TiXmlNode *node);
-			Shader *createShaderFromXMLNode(TiXmlNode *node);
-			Shader *createShader(String shaderType, String name, String vpName, String fpName, bool screenShader);
+			Shader *setShaderFromXMLNode(ResourcePool *resourcePool, TiXmlNode *node);
+			Shader *createShaderFromXMLNode(ResourcePool *resourcePool, TiXmlNode *node);
+			Shader *createShader(ResourcePool *resourcePool, String shaderType, String name, String vpName, String fpName, bool screenShader);
 		
-			std::vector<Material*> loadMaterialsFromFile(String fileName);
-			std::vector<Shader*> loadShadersFromFile(String fileName);		
-			std::vector<Cubemap*> loadCubemapsFromFile(String fileName);	
+			std::vector<Material*> loadMaterialsFromFile(ResourcePool *resourcePool, const String &fileName);
+			std::vector<Shader*> loadShadersFromFile(ResourcePool *resourcePool, String fileName);
+			std::vector<Cubemap*> loadCubemapsFromFile(String fileName);
 						
 			void addMaterial(Material *material);
 			void addShader(Shader *shader);

+ 3 - 2
Core/Contents/Include/PolyModule.h

@@ -21,6 +21,7 @@ namespace Polycode {
 	class ShaderBinding;
 	class Resource;
 	class ShaderProgram;
+    class ResourcePool;
 	
 	class _PolyExport PolycodeModule : public PolyBase {
 	public:
@@ -49,8 +50,8 @@ namespace Polycode {
 		virtual bool acceptsExtension(const String& extension) = 0;
 		virtual ShaderProgram* createProgramFromFile(const String& extension, const String& fullPath) = 0;
 		virtual String getShaderType() = 0;
-		virtual Shader *createShader(TiXmlNode *node) = 0;
-		virtual Shader *createShader(String name, String vpName, String fpName) = 0;
+		virtual Shader *createShader(ResourcePool *resourcePool, TiXmlNode *node) = 0;
+		virtual Shader *createShader(ResourcePool *resourcePool, String name, String vpName, String fpName) = 0;
 			
 		virtual bool applyShaderMaterial(Renderer *renderer, Material *material, ShaderBinding *localOptions, unsigned int shaderIndex) = 0;
 		bool hasShader(Shader *shader) { for(int i=0; i < shaders.size(); i++) { if(shaders[i] == shader){ return true; } } return false; }	

+ 54 - 52
Core/Contents/Include/PolyResourceManager.h

@@ -33,6 +33,41 @@ namespace Polycode {
 	class Resource;
 	class PolycodeShaderModule;
 	class String;
+    
+    class _PolyExport ResourcePool : public EventDispatcher {
+        public:
+            ResourcePool(const String &name, ResourcePool *fallbackPool);
+            ~ResourcePool();
+        
+            void setFallbackPool(ResourcePool *pool);
+        
+			void addResource(Resource *resource);
+			void removeResource(Resource *resource);
+            bool hasResource(Resource *resource);
+        
+			Resource *getResource(int resourceType, const String& resourceName) const;
+        
+            String getName();
+            void setName(const String &name);
+        
+            Resource *getResourceByPath(const String& resourcePath) const;
+			void Update(int elapsed);
+        
+			std::vector<Resource *> getResources(int resourceType);
+        
+			void checkForChangedFiles();
+        
+			bool reloadResourcesOnModify;
+            bool dispatchChangeEvents;
+        
+        private:
+        
+            ResourcePool *fallbackPool;
+            String name;
+			int ticksSinceCheck;
+            std::vector <Resource*> resources;
+        
+    };
 
 	/**
 	* Manages loading and unloading of resources from directories and archives. Should only be accessed via the CoreServices singleton. 
@@ -42,24 +77,7 @@ namespace Polycode {
 			ResourceManager();
 			~ResourceManager();
 			
-			/** 
-			* Adds a new resource.
-			* @param resource Resource to add.
-			*/ 
-			void addResource(Resource *resource);
 
-			/** 
-			* Removes a resource.
-			* @param resource Resource to resource.
-			*/ 
-			void removeResource(Resource *resource);
-			
-			
-			/**
-			* Returns true if the following resource has been adde to the resource manager.
-			* @param resource Resource to check.
-			*/
-			bool hasResource(Resource *resource);
 			/**
 			* Loads resources from a directory.
 			* @param dirPath Path to directory to load resources from.
@@ -78,46 +96,30 @@ namespace Polycode {
 			void removeArchive(const String& path);
 
 		
-			bool readFile(const String& fileName) { return false;}
-		
-			void parseTextures(const String& dirPath, bool recursive, const String& basePath);
-			void parseMaterials(const String& dirPath, bool recursive);
-			void parseShaders(const String& dirPath, bool recursive);
-			void parsePrograms(const String& dirPath, bool recursive);
-			void parseCubemaps(const String& dirPath, bool recursive);
-			void parseOthers(const String& dirPath, bool recursive);
-		
-			/**
-			* Request a loaded resource. You need to manually cast it to its subclass based on its type.
-			* @param resourceType Type of resource. See Resource for available resource types.
-			* @param resourceName Name of the resource to request.
-			*/
-			Resource *getResource(int resourceType, const String& resourceName) const;
-
-			Resource *getResourceByPath(const String& resourcePath) const;
-
-		
-			/**
-			 * Request a full set of loaded resources. You need to manually cast them to their subclasses based on their type.
-			 * @param resourceType Type of resource. See Resource for available resource types.
-			 */
-			std::vector<Resource *> getResources(int resourceType);
-		
-			void addShaderModule(PolycodeShaderModule *module);
-		
-			void checkForChangedFiles();
+			void parseTexturesIntoPool(ResourcePool *pool, const String& dirPath, bool recursive, const String& basePath);
+			void parseMaterialsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
+			void parseShadersIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
+			void parseProgramsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
+			void parseCubemapsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
+            void parseOtherIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
 		
+            ResourcePool *getGlobalPool();
+        
+            ResourcePool *getResourcePoolByName(const String &name);
+		      
+            void addResourcePool(ResourcePool *pool);
+            void removeResourcePool(ResourcePool *pool);
+        
+			std::vector<Resource*> getResources(int resourceType);
+        
+			void removeResource(Resource *resource);
+        
 			void Update(int elapsed);
-			
-			bool reloadResourcesOnModify;			
-			bool dispatchChangeEvents;
-			
 			void handleEvent(Event *event);
 		
 		private:
-			int ticksSinceCheck;
 		
-			std::vector <Resource*> resources;
-			std::vector <PolycodeShaderModule*> shaderModules;
+            ResourcePool *globalPool;
+            std::vector <ResourcePool*> pools;
 	};
 }

+ 13 - 2
Core/Contents/Include/PolySceneEntityInstance.h

@@ -39,7 +39,8 @@ class SceneEntityInstanceResourceEntry;
 
 class SceneEntityInstance : public Entity {
 	public:
-		SceneEntityInstance(Scene *parentScene, const String& fileName);
+    
+        SceneEntityInstance(Scene *parentScene, const String& fileName);
 		SceneEntityInstance();
 		
 		static SceneEntityInstance *BlankSceneEntityInstance();
@@ -58,16 +59,26 @@ class SceneEntityInstance : public Entity {
 		bool loadFromFile(const String& fileName);
         void applySceneMesh(ObjectEntry *entry, SceneMesh *sceneMesh);
 		
+        void linkResourcePool(ResourcePool *pool);
+        unsigned int getNumLinkedResourePools();
+        ResourcePool *getLinkedResourcePoolAtIndex(unsigned int index);
+    
+        void unlinkResourcePool(ResourcePool *pool);
+    
 		SceneEntityInstanceResourceEntry *getResourceEntry();
+
 		
 		String getFileName() const;
-		
 		bool cloneUsingReload;
 
 		String fileName;
 		
 	protected:
 		
+        void rebuildResourceLinks();
+    
+        ResourcePool *topLevelResourcePool;
+        std::vector<ResourcePool*> resourcePools;
         Scene *parentScene;
 		SceneEntityInstanceResourceEntry *resourceEntry;
 		

+ 8 - 2
Core/Contents/Include/PolySceneMesh.h

@@ -32,6 +32,7 @@ namespace Polycode {
 	class Texture;
 	class Skeleton;
 	class Image;
+    class ResourcePool;
 	
 	/**
 	* 3D polygonal mesh instance. The SceneMesh is the base for all polygonal 3d geometry. It can have simple textures or complex materials applied to it.
@@ -124,7 +125,7 @@ namespace Polycode {
 			* Set material by name. You can create materials in material files and name them there, then use this to set a material by name to a scene mesh.
 			* @param materialName Name of material to apply.
 			*/									
-			void setMaterialByName(const String& materialName);
+			void setMaterialByName(const String& materialName, ResourcePool *resourcePool = NULL);
 			
 			/**
 			* Set the mesh this scene mesh renders.
@@ -181,7 +182,12 @@ namespace Polycode {
 			
 			bool useGeometryHitDetection;
 			
-			bool customHitDetection(const Ray &ray);			
+			bool customHitDetection(const Ray &ray);
+
+            /**
+             * If this flag is set to true, the entity will render in wireframe.
+             */
+            bool renderWireframe;
 
 			
 		protected:

+ 1 - 1
Core/Contents/Source/PolyCamera.cpp

@@ -277,7 +277,7 @@ void Camera::setParentScene(Scene *parentScene) {
 }
 
 void Camera::setPostFilterByName(const String& materialName) {
-	Material *shaderMaterial = (Material*) CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, materialName);
+	Material *shaderMaterial = (Material*) CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, materialName);
 	if(shaderMaterial)
 		setPostFilter(shaderMaterial);		
 }

+ 0 - 1
Core/Contents/Source/PolyCoreServices.cpp

@@ -107,7 +107,6 @@ void CoreServices::installModule(PolycodeModule *module)  {
 	
 	switch(module->getType()) {
 		case PolycodeModule::TYPE_SHADER:
-			resourceManager->addShaderModule((PolycodeShaderModule*) module);
 			materialManager->addShaderModule((PolycodeShaderModule*) module);
 			renderer->addShaderModule((PolycodeShaderModule*) module);
 		break;

+ 1 - 9
Core/Contents/Source/PolyEntity.cpp

@@ -67,7 +67,6 @@ void Entity::initEntity() {
 	alphaTest = false;
 	blendingMode = Entity::defaultBlendingMode;
 	lockMatrix = false;
-	renderWireframe  = false;
 	colorAffectsChildren = true;
 	visibilityAffectsChildren = true;
 	ownsChildren = false;
@@ -116,7 +115,6 @@ void Entity::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) co
 	clone->billboardRoll = billboardRoll;
 	clone->alphaTest = alphaTest;
 	clone->backfaceCulled = backfaceCulled;
-	clone->renderWireframe = renderWireframe;
 	clone->depthWrite = depthWrite;
 	clone->depthTest = depthTest;
 	clone->blendingMode = blendingMode;
@@ -532,13 +530,7 @@ void Entity::transformAndRender() {
 	
 	renderer->setBlendingMode(blendingMode);
 	renderer->enableBackfaceCulling(backfaceCulled);
-	
-	if(renderWireframe) {
-		renderer->setWireframePolygonMode(true);
-	} else {
-		renderer->setWireframePolygonMode(false);
-    }
-    
+	   
 	if(visible) {
 		renderer->pushMatrix();		
 		renderer->translate3D(-anchorPoint.x * bBox.x * 0.5, -anchorPoint.y * bBox.y * 0.5 * yAdjust, -anchorPoint.z * bBox.z * 0.5);

+ 8 - 8
Core/Contents/Source/PolyGLSLShaderModule.cpp

@@ -112,15 +112,15 @@ String GLSLShaderModule::getShaderType() {
 	return "glsl";
 }
 
-Shader *GLSLShaderModule::createShader(String name, String vpName, String fpName) {
+Shader *GLSLShaderModule::createShader(ResourcePool *resourcePool, String name, String vpName, String fpName) {
 
 	GLSLShader *retShader = NULL;
 
 	GLSLProgram *vp = NULL;
 	GLSLProgram *fp = NULL;
 
-	vp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResourceByPath(vpName);
-	fp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResourceByPath(fpName);
+	vp = (GLSLProgram*)resourcePool->getResourceByPath(vpName);
+	fp = (GLSLProgram*)resourcePool->getResourceByPath(fpName);
 		
 	if(vp != NULL && fp != NULL) {
 		GLSLShader *shader = new GLSLShader(vp,fp);
@@ -131,7 +131,7 @@ Shader *GLSLShaderModule::createShader(String name, String vpName, String fpName
 	return retShader;
 }
 
-Shader *GLSLShaderModule::createShader(TiXmlNode *node) {
+Shader *GLSLShaderModule::createShader(ResourcePool *resourcePool, TiXmlNode *node) {
 	TiXmlNode* pChild;
 	GLSLProgram *vp = NULL;
 	GLSLProgram *fp = NULL;
@@ -146,27 +146,27 @@ Shader *GLSLShaderModule::createShader(TiXmlNode *node) {
 		
 		if(strcmp(pChild->Value(), "vp") == 0) {
 			String vpFileName = String(pChildElement->Attribute("source"));
-			vp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResourceByPath(vpFileName);
+			vp = (GLSLProgram*)resourcePool->getResourceByPath(vpFileName);
 			if(!vp) {
 				vp = (GLSLProgram*)CoreServices::getInstance()->getMaterialManager()->createProgramFromFile(vpFileName);
 				if(vp) {
 					vp->setResourcePath(vpFileName);
 					OSFileEntry entry = OSFileEntry(vpFileName, OSFileEntry::TYPE_FILE);
 					vp->setResourceName(entry.name);
-					CoreServices::getInstance()->getResourceManager()->addResource(vp);
+					resourcePool->addResource(vp);
 				}
 			}
 		}
 		if(strcmp(pChild->Value(), "fp") == 0) {
 			String fpFileName = String(pChildElement->Attribute("source"));		
-			fp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResourceByPath(fpFileName);
+			fp = (GLSLProgram*)resourcePool->getResourceByPath(fpFileName);
 			if(!fp) {
 				fp = (GLSLProgram*)CoreServices::getInstance()->getMaterialManager()->createProgramFromFile(fpFileName);
 				if(fp) {
 					fp->setResourcePath(fpFileName);
 					OSFileEntry entry = OSFileEntry(fpFileName, OSFileEntry::TYPE_FILE);					
 					fp->setResourceName(entry.name);
-					CoreServices::getInstance()->getResourceManager()->addResource(fp);				
+					resourcePool->addResource(fp);				
 				}
 			}			
 		}

+ 43 - 28
Core/Contents/Source/PolyMaterialManager.cpp

@@ -80,6 +80,28 @@ void MaterialManager::reloadPrograms() {
 	}
 }
 
+void MaterialManager::loadMaterialLibraryIntoPool(ResourcePool *pool, const String &materialFile) {
+    std::vector<Shader*> shaders =loadShadersFromFile(pool, materialFile);
+
+    for(int s=0; s < shaders.size(); s++) {
+        pool->addResource(shaders[s]);
+        addShader(shaders[s]);
+    }
+    
+    std::vector<Cubemap*> cubemaps = loadCubemapsFromFile(materialFile);
+    for(int c=0; c < cubemaps.size(); c++) {
+        pool->addResource(cubemaps[c]);
+    }
+    
+    std::vector<Material*> materials = loadMaterialsFromFile(pool, materialFile);
+    
+    for(int m=0; m < materials.size(); m++) {
+        materials[m]->setResourceName(materials[m]->getName());
+        pool->addResource(materials[m]);
+        addMaterial(materials[m]);
+    }
+}
+
 ShaderProgram *MaterialManager::createProgramFromFile(String programPath) {
 	OSFileEntry entry(programPath, OSFileEntry::TYPE_FILE);
 	   
@@ -103,11 +125,15 @@ void MaterialManager::addShaderModule(PolycodeShaderModule *module) {
 
 #define DEFAULT_TEXTURE "default/default.png"
 
-Texture *MaterialManager::createTextureFromFile(const String& fileName, bool clamp, bool createMipmaps) {
+Texture *MaterialManager::createTextureFromFile(const String& fileName, bool clamp, bool createMipmaps, ResourcePool *resourcePool) {
 	if(fileName.size() == 0) {
 		Logger::log("empty texture filename, using default texture.\n");
 		return getTextureByResourcePath(DEFAULT_TEXTURE);
 	}
+    
+    if(!resourcePool) {
+        resourcePool = CoreServices::getInstance()->getResourceManager()->getGlobalPool();
+    }
 
 	Texture *newTexture;
 	newTexture = getTextureByResourcePath(fileName);
@@ -122,7 +148,7 @@ Texture *MaterialManager::createTextureFromFile(const String& fileName, bool cla
 		}
 		newTexture = createTexture(image->getWidth(), image->getHeight(), image->getPixels(), clamp, createMipmaps);
 		newTexture->setResourcePath(fileName);
-		CoreServices::getInstance()->getResourceManager()->addResource(newTexture);		
+        resourcePool->addResource(newTexture);
 	} else {
 		Logger::log("Error loading image (\"%s\"), using default texture.\n", fileName.c_str());		
 		newTexture = getTextureByResourcePath(DEFAULT_TEXTURE);
@@ -181,13 +207,13 @@ Shader *MaterialManager::getShaderByIndex(unsigned int index) {
 		return NULL;
 }
 
-Shader *MaterialManager::createShader(String shaderType, String name, String vpName, String fpName, bool screenShader) {
+Shader *MaterialManager::createShader(ResourcePool *resourcePool, String shaderType, String name, String vpName, String fpName, bool screenShader) {
 	Shader *retShader = NULL;
 	
 	for(int m=0; m < shaderModules.size(); m++) {
 		PolycodeShaderModule *shaderModule = shaderModules[m];
 		if(shaderModule->getShaderType() == shaderType) {
-			retShader = shaderModule->createShader(name, vpName, fpName);
+			retShader = shaderModule->createShader(resourcePool, name, vpName, fpName);
 		}
 	}
 	
@@ -201,7 +227,7 @@ Shader *MaterialManager::createShader(String shaderType, String name, String vpN
 	return retShader;
 }
 
-Shader *MaterialManager::createShaderFromXMLNode(TiXmlNode *node) {
+Shader *MaterialManager::createShaderFromXMLNode(ResourcePool *resourcePool, TiXmlNode *node) {
 	TiXmlElement *nodeElement = node->ToElement();
 	if (!nodeElement) return NULL; // Skip comment nodes
 	
@@ -212,7 +238,7 @@ Shader *MaterialManager::createShaderFromXMLNode(TiXmlNode *node) {
 		for(int m=0; m < shaderModules.size(); m++) {
 			PolycodeShaderModule *shaderModule = shaderModules[m];
 			if(shaderModule->getShaderType() == shaderType) {
-				retShader = shaderModule->createShader(node);
+				retShader = shaderModule->createShader(resourcePool, node);
 			}
 		}		
 	}
@@ -246,7 +272,7 @@ Shader *MaterialManager::createShaderFromXMLNode(TiXmlNode *node) {
 	return retShader;
 }
 
-Shader *MaterialManager::setShaderFromXMLNode(TiXmlNode *node) {
+Shader *MaterialManager::setShaderFromXMLNode(ResourcePool *resourcePool, TiXmlNode *node) {
 	TiXmlElement *nodeElement = node->ToElement();
 	if (!nodeElement) return NULL; // Skip comment nodes
 	
@@ -258,22 +284,11 @@ Shader *MaterialManager::setShaderFromXMLNode(TiXmlNode *node) {
 			retShader = fShader;
 		}
 	} else {
-		retShader = (Shader*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_SHADER, nodeElement->Attribute("name"));
+		retShader = (Shader*)resourcePool->getResource(Resource::RESOURCE_SHADER, nodeElement->Attribute("name"));
 	}
 	return retShader;
 }
 
-
-//			for (pChild = node->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
-//				if(strcmp(pChild->Value(), "textures") == 0) {
-//					for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
-//						if(strcmp(pChild2->Value(), "texture") == 0)
-//							fShader->setDiffuseTexture((Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, pChild2->ToElement()->GetText()));
-//					}
-//				}
-//			}
-
-
 Cubemap *MaterialManager::cubemapFromXMLNode(TiXmlNode *node) {
 	TiXmlElement *nodeElement = node->ToElement();
 	if (!nodeElement) return NULL; // Skip comment nodes
@@ -308,7 +323,7 @@ void MaterialManager::addShader(Shader *shader) {
 	shaders.push_back(shader);
 }
 
-std::vector<Shader*> MaterialManager::loadShadersFromFile(String fileName) {
+std::vector<Shader*> MaterialManager::loadShadersFromFile(ResourcePool *resourcePool, String fileName) {
 	std::vector<Shader*> retVector;
 	
 	TiXmlDocument doc(fileName.c_str());
@@ -321,7 +336,7 @@ std::vector<Shader*> MaterialManager::loadShadersFromFile(String fileName) {
 		if(mElem) {
 			TiXmlNode* pChild;					
 			for (pChild = mElem->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {	
-				Shader *newShader = createShaderFromXMLNode(pChild);
+				Shader *newShader = createShaderFromXMLNode(resourcePool, pChild);
 				if(newShader != NULL) {
 					Logger::log("Adding shader %s\n", newShader->getName().c_str());
 					newShader->setResourceName(newShader->getName());
@@ -357,7 +372,7 @@ std::vector<Cubemap*> MaterialManager::loadCubemapsFromFile(String fileName) {
 	return retVector;
 }
 
-std::vector<Material*> MaterialManager::loadMaterialsFromFile(String fileName) {
+std::vector<Material*> MaterialManager::loadMaterialsFromFile(ResourcePool *resourcePool, const String &fileName) {
 	std::vector<Material*> retVector;
 	
 	TiXmlDocument doc(fileName.c_str());
@@ -370,7 +385,7 @@ std::vector<Material*> MaterialManager::loadMaterialsFromFile(String fileName) {
 		if(mElem) {
 			TiXmlNode* pChild;					
 			for (pChild = mElem->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
-				Material *newMat = materialFromXMLNode(pChild);
+				Material *newMat = materialFromXMLNode(resourcePool, pChild);
 				if (newMat) {
 					retVector.push_back(newMat);
 				}
@@ -381,11 +396,11 @@ std::vector<Material*> MaterialManager::loadMaterialsFromFile(String fileName) {
 	return retVector;
 }
 
-Material *MaterialManager::createMaterial(String materialName, String shaderName) {
+Material *MaterialManager::createMaterial(ResourcePool *resourcePool, String materialName, String shaderName) {
 	Material *newMaterial = new Material(materialName);
 	newMaterial->setResourceName(materialName);
 	
-	Shader *retShader = (Shader*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_SHADER, shaderName);
+	Shader *retShader = (Shader*)resourcePool->getResource(Resource::RESOURCE_SHADER, shaderName);
 	
 	if(retShader) {
 		ShaderBinding *newShaderBinding = retShader->createBinding();
@@ -395,7 +410,7 @@ Material *MaterialManager::createMaterial(String materialName, String shaderName
 	return newMaterial;
 }
 
-Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
+Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXmlNode *node) {
 	TiXmlElement *nodeElement = node->ToElement();
 	if (!nodeElement) return NULL; // Skip comment nodes
 
@@ -472,7 +487,7 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 		if (!pChild3Element) continue; // Skip comment nodes
 		
 		if(strcmp(pChild3->Value(), "shader") == 0) {
-			materialShader = setShaderFromXMLNode(pChild3);
+			materialShader = setShaderFromXMLNode(resourcePool, pChild3);
 			if(materialShader) {
 				newShaderBinding = materialShader->createBinding();
 				materialShaders.push_back(materialShader);
@@ -560,7 +575,7 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 								if(pChild2Element->Attribute("name")) {
 									tname =  pChild2Element->Attribute("name");
 								}
-								newShaderBinding->addCubemap(tname, (Cubemap*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_CUBEMAP, pChild2Element->GetText()));
+								newShaderBinding->addCubemap(tname, (Cubemap*)resourcePool->getResource(Resource::RESOURCE_CUBEMAP, pChild2Element->GetText()));
 							}
 							
 						}

+ 226 - 141
Core/Contents/Source/PolyResourceManager.cpp

@@ -38,39 +38,175 @@
 using std::vector;
 using namespace Polycode;
 
-ResourceManager::ResourceManager() : EventDispatcher() {
-	PHYSFS_init(NULL);
-	ticksSinceCheck = 0;
-	reloadResourcesOnModify = false;
+ResourcePool::ResourcePool(const String &name, ResourcePool *fallbackPool) {
+    
+    this->name = name;
+    this->fallbackPool = fallbackPool;
 	dispatchChangeEvents = false;
+	reloadResourcesOnModify = false;
+	ticksSinceCheck = 0;
 }
 
-ResourceManager::~ResourceManager() {
-		printf("Shutting down resource manager...\n");
-		PHYSFS_deinit();
-		
-		for(int i=0; i < resources.size(); i++)	{
-			if(resources[i]->getResourceType() == Resource::RESOURCE_MATERIAL) {
-				delete resources[i];
-			}
+ResourcePool::~ResourcePool() {
+    
+    CoreServices::getInstance()->getResourceManager()->removeResourcePool(this);
+    
+    for(int i=0; i < resources.size(); i++)	{
+        if(resources[i]->getResourceType() == Resource::RESOURCE_MATERIAL) {
+            delete resources[i];
+        }
+    }
+    
+    for(int i=0; i < resources.size(); i++)	{
+        if(resources[i]->getResourceType() == Resource::RESOURCE_SHADER) {
+            delete resources[i];
+        }
+    }
+    
+    for(int i=0; i < resources.size(); i++)	{
+        if(resources[i]->getResourceType() == Resource::RESOURCE_PROGRAM) {
+            delete resources[i];
+        }
+    }
+    
+    resources.clear();
+}
+
+String ResourcePool::getName() {
+    return name;
+}
+
+void ResourcePool::setName(const String &name) {
+    this->name = name;
+}
+
+void ResourcePool::removeResource(Resource *resource) {
+	for(int i=0;i<resources.size();i++) {
+		if(resources[i] == resource) {
+			resources.erase(resources.begin()+i);
+			return;
 		}
-		
-		for(int i=0; i < resources.size(); i++)	{
-			if(resources[i]->getResourceType() == Resource::RESOURCE_SHADER) {
-				delete resources[i];
-			}
+	}
+}
+
+bool ResourcePool::hasResource(Resource *resource) {
+	for(int i=0; i < resources.size(); i++) {
+		if(resources[i] == resource) {
+			return true;
+		}
+	}
+	return false;
+}
+
+void ResourcePool::addResource(Resource *resource) {
+    resource->addEventListener(this, Event::RESOURCE_CHANGE_EVENT);
+    resources.push_back(resource);
+    resource->resourceFileTime = OSBasics::getFileTime(resource->getResourcePath());
+    if(dispatchChangeEvents) {
+        dispatchEvent(new Event(), Event::CHANGE_EVENT);
+    }
+}
+
+void ResourcePool::setFallbackPool(ResourcePool *pool) {
+    fallbackPool = pool;
+}
+
+void ResourceManager::addDirResource(const String& dirPath, bool recursive) {
+	parseTexturesIntoPool(globalPool, dirPath, recursive, "");
+	parseProgramsIntoPool(globalPool, dirPath, recursive);
+	parseShadersIntoPool(globalPool, dirPath, recursive);
+	parseCubemapsIntoPool(globalPool, dirPath, recursive);
+	parseMaterialsIntoPool(globalPool, dirPath, recursive);
+	parseOtherIntoPool(globalPool, dirPath, recursive);
+}
+
+Resource *ResourcePool::getResourceByPath(const String& resourcePath) const {
+	for(int i =0; i < resources.size(); i++) {
+		if(resources[i]->getResourcePath() == resourcePath) {
+			return resources[i];
+		}
+	}
+    
+    if(fallbackPool) {
+        return fallbackPool->getResourceByPath(resourcePath);
+    } else {
+        Logger::log("Could not find resource for path [%s] in pool [%s]\n", resourcePath.c_str(), name.c_str());
+        return NULL;
+    }
+}
+
+std::vector<Resource*> ResourcePool::getResources(int resourceType) {
+	std::vector<Resource*> result;
+	for(int i =0; i < resources.size(); i++) {
+		if(resources[i]->getResourceType() == resourceType) {
+			result.push_back(resources[i]);
 		}
+	}
+    
+	return result;
+}
 
-		for(int i=0; i < resources.size(); i++)	{
-			if(resources[i]->getResourceType() == Resource::RESOURCE_PROGRAM) {
-				delete resources[i];
+Resource *ResourcePool::getResource(int resourceType, const String& resourceName) const {
+	for(int i =0; i < resources.size(); i++) {
+		if(resources[i]->getResourceName() == resourceName && resources[i]->getResourceType() == resourceType) {
+			return resources[i];
+		}
+	}
+	
+	if(resourceType == Resource::RESOURCE_TEXTURE && resourceName != "default/default.png") {
+		Logger::log("Texture [%s] not found in pool [%s], using default\n", resourceName.c_str(), name.c_str());
+		return getResource(Resource::RESOURCE_TEXTURE, "default/default.png");
+	}
+    
+    if(fallbackPool) {
+        return fallbackPool->getResource(resourceType, resourceName);
+    } else {
+        Logger::log("Could not find resource [%s] in pool [%s]\n", resourceName.c_str(), name.c_str());
+        
+        return NULL;
+    }
+}
+
+void ResourcePool::checkForChangedFiles() {
+	for(int i=0; i < resources.size(); i++) {
+		if(resources[i]->reloadOnFileModify == true) {
+			time_t newFileTime = OSBasics::getFileTime(resources[i]->getResourcePath());
+            //			printf("%s\n%lld %lld\n", resources[i]->getResourcePath().c_str(), newFileTime, resources[i]->resourceFileTime);
+			if((newFileTime != resources[i]->resourceFileTime) && newFileTime != 0) {
+				resources[i]->reloadResource();
+				resources[i]->resourceFileTime = newFileTime;
 			}
 		}
-		
-		resources.clear();
+	}
+}
+
+ResourceManager::ResourceManager() : EventDispatcher() {
+	PHYSFS_init(NULL);
+    globalPool = new ResourcePool("Global", NULL);
+}
+
+ResourceManager::~ResourceManager() {
+    printf("Shutting down resource manager...\n");
+    PHYSFS_deinit();
+
+    for(int i=0; i < pools.size(); i++)	{
+        delete pools[i];
+    }
+    pools.clear();
+}
+
+void ResourcePool::Update(int elapsed) {
+	if(!reloadResourcesOnModify)
+		return;
+    
+	ticksSinceCheck += elapsed;
+	if(ticksSinceCheck > RESOURCE_CHECK_INTERVAL) {
+		ticksSinceCheck = 0;
+		checkForChangedFiles();
+	}
 }
 
-void ResourceManager::parseShaders(const String& dirPath, bool recursive) {
+void ResourceManager::parseShadersIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
 	vector<OSFileEntry> resourceDir;
 	resourceDir = OSBasics::parseFolder(dirPath, false);
 	
@@ -78,25 +214,37 @@ void ResourceManager::parseShaders(const String& dirPath, bool recursive) {
 		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
 			if(resourceDir[i].extension == "mat") {
 				MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
-				std::vector<Shader*> shaders = materialManager->loadShadersFromFile(resourceDir[i].fullPath);
+				std::vector<Shader*> shaders = materialManager->loadShadersFromFile(pool, resourceDir[i].fullPath);
 				
 				for(int s=0; s < shaders.size(); s++) {
-					addResource(shaders[s]);
+					pool->addResource(shaders[s]);
 					materialManager->addShader(shaders[s]);
 				}
 			}
 		} else {
 			if(recursive)
-				parseShaders(dirPath+"/"+resourceDir[i].name, true);
+				parseShadersIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
 		}
 	}
 }
 
-void ResourceManager::addShaderModule(PolycodeShaderModule *module) {
-	shaderModules.push_back(module);
+void ResourceManager::parseOtherIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
+    vector<OSFileEntry> resourceDir;
+    resourceDir = OSBasics::parseFolder(dirPath, false);
+    for(int i=0; i < resourceDir.size(); i++) {
+        if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
+            if(resourceDir[i].extension == "ttf") {
+                Logger::log("Registering font: %s\n", resourceDir[i].nameWithoutExtension.c_str());
+                CoreServices::getInstance()->getFontManager()->registerFont(resourceDir[i].nameWithoutExtension, resourceDir[i].fullPath);
+            }
+        } else {
+            if(recursive)
+                parseOtherIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
+        }
+    }
 }
 
-void ResourceManager::parsePrograms(const String& dirPath, bool recursive) {
+void ResourceManager::parseProgramsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
 	vector<OSFileEntry> resourceDir;
 	resourceDir = OSBasics::parseFolder(dirPath, false);
 	for(int i=0; i < resourceDir.size(); i++) {	
@@ -107,16 +255,16 @@ void ResourceManager::parsePrograms(const String& dirPath, bool recursive) {
 			if(newProgram) {
 				newProgram->setResourceName(resourceDir[i].name);
 				newProgram->setResourcePath(resourceDir[i].fullPath);
-				addResource(newProgram);					
+				pool->addResource(newProgram);
 			}			
 		} else {
 			if(recursive)
-				parsePrograms(dirPath+"/"+resourceDir[i].name, true);
+				parseProgramsIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
 		}
 	}	
 }
 
-void ResourceManager::parseMaterials(const String& dirPath, bool recursive) {
+void ResourceManager::parseMaterialsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
 	vector<OSFileEntry> resourceDir;
 	resourceDir = OSBasics::parseFolder(dirPath, false);
 	
@@ -124,22 +272,22 @@ void ResourceManager::parseMaterials(const String& dirPath, bool recursive) {
 		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
 			if(resourceDir[i].extension == "mat") {				
 				MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();			
-				std::vector<Material*> materials = materialManager->loadMaterialsFromFile(resourceDir[i].fullPath);
+				std::vector<Material*> materials = materialManager->loadMaterialsFromFile(pool, resourceDir[i].fullPath);
 
 				for(int m=0; m < materials.size(); m++) {
 					materials[m]->setResourceName(materials[m]->getName());
-					addResource(materials[m]);
+					pool->addResource(materials[m]);
 					materialManager->addMaterial(materials[m]);
 				}
 			}
 		} else {
 			if(recursive)
-				parseMaterials(dirPath+"/"+resourceDir[i].name, true);
+				parseMaterialsIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
 		}
 	}
 }
 
-void ResourceManager::parseCubemaps(const String& dirPath, bool recursive) {
+void ResourceManager::parseCubemapsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
 	vector<OSFileEntry> resourceDir;
 	resourceDir = OSBasics::parseFolder(dirPath, false);
 	
@@ -150,51 +298,27 @@ void ResourceManager::parseCubemaps(const String& dirPath, bool recursive) {
 				MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();			
 				std::vector<Cubemap*> cubemaps = materialManager->loadCubemapsFromFile(resourceDir[i].fullPath);			
 				for(int c=0; c < cubemaps.size(); c++) {
-					addResource(cubemaps[c]);
+					pool->addResource(cubemaps[c]);
 				}			
 			}
 		} else {
 			if(recursive)
-				parseCubemaps(dirPath+"/"+resourceDir[i].name, true);
+				parseCubemapsIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
 		}
 	}	
 }
 
-bool ResourceManager::hasResource(Resource *resource) {
-	for(int i=0; i < resources.size(); i++) {
-		if(resources[i] == resource) {
-			return true;
-		}
-	}
-	return false;
-}
-
-void ResourceManager::addResource(Resource *resource) {
-	resource->addEventListener(this, Event::RESOURCE_CHANGE_EVENT);
-	resources.push_back(resource);
-	resource->resourceFileTime = OSBasics::getFileTime(resource->getResourcePath());
-	if(dispatchChangeEvents) {
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
-	}
-}
-
 void ResourceManager::handleEvent(Event *event) {
 	if(event->getEventCode() == Event::RESOURCE_CHANGE_EVENT) {
 		dispatchEvent(new Event(), Event::CHANGE_EVENT);	
 	}
 }
 
-void ResourceManager::removeResource(Resource *resource) {
-	for(int i=0;i<resources.size();i++) {
-		if(resources[i] == resource) {
-			resources.erase(resources.begin()+i);
-			return;
-		}
-	}	
+ResourcePool *ResourceManager::getGlobalPool() {
+    return globalPool;
 }
 
-
-void ResourceManager::parseTextures(const String& dirPath, bool recursive, const String& basePath) {
+void ResourceManager::parseTexturesIntoPool(ResourcePool *pool, const String& dirPath, bool recursive, const String& basePath) {
 	MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
 	vector<OSFileEntry> resourceDir;
 	resourceDir = OSBasics::parseFolder(dirPath, false);
@@ -211,38 +335,21 @@ void ResourceManager::parseTextures(const String& dirPath, bool recursive, const
 						t->setResourceName(basePath+"/"+resourceDir[i].name);
 						t->setResourcePath(resourceDir[i].fullPath);						
 					}
-					addResource(t);
+					pool->addResource(t);
 				}
 			}
 		} else {
 			if(recursive) {
 				if(basePath == "") {			
-					parseTextures(dirPath+"/"+resourceDir[i].name, true, resourceDir[i].name);
+					parseTexturesIntoPool(pool, dirPath+"/"+resourceDir[i].name, true, resourceDir[i].name);
 				} else {
-					parseTextures(dirPath+"/"+resourceDir[i].name, true, basePath+"/"+resourceDir[i].name);
+					parseTexturesIntoPool(pool, dirPath+"/"+resourceDir[i].name, true, basePath+"/"+resourceDir[i].name);
 				}
 			}
 		}
 	}
 }
 
-void ResourceManager::parseOthers(const String& dirPath, bool recursive) {
-	vector<OSFileEntry> resourceDir;
-	resourceDir = OSBasics::parseFolder(dirPath, false);
-	for(int i=0; i < resourceDir.size(); i++) {	
-		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-			if(resourceDir[i].extension == "ttf") {
-				Logger::log("Registering font: %s\n", resourceDir[i].nameWithoutExtension.c_str());
-				CoreServices::getInstance()->getFontManager()->registerFont(resourceDir[i].nameWithoutExtension, resourceDir[i].fullPath);
-			}
-		} else {
-			if(recursive)
-				parseOthers(dirPath+"/"+resourceDir[i].name, true);
-		}	
-	}
-}
-
-
 void ResourceManager::addArchive(const String& path) {
 	if(PHYSFS_addToSearchPath(path.c_str(), 1) == 0) {	
 		Logger::log("Error adding archive to resource manager... %s\n", PHYSFS_getLastError());
@@ -255,74 +362,52 @@ void ResourceManager::removeArchive(const String& path) {
 	PHYSFS_removeFromSearchPath(path.c_str());
 }
 
-
-void ResourceManager::addDirResource(const String& dirPath, bool recursive) {
-	parseTextures(dirPath, recursive, "");
-	parsePrograms(dirPath, recursive);
-	parseShaders(dirPath, recursive);
-	parseCubemaps(dirPath, recursive);	
-	parseMaterials(dirPath, recursive);
-	parseOthers(dirPath, recursive);	
+void ResourceManager::Update(int elapsed) {
+    globalPool->Update(elapsed);
+    for(int i=0; i < pools.size(); i++) {
+        pools[i]->Update(elapsed);
+    }
 }
 
-Resource *ResourceManager::getResourceByPath(const String& resourcePath) const {
-	Logger::log("requested %s\n", resourcePath.c_str());
-	for(int i =0; i < resources.size(); i++) {
-		if(resources[i]->getResourcePath() == resourcePath) {
-			return resources[i];
-		}
-	}
-	Logger::log("return NULL\n");	
-	return NULL;
+void ResourceManager::removeResource(Resource *resource) {
+    globalPool->removeResource(resource);
+    for(int i=0; i < pools.size(); i++) {
+        pools[i]->removeResource(resource);
+    }
 }
 
-Resource *ResourceManager::getResource(int resourceType, const String& resourceName) const {
-	Logger::log("requested %s\n", resourceName.c_str());
-	for(int i =0; i < resources.size(); i++) {
-		if(resources[i]->getResourceName() == resourceName && resources[i]->getResourceType() == resourceType) {
-			return resources[i];
-		}
-	}
-	
-	if(resourceType == Resource::RESOURCE_TEXTURE && resourceName != "default/default.png") {
-		Logger::log("Texture not found, using default\n");
-		return getResource(Resource::RESOURCE_TEXTURE, "default/default.png");
-	}	
-	Logger::log("return NULL\n");
-	// need to add some sort of default resource for each type
-	return NULL;
+void ResourceManager::addResourcePool(ResourcePool *pool) {
+    pools.push_back(pool);
 }
 
-void ResourceManager::checkForChangedFiles() {
-	for(int i=0; i < resources.size(); i++) {
-		if(resources[i]->reloadOnFileModify == true) {
-			time_t newFileTime = OSBasics::getFileTime(resources[i]->getResourcePath());
-//			printf("%s\n%lld %lld\n", resources[i]->getResourcePath().c_str(), newFileTime, resources[i]->resourceFileTime);
-			if((newFileTime != resources[i]->resourceFileTime) && newFileTime != 0) {
-				resources[i]->reloadResource();
-				resources[i]->resourceFileTime = newFileTime;
-			}
-		}
-	}
+ResourcePool *ResourceManager::getResourcePoolByName(const String &name) {
+    for(int i=0; i < pools.size(); i++) {
+        if(pools[i]->getName() == name) {
+            return pools[i];
+        }
+    }
+    return NULL;
 }
 
-void ResourceManager::Update(int elapsed) {
-	if(!reloadResourcesOnModify)
-		return;
-		
-	ticksSinceCheck += elapsed;
-	if(ticksSinceCheck > RESOURCE_CHECK_INTERVAL) {
-		ticksSinceCheck = 0;
-		checkForChangedFiles();
-	}
+void ResourceManager::removeResourcePool(ResourcePool *pool) {
+    for(int i=0; i < pools.size(); i++) {
+        if(pools[i] == pool) {
+            pools.erase(pools.begin()+i);
+            return;
+        }
+    }
 }
 
 std::vector<Resource*> ResourceManager::getResources(int resourceType) {
 	std::vector<Resource*> result;
-	for(int i =0; i < resources.size(); i++) {
-		if(resources[i]->getResourceType() == resourceType) {
-			result.push_back(resources[i]);
-		}
+
+    std::vector<Resource*> subresult = globalPool->getResources(resourceType);
+    result.insert(result.end(), subresult.begin(), subresult.end());
+    
+	for(int i =0; i < pools.size(); i++) {
+        subresult = pools[i]->getResources(resourceType);
+        result.insert(result.end(), subresult.begin(), subresult.end());
 	}
+    
 	return result;
 }

+ 76 - 7
Core/Contents/Source/PolySceneEntityInstance.cpp

@@ -56,12 +56,13 @@ SceneEntityInstance *SceneEntityInstance::BlankSceneEntityInstance() {
 
 SceneEntityInstance::SceneEntityInstance(Scene *parentScene, const String& fileName) : Entity() {
     this->parentScene = parentScene;
-	resourceEntry = new SceneEntityInstanceResourceEntry(this);		
+	resourceEntry = new SceneEntityInstanceResourceEntry(this);
 	loadFromFile(fileName);
 	resourceEntry->setResourceName(fileName);
 	resourceEntry->setResourcePath(fileName);
 	cloneUsingReload = false;
-	ownsChildren = true;	
+	ownsChildren = true;
+    topLevelResourcePool = CoreServices::getInstance()->getResourceManager()->getGlobalPool();
 }
 
 SceneEntityInstance::SceneEntityInstance() : Entity() {
@@ -104,6 +105,52 @@ void SceneEntityInstance::applyClone(Entity *clone, bool deepClone, bool ignoreE
 	}
 }
 
+
+void SceneEntityInstance::linkResourcePool(ResourcePool *pool) {
+    for(int i=0; i < resourcePools.size(); i++) {
+        if(resourcePools[i] == pool) {
+            return;
+        }
+    }
+    pool->setFallbackPool(topLevelResourcePool);
+    topLevelResourcePool = pool;
+    resourcePools.push_back(pool);
+}
+
+unsigned int SceneEntityInstance::getNumLinkedResourePools() {
+    return resourcePools.size();
+}
+
+ResourcePool *SceneEntityInstance::getLinkedResourcePoolAtIndex(unsigned int index) {
+    return resourcePools[index];
+}
+
+void SceneEntityInstance::rebuildResourceLinks() {
+    for(int i=0; i < resourcePools.size(); i++) {
+        if(i == 0) {
+            resourcePools[i]->setFallbackPool(CoreServices::getInstance()->getResourceManager()->getGlobalPool());
+        } else {
+            resourcePools[i]->setFallbackPool(resourcePools[i-1]);
+        }
+    }
+    
+    if(resourcePools.size() > 0) {
+        topLevelResourcePool = resourcePools[resourcePools.size()-1];
+    } else {
+        topLevelResourcePool = CoreServices::getInstance()->getResourceManager()->getGlobalPool();
+    }
+}
+
+void SceneEntityInstance::unlinkResourcePool(ResourcePool *pool) {
+    for(int i=0; i < resourcePools.size(); i++) {
+        if(resourcePools[i] == pool) {
+            resourcePools.erase(resourcePools.begin() + i);
+            rebuildResourceLinks();
+            return;
+        }
+    }
+}
+
 void SceneEntityInstance::applySceneMesh(ObjectEntry *entry, SceneMesh *sceneMesh) {
 	if(!entry) {
 		return;
@@ -111,7 +158,7 @@ void SceneEntityInstance::applySceneMesh(ObjectEntry *entry, SceneMesh *sceneMes
     
     ObjectEntry *materialName =(*entry)["material"];
     if(materialName) {
-        sceneMesh->setMaterialByName(materialName->stringVal);
+        sceneMesh->setMaterialByName(materialName->stringVal, topLevelResourcePool);
         if(sceneMesh->getMaterial()) {
             ObjectEntry *optionsEntry =(*entry)["shader_options"];
             if(optionsEntry) {
@@ -129,8 +176,11 @@ void SceneEntityInstance::applySceneMesh(ObjectEntry *entry, SceneMesh *sceneMes
                                     if(nameEntry && textureEntry->stringVal != "") {
                                         
                                         if(textureEntry->name == "cubemap") {
-                                            Cubemap *cubemap = (Cubemap*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_CUBEMAP, textureEntry->stringVal);
-                                            if(cubemap) {
+                                            Cubemap *cubemap;
+                                            
+                                            cubemap = (Cubemap*)topLevelResourcePool->getResource(Resource::RESOURCE_CUBEMAP, textureEntry->stringVal);
+                                                
+                                                                                      if(cubemap) {
                                                 sceneMesh->getLocalShaderOptions()->addCubemap(nameEntry->stringVal, cubemap);
                                             }
                                         } else {
@@ -453,6 +503,9 @@ String SceneEntityInstance::getFileName() const {
 }
 
 void SceneEntityInstance::clearInstance() {
+    
+    resourcePools.clear();
+    topLevelResourcePool = CoreServices::getInstance()->getResourceManager()->getGlobalPool();
 	for(int i=0; i < children.size(); i++) {
 		removeChild(children[i]);
 		children[i]->setOwnsChildrenRecursive(true);
@@ -473,9 +526,25 @@ bool SceneEntityInstance::loadFromFile(const String& fileName) {
         if(!loadObject.loadFromXML(fileName)) {
             Logger::log("Error loading entity instance.\n");
         }
-	}	
+	}
+    
+	ObjectEntry *settings = loadObject.root["settings"];
+    if(settings) {
+        ObjectEntry *matFiles = (*settings)["matFiles"];
+        for(int i=0; i < matFiles->length; i++) {
+            ObjectEntry *matFile = (*matFiles)[i];
+            if(matFile) {
+                ObjectEntry *path = (*matFile)["path"];
+                if(path) {
+                    ResourcePool *newPool = new ResourcePool(path->stringVal,  CoreServices::getInstance()->getResourceManager()->getGlobalPool());
+                    CoreServices::getInstance()->getMaterialManager()->loadMaterialLibraryIntoPool(newPool, path->stringVal);
+                    linkResourcePool(newPool);
+                }
+            }
+        }
+    }
+    
 	ObjectEntry *root = loadObject.root["root"];
-	
 	if(root) {
 		loadObjectEntryIntoEntity(root, this);
 	}

+ 19 - 5
Core/Contents/Source/PolySceneMesh.cpp

@@ -51,6 +51,7 @@ SceneMesh::SceneMesh(const String& fileName) : Entity(), texture(NULL), material
 	lineSmooth = false;
 	ownsMesh = true;
 	ownsSkeleton = true;
+    renderWireframe = false;
 	lineWidth = 1.0;
 	pointSize = 1.0;
 	pointSmooth = false;
@@ -67,6 +68,7 @@ SceneMesh::SceneMesh(Mesh *mesh) : Entity(), texture(NULL), material(NULL), skel
 	useVertexBuffer = false;
 	lineSmooth = false;
 	ownsMesh = true;
+    renderWireframe = false;
 	ownsSkeleton = true;	
 	lineWidth = 1.0;
 	pointSize = 1.0;
@@ -83,6 +85,7 @@ SceneMesh::SceneMesh(int meshType) : texture(NULL), material(NULL), skeleton(NUL
 	showVertexNormals = false;	
 	useVertexBuffer = false;	
 	lineSmooth = false;
+    renderWireframe = false;
 	ownsMesh = true;
 	ownsSkeleton = true;	
 	lineWidth = 1.0;
@@ -153,11 +156,16 @@ void SceneMesh::setMaterial(Material *material) {
 	
 }
 
-void SceneMesh::setMaterialByName(const String& materialName) {
-	Material *material =  (Material*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, materialName);
-	if(!material)
-		return;
-	setMaterial(material);
+void SceneMesh::setMaterialByName(const String& materialName, ResourcePool *resourcePool) {
+    
+    Material *material;
+    if(resourcePool) {
+        material =  (Material*)resourcePool->getResource(Resource::RESOURCE_MATERIAL, materialName);        
+    } else {
+        material =  (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, materialName);
+        
+    }
+    setMaterial(material);
 }
 
 Texture *SceneMesh::getTexture() const {
@@ -318,6 +326,12 @@ void SceneMesh::Render() {
 			renderer->setTexture(NULL);
 	}
 		
+    if(renderWireframe) {
+		renderer->setWireframePolygonMode(true);
+    } else {
+        renderer->setWireframePolygonMode(false);
+    }
+    
 	if(useVertexBuffer) {
 		renderer->drawVertexBuffer(mesh->getVertexBuffer(), mesh->useVertexColors);
 	} else {

File diff suppressed because it is too large
+ 3 - 3
IDE/Assets/ide_icons.ai


File diff suppressed because it is too large
+ 3 - 3
IDE/Assets/ui_theme_light.ai


+ 6 - 0
IDE/Build/Mac OS X/Polycode.xcodeproj/project.pbxproj

@@ -16,6 +16,7 @@
 		6D1CD96B164D9568006CDAB1 /* polycode_project.icns in Resources */ = {isa = PBXBuildFile; fileRef = 6D1CD96A164D9568006CDAB1 /* polycode_project.icns */; };
 		6D2AC99B14B8500400BB63DA /* PolycodeProjectEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2AC99A14B8500400BB63DA /* PolycodeProjectEditor.cpp */; };
 		6D30DEF1187E7E3B006086E7 /* EntityEditorTreeView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D30DEEF187E7E3B006086E7 /* EntityEditorTreeView.cpp */; };
+		6D30DEF5187E9DCD006086E7 /* EntityEditorSettingsView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D30DEF3187E9DCD006086E7 /* EntityEditorSettingsView.cpp */; };
 		6D34143412B816BC0034FA9B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D34143312B816BC0034FA9B /* IOKit.framework */; };
 		6D3B6C5B14B820A900727F17 /* ToolWindows.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D3B6C5A14B820A900727F17 /* ToolWindows.cpp */; };
 		6D3DC79D1622043A003ED2C9 /* PolycodeConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D3DC79C1622043A003ED2C9 /* PolycodeConsole.cpp */; };
@@ -97,6 +98,8 @@
 		6D2AC99D14B8500A00BB63DA /* PolycodeProjectEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolycodeProjectEditor.h; sourceTree = "<group>"; };
 		6D30DEEE187E7DF4006086E7 /* EntityEditorTreeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EntityEditorTreeView.h; sourceTree = "<group>"; };
 		6D30DEEF187E7E3B006086E7 /* EntityEditorTreeView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EntityEditorTreeView.cpp; sourceTree = "<group>"; };
+		6D30DEF2187E9DBE006086E7 /* EntityEditorSettingsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EntityEditorSettingsView.h; sourceTree = "<group>"; };
+		6D30DEF3187E9DCD006086E7 /* EntityEditorSettingsView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EntityEditorSettingsView.cpp; sourceTree = "<group>"; };
 		6D34143312B816BC0034FA9B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
 		6D3B6C5A14B820A900727F17 /* ToolWindows.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToolWindows.cpp; sourceTree = "<group>"; };
 		6D3B6C5C14B820B000727F17 /* ToolWindows.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToolWindows.h; sourceTree = "<group>"; };
@@ -390,6 +393,7 @@
 				6DCB60361822EDB1006701AF /* EditorGrid.h */,
 				6DCB60331822EAE5006701AF /* TransformGizmo.h */,
 				6D30DEEE187E7DF4006086E7 /* EntityEditorTreeView.h */,
+				6D30DEF2187E9DBE006086E7 /* EntityEditorSettingsView.h */,
 			);
 			name = entity_editor;
 			sourceTree = "<group>";
@@ -401,6 +405,7 @@
 				6DCB60341822EBDD006701AF /* EditorGrid.cpp */,
 				6DCB60311822EADE006701AF /* TransformGizmo.cpp */,
 				6D30DEEF187E7E3B006086E7 /* EntityEditorTreeView.cpp */,
+				6D30DEF3187E9DCD006086E7 /* EntityEditorSettingsView.cpp */,
 			);
 			name = entity_editor;
 			sourceTree = "<group>";
@@ -508,6 +513,7 @@
 				6D70AB2A12B29BF200EB6D94 /* NewFileWindow.cpp in Sources */,
 				6D8A55BC14B3EACB005F6411 /* PolycodeView.mm in Sources */,
 				6D6D3FA614B446A600219173 /* PolycodeToolLauncher.cpp in Sources */,
+				6D30DEF5187E9DCD006086E7 /* EntityEditorSettingsView.cpp in Sources */,
 				6DCAFD4314B519C900039F34 /* ExampleBrowserWindow.cpp in Sources */,
 				6D3B6C5B14B820A900727F17 /* ToolWindows.cpp in Sources */,
 				6D2AC99B14B8500400BB63DA /* PolycodeProjectEditor.cpp in Sources */,

+ 2 - 1
IDE/Contents/Include/EntityEditorPropertyView.h

@@ -36,7 +36,8 @@ class EntityEditorPropertyView : public UIElement {
         EntityEditorPropertyView();
         ~EntityEditorPropertyView();
     
-        void setEntity(Entity *entity);    
+        void setEntityInstance(SceneEntityInstance *instance);
+        void setEntity(Entity *entity);
         void handleEvent(Event *event);
         void updateShaderOptions();
     

+ 45 - 0
IDE/Contents/Include/EntityEditorSettingsView.h

@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2014 by Ivan Safrin
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ 
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "Polycode.h"
+#include "PolycodeUI.h"
+#include "PolycodeProps.h"
+#include "OSBasics.h"
+
+using namespace Polycode;
+
+
+class EntityEditorSettingsView : public UIElement {
+public:
+    EntityEditorSettingsView();
+    ~EntityEditorSettingsView();
+    
+    void setEntityInstance(SceneEntityInstance *instance);
+    
+    void Resize(Number width, Number height);
+    
+private:
+    PropList *entityProps;
+    LinkedMaterialsSheet *materialsSheet;
+};

+ 16 - 0
IDE/Contents/Include/PolycodeEntityEditor.h

@@ -28,6 +28,7 @@
 #include "PolycodeUI.h"
 #include "EntityEditorPropertyView.h"
 #include "EntityEditorTreeView.h"
+#include "EntityEditorSettingsView.h"
 
 #include "TrackballCamera.h"
 
@@ -80,6 +81,13 @@ class CameraPreviewWindow : public UIElement {
     
 };
 
+class SceneMeshSettings {
+    public:
+        Material *material;
+        bool backfaceCulled;
+        ShaderBinding *shaderBinding;
+};
+
 class EntityEditorMainView : public UIElement {
 		public:
 			EntityEditorMainView();
@@ -100,6 +108,9 @@ class EntityEditorMainView : public UIElement {
             void setEditorMode(int newMode);
             Entity *getSelectedEntity();
     
+            void setMaterialRecursive(const String &materialName, bool wireFrame, Entity *entity);
+            void restoreSettingsRecursive(Entity *entity);
+    
             void deleteSelected();
     
             Entity *getObjectRoot();
@@ -139,6 +150,8 @@ class EntityEditorMainView : public UIElement {
             UIComboBox *modeSwitchDropdown;
             UIMenu *addEntityMenu;
     
+            UIIconSelector *shadeModeSelector;
+    
             CameraPreviewWindow *cameraPreview;
     
             std::vector<ScenePrimitive*> icons;
@@ -159,6 +172,7 @@ class EntityEditorPropertyContainer : public UIElement {
         UIElement *currentView;
         EntityEditorPropertyView *propertyView;
         EntityEditorTreeView *treeView;
+        EntityEditorSettingsView *settingsView;
         UIIconSelector *propIconSelector;
 };
 
@@ -187,7 +201,9 @@ class PolycodeEntityEditor : public PolycodeEditor {
 		EntityEditorMainView *mainView;
         EntityEditorPropertyView *propertyView;
         EntityEditorTreeView *treeView;
+        EntityEditorSettingsView *settingsView;
     
+        SceneEntityInstance *loadedInstance;
 		UIHSizer *mainSizer;
         UIVSizer *rightSizer;
     

+ 3 - 1
IDE/Contents/Include/PolycodeFrame.h

@@ -311,7 +311,9 @@ public:
 
 	void handleEvent(Event *event);	
 	void showAssetBrowser(std::vector<String> extensions);
-	
+
+	void showAssetBrowserForPools(std::vector<ResourcePool*> pools, int resourceType);
+    
 	PolycodeProjectBrowser *getCurrentProjectBrowser();
 	PolycodeProjectFrame *getActiveProjectFrame();	
 	PolycodeProjectFrame *getProjectFrame(PolycodeProject *project);

+ 8 - 5
IDE/Contents/Include/PolycodeMaterialEditor.h

@@ -148,7 +148,7 @@ class MaterialBrowser : public UIElement {
 
 class CubemapEditorPane : public UIElement {
 	public:
-		CubemapEditorPane();
+		CubemapEditorPane(ResourcePool *resourcePool);
 		~CubemapEditorPane();
 		void Resize(Number width, Number height);
 		void setCubemap(Cubemap *cubemap);
@@ -174,7 +174,7 @@ class CubemapEditorPane : public UIElement {
 
 class PostEditorPane : public UIElement {
 	public:
-		PostEditorPane();
+		PostEditorPane(ResourcePool *resourcePool);
 		~PostEditorPane();
 		void Resize(Number width, Number height);
 		void setMaterial(Material *material);
@@ -211,7 +211,7 @@ class PostEditorPane : public UIElement {
 
 class ShaderEditorPane : public UIElement {
 	public:
-		ShaderEditorPane();
+		ShaderEditorPane(ResourcePool *resourcePool);
 		~ShaderEditorPane();
 		void Resize(Number width, Number height);
 		void setShader(Shader *shader);
@@ -225,7 +225,7 @@ class ShaderEditorPane : public UIElement {
 			
 	protected:
 	
-		
+        ResourcePool *resourcePool;
 		bool changingShader;
 
 		bool choosingVertexProgram;
@@ -276,7 +276,7 @@ class MaterialEditorPane : public UIElement {
 
 class MaterialMainWindow : public UIElement {
 	public:
-	MaterialMainWindow();
+	MaterialMainWindow(ResourcePool *resourcePool);
 	~MaterialMainWindow(){}
 	
 	void Resize(Number width, Number height);
@@ -305,6 +305,9 @@ class PolycodeMaterialEditor : public PolycodeEditor {
 	static String createStringValue(unsigned int type, void *value);
 	
 	protected:
+    
+        ResourcePool *resourcePool;
+    
 		UIImage *editorImage;
 		
 		MaterialBrowser *materialBrowser;

+ 90 - 21
IDE/Contents/Include/PolycodeProps.h

@@ -53,24 +53,24 @@ class PropProp : public UIElement {
 };
 
 class Vector3Prop : public PropProp {
-public:
-    Vector3Prop(String caption);
-    ~Vector3Prop();
-    void handleEvent(Event *event);
-    void set(const Vector3 &position);
+    public:
+        Vector3Prop(String caption);
+        ~Vector3Prop();
+        void handleEvent(Event *event);
+        void set(const Vector3 &position);
 
-    Vector3 get() const;
-    void setPropData(PolycodeEditorPropActionData* data);
-    
-    void setPropWidth(Number width);
-    
-    UITextInput *xInput;
-    UITextInput *yInput;
-    UITextInput *zInput;
-    
-    UILabel *labelX;
-    UILabel *labelY;
-    UILabel *labelZ;
+        Vector3 get() const;
+        void setPropData(PolycodeEditorPropActionData* data);
+        
+        void setPropWidth(Number width);
+        
+        UITextInput *xInput;
+        UITextInput *yInput;
+        UITextInput *zInput;
+        
+        UILabel *labelX;
+        UILabel *labelY;
+        UILabel *labelZ;
 };
 
 
@@ -114,6 +114,18 @@ class SliderProp : public PropProp {
 		Number currentValue;
 };
 
+class ButtonProp : public PropProp {
+    public:
+        ButtonProp(const String &caption);
+        ~ButtonProp();
+        void setPropWidth(Number width);
+        UIButton *getButton();
+    
+    private:
+    
+        UIButton *button;
+};
+
 
 class NumberProp : public PropProp {
 	public:
@@ -192,6 +204,19 @@ class ShaderPassProp : public PropProp {
 		
 };
 
+class RemovableStringProp : public PropProp {
+public:
+    RemovableStringProp(const String &caption);
+    ~RemovableStringProp();
+    void handleEvent(Event *event);
+    
+    String getCaption();
+    
+    UILabel *label;
+    UIImageButton *removeButton;
+};
+
+
 class CustomProp : public PropProp {
 	public:
 		CustomProp(String key, String value);
@@ -323,6 +348,27 @@ class BezierCurveProp : public PropProp {
 		UIButton *changeButton;
 };
 
+class MaterialProp : public PropProp {
+    public:
+        MaterialProp(const String &caption);
+        ~MaterialProp();
+    
+        void setEntityInstance(SceneEntityInstance *instance);
+        void set(Material *material);
+        Material *get();
+		void setPropWidth(Number width);
+        void handleEvent(Event *event);
+    
+    private:
+    
+        SceneEntityInstance *entityInstance;
+        UIRect *previewShape;
+        UIButton *changeButton;
+        UILabel *materialLabel;
+    
+        Material *currentMaterial;
+};
+
 class TextureProp : public PropProp {
 	public:
 		TextureProp(String caption);
@@ -474,7 +520,7 @@ class EntitySheet : public PropSheet {
 
 class ShaderPassesSheet : public PropSheet {
 	public:
-		ShaderPassesSheet();
+		ShaderPassesSheet(ResourcePool *resourcePool);
 		~ShaderPassesSheet();
 		void handleEvent(Event *event);			
 		void refreshPasses();
@@ -488,6 +534,8 @@ class ShaderPassesSheet : public PropSheet {
 
 		ShaderPassProp *selectedProp;
 
+        ResourcePool *resourcePool;
+    
 		UIButton *addButton;		
 		int removeIndex;		
 };
@@ -663,14 +711,14 @@ class MaterialPropSheet : public PropSheet {
         MaterialPropSheet();
         ~MaterialPropSheet();
     
+        void setEntityInstance(SceneEntityInstance *instance);
         void handleEvent(Event *event);
-        void reloadMaterials();
-    
         void setSceneMesh(SceneMesh *sceneMesh);
     
     protected:
+    
+        MaterialProp *materialProp;
         SceneMesh *sceneMesh;
-        ComboProp *materialProp;
 };
 
 class EntityPropSheet : public PropSheet {
@@ -780,6 +828,27 @@ class SoundSheet : public PropSheet {
 		SliderProp *pitch;
 };
 
+class LinkedMaterialsSheet : public PropSheet {
+    public:
+        LinkedMaterialsSheet();
+        ~LinkedMaterialsSheet();
+    
+        void handleEvent(Event *event);
+        void setEntityInstance(SceneEntityInstance *instance);
+    
+        void Update();
+    
+        void updateMaterials();
+    
+    
+    private:
+        SceneEntityInstance *instance;
+        ButtonProp *addMaterialProp;
+    
+        RemovableStringProp *propToRemove;
+    
+};
+
 class PropList : public UIElement {
 	public:
 		PropList(String caption="PROPERTIES");

+ 20 - 3
IDE/Contents/Include/TextureBrowser.h

@@ -38,14 +38,14 @@ public:
 
 class AssetEntry : public UIElement {
 	public:
-		AssetEntry(String assetPath, String assetName, String extension);
+		AssetEntry(String assetPath, String assetName, String extension, Resource *resource);
 		~AssetEntry();
 		
 		UIRect *imageShape;
 		UILabel *nameLabel;
 		
 		String assetPath;
-		
+        Resource *resource;
 		UIRect *selectShape;
 };
 
@@ -59,12 +59,17 @@ class AssetList : public UIElement {
 		bool hasExtension(String extension);
 		
 		void showFolder(String folderPath);
+        void showResourcePool(ResourcePool *pool, int resourceFilter);
+    
+        Resource *getSelectedResource();
+    
 		String selectedPath;
 		
 		void setExtensions(std::vector<String> extensions);
 		
 	protected:
 	
+        Resource *selectedResource;
 		UIImageButton *reloadButton;
 	
 		String currentFolderPath;
@@ -91,8 +96,17 @@ class AssetBrowser : public UIWindow {
 		void setExtensions(std::vector<String> extensions);
 		
 		void setProject(PolycodeProject *project);
-		
+    
+        void setBrowseMode(unsigned int newBrowseMode);
+
+        void setResourcePools(std::vector<ResourcePool*> pools, int resourceFilter);
+        void setResourceFilter(int resourceType);
 		void handleEvent(Event *event);
+    
+        Resource *getSelectedResource();
+    
+        static const int BROWSE_MODE_FILES = 0;
+        static const int BROWSE_MODE_RESOURCES = 1;
 	
 	protected:
 	
@@ -101,6 +115,9 @@ class AssetBrowser : public UIWindow {
 	
 		PolycodeProject *currentProject;
 	
+        unsigned int browseMode;
+        int resourceFilter;
+    
 		UIButton *cancelButton;
 		UIButton *okButton;
 		

BIN
IDE/Contents/Resources/Images/browserIcons/material_resource_icon.png


BIN
IDE/Contents/Resources/Images/browserIcons/materials_icon.png


BIN
IDE/Contents/Resources/Images/entityEditor/shade_full.png


BIN
IDE/Contents/Resources/Images/entityEditor/shade_solid.png


BIN
IDE/Contents/Resources/Images/entityEditor/shade_wire.png


BIN
IDE/Contents/Resources/ImagesRetina/browserIcons/material_resource_icon.png


BIN
IDE/Contents/Resources/ImagesRetina/browserIcons/materials_icon.png


BIN
IDE/Contents/Resources/ImagesRetina/entityEditor/shade_full.png


BIN
IDE/Contents/Resources/ImagesRetina/entityEditor/shade_solid.png


BIN
IDE/Contents/Resources/ImagesRetina/entityEditor/shade_wire.png


+ 5 - 1
IDE/Contents/Source/EntityEditorPropertyView.cpp

@@ -78,7 +78,11 @@ EntityEditorPropertyView::EntityEditorPropertyView() : UIElement() {
     entitySheet = new EntitySheet();
     entityProps->addPropSheet(entitySheet);
     entitySheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
-        
+    
+}
+
+void EntityEditorPropertyView::setEntityInstance(SceneEntityInstance *instance) {
+    materialSheet->setEntityInstance(instance);
 }
 
 void EntityEditorPropertyView::Resize(Number width, Number height) {

+ 46 - 0
IDE/Contents/Source/EntityEditorSettingsView.cpp

@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2014 by Ivan Safrin
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ 
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+#include "EntityEditorSettingsView.h"
+
+EntityEditorSettingsView::EntityEditorSettingsView() : UIElement() {
+    entityProps = new PropList("ENTITY SETTINGS");
+    addChild(entityProps);
+    
+    materialsSheet = new LinkedMaterialsSheet();
+    entityProps->addPropSheet(materialsSheet);
+    materialsSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
+
+}
+
+EntityEditorSettingsView::~EntityEditorSettingsView() {
+    
+}
+
+void EntityEditorSettingsView::setEntityInstance(SceneEntityInstance *instance) {
+    materialsSheet->setEntityInstance(instance);
+}
+
+void EntityEditorSettingsView::Resize(Number width, Number height) {
+    entityProps->Resize(width, height);
+    UIElement::Resize(width, height);
+}

+ 90 - 4
IDE/Contents/Source/PolycodeEntityEditor.cpp

@@ -273,6 +273,14 @@ EntityEditorMainView::EntityEditorMainView() {
     modeSwitchDropdown->setSelectedIndex(0);
     modeSwitchDropdown->addEventListener(this, UIEvent::CHANGE_EVENT);
     
+    shadeModeSelector = new UIIconSelector();
+    shadeModeSelector->addIcon("entityEditor/shade_full.png");
+    shadeModeSelector->addIcon("entityEditor/shade_solid.png");
+    shadeModeSelector->addIcon("entityEditor/shade_wire.png");
+//    topBar->addChild(shadeModeSelector);
+    shadeModeSelector->setPosition(320, 3);
+    shadeModeSelector->addEventListener(this, UIEvent::SELECT_EVENT);
+    
     editorMode = EDITOR_MODE_3D;
     
     input = CoreServices::getInstance()->getCore()->getInput();
@@ -644,6 +652,18 @@ void EntityEditorMainView::handleEvent(Event *event) {
                 break;
             }
         }
+    } else if(event->getDispatcher() == shadeModeSelector) {
+        switch(shadeModeSelector->getSelectedIndex()) {
+            case 0:
+                restoreSettingsRecursive(sceneObjectRoot);
+            break;
+            case 1:
+                setMaterialRecursive("Default", false, sceneObjectRoot);
+            break;
+            case 2:
+                setMaterialRecursive("", true, sceneObjectRoot);
+            break;
+        }
     } else {
         if(event->getEventCode() == InputEvent::EVENT_MOUSEDOWN ) {
             InputEvent *inputEvent = (InputEvent*) event;
@@ -664,6 +684,52 @@ void EntityEditorMainView::handleEvent(Event *event) {
     }
 }
 
+void EntityEditorMainView::restoreSettingsRecursive(Entity *entity) {
+    SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(entity);
+    if(sceneMesh && !entity->editorOnly) {
+        SceneMeshSettings *meshSettings = (SceneMeshSettings*) entity->getUserData();
+        if(meshSettings) {
+            sceneMesh->setMaterial(meshSettings->material);
+            sceneMesh->backfaceCulled = meshSettings->backfaceCulled;
+        }
+        sceneMesh->renderWireframe = false;
+    }
+    
+    for(int i=0; i < entity->getNumChildren(); i++) {
+        restoreSettingsRecursive(entity->getChildAtIndex(i));
+    }
+}
+
+void EntityEditorMainView::setMaterialRecursive(const String &materialName, bool wireFrame, Entity *entity) {
+    SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(entity);
+    if(sceneMesh && !entity->editorOnly) {
+        
+        if(!sceneMesh->getUserData()) {
+            SceneMeshSettings *meshSettings = new SceneMeshSettings();
+            meshSettings->material = sceneMesh->getMaterial();
+            meshSettings->backfaceCulled = sceneMesh->backfaceCulled;
+            sceneMesh->setUserData((void*)meshSettings);
+            
+        } else {
+            SceneMeshSettings *meshSettings = (SceneMeshSettings*) entity->getUserData();
+            meshSettings->material = sceneMesh->getMaterial();
+            meshSettings->backfaceCulled = sceneMesh->backfaceCulled;
+        }
+        
+        sceneMesh->setMaterialByName(materialName);
+        sceneMesh->renderWireframe = wireFrame;
+        if(wireFrame) {
+//            sceneMesh->setColor(RANDOM_NUMBER, RANDOM_NUMBER, RANDOM_NUMBER, 1.0);
+            sceneMesh->backfaceCulled = false;
+        }
+    }
+    
+    for(int i=0; i < entity->getNumChildren(); i++) {
+        setMaterialRecursive(materialName, wireFrame, entity->getChildAtIndex(i));
+    }
+
+}
+
 Scene *EntityEditorMainView::getMainScene() {
     return mainScene;
 }
@@ -773,6 +839,13 @@ EntityEditorPropertyContainer::EntityEditorPropertyContainer() : UIElement() {
     addChild(treeView);
     treeView->setPosition(0.0, 30.0);
     treeView->visible = false;
+    treeView->enabled = false;
+    
+    settingsView = new EntityEditorSettingsView();
+    addChild(settingsView);
+    settingsView->setPosition(0.0, 30.0);
+    settingsView->visible = false;
+    settingsView->enabled = false;
 }
 
 void EntityEditorPropertyContainer::handleEvent(Event *event) {
@@ -788,7 +861,7 @@ void EntityEditorPropertyContainer::handleEvent(Event *event) {
                 treeView->refreshTree();
             break;
             case 2:
-                currentView = treeView;
+                currentView = settingsView;
             break;
         }
         currentView->visible = true;
@@ -803,13 +876,14 @@ EntityEditorPropertyContainer::~EntityEditorPropertyContainer() {
 void EntityEditorPropertyContainer::Resize(Number width, Number height) {
     propertyView->Resize(width, height-30);
     treeView->Resize(width, height-30);
+    settingsView->Resize(width, height-30);
 }
 
 
 PolycodeEntityEditor::PolycodeEntityEditor() : PolycodeEditor(true){
 	mainSizer = new UIHSizer(300, 300, 300, false);
 	addChild(mainSizer);
-	
+    
 	mainView = new EntityEditorMainView();
     mainView->addEventListener(this, Event::CHANGE_EVENT);
 	mainSizer->addLeftChild(mainView);
@@ -819,6 +893,7 @@ PolycodeEntityEditor::PolycodeEntityEditor() : PolycodeEditor(true){
     propertyContainer = new EntityEditorPropertyContainer();
     propertyView = propertyContainer->propertyView;
     treeView = propertyContainer->treeView;
+    settingsView = propertyContainer->settingsView;
     
     treeView->addEventListener(this, Event::CHANGE_EVENT);
     
@@ -850,11 +925,13 @@ PolycodeEntityEditor::~PolycodeEntityEditor() {
 bool PolycodeEntityEditor::openFile(OSFileEntry filePath) {	
 	PolycodeEditor::openFile(filePath);
 //    return true;
-    SceneEntityInstance *loadedInstance = new SceneEntityInstance(mainView->getMainScene(), filePath.fullPath);
+    loadedInstance = new SceneEntityInstance(mainView->getMainScene(), filePath.fullPath);
+    
     mainView->setObjectRoot(loadedInstance);
     mainView->setEditorPropsRecursive(loadedInstance);
-    
     treeView->setRootEntity(loadedInstance);
+    propertyView->setEntityInstance(loadedInstance);
+    settingsView->setEntityInstance(loadedInstance);
     
 	return true;
 }
@@ -1185,9 +1262,18 @@ void PolycodeEntityEditor::saveShaderOptionsToEntry(ObjectEntry *entry, Material
 void PolycodeEntityEditor::saveFile() {
     Object saveObject;
     
+    ObjectEntry *settings = saveObject.root.addChild("settings");
+    ObjectEntry *linkedMaterialFiles = settings->addChild("matFiles");
+    for(int i=0; i < loadedInstance->getNumLinkedResourePools(); i++) {
+        ResourcePool *pool = loadedInstance->getLinkedResourcePoolAtIndex(i);
+        linkedMaterialFiles->addChild("matFile")->addChild("path", pool->getName());
+    }    
+    
     saveObject.root.name = "entity";
     ObjectEntry *children = saveObject.root.addChild("root");
     saveEntityToObjectEntry(mainView->getObjectRoot(), children);
+    
+    
     saveObject.saveToXML(filePath);
     setHasChanges(false);
 }

+ 11 - 0
IDE/Contents/Source/PolycodeFrame.cpp

@@ -1552,12 +1552,23 @@ TextInputPopup * PolycodeFrame::showTextInput(String caption, String action, Str
 	return textInputPopup;
 }
 
+void PolycodeFrame::showAssetBrowserForPools(std::vector<ResourcePool*> pools, int resourceType) {
+	if(!projectManager->getActiveProject()) {
+		return;
+	}
+	assetBrowser->setResourcePools(pools, resourceType);
+    assetBrowser->setBrowseMode(AssetBrowser::BROWSE_MODE_RESOURCES);
+	showModal(assetBrowser);
+    
+}
+
 void PolycodeFrame::showAssetBrowser(std::vector<String> extensions) {
 	if(!projectManager->getActiveProject()) {
 		return;
 	}
 	assetBrowser->setProject(projectManager->getActiveProject());
 	assetBrowser->setExtensions(extensions);
+   assetBrowser->setBrowseMode(AssetBrowser::BROWSE_MODE_FILES);
 	showModal(assetBrowser);
 }
 

+ 1 - 1
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -39,7 +39,7 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 
     Entity::defaultBlendingMode = Renderer::BLEND_MODE_NONE;
 	
-	CoreServices::getInstance()->getResourceManager()->reloadResourcesOnModify = true;
+	CoreServices::getInstance()->getResourceManager()->getGlobalPool()->reloadResourcesOnModify = true;
 	
 	runNextFrame = false;
 	

+ 32 - 31
IDE/Contents/Source/PolycodeMaterialEditor.cpp

@@ -28,7 +28,7 @@ extern UIColorPicker *globalColorPicker;
 extern UIGlobalMenu *globalMenu;
 extern PolycodeFrame *globalFrame;
 
-PostEditorPane::PostEditorPane() : UIElement() {
+PostEditorPane::PostEditorPane(ResourcePool *resourcePool) : UIElement() {
 	currentMaterial = NULL;
 	
 	bottomElement = new UIElement();
@@ -58,7 +58,7 @@ PostEditorPane::PostEditorPane() : UIElement() {
 	targetsProps = new RenderTargetsSheet();
 	propList->addPropSheet(targetsProps);
 		
-	passProps = new ShaderPassesSheet();
+	passProps = new ShaderPassesSheet(resourcePool);
 	propList->addPropSheet(passProps);
 	passProps->addEventListener(this, Event::CHANGE_EVENT);
 	passProps->addEventListener(this, Event::REMOVE_EVENT);
@@ -187,7 +187,7 @@ void PostEditorPane::handleEvent(Event *event) {
 
 
 
-CubemapEditorPane::CubemapEditorPane() : UIElement() {
+CubemapEditorPane::CubemapEditorPane(ResourcePool *resourcePool) : UIElement() {
 	currentCubemap = NULL;
 
 	headerBg = new UIRect(10,10);
@@ -241,7 +241,7 @@ CubemapEditorPane::CubemapEditorPane() : UIElement() {
 	baseProps->propHeight = 420;
 	propList->updateProps();
 		
-	Material *previewMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("CubemapPreview", "LightCube");
+	Material *previewMaterial = (Material*) CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "LightCube");
 	cubemapPreview->setMaterial(previewMaterial);
 	enabled = false;
 	
@@ -321,8 +321,9 @@ void CubemapEditorPane::Resize(Number width, Number height) {
 }
 
 
-ShaderEditorPane::ShaderEditorPane() : UIElement() {	
+ShaderEditorPane::ShaderEditorPane(ResourcePool *resourcePool) : UIElement() {
 
+    this->resourcePool = resourcePool;
 	changingShader = false;
 	currentShader = NULL;
 
@@ -437,7 +438,7 @@ void ShaderEditorPane::handleEvent(Event *event) {
 		if(newProgram) {
 			newProgram->setResourceName(entry.name);
 			newProgram->setResourcePath(newProgramPath);
-			CoreServices::getInstance()->getResourceManager()->addResource(newProgram);
+			resourcePool->addResource(newProgram);
 		}
 
 		if(choosingVertexProgram) {
@@ -688,9 +689,7 @@ MaterialPreviewBox::MaterialPreviewBox() : UIElement() {
 	previewBg->Yaw(45.0);
 	previewBg->backfaceCulled = false;
 	
-	Material *bgMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("MaterialEditorBg", "Unlit");
-	
-	previewBg->setMaterial(bgMaterial);
+	previewBg->setMaterialByName("Unlit");
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("materialEditor/material_grid.png");
 	if(previewBg->getLocalShaderOptions()) {
 	previewBg->getLocalShaderOptions()->addTexture("diffuse", tex);
@@ -987,12 +986,12 @@ MaterialEditorPane::~MaterialEditorPane() {
 
 }
 
-MaterialMainWindow::MaterialMainWindow() : UIElement() {
+MaterialMainWindow::MaterialMainWindow(ResourcePool *resourcePool) : UIElement() {
 
 	materialPane = new MaterialEditorPane();
-	shaderPane = new ShaderEditorPane();
-	cubemapPane = new CubemapEditorPane();
-	postPane = new PostEditorPane();
+	shaderPane = new ShaderEditorPane(resourcePool);
+	cubemapPane = new CubemapEditorPane(resourcePool);
+	postPane = new PostEditorPane(resourcePool);
 		
 	addChild(materialPane);
 	addChild(shaderPane);	
@@ -1107,11 +1106,13 @@ void MaterialBrowser::Resize(Number width, Number height) {
 }
 
 PolycodeMaterialEditor::PolycodeMaterialEditor() : PolycodeEditor(true){
+    resourcePool = new ResourcePool("Local",     CoreServices::getInstance()->getResourceManager()->getGlobalPool());
+    CoreServices::getInstance()->getResourceManager()->addResourcePool(resourcePool);
 	selectedMaterialNode = NULL;
 }
 
 PolycodeMaterialEditor::~PolycodeMaterialEditor() {
-	
+	delete resourcePool;
 }
 
 bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
@@ -1126,11 +1127,11 @@ bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
 	materialBrowser->addEventListener(this, Event::CHANGE_EVENT);
 	
 	
-	shaders = CoreServices::getInstance()->getMaterialManager()->loadShadersFromFile(filePath.fullPath);
+	shaders = CoreServices::getInstance()->getMaterialManager()->loadShadersFromFile(resourcePool, filePath.fullPath);
 	for(int i=0; i < shaders.size(); i++) {
 		materialBrowser->addShader(shaders[i]);		
 		CoreServices::getInstance()->getMaterialManager()->addShader(shaders[i]);
-		CoreServices::getInstance()->getResourceManager()->addResource(shaders[i]);		
+		resourcePool->addResource(shaders[i]);
 		shaders[i]->vp->reloadOnFileModify = true;
 		shaders[i]->fp->reloadOnFileModify = true;
 	}	
@@ -1138,11 +1139,11 @@ bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
 	cubemaps = CoreServices::getInstance()->getMaterialManager()->loadCubemapsFromFile(filePath.fullPath);
 	for(int i=0; i < cubemaps.size(); i++) {
 		materialBrowser->addCubemap(cubemaps[i]);
-		CoreServices::getInstance()->getResourceManager()->addResource(cubemaps[i]);
+        resourcePool->addResource(cubemaps[i]);
 	}	
 
 	
-	std::vector<Material*> mats = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(filePath.fullPath);
+	std::vector<Material*> mats = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(resourcePool, filePath.fullPath);
 	
 	materials.clear();
 	for(int i=0; i < mats.size(); i++) {
@@ -1155,14 +1156,14 @@ bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
 	
 	for(int i=0; i < materials.size(); i++) {
 		materialBrowser->addMaterial(materials[i]);
-		CoreServices::getInstance()->getResourceManager()->addResource(materials[i]);
+        resourcePool->addResource(materials[i]);
 	}
 
 	for(int i=0; i < postMaterials.size(); i++) {
 		materialBrowser->addPostMaterial(postMaterials[i]);
 	}
 	
-	mainWindow = new MaterialMainWindow();
+	mainWindow = new MaterialMainWindow(resourcePool);
 	mainSizer->addLeftChild(mainWindow);
 	
 	mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
@@ -1419,7 +1420,7 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 
 	if(event->getDispatcher() == materialBrowser->newPostButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
 	
-		Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("PostEffect"+String::IntToString(postMaterials.size()), "PassThrough");
+		Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial(resourcePool, "PostEffect"+String::IntToString(postMaterials.size()), "PassThrough");
 			newMaterial->screenMaterial = true;
 			materialBrowser->addPostMaterial(newMaterial)->setSelected();
 			postMaterials.push_back(newMaterial);
@@ -1427,15 +1428,15 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 	}	
 
 	if(event->getDispatcher() == materialBrowser->newMaterialButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
-		Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("Untitled", "DefaultShader");
+		Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial(resourcePool, "Untitled", "DefaultShader");
 			materialBrowser->addMaterial(newMaterial)->setSelected();
-			CoreServices::getInstance()->getResourceManager()->addResource(newMaterial);
+			resourcePool->addResource(newMaterial);
 			materials.push_back(newMaterial);
 			setHasChanges(true);			
 	}	
 
 	if(event->getDispatcher() == materialBrowser->newShaderButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
-			Shader *newShader = CoreServices::getInstance()->getMaterialManager()->createShader("glsl", "Untitled", "default/Unlit.vert", "default/Unlit.frag", false);
+			Shader *newShader = CoreServices::getInstance()->getMaterialManager()->createShader(resourcePool, "glsl", "Untitled", "default/Unlit.vert", "default/Unlit.frag", false);
 			if(newShader) {
 				materialBrowser->addShader(newShader);
 				shaders.push_back(newShader);
@@ -1448,17 +1449,17 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 
 	if(event->getDispatcher() == materialBrowser->newCubemapButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {	
 		Cubemap *cubemap = CoreServices::getInstance()->getRenderer()->createCubemap(
-							 (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
-							 (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
-							 (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
-							 (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
-							 (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
-							 (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"));
+							 (Texture*)resourcePool->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
+							 (Texture*)resourcePool->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
+							 (Texture*)resourcePool->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
+							 (Texture*)resourcePool->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
+							 (Texture*)resourcePool->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
+							 (Texture*)resourcePool->getResource(Resource::RESOURCE_TEXTURE, "default.png"));
 		cubemap->setResourceName("Cubemap"+String::IntToString(cubemaps.size()));
 		cubemaps.push_back(cubemap);
 		materialBrowser->addCubemap(cubemap);
 		setHasChanges(true);
-		CoreServices::getInstance()->getResourceManager()->addResource(cubemap);
+		resourcePool->addResource(cubemap);
 	}	
 
 	if(event->getDispatcher() == materialBrowser->removeButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {

+ 2 - 2
IDE/Contents/Source/PolycodeMeshEditor.cpp

@@ -78,8 +78,8 @@ PolycodeMeshEditor::PolycodeMeshEditor() : PolycodeEditor(true){
 	previewBase = new Entity();
 	previewScene->addChild(previewBase);
 
-	CoreServices::getInstance()->getResourceManager()->dispatchChangeEvents = true;	
-	CoreServices::getInstance()->getResourceManager()->addEventListener(this, Event::CHANGE_EVENT);
+	CoreServices::getInstance()->getResourceManager()->getGlobalPool()->dispatchChangeEvents = true;
+	CoreServices::getInstance()->getResourceManager()->getGlobalPool()->addEventListener(this, Event::CHANGE_EVENT);
 	
 	previewMesh = NULL;	
 	trackballCamera = new TrackballCamera(previewScene->getDefaultCamera(), previewShape);

+ 229 - 26
IDE/Contents/Source/PolycodeProps.cpp

@@ -350,6 +350,24 @@ PropProp::~PropProp() {
 
 }
 
+ButtonProp::ButtonProp(const String &caption) : PropProp("", "ButtonProp") {
+    button = new UIButton(caption, 100);
+    addChild(button);
+}
+
+ButtonProp::~ButtonProp() {
+    
+}
+
+UIButton *ButtonProp::getButton() {
+    return button;
+}
+
+void ButtonProp::setPropWidth(Number width) {
+    button->Resize(width-PROP_PADDING, button->getHeight());
+}
+
+
 Vector3Prop::Vector3Prop(String caption) : PropProp(caption, "Vector3") {
     
 	labelX = new UILabel("X:", 11);
@@ -519,6 +537,35 @@ Vector2Prop::~Vector2Prop() {
 
 }
 
+RemovableStringProp::RemovableStringProp(const String &caption) : PropProp("", "RemovableStringProp") {
+    
+    label = new UILabel(caption, 12);
+    addChild(label);
+    label->setPositionX(30);
+    
+   	removeButton = new UIImageButton("main/remove_icon.png", 1.0, 12, 12);
+	removeButton->addEventListener(this, UIEvent::CLICK_EVENT);
+    addChild(removeButton);
+	removeButton->setPosition(0, 2);
+
+	setHeight(25);
+}
+
+String RemovableStringProp::getCaption() {
+    return label->getText();
+}
+
+RemovableStringProp::~RemovableStringProp() {
+    
+}
+
+void RemovableStringProp::handleEvent(Event *event) {
+    if(event->getDispatcher() == removeButton) {
+        dispatchEvent(new Event(), Event::REMOVE_EVENT);
+    }
+}
+
+
 CustomProp::CustomProp(String key, String value) : PropProp("", "Custom") {
 	keyEntry = new UITextInput(false, 120, 12);
 	keyEntry->setText(key);
@@ -1013,6 +1060,84 @@ void BezierCurveProp::handleEvent(Event *event) {
 	}
 }
 
+MaterialProp::MaterialProp(const String &caption) : PropProp(caption, "Material"){
+    currentMaterial = NULL;
+    
+	previewShape = new UIRect(48, 48);
+	previewShape->setAnchorPoint(-1.0, -1.0, 0.0);
+	previewShape->setPosition(2, 1);
+	propContents->addChild(previewShape);
+    
+	changeButton = new UIButton("Change", 80);
+	propContents->addChild(changeButton);
+	changeButton->setPosition(60, 5);
+	changeButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	
+	materialLabel = new UILabel("", 12, "sans");
+	propContents->addChild(materialLabel);
+	materialLabel->setPosition(-100, 32);
+	materialLabel->color.a = 1.0;
+    
+	setHeight(60);
+}
+
+void MaterialProp::setEntityInstance(SceneEntityInstance *instance) {
+    entityInstance = instance;
+}
+
+MaterialProp::~MaterialProp() {
+    
+}
+
+
+void MaterialProp::handleEvent(Event *event) {
+    
+	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
+        
+            Resource *selectedResource = globalFrame->assetBrowser->getSelectedResource();
+            if(selectedResource) {
+                Material *material = (Material*) selectedResource;
+                set(material);
+                dispatchEvent(new Event(), Event::CHANGE_EVENT);
+                globalFrame->assetBrowser->removeAllHandlersForListener(this);
+            }
+
+        /*
+		dispatchEvent(new PropEvent(this, NULL, PropDataString(lastData), PropDataString(currentData)), PropEvent::EVENT_PROP_CHANGE);
+         */
+		globalFrame->hideModal();
+		
+	}
+    
+	if(event->getDispatcher() == changeButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
+		globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
+		
+		std::vector<ResourcePool*> pools;
+        pools.push_back(CoreServices::getInstance()->getResourceManager()->getGlobalPool());
+        for(int i=0; i < entityInstance->getNumLinkedResourePools(); i++) {
+            pools.push_back(entityInstance->getLinkedResourcePoolAtIndex(i));
+        }
+		globalFrame->showAssetBrowserForPools(pools, Resource::RESOURCE_MATERIAL);
+	}
+}
+
+void MaterialProp::set(Material *material) {
+    currentMaterial = material;
+    if(material) {
+        materialLabel->setText(material->getName());
+    }
+}
+
+Material *MaterialProp::get() {
+    return currentMaterial;
+}
+
+void MaterialProp::setPropWidth(Number width) {
+	changeButton->setPosition(width-changeButton->getWidth()-PROP_PADDING-100, 5);
+	previewShape->setPosition(changeButton->getPosition().x-48-10, 1);
+}
+
+
 TextureProp::TextureProp(String caption) : PropProp(caption, "Texture"){
 	previewShape = new UIRect(48, 48);
 	previewShape->setAnchorPoint(-1.0, -1.0, 0.0);
@@ -1520,7 +1645,8 @@ void RenderTargetProp::handleEvent(Event *event) {
 	PropProp::handleEvent(event);
 }
 
-ShaderPassesSheet::ShaderPassesSheet() : PropSheet("SHADER PASSES", "shaderPasses") {
+ShaderPassesSheet::ShaderPassesSheet(ResourcePool *resourcePool) : PropSheet("SHADER PASSES", "shaderPasses") {
+    this->resourcePool = resourcePool;
 	propHeight = 70;
 	addButton = new UIButton("Add Shader Pass", 150);
 	addButton->addEventListener(this, UIEvent::CLICK_EVENT);
@@ -1587,7 +1713,7 @@ void ShaderPassesSheet::handleEvent(Event *event) {
 
 	if(event->getDispatcher() == addButton) {
 	
-		Shader *defaultShader = (Shader*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_SHADER, "PassThrough");
+		Shader *defaultShader = (Shader*)resourcePool->getResource(Resource::RESOURCE_SHADER, "PassThrough");
 		if(defaultShader) {	
 			ShaderBinding *newShaderBinding = defaultShader->createBinding();		
 			material->addShader(defaultShader, newShaderBinding);
@@ -2733,10 +2859,10 @@ void ScenePrimitiveSheet::handleEvent(Event *event) {
 }
 
 MaterialPropSheet::MaterialPropSheet() : PropSheet("MATERIAL", "material") {
-    materialProp = new ComboProp("Material");
+    
+    materialProp = new MaterialProp("Material");
     addProp(materialProp);
     
-    propHeight = 70;
     enabled = false;
 }
 
@@ -2749,32 +2875,14 @@ void MaterialPropSheet::setSceneMesh(SceneMesh *sceneMesh) {
     
     if(sceneMesh) {
         enabled = true;
-        reloadMaterials();        
+        materialProp->set(sceneMesh->getMaterial());
     } else {
         enabled = false;
     }
 }
 
-void MaterialPropSheet::reloadMaterials() {
-
-	Resource *selectedMaterial = NULL;
-    
-    selectedMaterial = NULL;
-    if(sceneMesh) {
-        selectedMaterial = (Resource*)sceneMesh->getMaterial();
-    }
-		
-	materialProp->comboEntry->clearItems();
-	std::vector<Resource*> materials = CoreServices::getInstance()->getResourceManager()->getResources(Resource::RESOURCE_MATERIAL);
-	for(int i=0; i < materials.size(); i++) {
-        if(((Material*)materials[i])->screenMaterial) {
-            continue;
-        }
-		materialProp->comboEntry->addComboItem(materials[i]->getResourceName(), (void*) materials[i]);
-		if(selectedMaterial == materials[i]) {
-			materialProp->comboEntry->setSelectedIndex(i);
-		}
-	}
+void MaterialPropSheet::setEntityInstance(SceneEntityInstance *instance) {
+    materialProp->setEntityInstance(instance);
 }
 
 void MaterialPropSheet::handleEvent(Event *event) {
@@ -2784,7 +2892,7 @@ void MaterialPropSheet::handleEvent(Event *event) {
     }
         
     if(event->getDispatcher() == materialProp  && event->getEventCode() == Event::CHANGE_EVENT) {
-        Material *newMaterial = (Material*)materialProp->comboEntry->getSelectedItem()->data;
+        Material *newMaterial = materialProp->get();
         if(sceneMesh->getMaterial() != newMaterial) {
             sceneMesh->setMaterial(newMaterial);
         }
@@ -3263,6 +3371,101 @@ void SceneLabelSheet::handleEvent(Event *event) {
 	PropSheet::handleEvent(event);
 }
 
+LinkedMaterialsSheet::LinkedMaterialsSheet() : PropSheet("LINKED MATERIALS", "linked_materials") {
+    
+    addMaterialProp = new ButtonProp("Link materials file");
+    addProp(addMaterialProp);
+    addMaterialProp->getButton()->addEventListener(this, UIEvent::CLICK_EVENT);
+    
+    propToRemove = NULL;
+}
+
+LinkedMaterialsSheet::~LinkedMaterialsSheet() {
+    
+}
+
+void LinkedMaterialsSheet::Update() {
+    if(propToRemove) {
+        if(instance) {
+//            instance->removeLinkedMaterialFile(propToRemove->getCaption());
+            updateMaterials();
+        }
+        propToRemove = NULL;
+    }
+}
+
+void LinkedMaterialsSheet::handleEvent(Event *event) {
+    
+    if(!instance) {
+        return;
+    }
+    
+    for(int i=0; i < props.size(); i++) {
+        if(props[i] == event->getDispatcher()) {
+            propToRemove = (RemovableStringProp*) props[i];
+        }
+    }
+    
+    if(event->getDispatcher() == addMaterialProp->getButton()) {
+		globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
+		std::vector<String> extensions;
+		extensions.push_back("mat");
+		globalFrame->showAssetBrowser(extensions);
+        
+    } else if(event->getDispatcher() == globalFrame->assetBrowser) {
+		String materialPath = globalFrame->assetBrowser->getSelectedAssetPath();
+
+		String fullMaterialPath = globalFrame->assetBrowser->getFullSelectedAssetPath();
+		
+        
+        globalFrame->assetBrowser->removeAllHandlersForListener(this);
+        globalFrame->hideModal();
+        
+        ResourcePool *newPool = new ResourcePool(materialPath,  CoreServices::getInstance()->getResourceManager()->getGlobalPool());
+        CoreServices::getInstance()->getMaterialManager()->loadMaterialLibraryIntoPool(newPool, fullMaterialPath);
+        
+        instance->linkResourcePool(newPool);
+         updateMaterials();
+    }
+    PropSheet::handleEvent(event);
+}
+
+void LinkedMaterialsSheet::updateMaterials() {
+    if(!instance) {
+        return;
+    }
+    
+	for(int i=0; i < props.size(); i++) {
+		contents->removeChild(props[i]);
+		props[i]->removeAllHandlersForListener(this);
+        if(props[i] != addMaterialProp) {
+            delete props[i];
+        }
+	}
+	props.clear();
+    
+    for(int i=0; i < instance->getNumLinkedResourePools(); i++) {
+        ResourcePool *pool = instance->getLinkedResourcePoolAtIndex(i);
+        RemovableStringProp *newProp = new RemovableStringProp(pool->getName());
+        newProp->addEventListener(this, Event::REMOVE_EVENT);
+        addProp(newProp);
+    }
+    
+    addProp(addMaterialProp);
+}
+
+
+void LinkedMaterialsSheet::setEntityInstance(SceneEntityInstance *instance) {
+    this->instance = instance;
+    if(instance) {
+        enabled = true;
+        updateMaterials();
+    } else {
+        enabled = false;
+    }
+}
+
+
 SoundSheet::SoundSheet() : PropSheet("SOUND", "sound") {
 	sound = NULL;
     enabled = false;

+ 97 - 8
IDE/Contents/Source/TextureBrowser.cpp

@@ -22,8 +22,9 @@
  
 #include "TextureBrowser.h"
 
-AssetEntry::AssetEntry(String assetPath, String assetName, String extension) : UIElement() {
+AssetEntry::AssetEntry(String assetPath, String assetName, String extension, Resource *resource) : UIElement() {
 
+    this->resource = resource;
 	this->assetPath = assetPath;
 
 	if(assetName.length() > 20)
@@ -58,6 +59,10 @@ AssetEntry::AssetEntry(String assetPath, String assetName, String extension) : U
 		imageShape->loadTexture("browserIcons/shader_icon.png");
 	} else if(extension == "mesh") {
 		imageShape->loadTexture("browserIcons/mesh_icon.png");
+    } else if(extension == "mat") {
+		imageShape->loadTexture("browserIcons/materials_icon.png");
+    } else if(extension == "material_resource") {
+		imageShape->loadTexture("browserIcons/material_resource_icon.png");
 	}
 
 	
@@ -93,6 +98,10 @@ AssetList::~AssetList() {
 
 }
 
+Resource *AssetList::getSelectedResource() {
+    return selectedResource;
+}
+
 void AssetList::setExtensions(std::vector<String> extensions) {
 	this->extensions = extensions;
 	if(currentFolderPath != "") {
@@ -109,6 +118,50 @@ bool AssetList::hasExtension(String extension) {
 	return false;
 }
 
+void AssetList::showResourcePool(ResourcePool *pool, int resourceFilter) {
+	for(int i=0; i < assetEntries.size(); i++) {
+		removeChild(assetEntries[i]);
+		delete assetEntries[i];
+	}
+	assetEntries.clear();
+
+    selectedResource = NULL;
+    
+	currentEntry = NULL;
+	
+	Number xPos = 20;
+	Number yPos = 30;
+	
+    std::vector<Resource*> resources = pool->getResources(resourceFilter);
+    
+    String extension;
+    
+    if(resourceFilter == Resource::RESOURCE_MATERIAL ) {
+        extension = "material_resource";
+    }
+    
+	for(int i=0; i < resources.size(); i++) {
+        AssetEntry *newEntry = new AssetEntry("", resources[i]->getResourceName(), extension, resources[i]);
+        newEntry->selectShape->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
+        assetEntries.push_back(newEntry);
+        newEntry->setPosition(xPos, yPos);
+        xPos += 120;
+        if(xPos > 500) {
+            xPos = 20;
+            yPos += 100;
+        }
+        addChild(newEntry);
+	}
+	
+	setWidth(640);
+	
+	if(xPos == 20) {
+		setHeight(yPos+20);
+	} else {
+		setHeight(yPos + 120);
+	}
+}
+
 void AssetList::showFolder(String folderPath) {
 
 	currentFolderPath = folderPath;
@@ -130,7 +183,7 @@ void AssetList::showFolder(String folderPath) {
 		OSFileEntry entry = assets[i];
 		if(entry.type != OSFileEntry::TYPE_FOLDER) {
 			if(hasExtension(entry.extension)) {
-				AssetEntry *newEntry = new AssetEntry(entry.fullPath, entry.name, entry.extension);
+				AssetEntry *newEntry = new AssetEntry(entry.fullPath, entry.name, entry.extension, NULL);
 				newEntry->selectShape->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 				assetEntries.push_back(newEntry);
 				newEntry->setPosition(xPos, yPos);
@@ -169,6 +222,7 @@ void AssetList::handleEvent(Event *event) {
 					currentEntry->selectShape->visible = false;
 				}
 				currentEntry = assetEntries[i];
+                selectedResource = assetEntries[i]->resource;
 			}
 		}
 	}
@@ -176,6 +230,8 @@ void AssetList::handleEvent(Event *event) {
 
 AssetBrowser::AssetBrowser() : UIWindow(L"Asset Browser", 850, 500) {
 	defaultTemplateTree = NULL;
+    
+    browseMode = BROWSE_MODE_FILES;
 	
 	Config *conf = CoreServices::getInstance()->getConfig();	
 	String fontName = conf->getStringValue("Polycode", "uiDefaultFontName");
@@ -216,18 +272,38 @@ AssetBrowser::AssetBrowser() : UIWindow(L"Asset Browser", 850, 500) {
 	currentProject = NULL;
 }
 
+void AssetBrowser::setResourcePools(std::vector<ResourcePool*> pools, int resourceFilter) {
+    
+    this->resourceFilter = resourceFilter;
+    
+	templateContainer->getRootNode()->clearTree();
+	templateContainer->getRootNode()->setLabelText("Resource pools");
+	templateContainer->getRootNode()->setUserData(NULL);
+    
+    
+    for(int i=0; i < pools.size(); i++) {
+        ResourcePool *pool = pools[i];
+        UITree *newChild = templateContainer->getRootNode()->addTreeChild("folder.png", pool->getName(), (void*)pool);
+        newChild->setUserData(pool);
+    }
+    
+}
+
+void AssetBrowser::setBrowseMode(unsigned int newBrowseMode) {
+    browseMode = newBrowseMode;
+}
+
 void AssetBrowser::setProject(PolycodeProject *project) {
 	
 	templateContainer->getRootNode()->clearTree();
 
-	vector<OSFileEntry> templates = OSBasics::parseFolder(project->getRootFolder(), false);	
+	vector<OSFileEntry> templates = OSBasics::parseFolder(project->getRootFolder(), false);
 	templateContainer->getRootNode()->setLabelText(project->getProjectName());
-	
-	
+		
 	for(int i=0; i < templates.size(); i++) {
 		OSFileEntry entry = templates[i];
 		if(entry.type == OSFileEntry::TYPE_FOLDER) {
-			UITree *newChild = templateContainer->getRootNode()->addTreeChild("folder.png", entry.name, NULL);			
+			UITree *newChild = templateContainer->getRootNode()->addTreeChild("folder.png", entry.name, NULL);
 			FolderUserData *data = new FolderUserData();
 			data->type = 0;
 			data->folderPath = entry.fullPath;
@@ -264,6 +340,11 @@ void AssetBrowser::setExtensions(std::vector<String> extensions) {
 	assetList->setExtensions(extensions);
 }
 
+Resource *AssetBrowser::getSelectedResource() {
+	return assetList->getSelectedResource();
+    
+}
+
 void AssetBrowser::handleEvent(Event *event) {
 	if(event->getEventType() == "UIEvent") {
 		if(event->getEventCode() == UIEvent::CLICK_EVENT) {
@@ -280,8 +361,16 @@ void AssetBrowser::handleEvent(Event *event) {
 	if(event->getEventType() == "UITreeEvent" && event->getEventCode() == UITreeEvent::SELECTED_EVENT) {
 		if(event->getDispatcher() == templateContainer->getRootNode()) {
 			UITreeEvent *treeEvent = (UITreeEvent*) event;
-			FolderUserData *data = (FolderUserData *)treeEvent->selection->getUserData();
-			assetList->showFolder(data->folderPath);
+            
+            if(browseMode == BROWSE_MODE_FILES) {
+                FolderUserData *data = (FolderUserData *)treeEvent->selection->getUserData();
+                assetList->showFolder(data->folderPath);
+            } else {
+                ResourcePool *pool = (ResourcePool*) treeEvent->selection->getUserData();
+                if(pool) {
+                    assetList->showResourcePool(pool, resourceFilter);
+                }
+            }
 			listContainer->setContentSize(assetList->getWidth(), assetList->getHeight());
 			listContainer->setScrollValue(0,0);
 		}

Some files were not shown because too many files changed in this diff