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

Rewrote the particle system to use a single mesh instead of multiple entities, added a particle system property sheet to IDE editor

Ivan Safrin 12 лет назад
Родитель
Сommit
fa1b054f01

+ 0 - 2
Core/Contents/CMakeLists.txt

@@ -37,7 +37,6 @@ SET(polycore_SRCS
     Source/PolyMesh.cpp
     Source/PolyModule.cpp
     Source/PolyObject.cpp
-    Source/PolyParticle.cpp
     Source/PolyParticleEmitter.cpp
     Source/PolyPerlin.cpp
     Source/PolyPolygon.cpp
@@ -125,7 +124,6 @@ SET(polycore_HDRS
     Include/PolyModule.h
     Include/PolyObject.h
     Include/PolyParticleEmitter.h
-    Include/PolyParticle.h
     Include/PolyPerlin.h
     Include/PolyPolygon.h
     Include/PolyQuaternionCurve.h

+ 0 - 59
Core/Contents/Include/PolyParticle.h

@@ -1,59 +0,0 @@
-/*
-Copyright (C) 2011 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 "PolyGlobals.h"
-#include "PolyVector3.h"
-
-namespace Polycode {
-
-	class Entity;
-	class Material;
-	class Mesh;
-	class Texture;
-
-	class _PolyExport Particle : public PolyBase {
-		public:
-			Particle(int particleType, bool isScreenParticle, Material *material, Texture *texture, Mesh *particleMesh);
-			~Particle();
-			void Reset(bool continuious);
-			
-			void createSceneParticle(int particleType, Material *material, Mesh *particleMesh);
-		
-			Entity *particleBody;						
-			
-			Vector3 velVector;
-			Vector3 dirVector;	
-			Vector3 deviation;		
-			Number life;
-			Number lifespan;
-			Number brightnessDeviation;
-			Number perlinPosX;
-			Number perlinPosY;
-			Number perlinPosZ;
-			
-			static Mesh* billboardMesh;
-			
-			static const int BILLBOARD_PARTICLE = 0;
-			static const int MESH_PARTICLE = 1;
-	};
-}

+ 136 - 297
Core/Contents/Include/PolyParticleEmitter.h

@@ -22,303 +22,142 @@ THE SOFTWARE.
 
 #pragma once
 #include "PolyGlobals.h"
-#include "PolyString.h"
-#include "PolyVector3.h"
-#include "PolyMatrix4.h"
+#include "PolySceneMesh.h"
+#include "PolyCore.h"
+#include "PolyPerlin.h"
 #include "PolyBezierCurve.h"
-#include "PolyEntity.h"
 
 namespace Polycode {
-
-	class Entity;
-	class Material;
-	class Mesh;
-	class Particle;
-	class Perlin;
-	class Scene;
-	class SceneMesh;
-	class Screen;
-	class ScreenMesh;
-	class Texture;
-	class Timer;
-
-	/** 
-	* Particle emitter base.
-	*/
-	class _PolyExport ParticleEmitter {
-		public:
-			ParticleEmitter(const String& imageFile, Mesh *particleMesh, int particleType, int emitterType, Number lifespan, unsigned int numParticles, Vector3 direction, Vector3 gravity, Vector3 deviation, Vector3 emitterRadius);
-			virtual ~ParticleEmitter();
-		
-			virtual void dispatchTriggerCompleteEvent();
-		
-			void createParticles();
-			
-			/**
-			* Sets the speed at which particles rotate
-			* @param speed New rotation speed.
-			*/ 
-			void setRotationSpeed(Number speed);
-			
-			/**
-			* Sets the blending mode used for the particles. See documentation for the Entity for information on blending modes.
-			* @param mode New blending mode.
-			*/ 			
-			void setParticleBlendingMode(int mode);
-			
-			int getParticleBlendingMode() const;
-			
-			/**
-			* Turns depth write on and off for particles.
-			*/ 						
-			void setDepthWrite(bool val);
-			
-			/**
-			* Turns depth test on and off for particles.
-			*/ 									
-			void setDepthTest(bool val);		
-			
-			/**
-			* Turns alpha testing on and off for particles.
-			*/ 												
-			void setAlphaTest(bool val);
-
-			/**
-			* Enables perlin noise movement for particles.
-			*/ 														
-			void enablePerlin(bool val);
-			
-			/**
-			* Sets visibility of all particles in the system
-			*/
-			void setParticleVisibility(bool val);
-			
-			/**
-			* Enables perlin noise movement size.
-			*/ 														
-			void setPerlinModSize(Number size);
-
-			/**
-			* Enables or disables billboard mode for particles.
-			*/ 																	
-			void setBillboardMode(bool mode);
-			
-			/**
-			* Enables or disables the emitter
-			*/ 																				
-			void enableEmitter(bool val);
-			
-			/**
-			* Returns true if the emitter is enabled, false otherwise.
-			*/ 																							
-			bool emitterEnabled();
-
-			/**
-			* Sets the emitter radius on all 3 axises.
-			*/ 																										
-			void setEmitterRadius(Vector3 rad);
-
-			/**
-			* If set to true, will release all particles at once.
-			*/ 																													
-			void setAllAtOnce(bool val);
-			
-
-			unsigned int getNumParticles() const;
-
-			Particle *getParticleAtIndex(unsigned int index) const;
-
-			/**
-			* If emitter mode is TRIGGERED_EMITTER, calling this method will trigger particle emission.
-			*/ 
-			
-			void resetAll();
-	
-			void Trigger();
-			
-			void resetParticle(Particle *particle);
-			
-			/**
-			* Changes the particle count in the emitter.
-			*/ 																													
-			void setParticleCount(int count);
-		
-			virtual Vector3 getParticleCompoundScale();
-			virtual void addParticleBody(Entity *particleBody);
-			virtual Matrix4 getBaseMatrix();
-		
-			/**
-			* Particle movement speed multiplier
-			*/ 																																								
-			Number particleSpeedMod;
-			
-			/**
-			* Particle brightness deviation
-			*/ 																																										
-			Number brightnessDeviation;
-			
-			void updateEmitter();
-
-			/**
-			* Continuous emitter setting.
-			*/ 																													
-			static const int CONTINUOUS_EMITTER = 0;
-
-			/**
-			* Triggered emitter setting.
-			*/ 																																
-			static const int TRIGGERED_EMITTER = 1;
-			
-			/**
-			* Particle direction deviation
-			*/ 																																							
-			Vector3 deviation;
-			/**
-			* Particle direction and emission strength vector
-			*/ 																																								
-			Vector3 dirVector;
-			
-			/**
-			* Particle gravity strength vector
-			*/ 																																								
-			Vector3 gravVector;			
-
-			/**
-			* Lifespan of particles.
-			*/ 																																						
-			Number lifespan;
-		
-			/**
-			* If set to true, particles' rotation will follow their movement.
-			*/ 																																		
-			bool rotationFollowsPath;
-
-			/**
-			* Bezier curve that controls the scale of the particles.
-			*/ 																																				
-			BezierCurve scaleCurve;
-
-			/**
-			* Bezier curve that controls the red component of particles' color.
-			*/ 																																						
-			BezierCurve colorCurveR;
-			/**
-			* Bezier curve that controls the green component of particles' color.
-			*/ 																																								
-			BezierCurve colorCurveG;
-			/**
-			* Bezier curve that controls the blue component of particles' color.
-			*/ 																																								
-			BezierCurve colorCurveB;
-			/**
-			* Bezier curve that controls the alpha component of particles' color.
-			*/ 																																								
-			BezierCurve colorCurveA;
-			
-			/**
-			* If set to true, will use the color curves to control particle color. False by default.
-			*/
-			bool useColorCurves;
-			
-			/**
-			* If set to true, will use the scale curve to control particle scale. False by default.
-			*/			
-			bool useScaleCurves;
-			
-			Number particleSize;
-			
-			Texture *getParticleTexture() const;
-		
-			Vector3 emitterRadius;
-					
-			Number perlinModSize;
-
-			bool perlinEnabled;
-				
-			Number rotationSpeed;
-							
-			int emitterType;
-			
-			bool getIgnoreParentMatrix() const;
-			void setIgnoreParentMatrix(bool val);
-											
-		protected:
-		
-			bool ignoreParentMatrix;
-		
-			int blendingMode;
-		
-			bool isScreenEmitter;
-			Mesh *pMesh;
-		
-			bool allAtOnce;
-			int particleType;
-			Material *particleMaterial;
-			Texture *particleTexture;
-		
-			String textureFile;
-		
-			bool isEmitterEnabled;
-		
-						
-			Perlin *motionPerlin;
-			
-			Number numParticles;
-			std::vector<Particle*> particles;
-			
-			Number emitSpeed;
-			Timer *timer;
-	};
-
-	/**
-	* 3D particle emitter.
-	*/
-	class _PolyExport SceneParticleEmitter : public Entity, public ParticleEmitter {
-	public:
-		/**
-		* Constructor.
-		* @param materialName Name of the material to use for particles.
-		* @param particleParentScene Scene to create particles in.
-		* @param particleType Type of particles to create. Can be Particle::BILLBOARD_PARTICLE or Particle::MESH_PARTICLE
-		* @param emitterType Type of emitter to create. Can be ParticleEmitter::CONTINUOUS_EMITTER or ParticleEmitter::TRIGGERED_EMITTER
-		* @param lifespan Lifetime of particles in seconds.
-		* @param numParticles Total number of particles to create.
-		* @param direction Direction of the emitter, length of this vector controls emitter strength
-		* @param gravity Gravity direction and strength
-		* @param deviation Emitter deviation on each axis
-		* @param particleMesh If particle type is Particle::MESH_PARTICLE, this must be set to the mesh to use for each particle
-		* @param emitter If this is specified, particles will be emitted from this meshe's vertices.
-		*/
-		SceneParticleEmitter(const String& materialName, int particleType, int emitterType, Number lifespan, unsigned int numParticles, Vector3 direction, Vector3 gravity, Vector3 deviation, Vector3 emitterRadius, Mesh *particleMesh = NULL, SceneMesh *emitter = NULL);
-		virtual ~SceneParticleEmitter();		
-		
-		/**
-		* Returns the emitter (helper method for LUA).
-		*/ 
-		ParticleEmitter *getEmitter() { return this; }
-		
-		void respawnSceneParticles();
-		void addParticleBody(Entity *particleBody);
-		Matrix4 getBaseMatrix();
-		void Update();
-		
-		Vector3 getParticleCompoundScale();
-		
-		void dispatchTriggerCompleteEvent();
-		
-			/**
-			* Continuous emitter setting.
-			*/ 																													
-			static const int CONTINUOUS_EMITTER = 0;
-
-			/**
-			* Triggered emitter setting.
-			*/ 																																
-			static const int TRIGGERED_EMITTER = 1;
-		
-		
-	protected:
-		SceneMesh *emitterMesh;		
-	};	
-		
-}
+    
+    class SceneParticle {
+        public:
+            Number lifetime;
+            Vector3 position;
+            Vector3 velocity;
+            Vector3 perlinPos;
+            Vector3 rotation;
+            Number brightnessDeviation;
+            Number scale;
+            Color color;
+    };
+    
+    class SceneParticleEmitter : public SceneMesh {
+        public:
+            SceneParticleEmitter(unsigned int particleCount, Number lifetime, Number speed);
+            virtual ~SceneParticleEmitter();
+        
+            void setParticleCount(unsigned int newParticleCount);
+            unsigned int getParticleCount() const;
+        
+            void setParticleLifetime(Number lifetime);
+            Number getParticleLifetime() const;
+        
+            void setDirectionDeviation(const Vector3 &newDeviation);
+            Vector3 getDirectionDeviation() const;
+        
+            void setEmitterSize(const Vector3 &newSize);
+            Vector3 getEmitterSize() const;
+        
+            void setGravity(const Vector3 &newGravity);
+            Vector3 getGravity() const;
+        
+            void Update();
+            void Render();
+        
+            void updateParticles();
+            void rebuildParticles();
+        
+            void setUseFloorPlane(bool val);
+            void setFloorPlaneOffset(Number floorPlaneOffset);
+            void setFloorDamping(Number floorDamping);
+        
+            void setParticlesInWorldSpace(bool val);
+            bool getParticlesInWorldSpace() const;
+        
+            void setPerlinEnabled(bool val);
+            bool getPerlinEnabled() const;
+        
+            void setPerlinValue(const Vector3 &perlinValue);
+            Vector3 getPerlinValue() const;
+        
+            void setParticleType(unsigned int particleType);
+            unsigned int getParticleType() const;
+        
+            void setParticleSize(Number particleSize);
+            Number getParticleSize() const;
+        
+            void setParticleRotationSpeed(const Vector3 &rotationSpeed);
+            Vector3 getParticleRotationSpeed() const;
+        
+            void setParticleDirection(const Vector3 &direction);
+            Vector3 getParticleDirection() const;
+        
+            void setLoopParticles(bool val);
+            bool getLoopParticles() const;
+        
+            static const int PARTICLE_TYPE_POINT = 0;
+            static const int PARTICLE_TYPE_QUAD = 1;
+
+        
+            bool useScaleCurve;
+        
+            /**
+             * Bezier curve that controls the scale of the particles.
+             */
+            BezierCurve scaleCurve;
+        
+            bool useColorCurves;
+
+            /**
+             * Bezier curve that controls the red component of particles' color.
+             */
+            BezierCurve colorCurveR;
+            /**
+             * Bezier curve that controls the green component of particles' color.
+             */
+            BezierCurve colorCurveG;
+            /**
+             * Bezier curve that controls the blue component of particles' color.
+             */
+            BezierCurve colorCurveB;
+            /**
+             * Bezier curve that controls the alpha component of particles' color.
+             */
+            BezierCurve colorCurveA;
+        
+        protected:
+        
+            void resetParticle(unsigned int index);
+        
+            Core *core;
+            unsigned int particleCount;
+            std::vector<SceneParticle> particles;
+            Number particleSpeed;
+            Number lifetime;
+            Number timeStep;
+            Number cyclesLeftOver;
+        
+            Vector3 directionVector;
+            Vector3 directionDeviation;
+            Vector3 emitterSize;
+            Vector3 gravity;
+        
+            Matrix4 systemTrasnformMatrix;
+            bool useFloorPlane;
+            bool particlesInWorldSpace;
+            bool perlinEnabled;
+            Vector3 perlinValue;
+            Perlin *motionPerlin;
+            Number particleSize;
+            Vector3 particleRotationSpeed;
+        
+            Number floorPlaneOffset;
+            Number floorDamping;
+        
+            bool loopParticles;
+        
+            unsigned int particleType;
+            Quaternion q;
+    };
+    
+}

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

@@ -26,9 +26,9 @@ THE SOFTWARE.
 #include "PolyEntity.h"
 #include "PolyObject.h"
 #include "PolyParticleEmitter.h"
-#include "PolyParticle.h"
 #include "PolyScenePrimitive.h"
 #include "PolyResource.h"
+#include "PolyBezierCurve.h"
 #include "PolySound.h"
 
 namespace Polycode {

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

@@ -70,7 +70,6 @@
 #include "PolyScenePrimitive.h"
 #include "PolySceneLabel.h"
 #include "PolyParticleEmitter.h"
-#include "PolyParticle.h"
 #include "PolySceneRenderTexture.h"
 #include "PolyResource.h"
 #include "PolyThreaded.h"

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

@@ -82,7 +82,6 @@ namespace Polycode {
 		}
 		
 		meshHasVertexBuffer = false;
-		useVertexColors = false;
 	}
 	
 	VertexBuffer *Mesh::getVertexBuffer() {

+ 0 - 118
Core/Contents/Source/PolyParticle.cpp

@@ -1,118 +0,0 @@
-/*
- Copyright (C) 2011 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 "PolyParticle.h"
-#include "PolyMesh.h"
-#include "PolyPolygon.h"
-#include "PolySceneMesh.h"
-
-using namespace Polycode;
-
-Mesh *Particle::billboardMesh = 0;
-
-Particle::Particle(int particleType, bool isScreenParticle, Material *material, Texture *texture, Mesh *particleMesh) {
-	life = 0;
-	createSceneParticle(particleType, material, particleMesh);
-	
-	Reset(true);
-}
-
-void Particle::createSceneParticle(int particleType, Material *material, Mesh *particleMesh) {
-	switch(particleType) {
-		case BILLBOARD_PARTICLE:
-		{
-			if(!billboardMesh) {
-				billboardMesh = new Mesh(Mesh::QUAD_MESH);
-				
-				Polygon *imagePolygon = new Polygon();
-				imagePolygon->addVertex(0,1,0,0,0);	
-				imagePolygon->addVertex(1,1,0, 1, 0);			
-				imagePolygon->addVertex(1,0,0, 1, 1);		
-				imagePolygon->addVertex(0,0,0,0,1);
-
-				billboardMesh->addPolygon(imagePolygon);
-		
-		for(int i=0; i < billboardMesh->getPolygonCount(); i++) {
-			for(int j=0; j < billboardMesh->getPolygon(i)->getVertexCount(); j++) {
-				billboardMesh->getPolygon(i)->getVertex(j)->x = billboardMesh->getPolygon(i)->getVertex(j)->x - (1.0/2.0f);
-				billboardMesh->getPolygon(i)->getVertex(j)->z = billboardMesh->getPolygon(i)->getVertex(j)->z - (1.0/2.0f);
-			}
-		}
-
-		billboardMesh->calculateNormals();
-		billboardMesh->arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;		
-		billboardMesh->arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;				
-		billboardMesh->arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;						
-		billboardMesh->arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;					
-				
-			} 
-			SceneMesh *primitive = new SceneMesh(billboardMesh);
-			
-			primitive->setMaterial(material);
-			primitive->billboardMode = true;
-			primitive->billboardRoll = true;
-//			primitive->alphaTest = true;
-//			primitive->depthTest = false;
-			primitive->depthWrite = false;
-			primitive->backfaceCulled = false;
-			particleBody = primitive;			
-		}
-			break;
-		case MESH_PARTICLE: 
-		{
-			SceneMesh *primitive = new SceneMesh(particleMesh);
-			if(particleMesh->getMeshType() == Mesh::TRI_MESH)
-				primitive->cacheToVertexBuffer(true);
-			primitive->setMaterial(material);
-			//			primitive->billboardMode = true;
-			//			primitive->billboardRoll = true;
-			//primitive->depthTest = false;
-			//			primitive->backfaceCulled = false;
-			particleBody = primitive;						
-		}			
-		break;
-		default:
-			assert(0);
-		break;
-	}
-}
-
-
-void Particle::Reset(bool continuious) {
-	if(continuious) {
-		if(life > lifespan)
-			life = 0 + (life - lifespan);
-		else
-			life = 0;
-	} else {
-			life = 0;		
-	}
-
-	perlinPosX = (Number)rand()/RAND_MAX;
-	perlinPosY = (Number)rand()/RAND_MAX;
-	perlinPosZ = (Number)rand()/RAND_MAX;
-	
-}
-
-Particle::~Particle() {
-
-}

+ 262 - 411
Core/Contents/Source/PolyParticleEmitter.cpp

@@ -22,460 +22,311 @@
 
 #include "PolyParticleEmitter.h"
 #include "PolyCoreServices.h"
-#include "PolyParticle.h"
-#include "PolyPerlin.h"
-#include "PolyResource.h"
-#include "PolyScene.h"
-#include "PolyTimer.h"
-#include "PolyMaterialManager.h"
-#include "PolyResourceManager.h"
+#include "PolyCore.h"
+#include "PolyMesh.h"
 #include "PolyRenderer.h"
 
 using namespace Polycode;
 
-SceneParticleEmitter::SceneParticleEmitter(const String& materialName, int particleType, int emitterType, Number lifespan, unsigned int numParticles, Vector3 direction, Vector3 gravity, Vector3 deviation, Vector3 emitterRadius, Mesh *particleMesh, SceneMesh *emitter)
-: Entity(),
-ParticleEmitter(materialName, particleMesh, particleType, emitterType, lifespan, numParticles,  direction, gravity, deviation, emitterRadius)
-{
-	isScreenEmitter = false;
-	emitterMesh = emitter;	
-	createParticles();	
-	
+SceneParticleEmitter::SceneParticleEmitter(unsigned int particleCount, Number lifetime, Number speed) : SceneMesh(Mesh::POINT_MESH), particleCount(particleCount), particleSpeed(speed), lifetime(lifetime), directionVector(0.0, 1.0, 0.0), timeStep(0.01666), cyclesLeftOver(0.0), useFloorPlane(false), floorPlaneOffset(-1.0), floorDamping(0.5), particlesInWorldSpace(false), perlinEnabled(false), perlinValue(1.0,1.0,1.0), particleType(SceneParticleEmitter::PARTICLE_TYPE_POINT), particleSize(0.1), particleRotationSpeed(0.0, 0.0, 0.0), useColorCurves(false), useScaleCurve(false), loopParticles(true){
+    
+    core = CoreServices::getInstance()->getCore();
+    motionPerlin = new Perlin(3,5,1.0,RANDOM_NUMBER);
+    mesh->useVertexColors = true;
+    depthTest = false;
+    setParticleCount(particleCount);
+    
 }
 
 SceneParticleEmitter::~SceneParticleEmitter() {
-	
+    delete motionPerlin;
+}
+
+void SceneParticleEmitter::resetParticle(unsigned int index) {
+    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));
+    particles[index].velocity = q.applyTo(directionVector);
+    particles[index].position = Vector3(-emitterSize.x + (emitterSize.x * RANDOM_NUMBER * 2.0), -emitterSize.y + (emitterSize.y * RANDOM_NUMBER * 2.0), -emitterSize.z + (emitterSize.z * RANDOM_NUMBER * 2.0));
+    
+    if(particlesInWorldSpace) {
+        particles[index].position = systemTrasnformMatrix * particles[index].position;
+        particles[index].velocity = systemTrasnformMatrix.rotateVector( particles[index].velocity);
+    }
+}
+
+void SceneParticleEmitter::setParticleCount(unsigned int newParticleCount) {
+    particleCount = newParticleCount;
+    particles.resize(particleCount);
+    for(int i=0; i < particles.size(); i++) {
+        resetParticle(i);
+        particles[i].lifetime = RANDOM_NUMBER * lifetime;
+        particles[i].perlinPos = Vector3(RANDOM_NUMBER, RANDOM_NUMBER, RANDOM_NUMBER);
+        particles[i].brightnessDeviation = 1.0;
+        particles[i].scale = 1.0;
+    }
+}
+
+void SceneParticleEmitter::setGravity(const Vector3 &newGravity) {
+    gravity = newGravity;
+}
+
+void SceneParticleEmitter::setDirectionDeviation(const Vector3 &newDeviation) {
+    directionDeviation = newDeviation;
+}
+
+void SceneParticleEmitter::setEmitterSize(const Vector3 &newSize) {
+    emitterSize = newSize;
+}
+
+void SceneParticleEmitter::setParticleType(unsigned int particleType) {
+    this->particleType = particleType;
+}
+
+void SceneParticleEmitter::setParticleSize(Number particleSize) {
+    this->particleSize = particleSize;
+}
+
+void SceneParticleEmitter::setParticleRotationSpeed(const Vector3 &rotationSpeed) {
+    particleRotationSpeed = rotationSpeed;
+    for(int i=0; i < particles.size(); i++) {
+        particles[i].rotation = Vector3();
+    }
+}
+
+void SceneParticleEmitter::setLoopParticles(bool val) {
+    loopParticles = val;
+    for(int i=0; i < particles.size(); i++) {
+        resetParticle(i);
+        particles[i].lifetime = RANDOM_NUMBER * lifetime;
+    }
+}
+
+bool SceneParticleEmitter::getLoopParticles() const {
+    return loopParticles;
+}
+
+
+void SceneParticleEmitter::rebuildParticles() {
+    mesh->clearMesh();
+    
+    switch(particleType) {
+        case PARTICLE_TYPE_POINT:
+        {
+            mesh->setMeshType(Mesh::POINT_MESH);
+            Polycode::Polygon *poly = new Polycode::Polygon();
+            Matrix4 inverseMatrix = systemTrasnformMatrix.Inverse();
+            for(int i=0; i < particles.size(); i++) {
+                if(particles[i].lifetime > lifetime) {
+                    continue;
+                }
+                Vector3 vertexPosition = particles[i].position;
+                if(particlesInWorldSpace) {
+                    vertexPosition = inverseMatrix * vertexPosition;
+                }
+                poly->addVertex(vertexPosition.x, vertexPosition.y, vertexPosition.z, 0.5, 0.5)->vertexColor = particles[i].color;
+            }
+            mesh->addPolygon(poly);
+        }
+        break;
+        case PARTICLE_TYPE_QUAD:
+        {
+            mesh->setMeshType(Mesh::QUAD_MESH);
+            Matrix4 inverseMatrix = systemTrasnformMatrix.Inverse();
+            Matrix4 cameraMatrix = renderer->getCameraMatrix();
+            Quaternion q;
+            
+            Color vertexColor;
+            Number finalParticleSize;
+            for(int i=0; i < particles.size(); i++) {
+                if(particles[i].lifetime > lifetime) {
+                    continue;
+                }
+                q.fromAxes(particles[i].rotation.x, particles[i].rotation.y, particles[i].rotation.z);
+                vertexColor = particles[i].color;
+                finalParticleSize = particleSize * particles[i].scale;
+                
+                Polycode::Polygon *poly = new Polycode::Polygon();
+                Vector3 particlePosition = particles[i].position;
+                if(particlesInWorldSpace) {
+                    particlePosition = inverseMatrix * particlePosition;
+                }
+                
+                Vector3 vertexPosition = Vector3(-finalParticleSize, -finalParticleSize, 0.0);
+                vertexPosition = q.applyTo(vertexPosition);
+                vertexPosition = cameraMatrix.rotateVector(vertexPosition);
+                poly->addVertex(particlePosition.x+vertexPosition.x, particlePosition.y+vertexPosition.y, particlePosition.z+vertexPosition.z, 0.0, 0.0)->vertexColor = vertexColor;
+                
+                vertexPosition = Vector3(finalParticleSize, -finalParticleSize, 0.0);
+                vertexPosition = q.applyTo(vertexPosition);
+                vertexPosition = cameraMatrix.rotateVector(vertexPosition);
+                poly->addVertex(particlePosition.x+vertexPosition.x, particlePosition.y+vertexPosition.y, particlePosition.z+vertexPosition.z, 1.0, 0.0)->vertexColor = vertexColor;
+
+                vertexPosition = Vector3(finalParticleSize, finalParticleSize, 0.0);
+                vertexPosition = q.applyTo(vertexPosition);
+                vertexPosition = cameraMatrix.rotateVector(vertexPosition);
+                poly->addVertex(particlePosition.x+vertexPosition.x, particlePosition.y+vertexPosition.y, particlePosition.z+vertexPosition.z, 1.0, 1.0)->vertexColor = vertexColor;
+
+                vertexPosition = Vector3(-finalParticleSize, finalParticleSize, 0.0);
+                vertexPosition = q.applyTo(vertexPosition);
+                vertexPosition = cameraMatrix.rotateVector(vertexPosition);
+                poly->addVertex(particlePosition.x+vertexPosition.x, particlePosition.y+vertexPosition.y, particlePosition.z+vertexPosition.z, 0.0, 1.0)->vertexColor = vertexColor;
+
+                
+                mesh->addPolygon(poly);
+
+            }
+        }
+            break;
+            
+    }
+  
+    mesh->dirtyArrays();
+//    mesh->dirtyArray(RenderDataArray::VERTEX_DATA_ARRAY);
+ //   mesh->dirtyArray(RenderDataArray::COLOR_DATA_ARRAY);
 }
 
-void SceneParticleEmitter::respawnSceneParticles() {
-	for(int i=0; i < particles.size(); i++) {
-		Particle *particle = particles[i];
-		removeChild((Entity*)particle->particleBody);
-		addParticleBody(particle->particleBody);
-		resetParticle(particle);				
-		particle->life = lifespan * ((Number)rand()/RAND_MAX);		
-	}
-	updateEmitter();
+unsigned int SceneParticleEmitter::getParticleCount() const {
+    return particleCount;
 }
 
-void SceneParticleEmitter::addParticleBody(Entity *particleBody) {
-	addChild((Entity*)particleBody);	
-	particleBody->editorOnly = true;
+unsigned int SceneParticleEmitter::getParticleType() const {
+    return particleType;
 }
 
-void SceneParticleEmitter::dispatchTriggerCompleteEvent() {
-	((EventDispatcher*)this)->dispatchEvent(new Event(Event::COMPLETE_EVENT), Event::COMPLETE_EVENT);
+void SceneParticleEmitter::setUseFloorPlane(bool val) {
+    useFloorPlane = val;
 }
 
-Matrix4 SceneParticleEmitter::getBaseMatrix() {
-	rebuildTransformMatrix();
-	return getConcatenatedMatrix();
+void SceneParticleEmitter::setParticlesInWorldSpace(bool val) {
+    particlesInWorldSpace = val;
 }
 
-void SceneParticleEmitter::Update() {
-	updateEmitter();
-}
-
-ParticleEmitter::ParticleEmitter(const String& imageFile, Mesh *particleMesh, int particleType, int emitterType, Number lifespan, unsigned int numParticles,  Vector3 direction, Vector3 gravity, Vector3 deviation, Vector3 emitterRadius)  {
-	
-	this->emitterRadius = emitterRadius;	
-	isScreenEmitter = false;
-	dirVector = direction;
-	gravVector = gravity;
-	ignoreParentMatrix = false;
-	this->emitterType = emitterType;
-	// TODO: initialize emitSpeed
-	this->deviation = deviation;
-	pMesh = particleMesh;
-	rotationFollowsPath = false;
-	rotationSpeed = 100.0f;
-	perlinEnabled = false;
-	emitterRadius = Vector3(0.0f,0.0f,0.0f);
-	perlinModSize = 0.002;
-	brightnessDeviation = 0.0f;
-	particleSpeedMod = 1.0f;
-	isEmitterEnabled = true;
-	allAtOnce = false;
-	
-	blendingMode = Renderer::BLEND_MODE_NORMAL;
-	
-	particleSize = 1.0;
-	
-	scaleCurve.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
-	scaleCurve.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);	
-
-	colorCurveR.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
-	colorCurveR.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);	
-
-	colorCurveG.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
-	colorCurveG.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);	
-
-	colorCurveB.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
-	colorCurveB.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);	
-
-	colorCurveA.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
-	colorCurveA.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);	
-	
-	
-	this->particleType = particleType;
-	
-	this->numParticles = numParticles;
-
-	this->lifespan = lifespan;
-	timer = new Timer(true, 1);	
-	motionPerlin = new Perlin(3,5,1.0,rand());
-	
-	textureFile = imageFile;
-	
-	useColorCurves = false;
-	useScaleCurves = false;	
+void SceneParticleEmitter::setParticleLifetime(Number lifetime) {
+    this->lifetime = lifetime;
+    for(int i=0; i < particles.size(); i++) {
+        resetParticle(i);
+        particles[i].lifetime = RANDOM_NUMBER * lifetime;
+    }
+}
+
+Vector3 SceneParticleEmitter::getDirectionDeviation() const {
+    return directionDeviation;
+}
+
+Vector3 SceneParticleEmitter::getPerlinValue() const {
+    return perlinValue;
+}
+
+bool SceneParticleEmitter::getPerlinEnabled() const {
+    return perlinEnabled;
 }
 
-bool ParticleEmitter::getIgnoreParentMatrix() const {
-	return ignoreParentMatrix;
+Vector3 SceneParticleEmitter::getEmitterSize() const {
+    return emitterSize;
 }
 
-void ParticleEmitter::setIgnoreParentMatrix(bool val) {
-	ignoreParentMatrix = val;
-	for(int i=0; i < particles.size(); i++) {
-		particles[i]->particleBody->ignoreParentMatrix = ignoreParentMatrix;
-	}
+Vector3 SceneParticleEmitter::getGravity() const {
+    return gravity;
 }
 
+Number SceneParticleEmitter::getParticleLifetime() const {
+    return lifetime;
+}
 
-Texture *ParticleEmitter::getParticleTexture() const {
-	return particleTexture;
+bool SceneParticleEmitter::getParticlesInWorldSpace() const {
+    return particlesInWorldSpace;
 }
 
-			
-void ParticleEmitter::createParticles() {
-	
-	if(isScreenEmitter)
-		particleTexture = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(textureFile);	
-	else
-		particleMaterial = (Material*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, textureFile);	
-	
-	
-	Particle *particle;	
-	for(int i=0; i < numParticles; i++) {
-		particle = new Particle(particleType, isScreenEmitter, particleMaterial, particleTexture, pMesh);
-		particle->particleBody->ignoreParentMatrix = ignoreParentMatrix;
-		particle->velVector = dirVector;
-		particle->dirVector = dirVector;
-		particle->deviation = deviation;
-		particle->lifespan = lifespan;
-		particles.push_back(particle);
-		addParticleBody(particle->particleBody);					
-		resetParticle(particle);
-		particle->life = lifespan * ((Number)rand()/RAND_MAX);		
-	}
-	updateEmitter();	
+Number SceneParticleEmitter::getParticleSize() const {
+    return particleSize;
 }
 
-void ParticleEmitter::dispatchTriggerCompleteEvent() {
+void SceneParticleEmitter::setFloorPlaneOffset(Number floorPlaneOffset) {
+    this->floorPlaneOffset = floorPlaneOffset;
 }
 
-void ParticleEmitter::addParticleBody(Entity *particleBody) {
-}
-			
-Matrix4 ParticleEmitter::getBaseMatrix() {
-	return Matrix4();
+void SceneParticleEmitter::setParticleDirection(const Vector3 &direction) {
+    directionVector = direction;
 }
-			
-void ParticleEmitter::setEmitterRadius(Vector3 rad) {
-	emitterRadius = rad;
+
+Vector3 SceneParticleEmitter::getParticleDirection() const {
+    return directionVector;
 }
 
-void ParticleEmitter::setRotationSpeed(Number speed) {
-	rotationSpeed = speed;
+void SceneParticleEmitter::setFloorDamping(Number floorDamping) {
+    this->floorDamping = floorDamping;
 }
 
-void ParticleEmitter::setParticleVisibility(bool val) {
-	for(int i=0;i < particles.size(); i++) {
-		particles[i]->particleBody->visible = val;
-	}
+Vector3 SceneParticleEmitter::getParticleRotationSpeed() const {
+    return particleRotationSpeed;
 }
 
-void ParticleEmitter::setParticleBlendingMode(int mode) {
-	blendingMode = mode;
-	for(int i=0;i < particles.size(); i++) {
-		particles[i]->particleBody->setBlendingMode(mode);
-	}
+void SceneParticleEmitter::setPerlinEnabled(bool val) {
+    perlinEnabled = val;
 }
 
-int ParticleEmitter::getParticleBlendingMode() const {
-	return blendingMode;
+void SceneParticleEmitter::setPerlinValue(const Vector3 &perlinValue) {
+    this->perlinValue = perlinValue;
 }
 
-void ParticleEmitter::setAlphaTest(bool val) {
-	for(int i=0;i < particles.size(); i++) {
-		particles[i]->particleBody->alphaTest = val;
-	}		
+void SceneParticleEmitter::updateParticles() {
+    Number normLife;
+    
+    for(int i=0; i < particles.size(); i++) {
+        particles[i].lifetime += timeStep;
+        if(particles[i].lifetime > lifetime) {
+            if(loopParticles) {
+                resetParticle(i);
+            }
+        }
+        
+        normLife = particles[i].lifetime / lifetime;
+        if(useColorCurves) {
+            particles[i].color.setColor(colorCurveR.getHeightAt(normLife)*particles[i].brightnessDeviation,
+                                        colorCurveG.getHeightAt(normLife)*particles[i].brightnessDeviation,
+                                        colorCurveB.getHeightAt(normLife)*particles[i].brightnessDeviation,
+                                        colorCurveA.getHeightAt(normLife)*particles[i].brightnessDeviation);
+        } else {
+            particles[i].color = color;
+        }
+        
+        if(useScaleCurve) {
+            particles[i].scale = scaleCurve.getHeightAt(normLife);
+        } else {
+            particles[i].scale = 1.0;
+        }
+        
+        particles[i].rotation += particleRotationSpeed *timeStep;
+        
+        particles[i].velocity += gravity * timeStep;
+        particles[i].position += particles[i].velocity * timeStep * particleSpeed;
+        if(perlinEnabled) {
+            
+            particles[i].position += Vector3(motionPerlin->Get((particles[i].lifetime/lifetime), particles[i].perlinPos.x) * perlinValue.x * timeStep, motionPerlin->Get((particles[i].lifetime/lifetime), particles[i].perlinPos.y) * perlinValue.y * timeStep , motionPerlin->Get((particles[i].lifetime/lifetime), particles[i].perlinPos.z) * perlinValue.z * timeStep);
+        }
+        
+        if(useFloorPlane) {
+            if(particles[i].position.y <= floorPlaneOffset) {
+                particles[i].position.y = floorPlaneOffset;
+                particles[i].velocity.y *= -1.0 * floorDamping;
+            }
+        }
+    }
 }
 
-void ParticleEmitter::setDepthWrite(bool val) {
-	for(int i=0;i < particles.size(); i++) {
-		particles[i]->particleBody->depthWrite = val;
-	}	
+void SceneParticleEmitter::Render() {
+    rebuildParticles();
+    SceneMesh::Render();
 }
 
-void ParticleEmitter::setDepthTest(bool val) {
-	for(int i=0;i < particles.size(); i++) {
-		particles[i]->particleBody->depthTest= val;
-	}	
-}
-
-
-void ParticleEmitter::setBillboardMode(bool mode) {
-	for(int i=0;i < particles.size(); i++) {
-		particles[i]->particleBody->billboardMode = mode;
-	}
-}
-
-void ParticleEmitter::enablePerlin(bool val) {
-	perlinEnabled = val;
-}
-
-ParticleEmitter::~ParticleEmitter() {
-	
-}
-
-void ParticleEmitter::setParticleCount(int count) {
-	if(count > particles.size()) {
-		int oldSize  = count-particles.size();
-		Particle *particle;
-		for(int i=0; i  < oldSize; i++) {
-			particle = new Particle(particleType, isScreenEmitter, particleMaterial, particleTexture, pMesh);
-			particle->particleBody->ignoreParentMatrix = ignoreParentMatrix;
-			particle->velVector = dirVector;
-			particle->dirVector = dirVector;
-			particle->deviation = deviation;
-			particle->lifespan = lifespan;
-			particle->life = lifespan * ((Number)rand()/RAND_MAX);
-			particles.push_back(particle);
-			addParticleBody(particle->particleBody);
-		}
-	}
-	numParticles = count;
-	for(int i=0; i < particles.size(); i++) {
-		if(i < numParticles)
-			particles[i]->particleBody->visible =true;
-		else
-			particles[i]->particleBody->visible = false;
-	}
-	resetAll();
-}
-
-void ParticleEmitter::setPerlinModSize(Number size) {
-	perlinModSize = size;
-
-}
-
-void ParticleEmitter::enableEmitter(bool val) {
-	isEmitterEnabled = val;
-	if(val) {
-		for(int i=0;i < numParticles; i++) {
-			particles[i]->life = particles[i]->lifespan * ((Number)rand()/RAND_MAX);
-		}
-	}
-}
-
-void ParticleEmitter::Trigger() {
-	if(!isEmitterEnabled)
-		return;
-	for(int i=0;i < numParticles; i++) {
-			resetParticle(particles[i]);
-	}
-}
-
-bool ParticleEmitter::emitterEnabled() {
-	return isEmitterEnabled;
-}
-
-void ParticleEmitter::resetParticle(Particle *particle) {
-//	particle->particleBody->visible = true;
-	particle->lifespan  = lifespan;
-	Matrix4 concatMatrix = getBaseMatrix();
-	
-	Vector3	startVector;
-	
-	Vector3 compoundScale(1.0, 1.0, 1.0);
-	if(ignoreParentMatrix) {
-		compoundScale = getParticleCompoundScale();
-	}
-	
-	particle->dirVector = dirVector;
-//	if(emitterMesh) {
-//		Polygon *randPoly = emitterMesh->getMesh()->getPolygon(rand() % emitterMesh->getMesh()->getPolygonCount());		
-//		startVector = *randPoly->getVertex(rand() % 3);
-//		startVector = emitterMesh->getConcatenatedMatrix() * startVector;
-//	} else {
-		startVector = Vector3(-(emitterRadius.x/2.0f)+emitterRadius.x*((Number)rand()/RAND_MAX),-(emitterRadius.y/2.0f)+emitterRadius.y*((Number)rand()/RAND_MAX),-(emitterRadius.z/2.0f)+emitterRadius.z*((Number)rand()/RAND_MAX));	
-//	}
-		
-	
-	particle->Reset(emitterType != TRIGGERED_EMITTER);	
-	particle->velVector = particle->dirVector;
-	Number dev = ((deviation.x/2.0f)*-1.0f) + ((deviation.x)*((Number)rand()/RAND_MAX));
-	particle->velVector.x += dev;
-	dev = (deviation.y/2.0f*-1.0f) + ((deviation.y)*((Number)rand()/RAND_MAX));
-	particle->velVector.y += dev;
-	dev = (deviation.z/2.0f*-1.0f) + ((deviation.z)*((Number)rand()/RAND_MAX));
-	particle->velVector.z += dev;
-	
-	particle->brightnessDeviation = 1.0f - ( (-brightnessDeviation) + ((brightnessDeviation*2) * ((Number)rand()/RAND_MAX)));
-	
-//	particle->velVector = concatMatrix.rotateVector(particle->velVector);	
-
-	if(ignoreParentMatrix) {
-		particle->particleBody->setPosition(concatMatrix.getPosition());
-	} else {
-		particle->particleBody->setPosition(0.0, 0.0, 0.0);
-	}
-	
-	particle->particleBody->Translate(startVector);
-	particle->particleBody->rebuildTransformMatrix();	
-	
-	if(useScaleCurves) {
-		particle->particleBody->setScale(scaleCurve.getHeightAt(0) * particleSize * compoundScale.x,
-									 scaleCurve.getHeightAt(0) * particleSize * compoundScale.y,
-									 scaleCurve.getHeightAt(0) * particleSize * compoundScale.z);
-	} else {
-		particle->particleBody->setScale(particleSize  * compoundScale.x, particleSize * compoundScale.y, particleSize * compoundScale.z);
-	}
-	
-	if(useColorCurves) {
-		particle->particleBody->color.setColor(colorCurveR.getHeightAt(0),
-										   colorCurveG.getHeightAt(0),
-										   colorCurveB.getHeightAt(0),
-										   colorCurveA.getHeightAt(0));
-	} else {
-		particle->particleBody->color.setColor(1.0, 1.0, 1.0, 1.0);
-	}
-	
-			
-}
-
-Vector3 SceneParticleEmitter::getParticleCompoundScale() {
-	return getCompoundScale();
-}
-
-
-Vector3 ParticleEmitter::getParticleCompoundScale() {
-	return Vector3();
-}
-			
-void ParticleEmitter::resetAll() {
-	for(int i=0;i < particles.size(); i++) {
-		if(allAtOnce)
-			particles[i]->life = 0;
-		else
-			particles[i]->life = particles[i]->lifespan * ((Number)rand()/RAND_MAX);
-	}
-}
-
-void ParticleEmitter::setAllAtOnce(bool val) {
-	allAtOnce = val;
-	resetAll();
-}
-
-unsigned int ParticleEmitter::getNumParticles() const {
-	return numParticles;
-}
-
-Particle *ParticleEmitter::getParticleAtIndex(unsigned int index) const {
-	if(index < particles.size()) {
-		return particles[index];
-	} else {
-		return NULL;
-	}
-}
-
-
-void ParticleEmitter::updateEmitter() {	
-	
-	Vector3 translationVector;
-	Number elapsed = timer->getElapsedf();
-	
-	Particle *particle;
-	Number normLife;
-	
-	Vector3 compoundScale(1.0, 1.0, 1.0);
-	if(ignoreParentMatrix) {
-		compoundScale = getParticleCompoundScale();
-	}
-	
-	for(int i=0;i < numParticles; i++) {	
-		particle = particles[i];
-		
-		normLife = particle->life / particle->lifespan;
-		Vector3 gVec = gravVector;
-		particle->life += elapsed;
-		particle->velVector -= gVec*elapsed*particleSpeedMod;
-		translationVector = particle->velVector;
-		translationVector = translationVector*elapsed*particleSpeedMod;
-		if(perlinEnabled) {
-			translationVector.x += ((perlinModSize * motionPerlin->Get((particle->life/particle->lifespan), particle->perlinPosX))*elapsed*particleSpeedMod);
-			translationVector.y += ((perlinModSize * motionPerlin->Get((particle->life/particle->lifespan), particle->perlinPosY))*elapsed*particleSpeedMod);
-			translationVector.z += ((perlinModSize * motionPerlin->Get((particle->life/particle->lifespan), particle->perlinPosZ))*elapsed*particleSpeedMod);
-		}
-		
-		if(isScreenEmitter) {		
-			translationVector.z = 0;
-		}
-		
-		particle->particleBody->Translate(translationVector);
-		
-		
-		if(rotationFollowsPath)  {
-			if(isScreenEmitter) {
-				Number angle = atan2(translationVector.x, translationVector.y);
-				particle->particleBody->setRoll(360 - ((angle * TODEGREES)+180));
-			
-			} else {
-				particle->particleBody->lookAt(particle->particleBody->getPosition() + translationVector, Vector3(1,0,0));			
-			}
-		} else {
-			if(isScreenEmitter) {
-				particle->particleBody->Roll(rotationSpeed*elapsed);
-			} else {
-				particle->particleBody->Roll(rotationSpeed*elapsed);
-				particle->particleBody->Pitch(rotationSpeed*elapsed);
-				particle->particleBody->Yaw(rotationSpeed*elapsed);						
-			}
-		}		
-		
-//		if(isScreenEmitter)
-//			particle->particleBody->setPositionZ(0);		
-		
-		if(useColorCurves) {
-			particle->particleBody->color.setColor(colorCurveR.getHeightAt(normLife)*particle->brightnessDeviation,
-											   colorCurveG.getHeightAt(normLife)*particle->brightnessDeviation,
-											   colorCurveB.getHeightAt(normLife)*particle->brightnessDeviation,
-											   colorCurveA.getHeightAt(normLife)*particle->brightnessDeviation);
-		} else {
-			particle->particleBody->color.setColor(particle->brightnessDeviation,
-											   particle->brightnessDeviation,
-											   particle->brightnessDeviation,
-											   1.0);		
-		}
-	
-		if(useScaleCurves) {
-			particle->particleBody->setScale(scaleCurve.getHeightAt(normLife) * particleSize * compoundScale.x,
-										 scaleCurve.getHeightAt(normLife) * particleSize * compoundScale.y,
-										 scaleCurve.getHeightAt(normLife) * particleSize * compoundScale.z);
-		
-		} else {
-			particle->particleBody->setScale(particleSize*compoundScale.x, particleSize*compoundScale.y, particleSize*compoundScale.z);
-		}
-		
-		if(particle->life > particle->lifespan && isEmitterEnabled) {
-			if(emitterType == CONTINUOUS_EMITTER) {
-				resetParticle(particle);
-			} else {
-			//	dispatchTriggerCompleteEvent();
-//				particle->particleBody->visible = false;
-			}
-		}
-	}
+void SceneParticleEmitter::Update() {
+    systemTrasnformMatrix = getConcatenatedMatrix();
+    Number elapsed = core->getElapsed() + cyclesLeftOver;
+    
+    while(elapsed > timeStep) {
+        elapsed -= timeStep;
+        updateParticles();
+    }
+    cyclesLeftOver = elapsed;
+    SceneMesh::Update();
 }

+ 5 - 3
Core/Contents/Source/PolySceneLine.cpp

@@ -74,12 +74,14 @@ void SceneLine::Update(){
 	if(ent1 != NULL && ent2 != NULL) {
 		v1 = ent1->getConcatenatedMatrix().getPosition();
 		v2 = ent2->getConcatenatedMatrix().getPosition();
+        mesh->getPolygon(0)->getVertex(0)->set(v1.x,v1.y,v1.z);
+        mesh->getPolygon(0)->getVertex(1)->set(v2.x,v2.y,v2.z);
 	} else {
 		v1 = start;
 		v2 = end;
+        mesh->getPolygon(0)->getVertex(0)->set(v1.x,v1.y*yAdjust,v1.z);
+        mesh->getPolygon(0)->getVertex(1)->set(v2.x,v2.y*yAdjust,v2.z);
 	}
 	
-	mesh->getPolygon(0)->getVertex(0)->set(v1.x,v1.y*yAdjust,v1.z);
-	mesh->getPolygon(0)->getVertex(1)->set(v2.x,v2.y*yAdjust,v2.z);
-	mesh->arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;	
+	mesh->arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
 }

Разница между файлами не показана из-за своего большого размера
+ 3 - 3
IDE/Assets/ide_icons.ai


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

@@ -48,5 +48,6 @@ class EntityEditorPropertyView : public UIElement {
         MaterialPropSheet *materialSheet;
         ScenePrimitiveSheet *primitiveSheet;
         SceneLightSheet *lightSheet;
+        ParticleEmitterSheet *particleSheet;
 };
 

+ 5 - 6
IDE/Contents/Include/PolycodeFrame.h

@@ -51,12 +51,11 @@ class EditPoint : public Entity {
 		
 		void setMode(unsigned int mode);
 
-		void limitPoint(UIImage *point);
+		void limitPoint(UIRect *point);
 								
-		UIImage *pointHandle;
-		
-		UIImage *controlHandle1;
-		UIImage *controlHandle2;
+		UIRect *pointHandle;
+		UIRect *controlHandle1;
+		UIRect *controlHandle2;
 		
 		SceneLine *connectorLine1;
 		SceneLine *connectorLine2;
@@ -134,7 +133,7 @@ class CurveEditor : public UIWindow {
 		UITreeContainer *treeContainer;
 		
 		unsigned int mode;
-		UIImage *bg;
+		UIRect *bg;
 		
 		EditCurve *selectedCurve;
 		std::vector<EditCurve*> curves;

+ 0 - 3
IDE/Contents/Include/PolycodeMaterialEditor.h

@@ -206,9 +206,6 @@ class PostEditorPane : public UIElement {
 		BoolProp *fp16Prop;
 		
 		PostPreviewBox *postPreview;
-		
-		Screen *previewScreen;
-		
 					
 };
 

+ 37 - 2
IDE/Contents/Include/PolycodeProps.h

@@ -554,6 +554,43 @@ class TransformSheet : public PropSheet {
         Vector3 lastRotation;
 };
 
+class ParticleEmitterSheet : public PropSheet {
+    public:
+        ParticleEmitterSheet();
+        ~ParticleEmitterSheet();
+    
+        void handleEvent(Event *event);
+        void setParticleEmitter(SceneParticleEmitter *emitter);
+    
+    protected:
+        SceneParticleEmitter *emitter;
+    
+        ComboProp *typeProp;
+        NumberProp *countProp;
+        NumberProp *lifetimeProp;
+        NumberProp *particleSizeProp;
+
+        BoolProp *worldParticlesProp;
+        BoolProp *loopingProp;
+
+        Vector3Prop *particleRotaionProp;
+    
+        Vector3Prop *gravityProp;
+        Vector3Prop *directionProp;
+        Vector3Prop *sizeProp;
+        Vector3Prop *deviationProp;
+    
+        BoolProp *perlinProp;
+        Vector3Prop *perlinSizeProp;
+    
+        BoolProp *useColorCurvesProp;
+        BezierRGBACurveProp *colorCurveProp;
+
+        BoolProp *useScaleCurvesProp;
+        BezierCurveProp *scaleCurveProp;
+
+};
+
 class SceneLightSheet : public PropSheet {
     public:
         SceneLightSheet();
@@ -670,10 +707,8 @@ class SceneSpriteSheet : public PropSheet {
 		SceneSpriteProp *spriteProp;
 		ComboProp *defaultAnimationProp;		
 		SceneSprite *lastSprite;
-		
 };
 
-
 class SceneEntityInstanceSheet : public PropSheet {
 	public:
 		SceneEntityInstanceSheet();

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


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


BIN
IDE/Contents/Resources/ImagesRetina/main/arrow.png


BIN
IDE/Contents/Resources/ImagesRetina/main/arrow_add.png


BIN
IDE/Contents/Resources/ImagesRetina/main/arrow_remove.png


BIN
IDE/Contents/Resources/ImagesRetina/main/curve_icon.png


BIN
IDE/Contents/Resources/ImagesRetina/main/selector.png


+ 9 - 0
IDE/Contents/Source/EntityEditorPropertyView.cpp

@@ -39,6 +39,11 @@ EntityEditorPropertyView::EntityEditorPropertyView() : UIElement() {
     entityProps->addPropSheet(lightSheet);
     lightSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
 
+    particleSheet = new ParticleEmitterSheet();
+    entityProps->addPropSheet(particleSheet);
+    particleSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
+    
+    
     primitiveSheet = new ScenePrimitiveSheet();
     entityProps->addPropSheet(primitiveSheet);
     primitiveSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
@@ -46,6 +51,7 @@ EntityEditorPropertyView::EntityEditorPropertyView() : UIElement() {
     entitySheet = new EntitySheet();
     entityProps->addPropSheet(entitySheet);
     entitySheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
+    
 }
 
 void EntityEditorPropertyView::Resize(Number width, Number height) {
@@ -64,6 +70,9 @@ void EntityEditorPropertyView::setEntity(Entity *entity) {
     ScenePrimitive *scenePrimitive = dynamic_cast<ScenePrimitive*>(entity);
     primitiveSheet->setScenePrimitive(scenePrimitive);
 
+    SceneParticleEmitter *emitter = dynamic_cast<SceneParticleEmitter*>(entity);
+    particleSheet->setParticleEmitter(emitter);
+
     entitySheet->setEntity(entity);
     transformSheet->setEntity(entity);
         

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

@@ -131,7 +131,7 @@ void EntityEditorMainView::Update() {
 }
 
 void EntityEditorMainView::createIcon(Entity *entity, String iconFile) {
-    ScenePrimitive *iconPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 0.3, 0.3);
+    ScenePrimitive *iconPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 0.4, 0.4);
     
     iconPrimitive->setMaterialByName("UnlitMaterial");
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("entityEditor/"+iconFile);
@@ -153,7 +153,9 @@ void EntityEditorMainView::setEditorProps(Entity *entity) {
     entity->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
     
     SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(entity);
-    if(sceneMesh) {
+    SceneParticleEmitter *emitter = dynamic_cast<SceneParticleEmitter*>(entity);
+    
+    if(sceneMesh && !emitter) {
         sceneMesh->wireFrameColor = Color(1.0, 0.8, 0.3, 1.0);
 //        sceneMesh->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX());
         sceneMesh->useGeometryHitDetection = true;
@@ -163,6 +165,12 @@ void EntityEditorMainView::setEditorProps(Entity *entity) {
     if(sceneLight) {
         createIcon(entity, "light_icon.png");
     }
+    
+    if(emitter) {
+        createIcon(entity, "emitter_icon.png");
+    }
+
+    
 }
 
 void EntityEditorMainView::addEntityFromMenu(String command) {
@@ -200,7 +208,6 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
     
     if(command == "add_light") {
         SceneLight *newLight = new SceneLight(SceneLight::AREA_LIGHT, mainScene, 1.0);
-        
         newLight->bBox = Vector3(0.5, 0.5, 0.5);
         mainScene->addLight(newLight);
         sceneObjectRoot->addChild(newLight);
@@ -218,6 +225,37 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         globalFrame->showAssetBrowser(extensions);
         return;
     }
+    
+    if(command == "add_particles") {
+        SceneParticleEmitter  *newEmitter = new SceneParticleEmitter(30, 3.0, 0.2);
+        newEmitter->bBox = Vector3(0.5, 0.5, 0.5);
+        
+        newEmitter->setParticleType(SceneParticleEmitter::PARTICLE_TYPE_QUAD);
+        
+        sceneObjectRoot->addChild(newEmitter);
+        setEditorProps(newEmitter);
+        newEmitter->setPosition(cursorPosition);
+        
+        
+        newEmitter->scaleCurve.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
+        newEmitter->scaleCurve.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);
+        
+        newEmitter->colorCurveR.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
+        newEmitter->colorCurveR.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);
+        
+        newEmitter->colorCurveG.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
+        newEmitter->colorCurveG.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);
+        
+        newEmitter->colorCurveB.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
+        newEmitter->colorCurveB.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);
+        
+        newEmitter->colorCurveA.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
+        newEmitter->colorCurveA.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);
+        
+        selectEntity(newEmitter);
+        return;
+        
+    }
 
 }
 
@@ -290,7 +328,9 @@ void EntityEditorMainView::doEntityDeselect(Entity *targetEntity) {
 
 void EntityEditorMainView::doEntitySelect(Entity *targetEntity) {
     SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(targetEntity);
-    if(sceneMesh) {
+    SceneParticleEmitter *emitter = dynamic_cast<SceneParticleEmitter*>(targetEntity);
+    
+    if(sceneMesh && ! emitter) {
         sceneMesh->overlayWireframe = true;
     }
 }

+ 43 - 38
IDE/Contents/Source/PolycodeFrame.cpp

@@ -38,7 +38,8 @@ EditPoint::EditPoint(BezierPoint *point, unsigned int type) : Entity() {
 	draggingPoint = NULL;
 	dragging = false;
 
-	controlHandle1 = new UIImage("Images/bezier_handle.png");
+	controlHandle1 = new UIRect(5, 5);
+    controlHandle1->setColor(0.0, 1.0, 0.3, 1.0);
 	controlHandle1->setAnchorPoint(0.0, 0.0, 0.0);
 	
 	controlHandle1->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
@@ -50,7 +51,8 @@ EditPoint::EditPoint(BezierPoint *point, unsigned int type) : Entity() {
 		
 	addChild(controlHandle1);
 	
-	controlHandle2 = new UIImage("Images/bezier_handle.png");
+	controlHandle2 = new UIRect(5, 5);
+    controlHandle2->setColor(0.0, 1.0, 0.3, 1.0);
 	controlHandle2->setAnchorPoint(0.0, 0.0, 0.0);
 	controlHandle2->processInputEvents = true;
 	
@@ -62,7 +64,8 @@ EditPoint::EditPoint(BezierPoint *point, unsigned int type) : Entity() {
 	
 	addChild(controlHandle2);
 	
-	pointHandle = new UIImage("Images/bezier_point.png");
+	pointHandle = new UIRect(8, 8);
+    pointHandle->setColor(1.0, 0.5, 0.2, 1.0);
 	pointHandle->processInputEvents = true;
 	pointHandle->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 	pointHandle->addEventListener(this, InputEvent::EVENT_MOUSEUP);
@@ -79,7 +82,7 @@ EditPoint::EditPoint(BezierPoint *point, unsigned int type) : Entity() {
 	} else {
 		connectorLine1 = new SceneLine(pointHandle, controlHandle1);
 		addChild(connectorLine1);
-		connectorLine1->setColorInt(39, 212, 255, 128);
+		connectorLine1->setColorInt(39, 212, 255, 100);
 		connectorLine1->setLineWidth(2.0);
 		connectorLine1->lineSmooth = true;
 	}
@@ -92,7 +95,7 @@ EditPoint::EditPoint(BezierPoint *point, unsigned int type) : Entity() {
 	} else {
 		connectorLine2 = new SceneLine(pointHandle, controlHandle2);
 		addChild(connectorLine2);
-		connectorLine2->setColorInt(39, 212, 255, 128);
+		connectorLine2->setColorInt(39, 212, 255, 100);
 		connectorLine2->setLineWidth(2.0);
 		connectorLine2->lineSmooth = true;
 	}	
@@ -110,14 +113,14 @@ void EditPoint::setMode(unsigned int mode) {
 
 void EditPoint::updateCurvePoint() {
 
-	point->p1.x = controlHandle1->getPosition2D().x/610;
-	point->p1.y = controlHandle1->getPosition2D().y/-254;	
+	point->p1.x = controlHandle1->getPosition2D().x/300;
+	point->p1.y = controlHandle1->getPosition2D().y/-100;
 
-	point->p2.x = pointHandle->getPosition2D().x/610;
-	point->p2.y = pointHandle->getPosition2D().y/-254;		
+	point->p2.x = pointHandle->getPosition2D().x/300;
+	point->p2.y = pointHandle->getPosition2D().y/-100;		
 	
-	point->p3.x = controlHandle2->getPosition2D().x/610;
-	point->p3.y = controlHandle2->getPosition2D().y/-254;	
+	point->p3.x = controlHandle2->getPosition2D().x/300;
+	point->p3.y = controlHandle2->getPosition2D().y/-100;	
 
 }
 
@@ -187,23 +190,23 @@ void EditPoint::handleEvent(Event *event) {
 	}
 }
 
-void EditPoint::limitPoint(UIImage *point) {
+void EditPoint::limitPoint(UIRect *point) {
 		if(point->getPosition().x < 0.0)
 			point->setPositionX(0.0);
-		if(point->getPosition().x > 610.0)
-			point->setPositionX(610.0);
+		if(point->getPosition().x > 300.0)
+			point->setPositionX(300.0);
 
 		if(point->getPosition().y > 0.0)
 			point->setPositionY(0.0);
-		if(point->getPosition().y < -254.0)
-			point->setPositionY(-254.0);
+		if(point->getPosition().y < -100.0)
+			point->setPositionY(-100.0);
 
 }
 
 void EditPoint::updatePosition() {
-	pointHandle->setPosition(610.0*point->p2.x, -254*point->p2.y, 0.0);	
-	controlHandle1->setPosition(610.0*point->p1.x, -254*point->p1.y, 0.0);	
-	controlHandle2->setPosition(610.0*point->p3.x, -254*point->p3.y, 0.0);	
+	pointHandle->setPosition(300.0*point->p2.x, -100*point->p2.y, 0.0);	
+	controlHandle1->setPosition(300.0*point->p1.x, -100*point->p1.y, 0.0);	
+	controlHandle2->setPosition(300.0*point->p3.x, -100*point->p3.y, 0.0);	
 }
 
 EditPoint::~EditPoint() {
@@ -227,7 +230,7 @@ EditCurve::EditCurve(BezierCurve *targetCurve, Color curveColor) : UIElement() {
 	visMesh->lineWidth = 2.0;
 
 	addChild(visMesh);
-	visMesh->setPosition(0, 254);	
+	visMesh->setPosition(0, 100);	
 	visMesh->color = curveColor;
 	
 	pointsBase = new UIElement();
@@ -264,7 +267,7 @@ void EditCurve::updatePoints() {
 		point->addEventListener(this, Event::CANCEL_EVENT);		
 		pointsBase->addChild(point);
 		points.push_back(point);
-		point->setPosition(0, 254);			
+		point->setPosition(0, 100);			
 	}
 }
 
@@ -315,59 +318,60 @@ void EditCurve::updateCurve() {
 	targetCurve->recalculateDistances();
 	targetCurve->rebuildBuffers();
 	
-	Number interval = 610.0/CURVE_SIZE;
+	Number interval = 300.0/CURVE_SIZE;
 	Number normInterval = 1.0/CURVE_SIZE;
 	
 	interval += interval/CURVE_SIZE;
 	normInterval += normInterval/CURVE_SIZE;
 		
 	for(int i=0; i < CURVE_SIZE; i++) {
-		poly->getVertex(i)->set(targetCurve->getPointAt(normInterval * i).x * 610, targetCurve->getPointAt(normInterval * i).y * -254.0, 0.0);
+		poly->getVertex(i)->set(targetCurve->getPointAt(normInterval * i).x * 300, targetCurve->getPointAt(normInterval * i).y * 100.0, 0.0);
 	}
 	
 	visMesh->getMesh()->arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
+    visMesh->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
 }
 
 EditCurve::~EditCurve() {
 
 }
 
-CurveEditor::CurveEditor() : UIWindow("", 750, 300) {
+CurveEditor::CurveEditor() : UIWindow("", 440, 160) {
 	
 	closeOnEscape = true;
 		
-	bg = new UIImage("Images/curve_editor_bg.png");
+	bg = new UIRect(300, 100);
+    bg->setColor(0.1, 0.1, 0.1, 1.0);
 	addChild(bg);
 	bg->setPosition(160, 63);
 	bg->processInputEvents = true;
 	bg->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 	
-	selectorImage = new UIImage("Images/ScreenEditor/selector.png");
-	selectorImage->setColor(0.0, 0.0, 0.0, 0.3);
+	selectorImage = new UIImage("main/selector.png", 24, 24);
 	addChild(selectorImage);
 		
-	selectButton = new UIImageButton("Images/ScreenEditor/arrow.png");
+	selectButton = new UIImageButton("main/arrow.png", 1.0, 24, 24);
 	addChild(selectButton);
 	selectButton->addEventListener(this, UIEvent::CLICK_EVENT);
 	selectButton->setPosition(170, 33);
 
-	addButton = new UIImageButton("Images/arrow_add.png");
+	addButton = new UIImageButton("main/arrow_add.png", 1.0, 24, 24);
 	addChild(addButton);
 	addButton->addEventListener(this, UIEvent::CLICK_EVENT);	
 	addButton->setPosition(170 + 32, 33);
 
-	removeButton = new UIImageButton("Images/arrow_remove.png");
+	removeButton = new UIImageButton("main/arrow_remove.png", 1.0, 24, 24);
 	addChild(removeButton);
 	removeButton->addEventListener(this, UIEvent::CLICK_EVENT);		
 	removeButton->setPosition(170 + 64, 33);
 	
-	selectorImage->setPosition(selectButton->getPosition().x - 4, selectButton->getPosition().y - 4);
+	selectorImage->setPosition(selectButton->getPosition().x, selectButton->getPosition().y);
 
 	selectedCurve = NULL;
 
 	setMode(0);
 	
-	treeContainer = new UITreeContainer("boxIcon.png", L"Curves", 145, 280);
+	treeContainer = new UITreeContainer("boxIcon.png", L"Curves", 145, 135);
 	treeContainer->getRootNode()->toggleCollapsed();
 	treeContainer->getRootNode()->addEventListener(this, UITreeEvent::SELECTED_EVENT);
 	treeContainer->setPosition(12, 33);
@@ -398,7 +402,7 @@ void CurveEditor::clearCurves() {
 
 void CurveEditor::addCurve(String name, BezierCurve *curve, Color curveColor) {
 
-	UITree *newNode = treeContainer->getRootNode()->addTreeChild("Images/curve_icon.png", name);
+	UITree *newNode = treeContainer->getRootNode()->addTreeChild("main/curve_icon.png", name);
 	EditCurve *editCurve = new EditCurve(curve, curveColor);
 	addChild(editCurve);
 	editCurve->setPosition(160, 63);	
@@ -423,8 +427,8 @@ void CurveEditor::handleEvent(Event *event) {
 				InputEvent *inputEvent = (InputEvent*)event;
 				if(selectedCurve) {
 					Vector2 pos = inputEvent->mousePosition;
-					pos.x = pos.x/610.0;
-					pos.y = 1.0-(pos.y/254.0);
+					pos.x = pos.x/300.0;
+					pos.y = 1.0-(pos.y/100.0);
 					
 					BezierCurve *targetCurve = selectedCurve->targetCurve;
 				
@@ -445,17 +449,17 @@ void CurveEditor::handleEvent(Event *event) {
 	}
 	
 	if(event->getDispatcher() == selectButton) {
-		selectorImage->setPosition(selectButton->getPosition().x - 4, selectButton->getPosition().y - 4);
+		selectorImage->setPosition(selectButton->getPosition().x, selectButton->getPosition().y);
 		setMode(0);
 	}
 
 	if(event->getDispatcher() == addButton) {
-		selectorImage->setPosition(addButton->getPosition().x - 4, addButton->getPosition().y - 4);
+		selectorImage->setPosition(addButton->getPosition().x, addButton->getPosition().y );
 		setMode(1);
 	}
 
 	if(event->getDispatcher() == removeButton) {
-		selectorImage->setPosition(removeButton->getPosition().x - 4, removeButton->getPosition().y - 4);
+		selectorImage->setPosition(removeButton->getPosition().x, removeButton->getPosition().y);
 		setMode(2);
 	}
 	
@@ -469,6 +473,7 @@ void CurveEditor::handleEvent(Event *event) {
 			if(curve) {
 				curve->Activate();
 				curve->setMode(mode);
+                curve->getParentEntity()->moveChildTop(curve);
 			}
 		}
 	}	

+ 147 - 8
IDE/Contents/Source/PolycodeProps.cpp

@@ -324,7 +324,7 @@ PropProp::PropProp(String caption, String type) : UIElement() {
 
 	suppressChangeEvent = false;
 	propType = type;
-	label = new UILabel(caption, 12);
+	label = new UILabel(caption, 11);
 	label->setPosition(0, 5);
 	addChild(label);
 	
@@ -345,17 +345,17 @@ Vector3Prop::Vector3Prop(String caption) : PropProp(caption, "Vector3") {
 	labelX = new UILabel("X:", 11);
 	labelX->color.a = 1.0;
 	propContents->addChild(labelX);
-	labelX->setPosition(-20, 6);
+	labelX->setPosition(-20, 5);
     
 	labelY = new UILabel("Y:", 11);
 	labelY->color.a = 1.0;
 	propContents->addChild(labelY);
-	labelY->setPosition(-20, 31);
+	labelY->setPosition(-20, 25);
 
     labelZ = new UILabel("Z:", 11);
 	labelZ->color.a = 1.0;
 	propContents->addChild(labelZ);
-	labelZ->setPosition(-20, 56);
+	labelZ->setPosition(-20, 45);
     
 	xInput = new UITextInput(false, 50, 12);
 	xInput->addEventListener(this, UIEvent::CHANGE_EVENT);
@@ -369,16 +369,16 @@ Vector3Prop::Vector3Prop(String caption) : PropProp(caption, "Vector3") {
 	yInput->setText("0");
 	yInput->setNumberOnly(true);
 	propContents->addChild(yInput);
-	yInput->setPosition(0, 25);
+	yInput->setPosition(0, 20);
 
     zInput = new UITextInput(false, 50, 12);
 	zInput->addEventListener(this, UIEvent::CHANGE_EVENT);
 	zInput->setText("0");
 	zInput->setNumberOnly(true);
 	propContents->addChild(zInput);
-	zInput->setPosition(0, 50);
+	zInput->setPosition(0, 40);
 
-	setHeight(75);
+	setHeight(65);
 }
 
 void Vector3Prop::setPropWidth(Number width) {
@@ -2139,7 +2139,7 @@ TransformSheet::TransformSheet() : PropSheet("TRANSFORM", "entity_transform") {
     rotationProp = new Vector3Prop("Rotation");
     addProp(rotationProp);
     
-    propHeight = 275;
+    propHeight = 235;
     
     enabled = false;
 }
@@ -2195,6 +2195,145 @@ void TransformSheet::handleEvent(Event *event) {
     PropSheet::handleEvent(event);
 }
 
+ParticleEmitterSheet::ParticleEmitterSheet() : PropSheet("PARTICLE EMITTER", "particle_emitter") {
+    emitter = NULL;
+
+    typeProp = new ComboProp("Type");
+    typeProp->comboEntry->addComboItem("Point");
+    typeProp->comboEntry->addComboItem("Quad");
+    addProp(typeProp);
+
+    countProp = new NumberProp("Count");
+    addProp(countProp);
+    
+    lifetimeProp = new NumberProp("Lifetime");
+    addProp(lifetimeProp);
+
+    particleSizeProp = new NumberProp("Size");
+    addProp(particleSizeProp);
+    
+    worldParticlesProp = new BoolProp("World space");
+    addProp(worldParticlesProp);
+    
+    loopingProp = new BoolProp("Loop");
+    addProp(loopingProp);
+    
+    particleRotaionProp = new Vector3Prop("Rotation");
+    addProp(particleRotaionProp);
+    
+    gravityProp = new Vector3Prop("Gravity");
+    addProp(gravityProp);
+    
+    directionProp = new Vector3Prop("Direction");
+    addProp(directionProp);
+
+    deviationProp = new Vector3Prop("Deviation");
+    addProp(deviationProp);
+
+    sizeProp = new Vector3Prop("Emitter size");
+    addProp(sizeProp);
+
+    perlinProp = new BoolProp("Movement noise");
+    addProp(perlinProp);
+    
+    perlinSizeProp = new Vector3Prop("Noise amount");
+    addProp(perlinSizeProp);
+
+    useColorCurvesProp = new BoolProp("Use color curves");
+    addProp(useColorCurvesProp);
+    
+    colorCurveProp = new BezierRGBACurveProp("Color curves");
+    addProp(colorCurveProp);
+
+    useScaleCurvesProp = new BoolProp("Use scale curve");
+    addProp(useScaleCurvesProp);
+    
+    scaleCurveProp = new BezierCurveProp("Scale curve", "Scale");
+    addProp(scaleCurveProp);
+    
+    propHeight = 700;
+    enabled = false;
+    
+}
+
+ParticleEmitterSheet::~ParticleEmitterSheet() {
+    
+}
+
+void ParticleEmitterSheet::handleEvent(Event *event) {
+    if(!emitter) {
+        return;
+    }
+    if(event->getEventCode() == Event::CHANGE_EVENT) {
+        if(event->getDispatcher() == typeProp) {
+            emitter->setParticleType(typeProp->get());
+        } else if(event->getDispatcher() == countProp) {
+                emitter->setParticleCount(countProp->get());
+        } else if(event->getDispatcher() == lifetimeProp) {
+            emitter->setParticleLifetime(lifetimeProp->get());
+        } else if(event->getDispatcher() == particleSizeProp) {
+            emitter->setParticleSize(particleSizeProp->get());
+        } else if(event->getDispatcher() == worldParticlesProp) {
+            emitter->setParticlesInWorldSpace(worldParticlesProp->get());
+        } else if(event->getDispatcher() == loopingProp) {
+            emitter->setLoopParticles(loopingProp->get());
+        } else if(event->getDispatcher() == particleRotaionProp) {
+            emitter->setParticleRotationSpeed(particleRotaionProp->get());
+        } else if(event->getDispatcher() == gravityProp) {
+            emitter->setGravity(gravityProp->get());
+        } else if(event->getDispatcher() == directionProp) {
+            emitter->setParticleDirection(directionProp->get());
+        } else if(event->getDispatcher() == sizeProp) {
+            emitter->setEmitterSize(sizeProp->get());
+        } else if(event->getDispatcher() == deviationProp) {
+            emitter->setDirectionDeviation(deviationProp->get());
+        } else if(event->getDispatcher() == perlinProp) {
+            emitter->setPerlinEnabled(perlinProp->get());
+        } else if(event->getDispatcher() == perlinSizeProp) {
+            emitter->setPerlinValue(perlinSizeProp->get());
+        } else if(event->getDispatcher() == useColorCurvesProp) {
+            emitter->useColorCurves = useColorCurvesProp->get();
+        } else if(event->getDispatcher() == useScaleCurvesProp) {
+            emitter->useScaleCurve = useScaleCurvesProp->get();
+        }
+
+    }
+    
+    PropSheet::handleEvent(event);
+}
+
+void ParticleEmitterSheet::setParticleEmitter(SceneParticleEmitter *emitter) {
+    this->emitter = emitter;
+    if(emitter) {
+        enabled = true;
+        typeProp->set(emitter->getParticleType());
+        countProp->set(emitter->getParticleCount());
+        lifetimeProp->set(emitter->getParticleLifetime());
+        particleSizeProp->set(emitter->getParticleSize());
+        worldParticlesProp->set(emitter->getParticlesInWorldSpace());
+        loopingProp->set(emitter->getLoopParticles());
+        particleRotaionProp->set(emitter->getParticleRotationSpeed());
+        gravityProp->set(emitter->getGravity());
+        directionProp->set(emitter->getParticleDirection());
+        sizeProp->set(emitter->getEmitterSize());
+        deviationProp->set(emitter->getDirectionDeviation());
+        perlinProp->set(emitter->getPerlinEnabled());
+        perlinSizeProp->set(emitter->getPerlinValue());
+        useColorCurvesProp->set(emitter->useColorCurves);
+        useScaleCurvesProp->set(emitter->useScaleCurve);
+        
+        colorCurveProp->curveR = &emitter->colorCurveR;
+        colorCurveProp->curveG = &emitter->colorCurveG;
+        colorCurveProp->curveB = &emitter->colorCurveB;
+        colorCurveProp->curveA = &emitter->colorCurveA;
+        
+        scaleCurveProp->curve = &emitter->scaleCurve;
+        
+    } else {
+        enabled = false;
+    }
+}
+
 SceneLightSheet::SceneLightSheet() : PropSheet("LIGHT", "scene_light") {
     typeProp = new ComboProp("Type");
     typeProp->comboEntry->addComboItem("Area");

Некоторые файлы не были показаны из-за большого количества измененных файлов