void BillboardParticleSystem::initParticle(sBillboardParticle* particle)
{
    // timeToLive
    // no negative life. prevent division by 0
    particle->timeToLive = _life + _lifeVar * CCRANDOM_MINUS1_1();
    particle->timeToLive = MAX(0, particle->timeToLive);

    // position
    particle->pos.x = _sourcePosition.x + _posVar.x * CCRANDOM_MINUS1_1();

    particle->pos.y = _sourcePosition.y + _posVar.y * CCRANDOM_MINUS1_1();

    // Color
    Color4F start;
    start.r = clampf(_startColor.r + _startColorVar.r * CCRANDOM_MINUS1_1(), 0, 1);
    start.g = clampf(_startColor.g + _startColorVar.g * CCRANDOM_MINUS1_1(), 0, 1);
    start.b = clampf(_startColor.b + _startColorVar.b * CCRANDOM_MINUS1_1(), 0, 1);
    start.a = clampf(_startColor.a + _startColorVar.a * CCRANDOM_MINUS1_1(), 0, 1);

    Color4F end;
    end.r = clampf(_endColor.r + _endColorVar.r * CCRANDOM_MINUS1_1(), 0, 1);
    end.g = clampf(_endColor.g + _endColorVar.g * CCRANDOM_MINUS1_1(), 0, 1);
    end.b = clampf(_endColor.b + _endColorVar.b * CCRANDOM_MINUS1_1(), 0, 1);
    end.a = clampf(_endColor.a + _endColorVar.a * CCRANDOM_MINUS1_1(), 0, 1);

    particle->color = start;
    particle->deltaColor.r = (end.r - start.r) / particle->timeToLive;
    particle->deltaColor.g = (end.g - start.g) / particle->timeToLive;
    particle->deltaColor.b = (end.b - start.b) / particle->timeToLive;
    particle->deltaColor.a = (end.a - start.a) / particle->timeToLive;

    // size
    float startS = _startSize + _startSizeVar * CCRANDOM_MINUS1_1();
    startS = MAX(0, startS); // No negative value

    particle->size = startS;

    if (_endSize == START_SIZE_EQUAL_TO_END_SIZE)
    {
        particle->deltaSize = 0;
    }
    else
    {
        float endS = _endSize + _endSizeVar * CCRANDOM_MINUS1_1();
        endS = MAX(0, endS); // No negative values
        particle->deltaSize = (endS - startS) / particle->timeToLive;
    }

    // rotation
    float startA = _startSpin + _startSpinVar * CCRANDOM_MINUS1_1();
    float endA = _endSpin + _endSpinVar * CCRANDOM_MINUS1_1();
    particle->rotation = startA;
    particle->deltaRotation = (endA - startA) / particle->timeToLive;

    // position
    if (_positionType == PositionType::FREE)
    {
        particle->startPos = this->convertToWorldSpace3D(Vec3::ZERO);
    }
    else if (_positionType == PositionType::RELATIVE)
    {
        particle->startPos.x = _position.x;
        particle->startPos.y = _position.y;
        particle->startPos.z = _positionZ;
    }

    // direction
    float a = CC_DEGREES_TO_RADIANS( _angle + _angleVar * CCRANDOM_MINUS1_1() );    

    // Mode Gravity: A
    if (_emitterMode == Mode::GRAVITY)
    {
        Vec2 v(cosf( a ), sinf( a ));
        float s = modeA.speed + modeA.speedVar * CCRANDOM_MINUS1_1();

        // direction
        particle->modeA.dir = v * s ;

        // radial accel
        particle->modeA.radialAccel = modeA.radialAccel + modeA.radialAccelVar * CCRANDOM_MINUS1_1();


        // tangential accel
        particle->modeA.tangentialAccel = modeA.tangentialAccel + modeA.tangentialAccelVar * CCRANDOM_MINUS1_1();

        // rotation is dir
        if(modeA.rotationIsDir)
            particle->rotation = -CC_RADIANS_TO_DEGREES(particle->modeA.dir.getAngle());
    }

    // Mode Radius: B
    else 
    {
        // Set the default diameter of the particle from the source position
        float startRadius = modeB.startRadius + modeB.startRadiusVar * CCRANDOM_MINUS1_1();
        float endRadius = modeB.endRadius + modeB.endRadiusVar * CCRANDOM_MINUS1_1();

        particle->modeB.radius = startRadius;

        if (modeB.endRadius == START_RADIUS_EQUAL_TO_END_RADIUS)
        {
            particle->modeB.deltaRadius = 0;
        }
        else
        {
            particle->modeB.deltaRadius = (endRadius - startRadius) / particle->timeToLive;
        }

        particle->modeB.angle = a;
        particle->modeB.degreesPerSecond = CC_DEGREES_TO_RADIANS(modeB.rotatePerSecond + modeB.rotatePerSecondVar * CCRANDOM_MINUS1_1());
    }    
}
void CCParticleSystem::initParticle(tCCParticle* particle)
{
    // timeToLive
    // no negative life. prevent division by 0
    particle->timeToLive = m_fLife + m_fLifeVar * CCRANDOM_MINUS1_1();
    particle->timeToLive = MAX(0, particle->timeToLive);

    // position
    particle->pos.x = m_tSourcePosition.x + m_tPosVar.x * CCRANDOM_MINUS1_1();

    particle->pos.y = m_tSourcePosition.y + m_tPosVar.y * CCRANDOM_MINUS1_1();


    // Color
    ccColor4F start;
    start.r = clampf(m_tStartColor.r + m_tStartColorVar.r * CCRANDOM_MINUS1_1(), 0, 1);
    start.g = clampf(m_tStartColor.g + m_tStartColorVar.g * CCRANDOM_MINUS1_1(), 0, 1);
    start.b = clampf(m_tStartColor.b + m_tStartColorVar.b * CCRANDOM_MINUS1_1(), 0, 1);
    start.a = clampf(m_tStartColor.a + m_tStartColorVar.a * CCRANDOM_MINUS1_1(), 0, 1);

    ccColor4F end;
    end.r = clampf(m_tEndColor.r + m_tEndColorVar.r * CCRANDOM_MINUS1_1(), 0, 1);
    end.g = clampf(m_tEndColor.g + m_tEndColorVar.g * CCRANDOM_MINUS1_1(), 0, 1);
    end.b = clampf(m_tEndColor.b + m_tEndColorVar.b * CCRANDOM_MINUS1_1(), 0, 1);
    end.a = clampf(m_tEndColor.a + m_tEndColorVar.a * CCRANDOM_MINUS1_1(), 0, 1);

    particle->color = start;
    particle->deltaColor.r = (end.r - start.r) / particle->timeToLive;
    particle->deltaColor.g = (end.g - start.g) / particle->timeToLive;
    particle->deltaColor.b = (end.b - start.b) / particle->timeToLive;
    particle->deltaColor.a = (end.a - start.a) / particle->timeToLive;

    // size
    float startS = m_fStartSize + m_fStartSizeVar * CCRANDOM_MINUS1_1();
    startS = MAX(0, startS); // No negative value

    particle->size = startS;

    if( m_fEndSize == kCCParticleStartSizeEqualToEndSize )
    {
        particle->deltaSize = 0;
    }
    else
    {
        float endS = m_fEndSize + m_fEndSizeVar * CCRANDOM_MINUS1_1();
        endS = MAX(0, endS); // No negative values
        particle->deltaSize = (endS - startS) / particle->timeToLive;
    }

    // rotation
    float startA = m_fStartSpin + m_fStartSpinVar * CCRANDOM_MINUS1_1();
    float endA = m_fEndSpin + m_fEndSpinVar * CCRANDOM_MINUS1_1();
    particle->rotation = startA;
    particle->deltaRotation = (endA - startA) / particle->timeToLive;

    // position
    if( m_ePositionType == kCCPositionTypeFree )
    {
        particle->startPos = this->convertToWorldSpace(CCPointZero);
    }
    else if ( m_ePositionType == kCCPositionTypeRelative )
    {
        particle->startPos = m_tPosition;
    }

    // direction
    float a = CC_DEGREES_TO_RADIANS( m_fAngle + m_fAngleVar * CCRANDOM_MINUS1_1() );    

    // Mode Gravity: A
    if (m_nEmitterMode == kCCParticleModeGravity) 
    {
        CCPoint v(cosf( a ), sinf( a ));
        float s = modeA.speed + modeA.speedVar * CCRANDOM_MINUS1_1();

        // direction
        particle->modeA.dir = ccpMult( v, s );

        // radial accel
        particle->modeA.radialAccel = modeA.radialAccel + modeA.radialAccelVar * CCRANDOM_MINUS1_1();
 

        // tangential accel
        particle->modeA.tangentialAccel = modeA.tangentialAccel + modeA.tangentialAccelVar * CCRANDOM_MINUS1_1();

    }

    // Mode Radius: B
    else 
    {
        // Set the default diameter of the particle from the source position
        float startRadius = modeB.startRadius + modeB.startRadiusVar * CCRANDOM_MINUS1_1();
        float endRadius = modeB.endRadius + modeB.endRadiusVar * CCRANDOM_MINUS1_1();

        particle->modeB.radius = startRadius;

        if(modeB.endRadius == kCCParticleStartRadiusEqualToEndRadius)
        {
            particle->modeB.deltaRadius = 0;
        }
        else
        {
            particle->modeB.deltaRadius = (endRadius - startRadius) / particle->timeToLive;
        }

        particle->modeB.angle = a;
        particle->modeB.degreesPerSecond = CC_DEGREES_TO_RADIANS(modeB.rotatePerSecond + modeB.rotatePerSecondVar * CCRANDOM_MINUS1_1());
    }    
}
bool TestAEPlugin::init()
{
	bool bRet = false;
	do {
		CC_BREAK_IF(!CCLayer::init());
		
		ActionContext::getContext()->initialize();
		
		CCLayerColor * colorBG = CCLayerColor::create(ccc4(0xff, 0xff, 0xff, 0xff));
		this->addChild(colorBG);
		
		CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Role.plist");
		
		std::string file = CCFileUtils::sharedFileUtils()->fullPathForFilename("Animator_Moudle.plist");
		CCDictionary* dict = CCDictionary::createWithContentsOfFile(file.c_str());
		AnimatorModuleData* moduleData = AnimatorModuleData::data(dict);
		AnimatorModuleDataCache::sharedCache()->addData(moduleData, file);
		
		file = CCFileUtils::sharedFileUtils()->fullPathForFilename("Animator_SettingData.plist");
		dict = CCDictionary::createWithContentsOfFile(file.c_str());
		AnimatorSettingData* settingData = AnimatorSettingData::data(dict);
		AnimatorSettingDataCache::sharedCache()->addData(settingData, file);
		
		file = CCFileUtils::sharedFileUtils()->fullPathForFilename(settingData->m_animatorFile.c_str());
		dict = CCDictionary::createWithContentsOfFile(file.c_str());
		CCAnimation * animation = YHAnimationHelper::createAnimation_Ver2(dict);
		CCAnimationCache::sharedAnimationCache()->addAnimation(animation, settingData->m_animatorFile.c_str());
		
		file = CCFileUtils::sharedFileUtils()->fullPathForFilename(settingData->m_animatorDataFile.c_str());
		dict = CCDictionary::createWithContentsOfFile(file.c_str());
		AnimatorData* animatorData = AnimatorData::data(dict);
		AnimatorDataCache::sharedCache()->addData(animatorData, settingData->m_animatorDataFile);
		
		for (int i=0; i<100; ++i)
		{
			moduleData = AnimatorModuleDataCache::sharedCache()->getData("Animator_Moudle.plist");
			CCSprite* sp = moduleData->createSpecialSprite();
			sp->setPosition(ccp(CCRANDOM_MINUS1_1() * 200.0f, CCRANDOM_MINUS1_1()* 200.0f));
			addChild(sp);
			
			CCSprite* sp1 = CCSprite::create();
			settingData = AnimatorSettingDataCache::sharedCache()->getData("Animator_SettingData.plist");
			animation = CCAnimationCache::sharedAnimationCache()->animationByName(settingData->m_animatorFile.c_str());
			animatorData = AnimatorDataCache::sharedCache()->getData(settingData->m_animatorDataFile);
			YHAnimationHelper::runActionWithSprite(sp1, animation, true, animatorData);
			sp->addChild(sp1, 1, 1);
		}
		
		AnimatorModuleDataCache::sharedCache()->clean();
		AnimatorSettingDataCache::sharedCache()->clean();
		AnimatorDataCache::sharedCache()->clean();
		
		/// testModule
//		file = CCFileUtils::sharedFileUtils()->fullPathForFilename("Animator_Moudle.plist");
//		dict = CCDictionary::createWithContentsOfFile(file.c_str());
//		CCSpecialSprite* ssp = CCSpecialSprite::create(dict);
//		CCSpriteBatchNode* batchNode = CCSpriteBatchNode::create("Icon.png");
//		CCSprite* sp = CCSprite::create("Icon.png");
//		addChild(batchNode);
//		ssp->addChild(sp, 1, 1);
//		ssp->setPosition(ccp(200,200));
//		batchNode->addChild(ssp);
		
//		CCAnchorPointBy * apb = CCAnchorPointBy::create(5.0f, ccp(1.5f, 1.5f));
//		CCMoveTo * action = CCMoveTo::create(5.0f, ccp(100, 100));
//		CCSprite * icon = CCSprite::create("Icon.png");
//		icon->setPosition(ccp(240, 160));
//		icon->runAction((CCAnchorPointBy *)apb->reverse()->copyWithZone(NULL));
//		icon->runAction(apb);
//		icon->runAction((CCAction *)action->copyWithZone(NULL));
//		this->addChild(icon);
			
		bRet = true;
	} while (0);
	
	return bRet;
}