Просмотр исходного кода

Implemented Clone/applyClone for all Scene entities;2C, implemented Copy/Paste in the Entity editor, fixed some redundant shader parameter code

Ivan Safrin 12 лет назад
Родитель
Сommit
bfd0de6096
34 измененных файлов с 620 добавлено и 214 удалено
  1. 4 0
      Core/Contents/Include/PolyCamera.h
  2. 1 1
      Core/Contents/Include/PolyEntity.h
  3. 1 30
      Core/Contents/Include/PolyGLSLShader.h
  4. 3 0
      Core/Contents/Include/PolyLabel.h
  5. 6 1
      Core/Contents/Include/PolyMesh.h
  6. 7 0
      Core/Contents/Include/PolyParticleEmitter.h
  7. 5 1
      Core/Contents/Include/PolySceneLabel.h
  8. 7 8
      Core/Contents/Include/PolySceneLight.h
  9. 5 6
      Core/Contents/Include/PolySceneMesh.h
  10. 3 0
      Core/Contents/Include/PolyScenePrimitive.h
  11. 6 0
      Core/Contents/Include/PolySceneSound.h
  12. 1 0
      Core/Contents/Include/PolySceneSprite.h
  13. 44 23
      Core/Contents/Include/PolyShader.h
  14. 23 1
      Core/Contents/Source/PolyCamera.cpp
  15. 7 4
      Core/Contents/Source/PolyEntity.cpp
  16. 0 62
      Core/Contents/Source/PolyGLSLShader.cpp
  17. 2 2
      Core/Contents/Source/PolyGLSLShaderModule.cpp
  18. 8 0
      Core/Contents/Source/PolyLabel.cpp
  19. 27 0
      Core/Contents/Source/PolyMesh.cpp
  20. 49 1
      Core/Contents/Source/PolyParticleEmitter.cpp
  21. 1 1
      Core/Contents/Source/PolyRenderer.cpp
  22. 6 10
      Core/Contents/Source/PolySceneEntityInstance.cpp
  23. 1 1
      Core/Contents/Source/PolySceneImage.cpp
  24. 24 1
      Core/Contents/Source/PolySceneLabel.cpp
  25. 32 6
      Core/Contents/Source/PolySceneLight.cpp
  26. 39 8
      Core/Contents/Source/PolySceneMesh.cpp
  27. 11 0
      Core/Contents/Source/PolyScenePrimitive.cpp
  28. 22 0
      Core/Contents/Source/PolySceneSound.cpp
  29. 34 17
      Core/Contents/Source/PolySceneSprite.cpp
  30. 141 9
      Core/Contents/Source/PolyShader.cpp
  31. 14 0
      IDE/Contents/Include/PolycodeEntityEditor.h
  32. 1 0
      IDE/Contents/Include/PolycodeProps.h
  33. 79 20
      IDE/Contents/Source/PolycodeEntityEditor.cpp
  34. 6 1
      IDE/Contents/Source/PolycodeProps.cpp

+ 4 - 0
Core/Contents/Include/PolyCamera.h

@@ -112,6 +112,7 @@ namespace Polycode {
             Number getFarClipppingPlane();
             Number getFarClipppingPlane();
         
         
 			void setParentScene(Scene *parentScene);
 			void setParentScene(Scene *parentScene);
+            Scene *getParentScene() const;
 			
 			
 			void doCameraTransform();
 			void doCameraTransform();
 			void setLightDepthTexture(Texture *texture);			
 			void setLightDepthTexture(Texture *texture);			
@@ -158,6 +159,9 @@ namespace Polycode {
 			*/			
 			*/			
 			Material *getScreenShaderMaterial() { return filterShaderMaterial; }	
 			Material *getScreenShaderMaterial() { return filterShaderMaterial; }	
 			
 			
+        
+            virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
 			
 			
 			Matrix4 getProjectionMatrix();
 			Matrix4 getProjectionMatrix();
 			
 			

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

@@ -102,7 +102,7 @@ namespace Polycode {
 			virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
 			virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
 
 
 			/**
 			/**
- 			* This method must be implemented by all subvlasses implementing Clone.
+ 			* This method must be implemented by all subclasses implementing Clone.
  			*/
  			*/
 			virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
 			virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
 		
 		

+ 1 - 30
Core/Contents/Include/PolyGLSLShader.h

@@ -31,17 +31,6 @@ namespace Polycode {
 
 
 	class GLSLProgram;
 	class GLSLProgram;
 
 
-	typedef struct {
-		Texture *texture;
-		String name;
-	} GLSLTextureBinding;
-
-	typedef struct {
-		Cubemap *cubemap;
-		String name;
-	} GLSLCubemapBinding;
-	
-	
 	class _PolyExport GLSLShader : public Shader {
 	class _PolyExport GLSLShader : public Shader {
 		public:
 		public:
 			GLSLShader(GLSLProgram *vp, GLSLProgram *fp);
 			GLSLShader(GLSLProgram *vp, GLSLProgram *fp);
@@ -61,23 +50,5 @@ namespace Polycode {
 			
 			
 			void linkProgram();			
 			void linkProgram();			
 			void unlinkProgram();
 			void unlinkProgram();
-	};
-	
-	class _PolyExport GLSLShaderBinding : public ShaderBinding {
-		public:
-			GLSLShaderBinding(GLSLShader *shader);
-			virtual ~GLSLShaderBinding();
-			
-			void clearCubemap(const String& name);
-			void addTexture(const String& name, Texture *texture);
-			void addCubemap(const String& name, Cubemap *cubemap);
-			void clearTexture(const String& name);
-			Texture *getTexture(const String& name);
-			Cubemap *getCubemap(const String& name);
-			
-			std::vector<GLSLTextureBinding> textures;
-			std::vector<GLSLCubemapBinding> cubemaps;
-		
-			GLSLShader *glslShader;
-	};
+	};	
 }
 }

+ 3 - 0
Core/Contents/Include/PolyLabel.h

@@ -81,6 +81,9 @@ namespace Polycode {
 			void setColorForRange(Color color, unsigned int rangeStart, unsigned int rangeEnd);
 			void setColorForRange(Color color, unsigned int rangeStart, unsigned int rangeEnd);
 		
 		
 			Color getColorForIndex(unsigned int index);
 			Color getColorForIndex(unsigned int index);
+        
+            bool getPremultiplyAlpha() const;
+            void setPremultiplyAlpha(bool val);
 		
 		
 			void setFont(Font *newFont);
 			void setFont(Font *newFont);
 			Font *getFont() const;
 			Font *getFont() const;

+ 6 - 1
Core/Contents/Include/PolyMesh.h

@@ -266,7 +266,10 @@ namespace Polycode {
 			* Returns the vertex buffer for the mesh.
 			* Returns the vertex buffer for the mesh.
 			* @return The vertex buffer for this mesh.
 			* @return The vertex buffer for this mesh.
 			*/
 			*/
-			VertexBuffer *getVertexBuffer();		
+			VertexBuffer *getVertexBuffer();
+        
+        
+            Mesh *Copy() const;
 			
 			
 			/**
 			/**
 			* Returns the radius of the mesh (furthest vertex away from origin).
 			* Returns the radius of the mesh (furthest vertex away from origin).
@@ -375,6 +378,8 @@ namespace Polycode {
         
         
             Vector3 getFaceNormalForVertex(unsigned int index);
             Vector3 getFaceNormalForVertex(unsigned int index);
         
         
+            void addFaceNormal(Vector3 faceNormal);
+        
 		protected:
 		protected:
         
         
             Vector3 calculateFaceTangent(Vertex *v1, Vertex *v2, Vertex *v3);
             Vector3 calculateFaceTangent(Vertex *v1, Vertex *v2, Vertex *v3);

+ 7 - 0
Core/Contents/Include/PolyParticleEmitter.h

@@ -77,6 +77,9 @@ namespace Polycode {
             void setPerlinEnabled(bool val);
             void setPerlinEnabled(bool val);
             bool getPerlinEnabled() const;
             bool getPerlinEnabled() const;
         
         
+            Number getParticleSpeed() const;
+            void setParticleSpeed(Number speed);
+        
             void setPerlinValue(const Vector3 &perlinValue);
             void setPerlinValue(const Vector3 &perlinValue);
             Vector3 getPerlinValue() const;
             Vector3 getPerlinValue() const;
         
         
@@ -125,6 +128,10 @@ namespace Polycode {
              */
              */
             BezierCurve colorCurveA;
             BezierCurve colorCurveA;
         
         
+        
+            virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
+        
         protected:
         protected:
         
         
             void resetParticle(unsigned int index);
             void resetParticle(unsigned int index);

+ 5 - 1
Core/Contents/Include/PolySceneLabel.h

@@ -57,7 +57,12 @@ namespace Polycode {
 			* @param newText New text to display.
 			* @param newText New text to display.
 			*/ 
 			*/ 
 			void setText(const String& newText);
 			void setText(const String& newText);
+        
+            virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
 			
 			
+			void updateFromLabel();
+        
 			Label *getLabel();
 			Label *getLabel();
 			
 			
 			bool positionAtBaseline;
 			bool positionAtBaseline;
@@ -69,7 +74,6 @@ namespace Polycode {
 						
 						
 		protected:
 		protected:
 			
 			
-			void updateFromLabel();        
 			     
 			     
 			Number actualHeight;
 			Number actualHeight;
             Number labelScale;
             Number labelScale;

+ 7 - 8
Core/Contents/Include/PolySceneLight.h

@@ -179,17 +179,18 @@ namespace Polycode {
 			* Returns the light type.
 			* Returns the light type.
 			*/
 			*/
 			int getLightType() const { return type; }
 			int getLightType() const { return type; }
-		
-			/**
-			* If set to true, draws a wireframe primitive visualizing the light.
-			*/
-			void enableDebugDraw(bool val);
 			
 			
 			void setLightImportance(int newImportance);
 			void setLightImportance(int newImportance);
 			int getLightImportance() const;
 			int getLightImportance() const;
         
         
             void setLightType(int lightType);
             void setLightType(int lightType);
-			
+		
+            virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
+        
+            Scene *getParentScene() const;
+            void setParentScene(Scene *scene);
+        
 		protected:
 		protected:
 		
 		
 			Number spotlightExponent;
 			Number spotlightExponent;
@@ -214,8 +215,6 @@ namespace Polycode {
 			unsigned int shadowMapRes;
 			unsigned int shadowMapRes;
 			Number shadowMapFOV;	
 			Number shadowMapFOV;	
 			bool shadowsEnabled;
 			bool shadowsEnabled;
-        
-            bool debugDraw;
 		
 		
 			Number distance;
 			Number distance;
 			Mesh *lightMesh;
 			Mesh *lightMesh;

+ 5 - 6
Core/Contents/Include/PolySceneMesh.h

@@ -150,14 +150,11 @@ namespace Polycode {
 			* If this is set to true, the mesh will be cached to a hardware vertex buffer if those are available. This can dramatically speed up rendering.
 			* If this is set to true, the mesh will be cached to a hardware vertex buffer if those are available. This can dramatically speed up rendering.
 			*/
 			*/
 			void cacheToVertexBuffer(bool cache);
 			void cacheToVertexBuffer(bool cache);
-	
-			unsigned int lightmapIndex;
-			
-			bool showVertexNormals;
-	
+				
 			void setLineWidth(Number newWidth);
 			void setLineWidth(Number newWidth);
 
 
             String getFilename();
             String getFilename();
+            void setFilename(String fileName);
         
         
             void loadFromFile(String fileName);
             void loadFromFile(String fileName);
         
         
@@ -185,7 +182,9 @@ namespace Polycode {
 			bool customHitDetection(const Ray &ray);
 			bool customHitDetection(const Ray &ray);
         
         
             bool forceMaterial;
             bool forceMaterial;
-
+        
+            virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
 			
 			
 		protected:
 		protected:
 		
 		

+ 3 - 0
Core/Contents/Include/PolyScenePrimitive.h

@@ -136,6 +136,9 @@ namespace Polycode {
             Number getPrimitiveParameter3() const;
             Number getPrimitiveParameter3() const;
             Number getPrimitiveParameter4() const;
             Number getPrimitiveParameter4() const;
             Number getPrimitiveParameter5() const;
             Number getPrimitiveParameter5() const;
+        
+            virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
 		
 		
 		protected:
 		protected:
 
 

+ 6 - 0
Core/Contents/Include/PolySceneSound.h

@@ -47,7 +47,13 @@ namespace Polycode {
 			SceneSound(const String& fileName, Number referenceDistance, Number maxDistance, bool directionalSound = false);
 			SceneSound(const String& fileName, Number referenceDistance, Number maxDistance, bool directionalSound = false);
 			virtual ~SceneSound();			
 			virtual ~SceneSound();			
 			void Update();
 			void Update();
+        
+            virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
 			
 			
+            bool isDirectionalSound() const;
+            void setDirectionalSound(bool val);
+        
 			/**
 			/**
 			* Returns the sound object associated with this positional sound.
 			* Returns the sound object associated with this positional sound.
 			*/
 			*/

+ 1 - 0
Core/Contents/Include/PolySceneSprite.h

@@ -109,6 +109,7 @@ class _PolyExport SceneSprite : public ScenePrimitive
 		Vector2 getSpriteSize();
 		Vector2 getSpriteSize();
 	
 	
 		String getFileName() const;
 		String getFileName() const;
+        void setSpriteFilename(String fileName);
 	
 	
 		void recalculateSpriteDimensions();
 		void recalculateSpriteDimensions();
     
     

+ 44 - 23
Core/Contents/Include/PolyShader.h

@@ -26,6 +26,7 @@ THE SOFTWARE.
 #include "PolyColor.h"
 #include "PolyColor.h"
 #include "PolyVector2.h"
 #include "PolyVector2.h"
 #include "PolyVector3.h"
 #include "PolyVector3.h"
+#include "PolyMatrix4.h"
 #include "PolyResource.h"
 #include "PolyResource.h"
 #include <string.h>
 #include <string.h>
 
 
@@ -49,7 +50,17 @@ namespace Polycode {
 	static const int PARAM_VECTOR3 = 3;
 	static const int PARAM_VECTOR3 = 3;
 	static const int PARAM_COLOR = 4;
 	static const int PARAM_COLOR = 4;
 	static const int PARAM_MATRIX = 5;
 	static const int PARAM_MATRIX = 5;
-	};	
+	};
+	
+	typedef struct {
+		Texture *texture;
+		String name;
+	} TextureBinding;
+    
+	typedef struct {
+		Cubemap *cubemap;
+		String name;
+	} CubemapBinding;
 
 
 	class _PolyExport ShaderProgram : public Resource {
 	class _PolyExport ShaderProgram : public Resource {
 		public:
 		public:
@@ -76,7 +87,7 @@ namespace Polycode {
 			void setName(const String& name);
 			void setName(const String& name);
 			const String& getName() const;
 			const String& getName() const;
 			
 			
-			virtual ShaderBinding *createBinding() = 0;
+			ShaderBinding *createBinding();
 			virtual void reload() {}								
 			virtual void reload() {}								
 			
 			
 			int getExpectedParamType(String name);
 			int getExpectedParamType(String name);
@@ -127,21 +138,27 @@ namespace Polycode {
 		public:
 		public:
         
         
             LocalShaderParam();
             LocalShaderParam();
+            ~LocalShaderParam();
+            LocalShaderParam *Copy();
         
         
 			String name;
 			String name;
 			void *data;
 			void *data;
+			int type;
+            bool ownsPointer;
 		
 		
-		// Convenience getters/setters for Lua users
-		Number getNumber()         { return *((Number *)data); }
-		Vector2 getVector2()       { return *((Vector2 *)data); }
-		Vector3 getVector3()       { return *((Vector3 *)data); }
-		Color getColor()           { return *((Color *)data); }
-		void setNumber(Number x)   { memcpy(data, &x, sizeof(x)); }
-		void setVector2(Vector2 x) { memcpy(data, &x, sizeof(x)); }
-		void setVector3(Vector3 x) { memcpy(data, &x, sizeof(x)); }
-		void setColor(Color x)     { static_cast<Color*>(data)->setColor(&x); }
-        
-        void setParamValueFromString(int type, String pvalue);
+            // Convenience getters/setters for Lua users
+            Number getNumber()         { return *((Number *)data); }
+            Vector2 getVector2()       { return *((Vector2 *)data); }
+            Vector3 getVector3()       { return *((Vector3 *)data); }
+            Matrix4 getMatrix4()       { return *((Matrix4 *)data); }
+            Color getColor()           { return *((Color *)data); }
+            void setNumber(Number x)   { memcpy(data, &x, sizeof(x)); }
+            void setVector2(Vector2 x) { memcpy(data, &x, sizeof(x)); }
+            void setVector3(Vector3 x) { memcpy(data, &x, sizeof(x)); }
+            void setMatrix4(Matrix4 x) { memcpy(data, &x, sizeof(x)); }
+            void setColor(Color x)     { static_cast<Color*>(data)->setColor(&x); }
+            
+            void setParamValueFromString(int type, String pvalue);
 	};	
 	};	
 	
 	
 	class RenderTargetBinding : public PolyBase {
 	class RenderTargetBinding : public PolyBase {
@@ -160,15 +177,18 @@ namespace Polycode {
 		public:
 		public:
 			ShaderBinding(Shader *shader);
 			ShaderBinding(Shader *shader);
 			virtual ~ShaderBinding();
 			virtual ~ShaderBinding();
-
-			virtual Texture *getTexture(const String& name){ return NULL;};
-			virtual Cubemap *getCubemap(const String& name){ return NULL;};			
-			virtual void clearTexture(const String& name){};
-			virtual void clearCubemap(const String& name){};
-			virtual void addTexture(const String& name, Texture *texture)  {};
+        
+            void copyTo(ShaderBinding *targetBinding);
+
+            Texture *getTexture(const String& name);
+            Cubemap *getCubemap(const String& name);
+			void clearTexture(const String& name);
+			void clearCubemap(const String& name);
+            void addTexture(const String& name, Texture *texture);
+            void addCubemap(const String& name, Cubemap *cubemap);
+        
 			LocalShaderParam *addParam(int type, const String& name);
 			LocalShaderParam *addParam(int type, const String& name);
-			virtual void addCubemap(const String& name, Cubemap *cubemap) {};
-		
+			LocalShaderParam *addParamPointer(int type, const String& name, void *ptr);        
 			unsigned int getNumLocalParams();
 			unsigned int getNumLocalParams();
 			LocalShaderParam *getLocalParam(unsigned int index);
 			LocalShaderParam *getLocalParam(unsigned int index);
 			LocalShaderParam *getLocalParamByName(const String& name);
 			LocalShaderParam *getLocalParamByName(const String& name);
@@ -190,8 +210,9 @@ namespace Polycode {
 
 
 			unsigned int getNumOutTargetBindings();
 			unsigned int getNumOutTargetBindings();
 			RenderTargetBinding *getOutTargetBinding(unsigned int index);
 			RenderTargetBinding *getOutTargetBinding(unsigned int index);
-			
-			LocalShaderParam *addLocalParam(const String& name, void *ptr);
+			            
+            std::vector<TextureBinding> textures;
+            std::vector<CubemapBinding> cubemaps;
 		
 		
 			Shader* shader;
 			Shader* shader;
 			std::vector<LocalShaderParam*> localParams;
 			std::vector<LocalShaderParam*> localParams;

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

@@ -268,6 +268,28 @@ void Camera::buildFrustumPlanes() {
 
 
 }
 }
 
 
+Entity *Camera::Clone(bool deepClone, bool ignoreEditorOnly) const {
+    Camera *newCamera = new Camera(NULL);
+    applyClone(newCamera, deepClone, ignoreEditorOnly);
+    return newCamera;
+}
+
+void Camera::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
+    Entity::applyClone(clone, deepClone, ignoreEditorOnly);
+    
+    Camera *cloneCamera = (Camera*) clone;
+    cloneCamera->setFOV(fov);
+    cloneCamera->setOrthoMode(orthoMode);
+    cloneCamera->setOrthoSizeMode(orthoSizeMode);
+    cloneCamera->setOrthoSize(orthoSizeX, orthoSizeY);
+    cloneCamera->setClippingPlanes(nearClipPlane, farClipPlane);
+    cloneCamera->setExposureLevel(exposureLevel);
+}
+
+Scene *Camera::getParentScene() const {
+    return parentScene;
+}
+
 bool Camera::canSee(Entity *entity) {
 bool Camera::canSee(Entity *entity) {
 	return isSphereInFrustum(entity->getPosition(), entity->getBBoxRadius());
 	return isSphereInFrustum(entity->getPosition(), entity->getBBoxRadius());
 }
 }
@@ -303,7 +325,7 @@ void Camera::setPostFilter(Material *shaderMaterial) {
 	for(int i=0; i < shaderMaterial->getNumShaders(); i++) {
 	for(int i=0; i < shaderMaterial->getNumShaders(); i++) {
 		ShaderBinding* binding = shaderMaterial->getShader(i)->createBinding();		
 		ShaderBinding* binding = shaderMaterial->getShader(i)->createBinding();		
 		localShaderOptions.push_back(binding);
 		localShaderOptions.push_back(binding);
-		binding->addLocalParam("exposure", (void*)&exposureLevel);				
+		binding->addParamPointer(ProgramParam::PARAM_NUMBER, "exposure", (void*)&exposureLevel);
 	}
 	}
 
 
 	_hasFilterShader = true;
 	_hasFilterShader = true;

+ 7 - 4
Core/Contents/Source/PolyEntity.cpp

@@ -106,9 +106,9 @@ Entity *Entity::Clone(bool deepClone, bool ignoreEditorOnly) const {
 
 
 void Entity::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
 void Entity::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
 	clone->ownsChildren = ownsChildren;
 	clone->ownsChildren = ownsChildren;
-	clone->position = position;
-	clone->rotation = rotation;
-	clone->scale = scale;
+	clone->setPosition(position);
+	clone->setRotationEuler(rotation);
+	clone->setScale(scale);
 	clone->color = color;
 	clone->color = color;
 	clone->custEntityType = custEntityType;
 	clone->custEntityType = custEntityType;
 	clone->billboardMode = billboardMode;	
 	clone->billboardMode = billboardMode;	
@@ -127,7 +127,10 @@ void Entity::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) co
 	clone->ignoreParentMatrix = ignoreParentMatrix;
 	clone->ignoreParentMatrix = ignoreParentMatrix;
 	clone->enableScissor = enableScissor;
 	clone->enableScissor = enableScissor;
 	clone->scissorBox = scissorBox;
 	clone->scissorBox = scissorBox;
-	clone->editorOnly = editorOnly;	
+	clone->editorOnly = editorOnly;
+	clone->snapToPixels = snapToPixels;
+    clone->setAnchorPoint(anchorPoint);
+    
 	clone->id = id;
 	clone->id = id;
 	if(tags == NULL) {
 	if(tags == NULL) {
 		clone->tags = NULL;
 		clone->tags = NULL;

+ 0 - 62
Core/Contents/Source/PolyGLSLShader.cpp

@@ -60,64 +60,6 @@ extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocation;
 
 
 using namespace Polycode;
 using namespace Polycode;
 
 
-GLSLShaderBinding::GLSLShaderBinding(GLSLShader *shader) : ShaderBinding(shader) {
-	glslShader = shader;
-}
-
-GLSLShaderBinding::~GLSLShaderBinding() {
-	
-}
-
-Cubemap *GLSLShaderBinding::getCubemap(const String& name) {
-	for(int i=0; i < cubemaps.size(); i++) {
-		if(cubemaps[i].name == name) {			
-			return cubemaps[i].cubemap;
-		}
-	}
-	return NULL;
-}
-
-Texture *GLSLShaderBinding::getTexture(const String& name) {
-	for(int i=0; i < textures.size(); i++) {
-		if(textures[i].name == name) {			
-			return textures[i].texture;
-		}
-	}
-	return NULL;
-}
-			
-void GLSLShaderBinding::addTexture(const String& name, Texture *texture) {
-	GLSLTextureBinding binding;
-	binding.name = name;
-	binding.texture = texture;
-	textures.push_back(binding);
-}
-
-void GLSLShaderBinding::addCubemap(const String& name, Cubemap *cubemap) {
-	GLSLCubemapBinding binding;
-	binding.cubemap = cubemap;
-	binding.name = name;
-	cubemaps.push_back(binding);
-}
-
-void GLSLShaderBinding::clearCubemap(const String& name) {
-	for(int i=0; i < cubemaps.size(); i++) {
-		if(cubemaps[i].name == name) {
-			cubemaps.erase(cubemaps.begin()+i);
-			return;
-		}
-	}
-}
-
-void GLSLShaderBinding::clearTexture(const String& name) {
-	for(int i=0; i < textures.size(); i++) {
-		if(textures[i].name == name) {
-			textures.erase(textures.begin()+i);
-			return;
-		}
-	}
-}
-
 int GLSLShader::getPolycodeParamType(int glType) {
 int GLSLShader::getPolycodeParamType(int glType) {
 	switch(glType) {
 	switch(glType) {
 		case GL_FLOAT:
 		case GL_FLOAT:
@@ -266,7 +208,3 @@ void GLSLShader::reload() {
 GLSLShader::~GLSLShader() {
 GLSLShader::~GLSLShader() {
 	unlinkProgram();
 	unlinkProgram();
 }
 }
-
-ShaderBinding *GLSLShader::createBinding() {
-	return new GLSLShaderBinding(this);
-}

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

@@ -420,7 +420,7 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
 	glUniformMatrix4fv(mloc, 1, false, mat);
 	glUniformMatrix4fv(mloc, 1, false, mat);
 		
 		
 		
 		
-	GLSLShaderBinding *cgBinding = (GLSLShaderBinding*)material->getShaderBinding(shaderIndex);
+	ShaderBinding *cgBinding = material->getShaderBinding(shaderIndex);
 	
 	
 	for(int i=0; i < glslShader->expectedParams.size(); i++) {
 	for(int i=0; i < glslShader->expectedParams.size(); i++) {
 		ProgramParam param = glslShader->expectedParams[i];
 		ProgramParam param = glslShader->expectedParams[i];
@@ -450,7 +450,7 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
 		}
 		}
 	}	
 	}	
 	
 	
-	cgBinding = (GLSLShaderBinding*)localOptions;
+	cgBinding = localOptions;
 	for(int i=0; i < cgBinding->textures.size(); i++) {
 	for(int i=0; i < cgBinding->textures.size(); i++) {
 		OpenGLTexture *glTexture = (OpenGLTexture*)cgBinding->textures[i].texture;
 		OpenGLTexture *glTexture = (OpenGLTexture*)cgBinding->textures[i].texture;
 		if(glTexture) {		
 		if(glTexture) {		

+ 8 - 0
Core/Contents/Source/PolyLabel.cpp

@@ -76,6 +76,14 @@ unsigned int Label::getSize() const {
 	return size;
 	return size;
 }
 }
 
 
+bool Label::getPremultiplyAlpha() const {
+    return premultiplyAlpha;
+}
+
+void Label::setPremultiplyAlpha(bool val) {
+    premultiplyAlpha = val;
+}
+
 void Label::setSize(int newSize) {
 void Label::setSize(int newSize) {
 	size = newSize;
 	size = newSize;
 	_optionsChanged	= true;
 	_optionsChanged	= true;

+ 27 - 0
Core/Contents/Source/PolyMesh.cpp

@@ -391,6 +391,33 @@ void Mesh::createCircle(Number w, Number h, unsigned int numSegments) {
     arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;			
     arrayDirtyMap[RenderDataArray::TANGENT_DATA_ARRAY] = true;			
 }
 }
 
 
+Mesh *Mesh::Copy() const {
+    Mesh *newMesh = new Mesh(meshType);
+    newMesh->indexedMesh = indexedMesh;
+    newMesh->setUseFaceNormals(useFaceNormals);
+    
+    for(int i=0; i < vertices.size(); i++) {
+        Vertex *v = new Vertex();
+        (*v) = *(vertices[i]);
+        newMesh->addVertex(v);
+    }
+
+    for(int i=0; i < indices.size(); i++) {
+        newMesh->addIndex(indices[i]);
+    }
+
+    for(int i=0; i < faceNormals.size(); i++) {
+        newMesh->addFaceNormal(faceNormals[i]);
+    }
+    
+    newMesh->dirtyArrays();
+    return newMesh;
+}
+
+void Mesh::addFaceNormal(Vector3 faceNormal) {
+    faceNormals.push_back(faceNormal);
+}
+
 void Mesh::createLineCircle(Number w, Number h, unsigned int numSegments) {
 void Mesh::createLineCircle(Number w, Number h, unsigned int numSegments) {
     setMeshType(Mesh::TRIFAN_MESH);
     setMeshType(Mesh::TRIFAN_MESH);
  
  

+ 49 - 1
Core/Contents/Source/PolyParticleEmitter.cpp

@@ -35,13 +35,53 @@ SceneParticleEmitter::SceneParticleEmitter(unsigned int particleCount, Number li
     mesh->useVertexColors = true;
     mesh->useVertexColors = true;
     depthWrite = false;
     depthWrite = false;
     setParticleCount(particleCount);
     setParticleCount(particleCount);
-    
 }
 }
 
 
 SceneParticleEmitter::~SceneParticleEmitter() {
 SceneParticleEmitter::~SceneParticleEmitter() {
     delete motionPerlin;
     delete motionPerlin;
 }
 }
 
 
+Entity *SceneParticleEmitter::Clone(bool deepClone, bool ignoreEditorOnly) const {
+    SceneParticleEmitter *newEmitter = new SceneParticleEmitter(1, 1, 1);
+    applyClone(newEmitter, deepClone, ignoreEditorOnly);
+    return newEmitter;
+}
+
+void SceneParticleEmitter::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
+    
+    SceneMesh::applyClone(clone, deepClone, ignoreEditorOnly);
+    
+    SceneParticleEmitter *cloneEmitter = (SceneParticleEmitter*) clone;
+    
+    cloneEmitter->setParticleCount(particleCount);
+    cloneEmitter->setParticleSpeed(particleSpeed);
+    cloneEmitter->setParticleLifetime(lifetime);
+    cloneEmitter->setParticleDirection(directionVector);
+    cloneEmitter->setDirectionDeviation(directionDeviation);
+    cloneEmitter->setEmitterSize(emitterSize);
+    cloneEmitter->setGravity(gravity);
+    cloneEmitter->setUseFloorPlane(useFloorPlane);
+    cloneEmitter->setParticlesInWorldSpace(particlesInWorldSpace);
+    cloneEmitter->setPerlinEnabled(perlinEnabled);
+    cloneEmitter->setPerlinValue(perlinValue);
+    cloneEmitter->setParticleSize(particleSize);
+    cloneEmitter->setFloorPlaneOffset(floorPlaneOffset);
+    cloneEmitter->setFloorDamping(floorDamping);
+    cloneEmitter->setLoopParticles(loopParticles);
+    cloneEmitter->setParticleType(particleType);
+    
+    cloneEmitter->scaleCurve = scaleCurve;
+    cloneEmitter->useScaleCurve = useScaleCurve;
+
+    cloneEmitter->colorCurveR = colorCurveR;
+    cloneEmitter->colorCurveG = colorCurveG;
+    cloneEmitter->colorCurveB = colorCurveB;
+    cloneEmitter->colorCurveA = colorCurveA;
+    cloneEmitter->useColorCurves = useColorCurves;
+    
+    cloneEmitter->getMesh()->useVertexColors = true;
+}
+
 void SceneParticleEmitter::resetParticle(unsigned int index) {
 void SceneParticleEmitter::resetParticle(unsigned int index) {
     particles[index].lifetime = 0.0;
     particles[index].lifetime = 0.0;
     q.fromAxes(-directionDeviation.x + (directionDeviation.x * RANDOM_NUMBER * 2.0), -directionDeviation.y + (directionDeviation.y * RANDOM_NUMBER * 2.0), -directionDeviation.z + (directionDeviation.z * RANDOM_NUMBER * 2.0));
     q.fromAxes(-directionDeviation.x + (directionDeviation.x * RANDOM_NUMBER * 2.0), -directionDeviation.y + (directionDeviation.y * RANDOM_NUMBER * 2.0), -directionDeviation.z + (directionDeviation.z * RANDOM_NUMBER * 2.0));
@@ -262,6 +302,14 @@ void SceneParticleEmitter::setPerlinEnabled(bool val) {
     perlinEnabled = val;
     perlinEnabled = val;
 }
 }
 
 
+Number SceneParticleEmitter::getParticleSpeed() const {
+    return particleSpeed;
+}
+
+void SceneParticleEmitter::setParticleSpeed(Number speed) {
+    particleSpeed = speed;
+}
+
 void SceneParticleEmitter::setPerlinValue(const Vector3 &perlinValue) {
 void SceneParticleEmitter::setPerlinValue(const Vector3 &perlinValue) {
     this->perlinValue = perlinValue;
     this->perlinValue = perlinValue;
 }
 }

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

@@ -237,7 +237,7 @@ void Renderer::setRendererShaderParams(Shader *shader, ShaderBinding *binding) {
 	for(int i=0; i < shader->expectedParams.size(); i++) {
 	for(int i=0; i < shader->expectedParams.size(); i++) {
 		void *dataPtr = getDataPointerForName(shader->expectedParams[i].name);
 		void *dataPtr = getDataPointerForName(shader->expectedParams[i].name);
 		if(dataPtr) {
 		if(dataPtr) {
-			binding->addLocalParam(shader->expectedParams[i].name, dataPtr);
+			binding->addParamPointer(shader->expectedParams[i].type, shader->expectedParams[i].name, dataPtr);
 		}
 		}
 	}
 	}
 }
 }

+ 6 - 10
Core/Contents/Source/PolySceneEntityInstance.cpp

@@ -307,6 +307,7 @@ Entity *SceneEntityInstance::loadObjectEntryIntoEntity(ObjectEntry *entry, Entit
             SceneParticleEmitter *emitter = new SceneParticleEmitter(1, 1, 1);
             SceneParticleEmitter *emitter = new SceneParticleEmitter(1, 1, 1);
 
 
             emitter->setParticleType((*emitterEntry)["type"]->intVal);
             emitter->setParticleType((*emitterEntry)["type"]->intVal);
+            emitter->setParticleSpeed((*emitterEntry)["speed"]->NumberVal);
             emitter->setParticleCount((*emitterEntry)["count"]->intVal);
             emitter->setParticleCount((*emitterEntry)["count"]->intVal);
             emitter->setParticleLifetime((*emitterEntry)["lifetime"]->NumberVal);
             emitter->setParticleLifetime((*emitterEntry)["lifetime"]->NumberVal);
             emitter->setParticleSize((*emitterEntry)["size"]->NumberVal);
             emitter->setParticleSize((*emitterEntry)["size"]->NumberVal);
@@ -327,16 +328,11 @@ Entity *SceneEntityInstance::loadObjectEntryIntoEntity(ObjectEntry *entry, Entit
             emitter->useColorCurves = (*emitterEntry)["useColorCurves"]->boolVal;
             emitter->useColorCurves = (*emitterEntry)["useColorCurves"]->boolVal;
             emitter->useScaleCurve = (*emitterEntry)["useScaleCurve"]->boolVal;
             emitter->useScaleCurve = (*emitterEntry)["useScaleCurve"]->boolVal;
             
             
-            if(emitter->useColorCurves) {
-                parseObjectIntoCurve((*emitterEntry)["colorCurveR"], &emitter->colorCurveR);
-                parseObjectIntoCurve((*emitterEntry)["colorCurveG"], &emitter->colorCurveG);
-                parseObjectIntoCurve((*emitterEntry)["colorCurveB"], &emitter->colorCurveB);
-                parseObjectIntoCurve((*emitterEntry)["colorCurveA"], &emitter->colorCurveA);
-            }
-            
-            if(emitter->useScaleCurve) {
-                parseObjectIntoCurve((*emitterEntry)["scaleCurve"], &emitter->scaleCurve);
-            }
+            parseObjectIntoCurve((*emitterEntry)["colorCurveR"], &emitter->colorCurveR);
+            parseObjectIntoCurve((*emitterEntry)["colorCurveG"], &emitter->colorCurveG);
+            parseObjectIntoCurve((*emitterEntry)["colorCurveB"], &emitter->colorCurveB);
+            parseObjectIntoCurve((*emitterEntry)["colorCurveA"], &emitter->colorCurveA);
+            parseObjectIntoCurve((*emitterEntry)["scaleCurve"], &emitter->scaleCurve);
             
             
             applySceneMesh((*entry)["SceneMesh"], emitter);
             applySceneMesh((*entry)["SceneMesh"], emitter);
 			entity = emitter;
 			entity = emitter;

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

@@ -79,7 +79,7 @@ Entity *SceneImage::Clone(bool deepClone, bool ignoreEditorOnly) const {
 }
 }
 
 
 void SceneImage::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
 void SceneImage::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
-	//ScreenShape::applyClone(clone, deepClone, ignoreEditorOnly);
+	ScenePrimitive::applyClone(clone, deepClone, ignoreEditorOnly);
 }
 }
 
 
 void SceneImage::setImageCoordinates(Number x, Number y, Number width, Number height, Number realWidth, Number realHeight) {
 void SceneImage::setImageCoordinates(Number x, Number y, Number width, Number height, Number realWidth, Number realHeight) {

+ 24 - 1
Core/Contents/Source/PolySceneLabel.cpp

@@ -44,9 +44,32 @@ SceneLabel::SceneLabel(const String& text, int size, const String& fontName, int
 	snapToPixels = SceneLabel::defaultSnapToPixels;	
 	snapToPixels = SceneLabel::defaultSnapToPixels;	
 	setLabelActualHeight(actualHeight);
 	setLabelActualHeight(actualHeight);
 }
 }
-			
+
+Entity *SceneLabel::Clone(bool deepClone, bool ignoreEditorOnly) const {
+	SceneLabel *newLabel = new SceneLabel(label->getText(), label->getSize(), label->getFont()->getFontName(), actualHeight, label->getPremultiplyAlpha());
+    applyClone(newLabel, deepClone, ignoreEditorOnly);
+    return newLabel;
+}
+
+void SceneLabel::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
+    
+    SceneLabel* cloneLabel = (SceneLabel*) clone;
+    
+
+    cloneLabel->getLabel()->setSize(label->getSize());
+    cloneLabel->getLabel()->setAntialiasMode(label->getAntialiasMode());
+    cloneLabel->getLabel()->setFont(label->getFont());
+    cloneLabel->getLabel()->setPremultiplyAlpha(label->getPremultiplyAlpha());
+    cloneLabel->setLabelActualHeight(actualHeight);
+    cloneLabel->positionAtBaseline = positionAtBaseline;
+    cloneLabel->setText(label->getText());
+    
+    ScenePrimitive::applyClone(clone, deepClone, ignoreEditorOnly);
+}
+
 
 
 SceneLabel::~SceneLabel() {
 SceneLabel::~SceneLabel() {
+    delete label;
 }
 }
 
 
 Label *SceneLabel::getLabel() {
 Label *SceneLabel::getLabel() {

+ 32 - 6
Core/Contents/Source/PolySceneLight.cpp

@@ -56,8 +56,6 @@ SceneLight::SceneLight(int type, Scene *parentScene, Number intensity, Number co
 	setSpotlightProperties(40,0.1);
 	setSpotlightProperties(40,0.1);
 	
 	
 	lightImportance = 0;
 	lightImportance = 0;
-    
-    debugDraw = false;
 }
 }
 
 
 void SceneLight::setLightType(int lightType) {
 void SceneLight::setLightType(int lightType) {
@@ -72,10 +70,6 @@ int SceneLight::getLightImportance() const {
 	return lightImportance;
 	return lightImportance;
 }
 }
 
 
-void SceneLight::enableDebugDraw(bool val) {
-    debugDraw = val;
-}
-
 void SceneLight::enableShadows(bool val, unsigned int resolution) {
 void SceneLight::enableShadows(bool val, unsigned int resolution) {
 	if(val) {
 	if(val) {
         if(zBufferTexture) {
         if(zBufferTexture) {
@@ -146,6 +140,38 @@ void SceneLight::renderDepthMap(Scene *scene) {
 	CoreServices::getInstance()->getRenderer()->setViewportSizeAndFOV(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes(), 45.0f);
 	CoreServices::getInstance()->getRenderer()->setViewportSizeAndFOV(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes(), 45.0f);
 }
 }
 
 
+Entity *SceneLight::Clone(bool deepClone, bool ignoreEditorOnly) const {
+    SceneLight *newLight = new SceneLight(type, NULL, intensity, constantAttenuation, linearAttenuation, quadraticAttenuation);
+    applyClone(newLight, deepClone, ignoreEditorOnly);
+    return newLight;
+}
+
+void SceneLight::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
+    Entity::applyClone(clone, deepClone, ignoreEditorOnly);
+    SceneLight *cloneLight = (SceneLight*) clone;
+    
+    cloneLight->setAttenuation(constantAttenuation, linearAttenuation, quadraticAttenuation);
+    cloneLight->setIntensity(intensity);
+    cloneLight->lightColor = lightColor;
+    cloneLight->specularLightColor = specularLightColor;
+    cloneLight->enableShadows(shadowsEnabled, shadowMapRes);
+    cloneLight->setShadowMapFOV(shadowMapFOV);
+    cloneLight->setSpotlightProperties(spotlightCutoff, spotlightExponent);
+    cloneLight->setLightType(type);
+}
+
+Scene *SceneLight::getParentScene() const {
+    return parentScene;
+}
+
+void SceneLight::setParentScene(Scene *scene) {
+    parentScene = scene;
+    if(spotCamera) {
+        spotCamera->setParentScene(scene);
+    }
+}
+
+
 const Matrix4& SceneLight::getLightViewMatrix() const {
 const Matrix4& SceneLight::getLightViewMatrix() const {
 	return lightViewMatrix;
 	return lightViewMatrix;
 }
 }

+ 39 - 8
Core/Contents/Source/PolySceneMesh.cpp

@@ -45,8 +45,6 @@ SceneMesh *SceneMesh::SceneMeshWithType(int meshType) {
 
 
 SceneMesh::SceneMesh(const String& fileName) : Entity(), texture(NULL), material(NULL), skeleton(NULL), localShaderOptions(NULL) {
 SceneMesh::SceneMesh(const String& fileName) : Entity(), texture(NULL), material(NULL), skeleton(NULL), localShaderOptions(NULL) {
     loadFromFile(fileName);
     loadFromFile(fileName);
-	lightmapIndex=0;
-	showVertexNormals = false;
 	useVertexBuffer = false;
 	useVertexBuffer = false;
 	lineSmooth = false;
 	lineSmooth = false;
 	ownsMesh = true;
 	ownsMesh = true;
@@ -63,8 +61,6 @@ SceneMesh::SceneMesh(Mesh *mesh) : Entity(), texture(NULL), material(NULL), skel
 	this->mesh = mesh;
 	this->mesh = mesh;
 	bBoxRadius = mesh->getRadius();
 	bBoxRadius = mesh->getRadius();
 	bBox = mesh->calculateBBox();
 	bBox = mesh->calculateBBox();
-	lightmapIndex=0;
-	showVertexNormals = false;	
 	useVertexBuffer = false;
 	useVertexBuffer = false;
 	lineSmooth = false;
 	lineSmooth = false;
 	ownsMesh = true;
 	ownsMesh = true;
@@ -81,8 +77,6 @@ SceneMesh::SceneMesh(int meshType) : texture(NULL), material(NULL), skeleton(NUL
 	mesh = new Mesh(meshType);
 	mesh = new Mesh(meshType);
 	bBoxRadius = mesh->getRadius();
 	bBoxRadius = mesh->getRadius();
 	bBox = mesh->calculateBBox();
 	bBox = mesh->calculateBBox();
-	lightmapIndex=0;
-	showVertexNormals = false;	
 	useVertexBuffer = false;	
 	useVertexBuffer = false;	
 	lineSmooth = false;
 	lineSmooth = false;
 	ownsMesh = true;
 	ownsMesh = true;
@@ -97,11 +91,9 @@ void SceneMesh::setMesh(Mesh *mesh) {
 	this->mesh = mesh;
 	this->mesh = mesh;
 	bBoxRadius = mesh->getRadius();
 	bBoxRadius = mesh->getRadius();
 	bBox = mesh->calculateBBox();
 	bBox = mesh->calculateBBox();
-	showVertexNormals = false;	
 	useVertexBuffer = false;	
 	useVertexBuffer = false;	
 }
 }
 
 
-
 SceneMesh::~SceneMesh() {
 SceneMesh::~SceneMesh() {
 	if(ownsSkeleton)
 	if(ownsSkeleton)
 		delete skeleton;
 		delete skeleton;
@@ -110,6 +102,45 @@ SceneMesh::~SceneMesh() {
 	delete localShaderOptions;
 	delete localShaderOptions;
 }
 }
 
 
+Entity *SceneMesh::Clone(bool deepClone, bool ignoreEditorOnly) const {
+    SceneMesh *newEntity = new SceneMesh(mesh->getMeshType());
+    applyClone(newEntity, deepClone, ignoreEditorOnly);
+    return newEntity;
+}
+
+void SceneMesh::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
+    Entity::applyClone(clone, deepClone, ignoreEditorOnly);
+    SceneMesh *_clone = (SceneMesh*) clone;
+    
+    _clone->lineWidth = lineWidth;
+    _clone->lineSmooth = lineSmooth;
+    _clone->pointSize = pointSize;
+    _clone->pointSmooth = pointSmooth;
+    _clone->ownsMesh = ownsMesh;
+    _clone->ownsSkeleton = ownsSkeleton;
+    _clone->overlayWireframe = overlayWireframe;
+    _clone->wireFrameColor = wireFrameColor;
+    _clone->useGeometryHitDetection = useGeometryHitDetection;
+    _clone->forceMaterial = forceMaterial;
+    _clone->setFilename(fileName);
+    
+    Mesh *newMesh = mesh->Copy();
+    _clone->setMesh(newMesh);
+    
+    if(useVertexBuffer) {
+        _clone->cacheToVertexBuffer(true);
+    }
+    
+    _clone->setMaterial(material);
+    if(material) {
+        localShaderOptions->copyTo(_clone->getLocalShaderOptions());
+    }
+}
+
+void SceneMesh::setFilename(String fileName) {
+    this->fileName = fileName;
+}
+
 void SceneMesh::loadFromFile(String fileName) {
 void SceneMesh::loadFromFile(String fileName) {
 	mesh = new Mesh(fileName);
 	mesh = new Mesh(fileName);
 	bBoxRadius = mesh->getRadius();
 	bBoxRadius = mesh->getRadius();

+ 11 - 0
Core/Contents/Source/PolyScenePrimitive.cpp

@@ -127,6 +127,17 @@ void ScenePrimitive::recreatePrimitive() {
 	}
 	}
 }
 }
 
 
+Entity *ScenePrimitive::Clone(bool deepClone, bool ignoreEditorOnly) const {
+    ScenePrimitive *newEntity = new ScenePrimitive(type, v1, v2, v3, v4, v5);
+    applyClone(newEntity, deepClone, ignoreEditorOnly);
+    return newEntity;
+}
+
+void ScenePrimitive::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
+    SceneMesh::applyClone(clone, deepClone, ignoreEditorOnly);    
+    ((ScenePrimitive*)clone)->setPrimitiveOptions(type, v1, v2, v3, v4, v5);
+}
+
 void ScenePrimitive::setPrimitiveOptions(int type, Number v1, Number v2, Number v3,Number v4,Number v5) {
 void ScenePrimitive::setPrimitiveOptions(int type, Number v1, Number v2, Number v3,Number v4,Number v5) {
 
 
 	this->type = type;
 	this->type = type;

+ 22 - 0
Core/Contents/Source/PolySceneSound.cpp

@@ -43,6 +43,21 @@ void SceneSoundListener::Update() {
 	CoreServices::getInstance()->getSoundManager()->setListenerOrientation(direction, upVector);
 	CoreServices::getInstance()->getSoundManager()->setListenerOrientation(direction, upVector);
 }
 }
 
 
+Entity *SceneSound::Clone(bool deepClone, bool ignoreEditorOnly) const {
+    SceneSound *newSound = new SceneSound(sound->getFileName(), sound->getReferenceDistance(), sound->getMaxDistance(), directionalSound);
+    applyClone(newSound, deepClone, ignoreEditorOnly);
+    return newSound;
+}
+
+void SceneSound::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
+    Entity::applyClone(clone, deepClone, ignoreEditorOnly);
+    SceneSound *cloneSound = (SceneSound*) clone;
+    
+    cloneSound->getSound()->setPositionalProperties(sound->getReferenceDistance(), sound->getMaxDistance());
+    cloneSound->setDirectionalSound(directionalSound);
+    cloneSound->getSound()->setVolume(sound->getVolume());
+    cloneSound->getSound()->setPitch(sound->getPitch());
+}
 
 
 SceneSound::SceneSound(const String& fileName, Number referenceDistance, Number maxDistance, bool directionalSound) : Entity() {
 SceneSound::SceneSound(const String& fileName, Number referenceDistance, Number maxDistance, bool directionalSound) : Entity() {
 
 
@@ -57,6 +72,13 @@ SceneSound::~SceneSound() {
 	delete sound;
 	delete sound;
 }
 }
 
 
+bool SceneSound::isDirectionalSound() const {
+    return directionalSound;
+}
+void SceneSound::setDirectionalSound(bool val) {
+    directionalSound = val;
+}
+
 void SceneSound::Update() {
 void SceneSound::Update() {
 	Matrix4 finalMatrix = getConcatenatedMatrix();
 	Matrix4 finalMatrix = getConcatenatedMatrix();
 	sound->setSoundPosition(finalMatrix.getPosition());
 	sound->setSoundPosition(finalMatrix.getPosition());

+ 34 - 17
Core/Contents/Source/PolySceneSprite.cpp

@@ -56,12 +56,30 @@ SceneSprite::SceneSprite(const String& fileName) : ScenePrimitive(ScenePrimitive
 	currentAnimation = NULL;	
 	currentAnimation = NULL;	
 	paused = false;
 	paused = false;
 
 
-	resourceEntry = new SceneSpriteResourceEntry(this);		
+	resourceEntry = new SceneSpriteResourceEntry(this);
 	loadFromFile(fileName);
 	loadFromFile(fileName);
 	resourceEntry->setResourceName(fileName);
 	resourceEntry->setResourceName(fileName);
 	resourceEntry->setResourcePath(fileName);	
 	resourceEntry->setResourcePath(fileName);	
 }
 }
 
 
+SceneSprite::SceneSprite(const String& fileName, Number spriteWidth, Number spriteHeight) : ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 1, 1) {
+	this->spriteWidth = spriteWidth;
+	this->spriteHeight = spriteHeight;
+	loadTexture(fileName);
+    resourceEntry = NULL;
+    
+	currentFrame = 0;
+	currentAnimation = NULL;
+	paused = false;
+    actualSpriteSize.x = spriteWidth;
+    actualSpriteSize.y = spriteHeight;
+    
+    setSpriteSize(spriteWidth, spriteHeight);
+	setPrimitiveOptions(ScenePrimitive::TYPE_VPLANE, spriteWidth, spriteHeight);
+    
+    recalculateSpriteDimensions();
+}
+
 Entity *SceneSprite::Clone(bool deepClone, bool ignoreEditorOnly) const {
 Entity *SceneSprite::Clone(bool deepClone, bool ignoreEditorOnly) const {
 	SceneSprite *newSprite = new SceneSprite(getTexture()->getResourcePath(), spriteWidth, spriteHeight);
 	SceneSprite *newSprite = new SceneSprite(getTexture()->getResourcePath(), spriteWidth, spriteHeight);
 	for(int i=0; i < animations.size(); i++) {
 	for(int i=0; i < animations.size(); i++) {
@@ -70,12 +88,26 @@ Entity *SceneSprite::Clone(bool deepClone, bool ignoreEditorOnly) const {
 	if(currentAnimation) {
 	if(currentAnimation) {
 		newSprite->playAnimation(currentAnimation->name, currentFrame, playingOnce);
 		newSprite->playAnimation(currentAnimation->name, currentFrame, playingOnce);
 	}
 	}
+    
+    newSprite->setSpriteFilename(fileName);
 	applyClone(newSprite, deepClone, ignoreEditorOnly);
 	applyClone(newSprite, deepClone, ignoreEditorOnly);
+    
+    newSprite->setActualSpriteSize(actualSpriteSize.x, actualSpriteSize.y);
+    
 	return newSprite;
 	return newSprite;
 }
 }
 
 
 void SceneSprite::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
 void SceneSprite::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
-//	ScreenShape::applyClone(clone, deepClone, ignoreEditorOnly);	
+	ScenePrimitive::applyClone(clone, deepClone, ignoreEditorOnly);
+}
+
+void SceneSprite::setSpriteFilename(String fileName) {
+    this->fileName = fileName;
+    if(!resourceEntry) {
+        resourceEntry = new SceneSpriteResourceEntry(this);
+    }
+    resourceEntry->setResourceName(fileName);
+    resourceEntry->setResourcePath(fileName);
 }
 }
 
 
 bool SceneSprite::loadFromFile(const String& fileName) {
 bool SceneSprite::loadFromFile(const String& fileName) {
@@ -165,21 +197,6 @@ SceneSpriteResourceEntry *SceneSprite::getResourceEntry() {
 	return resourceEntry;
 	return resourceEntry;
 }
 }
 
 
-SceneSprite::SceneSprite(const String& fileName, Number spriteWidth, Number spriteHeight) : ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 1, 1) {
-	this->spriteWidth = spriteWidth;
-	this->spriteHeight = spriteHeight;	
-	loadTexture(fileName);
-		
-	recalculateSpriteDimensions();
-	currentFrame = 0;
-	currentAnimation = NULL;	
-	paused = false;
-    actualSpriteSize.x = spriteWidth;
-    actualSpriteSize.y = spriteHeight;
-    
-	setPrimitiveOptions(ScenePrimitive::TYPE_VPLANE, spriteWidth, spriteHeight);	
-}
-
 SceneSprite::~SceneSprite() {
 SceneSprite::~SceneSprite() {
 	
 	
 }
 }

+ 141 - 9
Core/Contents/Source/PolyShader.cpp

@@ -118,23 +118,26 @@ LocalShaderParam *ShaderBinding::getLocalParamByName(const String& name) {
 	return NULL;
 	return NULL;
 }
 }
 
 
-LocalShaderParam *ShaderBinding::addLocalParam(const String& name, void *ptr) {
-	LocalShaderParam *newParam = new LocalShaderParam();
-	newParam->name = name;
-	newParam->data = ptr;
-	localParams.push_back(newParam);
-	return newParam;
-}
-
 LocalShaderParam * ShaderBinding::addParam(int type, const String& name) {
 LocalShaderParam * ShaderBinding::addParam(int type, const String& name) {
 	void *defaultData = ProgramParam::createParamData(type);
 	void *defaultData = ProgramParam::createParamData(type);
 	LocalShaderParam *newParam = new LocalShaderParam();
 	LocalShaderParam *newParam = new LocalShaderParam();
 	newParam->data = defaultData;
 	newParam->data = defaultData;
 	newParam->name = name;
 	newParam->name = name;
+    newParam->type = type;
 	localParams.push_back(newParam);
 	localParams.push_back(newParam);
 	return newParam;
 	return newParam;
 }
 }
 
 
+LocalShaderParam *ShaderBinding::addParamPointer(int type, const String& name, void *ptr) {
+    LocalShaderParam *newParam = new LocalShaderParam();
+    newParam->name = name;
+    newParam->data = ptr;
+    newParam->type = type;
+    newParam->ownsPointer = false;
+    localParams.push_back(newParam);
+    return newParam;
+}
+
 void ShaderBinding::addRenderTargetBinding(RenderTargetBinding *binding) {
 void ShaderBinding::addRenderTargetBinding(RenderTargetBinding *binding) {
 	renderTargetBindings.push_back(binding);
 	renderTargetBindings.push_back(binding);
 	switch (binding->mode) {
 	switch (binding->mode) {
@@ -186,7 +189,22 @@ void ShaderBinding::removeRenderTargetBinding(RenderTargetBinding *binding) {
 			return;
 			return;
 		}
 		}
 	}
 	}
-	
+}
+
+void ShaderBinding::copyTo(ShaderBinding *targetBinding) {
+    for(int i=0; i < textures.size(); i++) {
+        targetBinding->textures.push_back(textures[i]);
+    }
+    
+    for(int i=0; i < cubemaps.size(); i++) {
+        targetBinding->cubemaps.push_back(cubemaps[i]);
+    }
+
+    for(int i=0; i < localParams.size(); i++) {
+        LocalShaderParam *copyParam = localParams[i]->Copy();
+        targetBinding->localParams.push_back(copyParam);
+    }
+    
 }
 }
 
 
 unsigned int ShaderBinding::getNumRenderTargetBindings() {
 unsigned int ShaderBinding::getNumRenderTargetBindings() {
@@ -247,6 +265,10 @@ int Shader::getExpectedParamType(String name) {
 	return ProgramParam::PARAM_UNKNOWN;
 	return ProgramParam::PARAM_UNKNOWN;
 }
 }
 
 
+ShaderBinding *Shader::createBinding() {
+    return new ShaderBinding(this);
+}
+
 Shader::~Shader() {
 Shader::~Shader() {
 
 
 }
 }
@@ -265,6 +287,66 @@ const String& Shader::getName() const {
 
 
 LocalShaderParam::LocalShaderParam() {
 LocalShaderParam::LocalShaderParam() {
     data = NULL;
     data = NULL;
+    ownsPointer = true;
+}
+
+LocalShaderParam::~LocalShaderParam() {
+    if(ownsPointer) {
+        switch(type) {
+            case ProgramParam::PARAM_NUMBER:
+                delete ((Number*) data);
+            break;
+            case ProgramParam::PARAM_VECTOR2:
+                delete ((Vector2*) data);
+            break;
+            case ProgramParam::PARAM_VECTOR3:
+                delete ((Vector3*) data);
+            break;
+            case ProgramParam::PARAM_COLOR:
+                delete ((Color*) data);
+            break;
+            case ProgramParam::PARAM_MATRIX:
+                delete ((Matrix4*) data);
+            break;
+        }
+    }
+}
+
+LocalShaderParam *LocalShaderParam::Copy() {
+    LocalShaderParam *copyParam = new LocalShaderParam();
+    copyParam->name = name;
+    copyParam->type = type;
+    copyParam->data = ProgramParam::createParamData(type);
+    copyParam->ownsPointer = ownsPointer;
+    
+    switch(type) {
+        case ProgramParam::PARAM_NUMBER:
+        {
+            copyParam->setNumber(getNumber());
+        }
+        break;
+        case ProgramParam::PARAM_VECTOR2:
+        {
+            copyParam->setVector2(getVector2());
+        }
+        break;
+        case ProgramParam::PARAM_VECTOR3:
+        {
+            copyParam->setVector3(getVector3());
+        }
+        break;
+        case ProgramParam::PARAM_COLOR:
+        {
+            copyParam->setColor(getColor());
+        }
+        break;
+        case ProgramParam::PARAM_MATRIX:
+        {
+            copyParam->setMatrix4(getMatrix4());
+        }
+        break;
+    }
+    return copyParam;
 }
 }
 
 
 void LocalShaderParam::setParamValueFromString(int type, String pvalue) {
 void LocalShaderParam::setParamValueFromString(int type, String pvalue) {
@@ -306,3 +388,53 @@ void LocalShaderParam::setParamValueFromString(int type, String pvalue) {
                 break;
                 break;
         }
         }
 }
 }
+
+Cubemap *ShaderBinding::getCubemap(const String& name) {
+	for(int i=0; i < cubemaps.size(); i++) {
+		if(cubemaps[i].name == name) {
+			return cubemaps[i].cubemap;
+		}
+	}
+	return NULL;
+}
+
+Texture *ShaderBinding::getTexture(const String& name) {
+	for(int i=0; i < textures.size(); i++) {
+		if(textures[i].name == name) {
+			return textures[i].texture;
+		}
+	}
+	return NULL;
+}
+
+void ShaderBinding::addTexture(const String& name, Texture *texture) {
+	TextureBinding binding;
+	binding.name = name;
+	binding.texture = texture;
+	textures.push_back(binding);
+}
+
+void ShaderBinding::addCubemap(const String& name, Cubemap *cubemap) {
+	CubemapBinding binding;
+	binding.cubemap = cubemap;
+	binding.name = name;
+	cubemaps.push_back(binding);
+}
+
+void ShaderBinding::clearCubemap(const String& name) {
+	for(int i=0; i < cubemaps.size(); i++) {
+		if(cubemaps[i].name == name) {
+			cubemaps.erase(cubemaps.begin()+i);
+			return;
+		}
+	}
+}
+
+void ShaderBinding::clearTexture(const String& name) {
+	for(int i=0; i < textures.size(); i++) {
+		if(textures[i].name == name) {
+			textures.erase(textures.begin()+i);
+			return;
+		}
+	}
+}

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

@@ -37,6 +37,12 @@
 
 
 using namespace Polycode;
 using namespace Polycode;
 
 
+class EntityEditorClipboardData {
+public:
+    EntityEditorClipboardData(){}
+    std::vector<Entity*> entities;
+};
+
 class LightDisplay : public Entity {
 class LightDisplay : public Entity {
 public:
 public:
     LightDisplay(SceneLight *light);
     LightDisplay(SceneLight *light);
@@ -108,11 +114,15 @@ class EntityEditorMainView : public UIElement {
             void doEntitySelect(Entity *targetEntity);
             void doEntitySelect(Entity *targetEntity);
             void setEditorMode(int newMode);
             void setEditorMode(int newMode);
             Entity *getSelectedEntity();
             Entity *getSelectedEntity();
+            std::vector<Entity*> getSelectedEntities();
     
     
             void setOverlayWireframeRecursive(Entity *targetEntity, bool val);
             void setOverlayWireframeRecursive(Entity *targetEntity, bool val);
             void setLinkedEntityPropsRecursive(SceneEntityInstance *parentInstance, Entity *entity);
             void setLinkedEntityPropsRecursive(SceneEntityInstance *parentInstance, Entity *entity);
     
     
+            void Paste(EntityEditorClipboardData *data);
+    
             void disableLighting(bool disable);
             void disableLighting(bool disable);
+            void selectNone();
     
     
             void onGainFocus();
             void onGainFocus();
             void onLoseFocus();
             void onLoseFocus();
@@ -205,6 +215,10 @@ class PolycodeEntityEditor : public PolycodeEditor {
     
     
         void saveEntityToObjectEntry(Entity *entity, ObjectEntry *entry);
         void saveEntityToObjectEntry(Entity *entity, ObjectEntry *entry);
     
     
+        String Copy(void **data);
+        void Paste(void *data, String clipboardType);
+        void destroyClipboardData(void *data, String type);
+    
         void handleEvent(Event *event);
         void handleEvent(Event *event);
     
     
 	protected:
 	protected:

+ 1 - 0
IDE/Contents/Include/PolycodeProps.h

@@ -618,6 +618,7 @@ class ParticleEmitterSheet : public PropSheet {
         NumberProp *countProp;
         NumberProp *countProp;
         NumberProp *lifetimeProp;
         NumberProp *lifetimeProp;
         NumberProp *particleSizeProp;
         NumberProp *particleSizeProp;
+        NumberProp *particleSpeedProp;
 
 
         BoolProp *worldParticlesProp;
         BoolProp *worldParticlesProp;
         BoolProp *loopingProp;
         BoolProp *loopingProp;

+ 79 - 20
IDE/Contents/Source/PolycodeEntityEditor.cpp

@@ -323,6 +323,10 @@ EntityEditorMainView::EntityEditorMainView() {
     input->addEventListener(this, InputEvent::EVENT_KEYDOWN);
     input->addEventListener(this, InputEvent::EVENT_KEYDOWN);
 }
 }
 
 
+std::vector<Entity*> EntityEditorMainView::getSelectedEntities() {
+    return selectedEntities;
+}
+
 void EntityEditorMainView::setEditorMode(int newMode) {
 void EntityEditorMainView::setEditorMode(int newMode) {
     editorMode = newMode;
     editorMode = newMode;
     if(editorMode == EDITOR_MODE_3D) {
     if(editorMode == EDITOR_MODE_3D) {
@@ -352,6 +356,19 @@ Entity *EntityEditorMainView::getSelectedEntity() {
     }
     }
 }
 }
 
 
+
+void EntityEditorMainView::Paste(EntityEditorClipboardData *data) {
+    
+    selectNone();
+    
+    for(int i=0; i < data->entities.size(); i++) {
+        Entity *entity = data->entities[i]->Clone(true, true);
+        setEditorPropsRecursive(entity);
+        sceneObjectRoot->addChild(entity);
+        selectEntity(entity, true);
+    }
+}
+
 void EntityEditorMainView::Update() {
 void EntityEditorMainView::Update() {
     
     
     if(entitiesToSelect.size() != 0) {
     if(entitiesToSelect.size() != 0) {
@@ -417,7 +434,9 @@ void EntityEditorMainView::createIcon(Entity *entity, String iconFile) {
 void EntityEditorMainView::setEditorPropsRecursive(Entity *entity) {
 void EntityEditorMainView::setEditorPropsRecursive(Entity *entity) {
     setEditorProps(entity);
     setEditorProps(entity);
     for(int i=0; i < entity->getNumChildren(); i++) {
     for(int i=0; i < entity->getNumChildren(); i++) {
-        setEditorProps(entity->getChildAtIndex(i));
+        if(!entity->getChildAtIndex(i)->editorOnly) {
+            setEditorProps(entity->getChildAtIndex(i));
+        }
     }
     }
 }
 }
 
 
@@ -465,6 +484,10 @@ void EntityEditorMainView::setEditorProps(Entity *entity) {
     if(sceneLight) {
     if(sceneLight) {
         createIcon(entity, "light_icon.png");
         createIcon(entity, "light_icon.png");
         LightDisplay *lightVis = new LightDisplay(sceneLight);
         LightDisplay *lightVis = new LightDisplay(sceneLight);
+        if(!sceneLight->getParentScene()) {
+            sceneLight->setParentScene(mainScene);
+            mainScene->addLight(sceneLight);
+        }
     }
     }
     
     
     if(emitter) {
     if(emitter) {
@@ -566,7 +589,6 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         selectEntity(newLabel);
         selectEntity(newLabel);
         return;
         return;
     }
     }
-
     
     
     if(command == "add_light") {
     if(command == "add_light") {
         SceneLight *newLight = new SceneLight(SceneLight::POINT_LIGHT, mainScene, 1.0);
         SceneLight *newLight = new SceneLight(SceneLight::POINT_LIGHT, mainScene, 1.0);
@@ -751,12 +773,7 @@ void EntityEditorMainView::handleEvent(Event *event) {
                 break;
                 break;
                 case KEY_ESCAPE:
                 case KEY_ESCAPE:
                 {
                 {
-                    for(int i=0; i < selectedEntities.size(); i++) {
-                        doEntityDeselect(selectedEntities[i]);
-                    }
-                    selectedEntities.clear();
-                    transformGizmo->setTransformSelection(selectedEntities);
-                    dispatchEvent(new Event(), Event::CHANGE_EVENT);                    
+                    selectNone();
                 }
                 }
                 break;
                 break;
             }
             }
@@ -802,6 +819,15 @@ void EntityEditorMainView::handleEvent(Event *event) {
     }
     }
 }
 }
 
 
+void EntityEditorMainView::selectNone() {
+    for(int i=0; i < selectedEntities.size(); i++) {
+        doEntityDeselect(selectedEntities[i]);
+    }
+    selectedEntities.clear();
+    transformGizmo->setTransformSelection(selectedEntities);
+    dispatchEvent(new Event(), Event::CHANGE_EVENT);
+}
+
 void EntityEditorMainView::disableLighting(bool disable) {
 void EntityEditorMainView::disableLighting(bool disable) {
     
     
     lightsDisabled = disable;
     lightsDisabled = disable;
@@ -925,15 +951,16 @@ void EntityEditorMainView::Resize(Number width, Number height) {
     
     
     Vector2 screenPos = renderTextureShape->getScreenPosition(globalScene->getDefaultCamera()->getProjectionMatrix(), globalScene->getDefaultCamera()->getTransformMatrix(), globalScene->getDefaultCamera()->getViewport());
     Vector2 screenPos = renderTextureShape->getScreenPosition(globalScene->getDefaultCamera()->getProjectionMatrix(), globalScene->getDefaultCamera()->getTransformMatrix(), globalScene->getDefaultCamera()->getViewport());
     
     
+	renderTexture->resizeRenderTexture(width, height-30);
+	renderTextureShape->setTexture(renderTexture->getTargetTexture());		
+	renderTextureShape->Resize(width, height-30);
+    
 	mainScene->sceneMouseRect.x = screenPos.x;
 	mainScene->sceneMouseRect.x = screenPos.x;
 	mainScene->sceneMouseRect.y = screenPos.y;
 	mainScene->sceneMouseRect.y = screenPos.y;
 	mainScene->sceneMouseRect.w = renderTextureShape->getWidth();
 	mainScene->sceneMouseRect.w = renderTextureShape->getWidth();
 	mainScene->sceneMouseRect.h = renderTextureShape->getHeight();
 	mainScene->sceneMouseRect.h = renderTextureShape->getHeight();
     mainScene->remapMouse = true;
     mainScene->remapMouse = true;
     
     
-	renderTexture->resizeRenderTexture(width, height-30);
-	renderTextureShape->setTexture(renderTexture->getTargetTexture());		
-	renderTextureShape->Resize(width, height-30);
     Update();
     Update();
 }
 }
 
 
@@ -1123,6 +1150,7 @@ void PolycodeEntityEditor::saveEntityToObjectEntry(Entity *entity, ObjectEntry *
         ObjectEntry *emitterEntry = entry->addChild("SceneParticleEmitter");
         ObjectEntry *emitterEntry = entry->addChild("SceneParticleEmitter");
         emitterEntry->addChild("type", (int)emitter->getParticleType());
         emitterEntry->addChild("type", (int)emitter->getParticleType());
         emitterEntry->addChild("count", (int)emitter->getParticleCount());
         emitterEntry->addChild("count", (int)emitter->getParticleCount());
+        emitterEntry->addChild("speed", emitter->getParticleSpeed());
         emitterEntry->addChild("lifetime", emitter->getParticleLifetime());
         emitterEntry->addChild("lifetime", emitter->getParticleLifetime());
         emitterEntry->addChild("size", emitter->getParticleSize());
         emitterEntry->addChild("size", emitter->getParticleSize());
         emitterEntry->addChild("world", emitter->getParticlesInWorldSpace());
         emitterEntry->addChild("world", emitter->getParticlesInWorldSpace());
@@ -1149,15 +1177,12 @@ void PolycodeEntityEditor::saveEntityToObjectEntry(Entity *entity, ObjectEntry *
         emitterEntry->addChild("useColorCurves", emitter->useColorCurves);
         emitterEntry->addChild("useColorCurves", emitter->useColorCurves);
         emitterEntry->addChild("useScaleCurve", emitter->useScaleCurve);
         emitterEntry->addChild("useScaleCurve", emitter->useScaleCurve);
         
         
-        if(emitter->useScaleCurve) {
-            saveCurveToObject(emitterEntry->addChild("scaleCurve"), &emitter->scaleCurve);
-        }
-        if(emitter->useColorCurves) {
-            saveCurveToObject(emitterEntry->addChild("colorCurveR"), &emitter->colorCurveR);
-            saveCurveToObject(emitterEntry->addChild("colorCurveG"), &emitter->colorCurveG);
-            saveCurveToObject(emitterEntry->addChild("colorCurveB"), &emitter->colorCurveB);
-            saveCurveToObject(emitterEntry->addChild("colorCurveA"), &emitter->colorCurveA);
-        }
+        saveCurveToObject(emitterEntry->addChild("scaleCurve"), &emitter->scaleCurve);
+            
+        saveCurveToObject(emitterEntry->addChild("colorCurveR"), &emitter->colorCurveR);
+        saveCurveToObject(emitterEntry->addChild("colorCurveG"), &emitter->colorCurveG);
+        saveCurveToObject(emitterEntry->addChild("colorCurveB"), &emitter->colorCurveB);
+        saveCurveToObject(emitterEntry->addChild("colorCurveA"), &emitter->colorCurveA);
     }
     }
     
     
     if(dynamic_cast<SceneSprite*>(entity)) {
     if(dynamic_cast<SceneSprite*>(entity)) {
@@ -1377,6 +1402,40 @@ void PolycodeEntityEditor::saveShaderOptionsToEntry(ObjectEntry *entry, Material
     }
     }
 }
 }
 
 
+String PolycodeEntityEditor::Copy(void **data) {
+    std::vector<Entity*> selectedEntities = mainView->getSelectedEntities();
+    
+    if(selectedEntities.size() > 0) {
+        EntityEditorClipboardData *newData = new EntityEditorClipboardData();
+        for(int i=0; i < selectedEntities.size(); i++) {
+            ScreenEntity *clone = (ScreenEntity*)selectedEntities[i]->Clone(true, true);
+            newData->entities.push_back(clone);
+        }
+        *data = (void*) newData;
+    }
+    return "Entity";
+}
+
+void PolycodeEntityEditor::destroyClipboardData(void *data, String type) {
+    if(type == "Entity") {
+        EntityEditorClipboardData *oldData = (EntityEditorClipboardData*) data;
+        for(int i=0; i < oldData->entities.size(); i++) {
+            delete oldData->entities[i];
+        }
+        delete oldData;
+    }
+}
+
+void PolycodeEntityEditor::Paste(void *data, String clipboardType) {
+    if(!data) {
+        return;
+    }
+    
+    if(clipboardType == "Entity") {
+        mainView->Paste((EntityEditorClipboardData*)data);
+    }
+}
+
 void PolycodeEntityEditor::saveFile() {
 void PolycodeEntityEditor::saveFile() {
     Object saveObject;
     Object saveObject;
     
     

+ 6 - 1
IDE/Contents/Source/PolycodeProps.cpp

@@ -2362,6 +2362,9 @@ ParticleEmitterSheet::ParticleEmitterSheet() : PropSheet("PARTICLE EMITTER", "pa
     particleSizeProp = new NumberProp("Size");
     particleSizeProp = new NumberProp("Size");
     addProp(particleSizeProp);
     addProp(particleSizeProp);
     
     
+    particleSpeedProp = new NumberProp("Speed");
+    addProp(particleSpeedProp);
+    
     worldParticlesProp = new BoolProp("World space");
     worldParticlesProp = new BoolProp("World space");
     addProp(worldParticlesProp);
     addProp(worldParticlesProp);
     
     
@@ -2419,6 +2422,8 @@ void ParticleEmitterSheet::handleEvent(Event *event) {
             emitter->setParticleType(typeProp->get());
             emitter->setParticleType(typeProp->get());
         } else if(event->getDispatcher() == countProp) {
         } else if(event->getDispatcher() == countProp) {
                 emitter->setParticleCount(countProp->get());
                 emitter->setParticleCount(countProp->get());
+        } else if(event->getDispatcher() == particleSpeedProp) {
+            emitter->setParticleSpeed(particleSpeedProp->get());
         } else if(event->getDispatcher() == lifetimeProp) {
         } else if(event->getDispatcher() == lifetimeProp) {
             emitter->setParticleLifetime(lifetimeProp->get());
             emitter->setParticleLifetime(lifetimeProp->get());
         } else if(event->getDispatcher() == particleSizeProp) {
         } else if(event->getDispatcher() == particleSizeProp) {
@@ -2463,6 +2468,7 @@ void ParticleEmitterSheet::setParticleEmitter(SceneParticleEmitter *emitter) {
         worldParticlesProp->set(emitter->getParticlesInWorldSpace());
         worldParticlesProp->set(emitter->getParticlesInWorldSpace());
         loopingProp->set(emitter->getLoopParticles());
         loopingProp->set(emitter->getLoopParticles());
         particleRotaionProp->set(emitter->getParticleRotationSpeed());
         particleRotaionProp->set(emitter->getParticleRotationSpeed());
+        particleSpeedProp->set(emitter->getParticleSpeed());
         gravityProp->set(emitter->getGravity());
         gravityProp->set(emitter->getGravity());
         directionProp->set(emitter->getParticleDirection());
         directionProp->set(emitter->getParticleDirection());
         sizeProp->set(emitter->getEmitterSize());
         sizeProp->set(emitter->getEmitterSize());
@@ -2563,7 +2569,6 @@ void SceneLightSheet::setSceneLight(SceneLight *light) {
     this->light = light;
     this->light = light;
     
     
     if(light) {
     if(light) {
-        light->enableDebugDraw(true);
         typeProp->set(light->getLightType());
         typeProp->set(light->getLightType());
         lightColorProp->set(light->lightColor);
         lightColorProp->set(light->lightColor);
         specularColorProp->set(light->specularLightColor);
         specularColorProp->set(light->specularLightColor);