//-----------------------------------------------------------------------
	TextureRotator::TextureRotator(void) : 
		ParticleAffector(),
		mUseOwnRotationSpeed(DEFAULT_USE_OWN_SPEED),
		mScaledRotationSpeed(Radian(0)),
		twoPiRad(Radian(Math::TWO_PI))
	{
		mDynRotation = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynRotation))->setValue(DEFAULT_ROTATION);
		mDynRotationSpeed = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynRotationSpeed))->setValue(DEFAULT_ROTATION_SPEED);
	}
	//-----------------------------------------------------------------------
	void EntityRenderer::_prepare(ParticleTechnique* technique)
	{
		/** 
			- This renderer is a ´hacky´ solution to display geometry-based particles. It pre-creates a 
			number of SceneNodes (childs of the parent Node to which the ParticleSystem is attached) and 
			Entities and uses these pools to display the particles. There are better solutions, but 
			this one is simple and fast enough, although it has some drawbacks.
			- Future solutions should rather make use of hardware instancing to display a large number of
			geometry-based particles at once.
		*/

		// Use the given technique, although it should be the same as mParentTechnique (must be set already)
		if (!technique || mRendererInitialised)
			return;

		std::stringstream ss; 
		ss << this;
		mEntityName = mMeshName + ss.str();
		mQuota = technique->getVisualParticleQuota();
		Ogre::SceneNode* parentNode = technique->getParentSystem()->getParentSceneNode();
		Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load(mMeshName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
		Ogre::Mesh* meshPointer = mesh.getPointer();
		Vector3 size = meshPointer->getBounds().getSize();
		mBoxWidth = size.x == 0.0f ? 1.0f : size.x;
		mBoxHeight = size.y == 0.0f ? 1.0f : size.y;
		mBoxDepth = size.z == 0.0f ? 1.0f : size.z;

		if (parentNode)
		{
			// Create number of VisualData objects including SceneNodes
			String sceneNodeName;
			for (size_t i = 0; i < mQuota; i++)
			{
				sceneNodeName = "ParticleUniverse" + ss.str() + StringConverter::toString(i);
				EntityRendererVisualData* visualData = 
					PU_NEW_T(EntityRendererVisualData, MEMCATEGORY_SCENE_OBJECTS)(parentNode->createChildSceneNode(sceneNodeName));

				mAllVisualData.push_back(visualData); // Managed by this renderer
				mVisualData.push_back(visualData); // Used to assign to a particle
			}

			// Create number of Entities
			Ogre::Entity* entity = technique->getParentSystem()->getSceneManager()->createEntity(mEntityName, mMeshName); // Base entity
			vector<EntityRendererVisualData*>::const_iterator it;
			vector<EntityRendererVisualData*>::const_iterator itEnd = mAllVisualData.end();
			size_t j;
			for (it = mAllVisualData.begin(), j = 0; it != itEnd; ++it, ++j)
			{
				Ogre::Entity* clonedEntity = entity->clone(mEntityName + StringConverter::toString(j));
				clonedEntity->setMaterialName(technique->getMaterialName());
				clonedEntity->setRenderQueueGroup(mQueueId);
				mEntities.push_back(clonedEntity);
				(*it)->node->attachObject(clonedEntity);
			}
			technique->getParentSystem()->getSceneManager()->destroyEntity(mEntityName);
		}

		_makeNodesVisible(false);
		mRendererInitialised = true;
	}
	//-----------------------------------------------------------------------
	VortexAffector::VortexAffector(void) : 
		ParticleAffector(),
		mRotation(Quaternion::IDENTITY),
		mRotationVector(DEFAULT_ROTATION_VECTOR)
	{
		mDynRotationSpeed = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynRotationSpeed))->setValue(DEFAULT_ROTATION_SPEED);
	}
	//-----------------------------------------------------------------------
	void BeamRenderer::_prepare(ParticleTechnique* technique)
	{
		if (!technique || mRendererInitialised)
			return;

		// Register itself to the technique
		if (mParentTechnique)
		{
			// Although it is safe to assume that technique == mParentTechnique, use the mParentTechnique, because the mParentTechnique is
			// also used for unregistering.
			mParentTechnique->addTechniqueListener(this);
		}

		mQuota = technique->getVisualParticleQuota();
		Ogre::SceneNode* parentNode = technique->getParentSystem()->getParentSceneNode();

		if (parentNode)
		{
			// Create BillboardChain
			Ogre::SceneManager* sceneManager = mParentTechnique->getParentSystem()->getSceneManager();
			std::stringstream ss; 
			ss << this;
			mBillboardChainName = "Beam" + ss.str();
			mBillboardChain = sceneManager->createBillboardChain(mBillboardChainName);
			mBillboardChain->setDynamic(true);
			mBillboardChain->setNumberOfChains(mQuota);
			mBillboardChain->setMaxChainElements(mMaxChainElements);
			mBillboardChain->setMaterialName(technique->getMaterialName());
			mBillboardChain->setRenderQueueGroup(mQueueId);
			mBillboardChain->setTextureCoordDirection(mTexCoordDirection);
			setUseVertexColours(mUseVertexColours);
			mBillboardChain->setOtherTextureCoordRange(0.0f, 1.0f);
			mBillboardChain->setVisible(true);

			// Create number of VisualData objects
			for (size_t i = 0; i < mQuota; i++)
			{
				for (size_t j = 0; j < mMaxChainElements; j++)
				{
					Ogre::BillboardChain::Element element;
					element = Ogre::BillboardChain::Element(Vector3::ZERO, _mRendererScale.x * mParentTechnique->getDefaultWidth(), 0.0f, ColourValue::White, Ogre::Quaternion::IDENTITY); // V1.51
					mBillboardChain->addChainElement(i, element);
				}
				BeamRendererVisualData* visualData = PU_NEW_T(BeamRendererVisualData, MEMCATEGORY_SCENE_OBJECTS)(i, mBillboardChain);
				for (size_t numDev = 0; numDev < mNumberOfSegments; ++numDev)
				{
					// Initialise the positions
					visualData->half[numDev] = Vector3::ZERO;
					visualData->destinationHalf[numDev] = Vector3::ZERO;
				}
				mAllVisualData.push_back(visualData); // Managed by this renderer
				mVisualData.push_back(visualData); // Used to assign to a particle
			}
			mRendererInitialised = true;
			parentNode->attachObject(mBillboardChain);
		}
	}
    //-----------------------------------------------------------------------
	void MeshSurfaceEmitter::build(void)
	{
		// Delete the mesh info if already existing
		if (mMeshInfo)
		{
			PU_DELETE_T(mMeshInfo, MeshInfo, MEMCATEGORY_SCENE_OBJECTS);
			mMeshInfo = 0;
		}

		// Generate meshinfo.
		mMeshInfo = PU_NEW_T(MeshInfo, MEMCATEGORY_SCENE_OBJECTS)(mMeshName, mDistribution, mOrientation, mScale);
	}
	//-----------------------------------------------------------------------
	void LightRenderer::_prepare(ParticleTechnique* technique)
	{
		if (!technique || mRendererInitialised)
			return;

		std::stringstream ss; 
		ss << this;
		mLightName = ss.str();
		mQuota = technique->getVisualParticleQuota();
		Ogre::SceneNode* parentNode = technique->getParentSystem()->getParentSceneNode();

		if (parentNode)
		{
			// Create number of VisualData objects including SceneNodes
			String sceneNodeName;
			for (size_t i = 0; i < mQuota; i++)
			{
				sceneNodeName = "ParticleUniverse" + ss.str() + StringConverter::toString(i);
				LightRendererVisualData* visualData = 
					PU_NEW_T(LightRendererVisualData, MEMCATEGORY_SCENE_OBJECTS)(parentNode->createChildSceneNode(sceneNodeName));

				mAllVisualData.push_back(visualData); // Managed by this renderer
				mVisualData.push_back(visualData); // Used to assign to a particle
			}

			// Create number of Lights
			vector<LightRendererVisualData*>::const_iterator it;
			vector<LightRendererVisualData*>::const_iterator itEnd = mAllVisualData.end();
			size_t j;
			Ogre::Light* light;
			for (it = mAllVisualData.begin(), j = 0; it != itEnd; ++it, ++j)
			{
				light = technique->getParentSystem()->getSceneManager()->createLight(mLightName + StringConverter::toString(j));
				(*it)->node->attachObject(light);
				light->setType(mLightType);
				light->setAttenuation(mAttenuationRange, mAttenuationConstant, mAttenuationLinear, mAttenuationQuadratic);
				light->setDiffuseColour(DEFAULT_DIFFUSE); // The light always gets the diffuse colour from the particle
				light->setSpecularColour(mSpecularColour);
				light->setSpotlightFalloff(mSpotlightFalloff);
				light->setSpotlightInnerAngle(mSpotlightInnerAngle);
				light->setSpotlightOuterAngle(mSpotlightOuterAngle);
				light->setPowerScale(mPowerScale);
				light->setRenderQueueGroup(mQueueId);
				light->setVisible(false);
				mLights.push_back(light);
				(*it)->light = light;
			}
		}

		_makeNodesVisible(false); // Make them invisibe, otherwise they light the scene before start
		mRendererInitialised = true;
	}
	//-----------------------------------------------------------------------
	bool JetAffectorTranslator::translateChildProperty(ScriptCompiler* compiler, const AbstractNodePtr &node)
	{
		PropertyAbstractNode* prop = reinterpret_cast<PropertyAbstractNode*>(node.get());
		ParticleAffector* af = any_cast<ParticleAffector*>(prop->parent->context);
		JetAffector* affector = static_cast<JetAffector*>(af);

		if (prop->name == token[TOKEN_ACCELERATION])
		{
			// Property: acceleration
			if (passValidateProperty(compiler, prop, token[TOKEN_ACCELERATION], VAL_REAL))
			{
				Real val = 0.0f;
				if(getReal(prop->values.front(), &val))
				{
					DynamicAttributeFixed* dynamicAttributeFixed = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
					dynamicAttributeFixed->setValue(val);
					affector->setDynAcceleration(dynamicAttributeFixed);
					return true;
				}
			}
		}
		else if (prop->name == token[TOKEN_JET_ACCELERATION])
		{
			// Property: jet_aff_accel (deprecated and replaced by 'acceleration')
			if (passValidateProperty(compiler, prop, token[TOKEN_JET_ACCELERATION], VAL_REAL))
			{
				Real val = 0.0f;
				if(getReal(prop->values.front(), &val))
				{
					DynamicAttributeFixed* dynamicAttributeFixed = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
					dynamicAttributeFixed->setValue(val);
					affector->setDynAcceleration(dynamicAttributeFixed);
					return true;
				}
			}
		}

		return false;
	}
	//-----------------------------------------------------------------------
	void ParticlePool::_increaseVisualParticlePool(size_t size, 
		Particle::ParticleBehaviourList& behaviours)
	{
		size_t oldSize = mVisualParticles.size();
		if (size < oldSize)
			return;

		// Create new visual particles
		VisualParticle* particle = 0;
		for (size_t i = oldSize; i < size; i++)
		{
			particle = PU_NEW_T(VisualParticle, MEMCATEGORY_SCENE_OBJECTS)();
			particle->copyBehaviours(behaviours);
			mVisualParticlesPool.addElement(particle);
			mVisualParticles.push_back(particle);
		}
	}
	//-----------------------------------------------------------------------
	bool VortexAffectorTranslator::translateChildProperty(ScriptCompiler* compiler, const AbstractNodePtr &node)
	{
		PropertyAbstractNode* prop = reinterpret_cast<PropertyAbstractNode*>(node.get());
		ParticleAffector* af = any_cast<ParticleAffector*>(prop->parent->context);
		VortexAffector* affector = static_cast<VortexAffector*>(af);

		if (prop->name == token[TOKEN_ROTATION_AXIS])
		{
			// Property: rotation_axis
			if (passValidateProperty(compiler, prop, token[TOKEN_ROTATION_AXIS], VAL_VECTOR3))
			{
				Vector3 val;
				if(getVector3(prop->values.begin(), prop->values.end(), &val))
				{
					affector->setRotationVector(val);
					return true;
				}
			}
		}
		else if (prop->name == token[TOKEN_VORTEX_ROTATION_VECTOR])
		{
			// Property: vortex_aff_vector (deprecated and replaced by 'rotation_axis')
			if (passValidateProperty(compiler, prop, token[TOKEN_VORTEX_ROTATION_VECTOR], VAL_VECTOR3))
			{
				Vector3 val;
				if(getVector3(prop->values.begin(), prop->values.end(), &val))
				{
					affector->setRotationVector(val);
					return true;
				}
			}
		}
		else if (prop->name == token[TOKEN_ROTATION_SPEED])
		{
			// Property: rotation_speed
			if (passValidateProperty(compiler, prop, token[TOKEN_ROTATION_SPEED], VAL_REAL))
			{
				Real val = 0.0f;
				if(getReal(prop->values.front(), &val))
				{
					DynamicAttributeFixed* dynamicAttributeFixed = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
					dynamicAttributeFixed->setValue(val);
					affector->setRotationSpeed(dynamicAttributeFixed);
					return true;
				}
			}
		}
		else if (prop->name == token[TOKEN_VORTEX_ROTATION_SPEED])
		{
			// Property: vortex_aff_speed (deprecated and replaced by 'rotation_speed')
			if (passValidateProperty(compiler, prop, token[TOKEN_VORTEX_ROTATION_SPEED], VAL_REAL))
			{
				Real val = 0.0f;
				if(getReal(prop->values.front(), &val))
				{
					DynamicAttributeFixed* dynamicAttributeFixed = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
					dynamicAttributeFixed->setValue(val);
					affector->setRotationSpeed(dynamicAttributeFixed);
					return true;
				}
			}
		}

		return false;
	}
	//-----------------------------------------------------------------------
	ParticleEmitter::ParticleEmitter(void) :
		Particle(),
		IAlias(),
		IElement(),
		mParentTechnique(0),
		mEmitsType(DEFAULT_EMITS),
		mEmitsName(StringUtil::BLANK),
		mRemainder(0),
		mDurationRemain(0),
		mRepeatDelayRemain(0),
		mDynDurationSet(false),
		mDynRepeatDelaySet(false),
		mParticleDirection(DEFAULT_DIRECTION),
		mOriginalParticleDirection(DEFAULT_DIRECTION),
		mParticleOrientation(Quaternion::IDENTITY),
		mParticleOrientationRangeStart(Quaternion::IDENTITY),
		mParticleOrientationRangeEnd(Quaternion::IDENTITY),
		mParticleOrientationRangeSet(false),
		mUpVector(Vector3::ZERO),
		mDynParticleAllDimensionsSet(false),
		mDynParticleWidthSet(false),
		mDynParticleHeightSet(false),
		mDynParticleDepthSet(false),
		mEmissionRateCameraDependency(0),
		mAutoDirection(DEFAULT_AUTO_DIRECTION),
		mForceEmission(DEFAULT_FORCE_EMISSION),
		mOriginalForceEmission(false),
		mForceEmissionExecuted(false),
		mOriginalForceEmissionExecuted(false),
		mName(StringUtil::BLANK),
		_mEmitterScale(Vector3::UNIT_SCALE),
		mParticleColour(DEFAULT_COLOUR),
		mParticleColourRangeStart(DEFAULT_START_COLOUR_RANGE),
		mParticleColourRangeEnd(DEFAULT_END_COLOUR_RANGE),
		mParticleColourRangeSet(false),
		mKeepLocal(false),
		mParticleTextureCoords(DEFAULT_TEXTURE_COORDS),
		mParticleTextureCoordsRangeStart(DEFAULT_START_TEXTURE_COORDS),
		mParticleTextureCoordsRangeEnd(DEFAULT_END_TEXTURE_COORDS),
		mParticleTextureCoordsRangeSet(false)
	{
		particleType = PT_EMITTER;
		mAliasType = AT_EMITTER;
		mDynEmissionRate = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynEmissionRate))->setValue(DEFAULT_EMISSION_RATE);
		mDynTotalTimeToLive = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynTotalTimeToLive))->setValue(DEFAULT_TIME_TO_LIVE);
		mDynParticleMass = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynParticleMass))->setValue(DEFAULT_MASS);
		mDynVelocity = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynVelocity))->setValue(DEFAULT_VELOCITY);
		mDynDuration = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynDuration))->setValue(DEFAULT_DURATION);
		mDynRepeatDelay = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynRepeatDelay))->setValue(DEFAULT_REPEAT_DELAY);
		mDynAngle = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynAngle))->setValue(DEFAULT_ANGLE);

		// Set the dimensions attributes to 0; the default is to use the default dimensions of the ParticleTechnique
		mDynParticleAllDimensions = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynParticleAllDimensions))->setValue(DEFAULT_DIMENSIONS);
		mDynParticleWidth = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynParticleWidth))->setValue(DEFAULT_WIDTH);
		mDynParticleHeight = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynParticleHeight))->setValue(DEFAULT_HEIGHT);
		mDynParticleDepth = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		(static_cast<DynamicAttributeFixed*>(mDynParticleDepth))->setValue(DEFAULT_DEPTH);
	}
	//-------------------------------------------------------------------------
	void DynamicAttributeTranslator::translate(ScriptCompiler* compiler, const AbstractNodePtr &node)
	{
		ObjectAbstractNode* obj = reinterpret_cast<ObjectAbstractNode*>(node.get());

		// The first value is the type
		String type = obj->name;

		if (type == token[TOKEN_DYN_RANDOM])
		{
			mDynamicAttribute = PU_NEW_T(DynamicAttributeRandom, MEMCATEGORY_SCENE_OBJECTS)();
		}
		else if (type == token[TOKEN_DYN_CURVED_LINEAR])
		{
			mDynamicAttribute = PU_NEW_T(DynamicAttributeCurved, MEMCATEGORY_SCENE_OBJECTS)(IT_LINEAR);
		}
		else if (type == token[TOKEN_DYN_CURVED_SPLINE])
		{
			mDynamicAttribute = PU_NEW_T(DynamicAttributeCurved, MEMCATEGORY_SCENE_OBJECTS)(IT_SPLINE);
		}
		else if (type == token[TOKEN_DYN_OSCILLATE])
		{
			mDynamicAttribute = PU_NEW_T(DynamicAttributeOscillate, MEMCATEGORY_SCENE_OBJECTS)();
		}
		else
		{
			// Create a fixed one.
			mDynamicAttribute = PU_NEW_T(DynamicAttributeFixed, MEMCATEGORY_SCENE_OBJECTS)();
		}

		// Run through properties
		for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
		{
			if((*i)->type == ANT_PROPERTY)
			{
				PropertyAbstractNode* prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
				if (prop->name == token[TOKEN_DYN_MIN])
				{
					// Property: min
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_RANDOM)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_MIN], VAL_REAL))
						{
							Real val = 0.0f;
							if(getReal(prop->values.front(), &val))
							{
								(static_cast<DynamicAttributeRandom*>(mDynamicAttribute))->setMin(val);
							}
						}
					}
				}
				else if (prop->name == token[TOKEN_DYN_MAX])
				{
					// Property: max
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_RANDOM)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_MAX], VAL_REAL))
						{
							Real val = 0.0f;
							if(getReal(prop->values.front(), &val))
							{
								(static_cast<DynamicAttributeRandom*>(mDynamicAttribute))->setMax(val);
							}
						}
					}
				}
				else if (prop->name == token[TOKEN_DYN_CONTROL_POINT])
				{
					// Property: control_point
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_CURVED)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_CONTROL_POINT], VAL_VECTOR2))
						{
							Vector2 val;
							if(getVector2(prop->values.begin(), prop->values.end(), &val))
							{
								(static_cast<DynamicAttributeCurved*>(mDynamicAttribute))->addControlPoint(val.x, val.y);
							}
						}
					}
				}
				else if (prop->name == token[TOKEN_DYN_OSCILLATE_FREQUENCY])
				{
					// Property: oscillate_frequency
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_OSCILLATE)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_OSCILLATE_FREQUENCY], VAL_REAL))
						{
							Real val = 0.0f;
							if(getReal(prop->values.front(), &val))
							{
								(static_cast<DynamicAttributeOscillate*>(mDynamicAttribute))->setFrequency(val);
							}
						}
					}
				}
				else if (prop->name == token[TOKEN_DYN_OSCILLATE_PHASE])
				{
					// Property: oscillate_phase
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_OSCILLATE)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_OSCILLATE_PHASE], VAL_REAL))
						{
							Real val = 0.0f;
							if(getReal(prop->values.front(), &val))
							{
								(static_cast<DynamicAttributeOscillate*>(mDynamicAttribute))->setPhase(val);
							}
						}
					}
				}
				else if (prop->name == token[TOKEN_DYN_OSCILLATE_BASE])
				{
					// Property: oscillate_base
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_OSCILLATE)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_OSCILLATE_BASE], VAL_REAL))
						{
							Real val = 0.0f;
							if(getReal(prop->values.front(), &val))
							{
								(static_cast<DynamicAttributeOscillate*>(mDynamicAttribute))->setBase(val);
							}
						}
					}
				}
				else if (prop->name == token[TOKEN_DYN_OSCILLATE_AMPLITUDE])
				{
					// Property: oscillate_amplitude
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_OSCILLATE)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_OSCILLATE_AMPLITUDE], VAL_REAL))
						{
							Real val = 0.0f;
							if(getReal(prop->values.front(), &val))
							{
								(static_cast<DynamicAttributeOscillate*>(mDynamicAttribute))->setAmplitude(val);
							}
						}
					}
				}
				else if (prop->name == token[TOKEN_DYN_OSCILLATE_TYPE])
				{
					// Property: oscillate_type
					if (mDynamicAttribute->getType() == DynamicAttribute::DAT_OSCILLATE)
					{
						if (passValidateProperty(compiler, prop, token[TOKEN_DYN_OSCILLATE_TYPE], VAL_STRING))
						{
							String val;
							if(getString(prop->values.front(), &val))
							{
								if (val == token[TOKEN_DYN_SINE])
								{
									(static_cast<DynamicAttributeOscillate*>(mDynamicAttribute))->setOscillationType(
										DynamicAttributeOscillate::OSCT_SINE);
								}
								else if (val == token[TOKEN_DYN_SQUARE])
								{
									(static_cast<DynamicAttributeOscillate*>(mDynamicAttribute))->setOscillationType(
										DynamicAttributeOscillate::OSCT_SQUARE);
								}
							}
						}
					}
				}
				else
				{
					errorUnexpectedProperty(compiler, prop);
				}

			}
			else if((*i)->type == ANT_OBJECT)
			{
				processNode(compiler, *i);
			}
            else
			{
				errorUnexpectedToken(compiler, *i);
			}
		}

		// Set it in the context
		obj->context = Any(mDynamicAttribute);
	}
	//-----------------------------------------------------------------------
	void RibbonTrailRenderer::_prepare(ParticleTechnique* technique)
	{
		if (!technique || mRendererInitialised)
			return;

		// Register itself to the technique
		if (mParentTechnique)
		{
			// Although it is safe to assume that technique == mParentTechnique, use the mParentTechnique, because the mParentTechnique is
			// also used for unregistering.
			mParentTechnique->addTechniqueListener(this);
		}

		mQuota = technique->getVisualParticleQuota();
		if (!mChildNode)
		{
			// Create a childnode if not created earlier
			std::stringstream ss; 
			ss << this;
			String childNodeNodeName = "ParticleUniverse" + ss.str();
			mChildNode = mParentTechnique->getParentSystem()->getParentSceneNode()->createChildSceneNode(childNodeNodeName);
			mChildNode->setInheritOrientation(false);
		}

		if (mChildNode)
		{
			// Create RibbonTrail
			Ogre::SceneManager* sceneManager = mParentTechnique->getParentSystem()->getSceneManager();
			mTrail = sceneManager->createRibbonTrail(mRibbonTrailName);
			mTrail->setNumberOfChains(mQuota);
			mTrail->setMaxChainElements(mMaxChainElements);
			mTrail->setMaterialName(technique->getMaterialName());
			mTrail->setRenderQueueGroup(mQueueId);
			if (mSetLength)
			{
				mTrail->setTrailLength(_mRendererScale.y * mTrailLength);
			}
			else
			{
				mTrail->setTrailLength(_mRendererScale.y * technique->getDefaultHeight());
			}
			mTrail->setUseVertexColours(mUseVertexColours);

			// Create number of VisualData objects
			String sceneNodeName;
			std::stringstream ss; 
			ss << this;
			for (size_t i = 0; i < mQuota; i++)
			{
				sceneNodeName = "ParticleUniverse" + ss.str() + StringConverter::toString(i);
				RibbonTrailRendererVisualData* visualData = 
					PU_NEW_T(RibbonTrailRendererVisualData, MEMCATEGORY_SCENE_OBJECTS)(mChildNode->createChildSceneNode(sceneNodeName), mTrail);
				visualData->node->setInheritOrientation(false);
				visualData->index = i;
				mAllVisualData.push_back(visualData); // Managed by this renderer
				mVisualData.push_back(visualData); // Used to assign to a particle
				if (mRandomInitialColour)
				{
					mTrail->setInitialColour(i, Math::UnitRandom(), Math::UnitRandom(), Math::UnitRandom());
				}
				else
				{
					mTrail->setInitialColour(i, mInitialColour);
				}
				mTrail->setColourChange(i, mColourChange);
				if (mSetWidth)
				{
					mTrail->setInitialWidth(i, _mRendererScale.x * mTrailWidth);
				}
				else
				{
					mTrail->setInitialWidth(i, _mRendererScale.x * mParentTechnique->getDefaultWidth());
				}
			}
			mChildNode->attachObject(mTrail);
			mRendererInitialised = true;
		}
	}
Пример #13
0
	//---------------------------------------------------------------------
	void ParticleUniversePlugin::install()
	{
#ifdef PU_PHYSICS_PHYSX
		// ----------------------- Create the PhysXBridge -----------------------
		mPhysXBridge = PU_NEW_T(PhysXBridge, MEMCATEGORY_SCENE_CONTROL)();
#endif // PU_PHYSICS_PHYSX

		// ----------------------- Create the particle system manager -----------------------
		mParticleSystemManager = PU_NEW_T(ParticleSystemManager, MEMCATEGORY_SCENE_CONTROL)();

#ifdef CN_MODIFY
		// ----------------------- Create the particle Renderer Manager ----------------------
		mParticleRendererManager = PU_NEW_T(ParticleRendererManager, MEMCATEGORY_SCENE_CONTROL)();
#endif

		// ----------------------- Create renderer factories -----------------------
		ParticleRendererFactory* particleRendererFactory;

		particleRendererFactory = PU_NEW BeamRendererFactory();
		mParticleSystemManager->addRendererFactory(particleRendererFactory);
		mRendererFactories.push_back(particleRendererFactory);

		particleRendererFactory = PU_NEW BillboardRendererFactory();
		mParticleSystemManager->addRendererFactory(particleRendererFactory);
		mRendererFactories.push_back(particleRendererFactory);

		particleRendererFactory = PU_NEW BoxRendererFactory();
		mParticleSystemManager->addRendererFactory(particleRendererFactory);
		mRendererFactories.push_back(particleRendererFactory);

		particleRendererFactory = PU_NEW SphereRendererFactory();
		mParticleSystemManager->addRendererFactory(particleRendererFactory);
		mRendererFactories.push_back(particleRendererFactory);

		particleRendererFactory = PU_NEW EntityRendererFactory();
		mParticleSystemManager->addRendererFactory(particleRendererFactory);
		mRendererFactories.push_back(particleRendererFactory);

		particleRendererFactory = PU_NEW RibbonTrailRendererFactory();
		mParticleSystemManager->addRendererFactory(particleRendererFactory);
		mRendererFactories.push_back(particleRendererFactory);

		particleRendererFactory = PU_NEW LightRendererFactory();
		mParticleSystemManager->addRendererFactory(particleRendererFactory);
		mRendererFactories.push_back(particleRendererFactory);

		// ----------------------- Create emitter factories -----------------------
		ParticleEmitterFactory* particleEmitterFactory;
		particleEmitterFactory = PU_NEW PointEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		particleEmitterFactory = PU_NEW LineEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		particleEmitterFactory = PU_NEW BoxEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		particleEmitterFactory = PU_NEW CircleEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		particleEmitterFactory = PU_NEW SphereSurfaceEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		particleEmitterFactory = PU_NEW VertexEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);
		
		particleEmitterFactory = PU_NEW MeshSurfaceEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		particleEmitterFactory = PU_NEW PositionEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		particleEmitterFactory = PU_NEW SlaveEmitterFactory();
		mParticleSystemManager->addEmitterFactory(particleEmitterFactory);
		mEmitterFactories.push_back(particleEmitterFactory);

		// ----------------------- Create affector factories -----------------------
		ParticleAffectorFactory* particleAffectorFactory;
		particleAffectorFactory = PU_NEW BaseForceAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW LinearForceAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW GravityAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW ParticleFollowerFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW VortexAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW RandomiserFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW LineAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW ScaleAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW ScaleVelocityAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW GeometryRotatorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW TextureRotatorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW TextureAnimatorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW JetAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW AlignAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW FlockCenteringAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW CollisionAvoidanceAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW VelocityMatchingAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW ColourAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW SineForceAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW BaseColliderFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW SphereColliderFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW PlaneColliderFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW BoxColliderFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW InterParticleColliderFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW PathFollowerFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		particleAffectorFactory = PU_NEW ForceFieldAffectorFactory();
		mParticleSystemManager->addAffectorFactory(particleAffectorFactory);
		mAffectorFactories.push_back(particleAffectorFactory);

		// ----------------------- Create observer factories -----------------------
		ParticleObserverFactory* particleObserverFactory;
		particleObserverFactory = PU_NEW OnExpireObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnEmissionObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnCountObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnEventFlagObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnCollisionObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnVelocityObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnTimeObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnPositionObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnClearObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnQuotaObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		particleObserverFactory = PU_NEW OnRandomObserverFactory();
		mParticleSystemManager->addObserverFactory(particleObserverFactory);
		mObserverFactories.push_back(particleObserverFactory);

		// ----------------------- Create event handler factories -----------------------
		ParticleEventHandlerFactory* particleEventHandlerFactory;
		particleEventHandlerFactory = PU_NEW DoExpireEventHandlerFactory();
		mParticleSystemManager->addEventHandlerFactory(particleEventHandlerFactory);
		mEventHandlerFactories.push_back(particleEventHandlerFactory);

		particleEventHandlerFactory = PU_NEW DoFreezeEventHandlerFactory();
		mParticleSystemManager->addEventHandlerFactory(particleEventHandlerFactory);
		mEventHandlerFactories.push_back(particleEventHandlerFactory);

		particleEventHandlerFactory = PU_NEW DoPlacementParticleEventHandlerFactory();
		mParticleSystemManager->addEventHandlerFactory(particleEventHandlerFactory);
		mEventHandlerFactories.push_back(particleEventHandlerFactory);

		particleEventHandlerFactory = PU_NEW DoStopSystemEventHandlerFactory();
		mParticleSystemManager->addEventHandlerFactory(particleEventHandlerFactory);
		mEventHandlerFactories.push_back(particleEventHandlerFactory);

		particleEventHandlerFactory = PU_NEW DoEnableComponentEventHandlerFactory();
		mParticleSystemManager->addEventHandlerFactory(particleEventHandlerFactory);
		mEventHandlerFactories.push_back(particleEventHandlerFactory);

		particleEventHandlerFactory = PU_NEW DoAffectorEventHandlerFactory();
		mParticleSystemManager->addEventHandlerFactory(particleEventHandlerFactory);
		mEventHandlerFactories.push_back(particleEventHandlerFactory);

		particleEventHandlerFactory = PU_NEW DoScaleEventHandlerFactory();
		mParticleSystemManager->addEventHandlerFactory(particleEventHandlerFactory);
		mEventHandlerFactories.push_back(particleEventHandlerFactory);

		// ----------------------- Create extern factories -----------------------
		ExternFactory* externFactory;
		externFactory = PU_NEW GravityExternFactory();
		mParticleSystemManager->addExternFactory(externFactory);
		mExternFactories.push_back(externFactory);

		externFactory = PU_NEW SphereColliderExternFactory();
		mParticleSystemManager->addExternFactory(externFactory);
		mExternFactories.push_back(externFactory);

		externFactory = PU_NEW BoxColliderExternFactory();
		mParticleSystemManager->addExternFactory(externFactory);
		mExternFactories.push_back(externFactory);

		externFactory = PU_NEW VortexExternFactory();
		mParticleSystemManager->addExternFactory(externFactory);
		mExternFactories.push_back(externFactory);

		externFactory = PU_NEW SceneDecoratorExternFactory();
		mParticleSystemManager->addExternFactory(externFactory);
		mExternFactories.push_back(externFactory);

#ifdef PU_PHYSICS_PHYSX
		externFactory = PU_NEW PhysXActorExternFactory();
		mParticleSystemManager->addExternFactory(externFactory);
		mExternFactories.push_back(externFactory);

		externFactory = PU_NEW PhysXFluidExternFactory();
		mParticleSystemManager->addExternFactory(externFactory);
		mExternFactories.push_back(externFactory);
#endif //PU_PHYSICS_PHYSX

		// ----------------------- Create behaviour factories -----------------------
		ParticleBehaviourFactory* particleBehaviourFactory;
		particleBehaviourFactory = PU_NEW SlaveBehaviourFactory();
		mParticleSystemManager->addBehaviourFactory(particleBehaviourFactory);
		mBehaviourFactories.push_back(particleBehaviourFactory);
	}