PolarEmitter::PolarEmitter(ParticleSystem* psys)
        : ParticleEmitter(psys)
		, mRadiusMin(0.0f)
		, mRadiusStep(0.0f)
		, mRadiusMax(0.0f)
	    , mThetaMin(0.0f)
		, mThetaStep(0.0f)
		, mThetaMax(0.0f)
	    , mPhiMin(0.0f)
	    , mPhiStep(0.0f)
		, mPhiMax(0.0f)
		, mThetaTotal(0.0f)
		, mPhiTotal(0.0f)
		, mRadiusTotal(0.0f)
		, mUsePolarStep(false)
		, mFlipYZAxis(false)
        , mResetRadiusCount(0)
        , mResetRadius(false)
        , mCurrentResetRadiusCount(0)

    {
        mType = "PolarEmitter";

        // Set up parameters
        if (createParamDictionary("PolarEmitter"))
        {
            addBaseParameters();

            // Add extra paramaters
            ParamDictionary* dict = getParamDictionary();
            dict->addParameter(ParameterDef("radius_start", 
                "The vector representing the force to apply.",
                PT_REAL),&msRadiusMinCmd);

			dict->addParameter(ParameterDef("radius_step", 
				"The vector representing the force to apply.",
				PT_REAL),&msRadiusStepCmd);

			dict->addParameter(ParameterDef("radius_end", 
				"The vector representing the force to apply.",
				PT_REAL),&msRadiusMaxCmd);

            dict->addParameter(ParameterDef("theta_start", 
                "The vector representing the force to apply.",
                PT_REAL),&msThetaMinCmd);

            dict->addParameter(ParameterDef("theta_step", 
                "The vector representing the force to apply.",
                PT_REAL),&msThetaStepCmd);

			dict->addParameter(ParameterDef("theta_end", 
				"The vector representing the force to apply.",
				PT_REAL),&msThetaMaxCmd);

			dict->addParameter(ParameterDef("phi_start", 
				"The vector representing the force to apply.",
				PT_REAL),&msPhiMinCmd);

            dict->addParameter(ParameterDef("phi_step", 
                "The vector representing the force to apply.",
                PT_REAL),&msPhiStepCmd);

			dict->addParameter(ParameterDef("phi_end", 
				"The vector representing the force to apply.",
				PT_REAL),&msPhiMaxCmd);

			dict->addParameter(ParameterDef("use_polar_step", 
				"The vector representing the force to apply.",
				PT_BOOL),&msUsePolarStepCmd);

			dict->addParameter(ParameterDef("flip_yz_axis", 
				"The vector representing the force to apply.",
				PT_BOOL),&msFlipYZAxisCmd);

            dict->addParameter(ParameterDef("reset_radius_count", 
                "when you use the radius step, this value can control the radius reset"
                "by emitting reset_radius_count particles.",
                PT_INT),&msResetRadiusCountCmd);

            dict->addParameter(ParameterDef("reset_radius", 
                "when you use the radius step, this value can control the radius reset.",
                PT_BOOL),&msResetRadiusCmd);
        }
    }  
Example #2
0
//-----------------------------------------------------------------------
void ParticleEmitter::addBaseParameters(void) {
  ParamDictionary* dict = getParamDictionary();

  dict->addParameter(ParameterDef("angle",
                                  "The angle up to which particles may vary in their initial direction "
                                  "from the emitters direction, in degrees." , PT_REAL),
                     &msAngleCmd);

  dict->addParameter(ParameterDef("colour",
                                  "The colour of emitted particles.", PT_COLOURVALUE),
                     &msColourCmd);

  dict->addParameter(ParameterDef("colour_range_start",
                                  "The start of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
                     &msColourRangeStartCmd);

  dict->addParameter(ParameterDef("colour_range_end",
                                  "The end of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
                     &msColourRangeEndCmd);

  dict->addParameter(ParameterDef("direction",
                                  "The base direction of the emitter." , PT_VECTOR3),
                     &msDirectionCmd);

  dict->addParameter(ParameterDef("emission_rate",
                                  "The number of particles emitted per second." , PT_REAL),
                     &msEmissionRateCmd);

  dict->addParameter(ParameterDef("position",
                                  "The position of the emitter relative to the particle system center." , PT_VECTOR3),
                     &msPositionCmd);

  dict->addParameter(ParameterDef("velocity",
                                  "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL),
                     &msVelocityCmd);

  dict->addParameter(ParameterDef("velocity_min",
                                  "The minimum initial velocity to be assigned to each particle." , PT_REAL),
                     &msMinVelocityCmd);

  dict->addParameter(ParameterDef("velocity_max",
                                  "The maximum initial velocity to be assigned to each particle." , PT_REAL),
                     &msMaxVelocityCmd);

  dict->addParameter(ParameterDef("time_to_live",
                                  "The lifetime of each particle in seconds." , PT_REAL),
                     &msTTLCmd);

  dict->addParameter(ParameterDef("time_to_live_min",
                                  "The minimum lifetime of each particle in seconds." , PT_REAL),
                     &msMinTTLCmd);

  dict->addParameter(ParameterDef("time_to_live_max",
                                  "The maximum lifetime of each particle in seconds." , PT_REAL),
                     &msMaxTTLCmd);

  dict->addParameter(ParameterDef("duration",
                                  "The length of time in seconds which an emitter stays enabled for." , PT_REAL),
                     &msDurationCmd);

  dict->addParameter(ParameterDef("duration_min",
                                  "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL),
                     &msMinDurationCmd);

  dict->addParameter(ParameterDef("duration_max",
                                  "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL),
                     &msMaxDurationCmd);

  dict->addParameter(ParameterDef("repeat_delay",
                                  "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL),
                     &msRepeatDelayCmd);

  dict->addParameter(ParameterDef("repeat_delay_min",
                                  "If set, after disabling an emitter will repeat (reenable) after this minimum number of seconds." , PT_REAL),
                     &msMinRepeatDelayCmd);

  dict->addParameter(ParameterDef("repeat_delay_max",
                                  "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL),
                     &msMaxRepeatDelayCmd);
}
	BillboardSetElement::BillboardSetElement(const String &type, System *system) :
	EffectElement(type, system),
	mBillboardSet(NULL),
    mBillboardColour(Ogre::ColourValue::White),
    mScaleIntervalTime(0.1f),
    mSizeChanged(false),
	mBillboardCount(5),
	mBillboardMaterial("BaseWhiteNoLighting"),
	mBillboardInterval(10.0f),
	mBillboardWidth(100.0f),
	mBillboardHeight(100.0f),
    mAlphaValue(1.0f),
    mColourChanged(false),
    mStacks(1),
    mSlices(1),
    mTexIntervalTime(0.1f),
    mCurrentTexIntervalTime(0.0f)
	{
        for (int i=0; i<MAX_STAGES; ++i)
        {
            mBillboardScale[i] = Ogre::Vector3(1.0f, 1.0f, 1.0f);
        }

		if ( initDefaults(mElementType) )
		{
			Ogre::ParamDictionary* dict = getParamDictionary();

			// Custom params      

            dict->addParameter(Ogre::ParameterDef("BillboardColour", 
                "BillboardColour",
                Ogre::PT_COLOURVALUE), &msBillboardColourCmd);

            dict->addParameter(Ogre::ParameterDef("BillboardAlpha", 
                "Billboard Alpha Value of first point and second point.",
                Ogre::PT_REAL),&msBillboardAlphaCmd);

			dict->addParameter(Ogre::ParameterDef("BillboardCount", 
				"the life time of the vertex.",
				Ogre::PT_INT),&msBillboardCountCmd);

			dict->addParameter(Ogre::ParameterDef("Material", 
				"alpha factor of head point.",
				Ogre::PT_STRING),&msBillboardMaterialCmd);

			dict->addParameter(Ogre::ParameterDef("BillboardInterval", 
				"alpha factor of tail point.",
				Ogre::PT_REAL),&msBillboardIntervalCmd);

			dict->addParameter(Ogre::ParameterDef("BillboardHeight", 
				"alpha factor of tail point.",
				Ogre::PT_REAL),&msBillboardHeightCmd);

			dict->addParameter(Ogre::ParameterDef("BillboardWidth", 
				"alpha factor of tail point.",
				Ogre::PT_REAL),&msBillboardWidthCmd); 

            for (int i=0;i<MAX_STAGES;i++)
            {
                msBillboardScaleCmd[i].mIndex	= i;

                Ogre::StringUtil::StrStreamType stage;
                stage << i;
                String	colour_title	= String("BillboardScale") + stage.str();
                String	colour_descr	= String("Stage ") + stage.str() +
                    String(" BillboardScale of first point and second point.");

                dict->addParameter(Ogre::ParameterDef(colour_title, colour_descr,
                    Ogre::PT_VECTOR3), &msBillboardScaleCmd[i]);
            }

            dict->addParameter(Ogre::ParameterDef("ScaleIntervalTime", 
                "the interval time of changing scale.",
                Ogre::PT_REAL),&msScaleIntervalTimeCmd);   

            dict->addParameter(Ogre::ParameterDef("stacks", 
                "the stacks of texture coordinates.",
                Ogre::PT_UNSIGNED_LONG),
                &msStacksCmd);

            dict->addParameter(Ogre::ParameterDef("slices",
                "the slices of texture coordinates.",
                Ogre::PT_UNSIGNED_LONG),
                &msSlicesCmd);

            dict->addParameter(Ogre::ParameterDef("TexIntervalTime", 
                "the interval time of changing texture index.",
                Ogre::PT_REAL),&msTexIntervalTimeCmd);   

		}    
	}
	//-----------------------------------------------------------------------
	TexCoordBillboardParticleRenderer::TexCoordBillboardParticleRenderer()
	{
		if (createParamDictionary("TexCoordBillboardParticleRenderer"))
		{
			ParamDictionary* dict = getParamDictionary();
			dict->addParameter(ParameterDef("billboard_type", 
				"The type of billboard to use. 'point' means a simulated spherical particle, " 
				"'oriented_common' means all particles in the set are oriented around common_direction, "
				"'oriented_self' means particles are oriented around their own direction, "
				"'perpendicular_common' means all particles are perpendicular to common_direction, "
				"and 'perpendicular_self' means particles are perpendicular to their own direction.",
				PT_STRING),
				&msBillboardTypeCmd);

            dict->addParameter(ParameterDef("billboard_origin", 
                "This setting controls the fine tuning of where a billboard appears in relation to it's position. "
                "Possible value are: 'top_left', 'top_center', 'top_right', 'center_left', 'center', 'center_right', "
                "'bottom_left', 'bottom_center' and 'bottom_right'. Default value is 'center'.",
                PT_STRING),
                &msBillboardOriginCmd);

            dict->addParameter(ParameterDef("billboard_rotation_type", 
                "This setting controls the billboard rotation type. "
                "'vertex' means rotate the billboard's vertices around their facing direction."
                "'texcoord' means rotate the billboard's texture coordinates. Default value is 'texcoord'.",
                PT_STRING),
                &msBillboardRotationTypeCmd);

			dict->addParameter(ParameterDef("common_direction", 
				"Only useful when billboard_type is oriented_common or perpendicular_common. "
				"When billboard_type is oriented_common, this parameter sets the common orientation for "
				"all particles in the set (e.g. raindrops may all be oriented downwards). "
				"When billboard_type is perpendicular_common, this parameter sets the perpendicular vector for "
				"all particles in the set (e.g. an aureola around the player and parallel to the ground).",
				PT_VECTOR3),
				&msCommonDirectionCmd);

			dict->addParameter(ParameterDef("common_up_vector",
				"Only useful when billboard_type is perpendicular_self or perpendicular_common. This "
				"parameter sets the common up-vector for all particles in the set (e.g. an aureola around "
				"the player and parallel to the ground).",
				PT_VECTOR3),
				&msCommonUpVectorCmd);

            dict->addParameter(ParameterDef("point_rendering",
                "Set whether or not particles will use point rendering "
                "rather than manually generated quads. This allows for faster "
                "rendering of point-oriented particles although introduces some "
                "limitations too such as requiring a common particle size."
                "Possible values are 'true' or 'false'.",
                PT_BOOL),
                &msPointRenderingCmd);
            dict->addParameter(ParameterDef("accurate_facing",
                "Set whether or not particles will be oriented to the camera "
                "based on the relative position to the camera rather than just "
                "the camera direction. This is more accurate but less optimal. "
                "Cannot be combined with point rendering.",
                PT_BOOL),
                &msAccurateFacingCmd);

            dict->addParameter(ParameterDef("speed_relatived_size_factor",
                "Sets the factor of the particle size relative to speed. If greater "
                "than zero, the particle size are relative to its speed as well as "
                "this factor. Otherwise, the particle rendering use its own size "
                "only. This parameters applies only to 'oriented_self' billboards. "
                "Default to zero as particle size unrelated to speed",
                PT_REAL),
                &msSpeedRelativedSizeFactorCmd);

			dict->addParameter(ParameterDef("stacks", 
				"the stacks of texture coordinates.",
				PT_UNSIGNED_LONG),
				&msStacksCmd);

			dict->addParameter(ParameterDef("slices",
				"the slices of texture coordinates.",
				PT_UNSIGNED_LONG),
				&msSlicesCmd);

			dict->addParameter(ParameterDef("repeat_times", 
				"the repeat times of the colour interpolate.",
				PT_REAL), &msRepeatTimesCmd);
		}

		mStacks = 1;
		mSlices = 1;

		mRepeatTimes = 1.0f;
	}
    //-----------------------------------------------------------------------
    BillboardParticleRenderer::BillboardParticleRenderer()
    {
        if (createParamDictionary("BillboardParticleRenderer"))
        {
            ParamDictionary* dict = getParamDictionary();
            dict->addParameter(ParameterDef("billboard_type", 
                "The type of billboard to use. 'point' means a simulated spherical particle, " 
                "'oriented_common' means all particles in the set are oriented around common_direction, "
                "'oriented_self' means particles are oriented around their own direction, "
                "'perpendicular_common' means all particles are perpendicular to common_direction, "
                "and 'perpendicular_self' means particles are perpendicular to their own direction.",
                PT_STRING),
                &msBillboardTypeCmd);

            dict->addParameter(ParameterDef("billboard_origin", 
                "This setting controls the fine tuning of where a billboard appears in relation to it's position. "
                "Possible value are: 'top_left', 'top_center', 'top_right', 'center_left', 'center', 'center_right', "
                "'bottom_left', 'bottom_center' and 'bottom_right'. Default value is 'center'.",
                PT_STRING),
                &msBillboardOriginCmd);

            dict->addParameter(ParameterDef("billboard_rotation_type", 
                "This setting controls the billboard rotation type. "
				"'vertex' means rotate the billboard's vertices around their facing direction."
                "'texcoord' means rotate the billboard's texture coordinates. Default value is 'texcoord'.",
                PT_STRING),
                &msBillboardRotationTypeCmd);

            dict->addParameter(ParameterDef("common_direction", 
                "Only useful when billboard_type is oriented_common or perpendicular_common. "
				"When billboard_type is oriented_common, this parameter sets the common orientation for "
				"all particles in the set (e.g. raindrops may all be oriented downwards). "
				"When billboard_type is perpendicular_common, this parameter sets the perpendicular vector for "
				"all particles in the set (e.g. an aureola around the player and parallel to the ground).",
                PT_VECTOR3),
                &msCommonDirectionCmd);

            dict->addParameter(ParameterDef("common_up_vector",
                "Only useful when billboard_type is perpendicular_self or perpendicular_common. This "
				"parameter sets the common up-vector for all particles in the set (e.g. an aureola around "
				"the player and parallel to the ground).",
                PT_VECTOR3),
                &msCommonUpVectorCmd);
            dict->addParameter(ParameterDef("point_rendering",
                "Set whether or not particles will use point rendering "
				"rather than manually generated quads. This allows for faster "
				"rendering of point-oriented particles although introduces some "
				"limitations too such as requiring a common particle size."
				"Possible values are 'true' or 'false'.",
                PT_BOOL),
                &msPointRenderingCmd);
			dict->addParameter(ParameterDef("accurate_facing",
				"Set whether or not particles will be oriented to the camera "
				"based on the relative position to the camera rather than just "
				"the camera direction. This is more accurate but less optimal. "
				"Cannot be combined with point rendering.",
				PT_BOOL),
				&msAccurateFacingCmd);
        }

        // Create billboard set
        mBillboardSet = OGRE_NEW BillboardSet("", 0, true);
        // World-relative axes
        mBillboardSet->setBillboardsInWorldSpace(true);
    }
    //-----------------------------------------------------------------------
    RevolutionAffector::RevolutionAffector(ParticleSystem* psys)
        :ParticleAffector(psys)
    {
        mType = "Revolution";

		mRotateAxis = Ogre::Vector3::UNIT_Y;
		mRotationSpeed = 0.0f;

		for (int i=0;i<MAX_STAGES;i++)
		{
			// set default colour to transparent grey, transparent since we might not want to display the particle here
			// grey because when a colour component is 0.5f the maximum difference to another colour component is 0.5f
			mRadiusIncrementAdj[i]	= 0.0f;
			mTimeAdj[i]		= 1.0f;
		}

		mRepeatTimes = 1.0f;

		mCenterOffsetMin = Ogre::Vector3::ZERO;
		mCenterOffsetMax = Ogre::Vector3::ZERO;

		mUseRadiusIncrementScale = false;

		mRadiusIncrement = 0.0f;

        // Default to gravity-like

        // Set up parameters
        if (createParamDictionary("RevolutionAffector"))
        {
            addBaseParameters();
            // Add extra paramaters
            ParamDictionary* dict = getParamDictionary();

			dict->addParameter(ParameterDef("rotation_speed", 
                "the speed of particle circle rotation.",
                PT_REAL),&msRotationSpeedCmd);

            dict->addParameter(ParameterDef("rotation_axis", 
                "The vector representing the force to apply.",
                PT_VECTOR3),&msRotationAxisCmd);

			dict->addParameter(ParameterDef("radius_increment", 
				"the speed of particle circle rotation.",
				PT_REAL),&msRadiusIncrementCmd);

			dict->addParameter(ParameterDef("center_offset_min", 
				"The vector representing the force to apply.",
				PT_VECTOR3),&msCenterOffsetMinCmd);

			dict->addParameter(ParameterDef("center_offset_max", 
				"The vector representing the force to apply.",
				PT_VECTOR3),&msCenterOffsetMaxCmd);

			for (int i=0;i<MAX_STAGES;i++)
			{
				msRadiusIncrementAdjustCmd[i].mIndex	= i;
				msTimeCmd[i].mIndex		= i;

				StringUtil::StrStreamType stage;
				stage << i;
				String	speed_title	= String("radius_increment_scale") + stage.str();
				String	time_title		= String("time") + stage.str();
				String	speed_descr	= String("Stage ") + stage.str() + String(" RadiusIncrementScale.");
				String	time_descr		= String("Stage ") + stage.str() + String(" time.");

				dict->addParameter(ParameterDef(speed_title, speed_descr, PT_REAL), &msRadiusIncrementAdjustCmd[i]);
				dict->addParameter(ParameterDef(time_title,   time_descr,   PT_REAL),		 &msTimeCmd[i]);
			}		

			dict->addParameter(ParameterDef("use_radius_increment_scale", 
				"the repeat times of the colour interpolate.",
				PT_BOOL), &msUseRadiusIncrementScaleCmd);

			dict->addParameter(ParameterDef("repeat_times", 
				"the repeat times of the colour interpolate.",
				PT_REAL), &msRepeatTimesCmd);
        }

    }
ShaderParticleRenderer::ShaderParticleRenderer()
    : mDefaultParticleSize(1, 1)
    , mKeepInLocalSpace(false)
    , mParentNode(NULL)
    , mParentIsTagPoint(false)
    , mSortMode(SM_DISTANCE)
    , mLightListUpdated(0)
    , mRadius(0.0f)
    , mRenderQueueID(RENDER_QUEUE_MAIN)
    , mVertexFormatTexture(false)
    , mVertexFormatSize(false)
    , mVertexFormatRotation(false)
    , mVertexFormatRotationSpeed(false)
    , mVertexFormatDirection(false)
    , mVertexFormatColour(false	)
    , mVertexFormatTTL(false)
    , mVertexFormatTotalTTL(false)
    , mVertexFormatTimeFragment(false)
    , mVertexFormatTimeFragmentInv(false)
    , mVertexSize(0)
{
    if (createParamDictionary("ShaderParticleRenderer"))
    {
        ParamDictionary* dict = getParamDictionary();
        dict->addParameter(ParameterDef("diffuse_colour",
            "Adds diffuse colour to vertex format (type = float4)",
            PT_BOOL),
            &msVertexFmtColour);

        dict->addParameter(ParameterDef("texture_coord",
            "Adds general texture coordinate to vertex format (type = float2)",
            PT_BOOL),
            &msVertexFmtTexture);

        dict->addParameter(ParameterDef("particle_size",
            "Adds particle size to vertex format (type = float2)",
            PT_BOOL),
            &msVertexFmtSize);

        dict->addParameter(ParameterDef("particle_rotation",
            "Adds particle rotation (in radians) to vertex format (type = float1)"
            "note: if particle_rotation_speed present in script, they are packed together as float2",
            PT_BOOL),
            &msVertexFmtRotation);

        dict->addParameter(ParameterDef("particle_rotation_speed",
            "Adds particle rotation speed (in radians/s) to vertex format (type = float1)"
            "note: if particle_rotation present in script, they are packed together as float2",
            PT_BOOL),
            &msVertexFmtRotationSpeed);

        dict->addParameter(ParameterDef("particle_direction",
            "Adds particle direction to vertex format (type = float3)"
            "note: it represent particle speed",
            PT_BOOL),
            &msVertexFmtDirection);

        dict->addParameter(ParameterDef("time_to_live",
            "Adds particle current time to live to vertex format (type = float1)"
            "note: this parameter can be packed with total_time_to_live, time_frag and time_frag_inv",
            PT_BOOL),
            &msVertexFmtTTL);

        dict->addParameter(ParameterDef("total_time_to_live",
            "Adds particle total time to live to vertex format (type = float1)"
            "note: this parameter can be packed with time_to_live, time_frag and time_frag_inv",
            PT_BOOL),
            &msVertexFmtTotalTTL);

        dict->addParameter(ParameterDef("time_frag",
            "Adds particle time fragment to vertex format (type = float1), which is ratio between ttl and total ttl"
            "note: this parameter can be packed with time_to_live, total_time_to_live and time_frag_inv",
            PT_BOOL),
            &msVertexFmtTimeFrag);

        dict->addParameter(ParameterDef("time_frag_inv",
            "Adds particle inverse time fragment to vertex format (type = float1), which is 1.0f - time_frag"
            "note: this parameter can be packed with time_to_live, total_time_to_live and time_frag",
            PT_BOOL),
            &msVertexFmtTimeFragInv);
    }

    mVertexData = OGRE_NEW VertexData;
    mIndexData  = OGRE_NEW IndexData;

    mTexCoordTable[0] = Vector2(0, 0);
    mTexCoordTable[1] = Vector2(1, 0);
    mTexCoordTable[2] = Vector2(1, 1);
    mTexCoordTable[3] = Vector2(0, 1);
}
    //-----------------------------------------------------------------------
    MeshRotationAffector::MeshRotationAffector(ParticleSystem* psys)
		:ParticleAffector(psys),
		mYawRotationSpeedRangeStart(0),
		mYawRotationSpeedRangeEnd(0),
		mYawRotationRangeStart(0),
		mYawRotationRangeEnd(0),
		mPitchRotationSpeedRangeStart(0),
		mPitchRotationSpeedRangeEnd(0),
		mPitchRotationRangeStart(0),
		mPitchRotationRangeEnd(0),
		mRollRotationSpeedRangeStart(0),
		mRollRotationSpeedRangeEnd(0),
		mRollRotationRangeStart(0),
		mRollRotationRangeEnd(0)
    {
        mType = "MeshRotator";
		
		// Init parameters
		if (createParamDictionary("MeshRotationAffector"))
		{
			ParamDictionary* dict = getParamDictionary();

			dict->addParameter(ParameterDef("yaw_rotation_speed_range_start", 
				"The start of a range of yaw rotation speed to be assigned to emitted particles.", PT_REAL),
				&msYawRotationSpeedRangeStartCmd);

			dict->addParameter(ParameterDef("yaw_rotation_speed_range_end", 
				"The end of a range of yaw rotation speed to be assigned to emitted particles.", PT_REAL),
				&msYawRotationSpeedRangeEndCmd);

			dict->addParameter(ParameterDef("yaw_rotation_range_start", 
				"The start of a range of yaw rotation angles to be assigned to emitted particles.", PT_REAL),
				&msYawRotationRangeStartCmd);

			dict->addParameter(ParameterDef("yaw_rotation_range_end", 
				"The end of a range of yaw rotation angles to be assigned to emitted particles.", PT_REAL),
				&msYawRotationRangeEndCmd);

			dict->addParameter(ParameterDef("pitch_rotation_speed_range_start", 
				"The start of a range of pitch rotation speed to be assigned to emitted particles.", PT_REAL),
				&msPitchRotationSpeedRangeStartCmd);

			dict->addParameter(ParameterDef("pitch_rotation_speed_range_end", 
				"The end of a range of pitch rotation speed to be assigned to emitted particles.", PT_REAL),
				&msPitchRotationSpeedRangeEndCmd);

			dict->addParameter(ParameterDef("pitch_rotation_range_start", 
				"The start of a range of pitch rotation angles to be assigned to emitted particles.", PT_REAL),
				&msPitchRotationRangeStartCmd);

			dict->addParameter(ParameterDef("pitch_rotation_range_end", 
				"The end of a range of pitch rotation angles to be assigned to emitted particles.", PT_REAL),
				&msPitchRotationRangeEndCmd);

			dict->addParameter(ParameterDef("roll_rotation_speed_range_start", 
				"The start of a range of roll rotation speed to be assigned to emitted particles.", PT_REAL),
				&msRollRotationSpeedRangeStartCmd);

			dict->addParameter(ParameterDef("roll_rotation_speed_range_end", 
				"The end of a range of roll rotation speed to be assigned to emitted particles.", PT_REAL),
				&msRollRotationSpeedRangeEndCmd);

			dict->addParameter(ParameterDef("roll_rotation_range_start", 
				"The start of a range of roll rotation angles to be assigned to emitted particles.", PT_REAL),
				&msRollRotationRangeStartCmd);

			dict->addParameter(ParameterDef("roll_rotation_range_end", 
				"The end of a range of roll rotation angles to be assigned to emitted particles.", PT_REAL),
				&msRollRotationRangeEndCmd);
		}
    }
	BeamElement::BeamElement(const String &type, System *system) :
	EffectElement(type, system),
	mNumBillboardElements(10),
	mNoiseXMin(0.0f),
	mNoiseXMax(0.0f),
	mNoiseYMin(0.0f),
	mNoiseYMax(0.0f),
	mNoiseZMin(0.0f),
	mNoiseZMax(0.0f),
    mDestPos(Ogre::Vector3::UNIT_Y), // 初始位置
	mWidth(10.0f),
	mBillboardChain(NULL),
	mMaterialName("BaseWhiteNoLighting"),
	mFrequency(20.0f),
	mFrequencyTime(0.0f)
	{
		if ( initDefaults(mElementType) )
		{
			Ogre::ParamDictionary* dict = getParamDictionary();

			// Custom params      
			dict->addParameter(Ogre::ParameterDef("NoiseXMin", 
				"min noise of x axis.",
				Ogre::PT_REAL),&msNoiseXMinCmd);

			dict->addParameter(Ogre::ParameterDef("NoiseXMax", 
				"max noise of x axis.",
				Ogre::PT_REAL),&msNoiseXMaxCmd);

			dict->addParameter(Ogre::ParameterDef("NoiseYMin", 
				"min noise of y axis.",
				Ogre::PT_REAL),&msNoiseYMinCmd);

			dict->addParameter(Ogre::ParameterDef("NoiseYMax", 
				"max noise of y axis.",
				Ogre::PT_REAL),&msNoiseYMaxCmd);

			dict->addParameter(Ogre::ParameterDef("NoiseZMin", 
				"min noise of z axis.",
				Ogre::PT_REAL),&msNoiseZMinCmd);

			dict->addParameter(Ogre::ParameterDef("NoiseZMax", 
				"max noise of z axis.",
				Ogre::PT_REAL),&msNoiseZMaxCmd);

			dict->addParameter(Ogre::ParameterDef("NumElements", 
				"the num of billboard chain elements.",
				Ogre::PT_INT),&msNumElementsCmd);

			dict->addParameter(Ogre::ParameterDef("Width", 
				"width of billboard.",
				Ogre::PT_REAL),&msWidthCmd);

			dict->addParameter(Ogre::ParameterDef("Colour", 
				"The colour of emitted particles.", Ogre::PT_COLOURVALUE),
				&msColourCmd);

			dict->addParameter(Ogre::ParameterDef("ColourRangeStart", 
				"The start of a range of colours to be assigned to emitted particles.", Ogre::PT_COLOURVALUE),
				&msColourRangeStartCmd);

			dict->addParameter(Ogre::ParameterDef("ColourRangeEnd", 
				"The end of a range of colours to be assigned to emitted particles.", Ogre::PT_COLOURVALUE),
				&msColourRangeEndCmd);

			dict->addParameter(Ogre::ParameterDef("Material", 
				"name of beam material.",
				Ogre::PT_STRING),&msMaterialCmd);

			dict->addParameter(Ogre::ParameterDef("Frequency", 
				"frequency of billboard.",
				Ogre::PT_REAL),&msFrequencyCmd);
		}

		mColourRangeStart = mColourRangeEnd = Ogre::ColourValue::White;
	}