/*---------------------------------------------------------------------*//**
	描画前処理
**//*---------------------------------------------------------------------*/
void ShapeModel::previseContents(const RenderCtx* rc)
{
	// ビュー座標計算無しフラグが立っている場合は抜ける
	if(TFW_IS_FLAG(getModelFlag(), MFLAG_NO_VIEWPOS) || (_viewpos == 0L))
	{
		return;
	}

	// 現在のカメラを取得
	Camera* cam = rc->getRenderer()->getCurrentCamera();
	if(cam == 0L)	{	return;	}

	// シェイプよりバウンディングボックスを得る
	Vector3F vBbCenterWk;
	f32 rBb;
	getAllShapesBoundingBox(&vBbCenterWk, &rBb);	// 計算する

	// 自身の姿勢行列を適用
	if(_mtxPosture != 0L)
	{
		_mtxPosture->mult(&vBbCenterWk, &vBbCenterWk); 
	}

	// アニメーションによる移動も適用
	if(TFW_IS_FLAG(getModelFlag(), MFLAG_ANIM_VIEWPOS))
	{
		if((_asetRef != 0L) && (_asetRef->getObjRootNum() > 0))
		{
			Matrix4F mtxAnimRoot;
			_asetRef->calcObjRootMatrix(0, &mtxAnimRoot, _ascAsetCtx);
			mtxAnimRoot.mult(&vBbCenterWk, &vBbCenterWk); 
		}
	}

	// ビュー座標を計算
	const Matrix4F* mtxView = cam->getViewMatrix();
	mtxView->mult(_viewpos, &vBbCenterWk);
}
/*---------------------------------------------------------------------*//**
	スキルフレーム処理 - 実行中
**//*---------------------------------------------------------------------*/
bool Char1504_Shika_EnemySpirit::execSkillAct(ExecRes* res, const ExecCtx* ec, s32 cntStep, f32 frmcntStep)
{
	const f32 FRAME_STEP = 0.76667f * FRAMERATE;

	if(cntStep == 1)
	{
		setBefaviorMaxFrame(FRAME_STEP);	// 最大の行動フレーム数設定
	}

	setBefaviorCurrentFrame(frmcntStep);	// 現在の行動フレーム数設定

	if(frmcntStep >= FRAME_STEP)	// 攻撃フレーム
	{
		const CharLogicData* cldat = getCharLogicData(); ASSERT(cldat != 0L);
		// 範囲内の対象をリストアップ
		f32 lenEffctvSq = cldat->getSkillRange() * cldat->getSkillRange();
		List<Unit*> listUnits;
		CalcUtils::collectUnitFanRange(
			&listUnits,
			getThisUnit()->getPosition(),
			getThisUnit()->getDirection()->y(),
			Unit::UNITFLAG_PC,
			lenEffctvSq,
			TFW_COS45	);	// ±45°以内
		// リストアップしたユニットにクラスタを投げる
		Unit* unitTrg = 0L;
		for(ListIterator<Unit*> it = listUnits.iterator(); it.has(); it.next())
		{
			unitTrg = it.object();
			break;
		}

#if 1
		TransStat tstat;
		EleneStat eestatSkill(cldat->getSkillOqlElene(), cldat->getSkillCurElene());
		tstat.setupForSkill(getThisUnit(), &eestatSkill);
		MagicInfluencer::serveGeneralMc(getThisUnit(), unitTrg, &tstat, GameParticleDef::PTCLK_SKILL_SHOCK_WAVE);
#else
		MagicSys* mgcsys = Game::getGame()->getMagicSys(); ASSERT(mgcsys != 0L);
		MagicClusterCreateParam mccprm(MagicClusterType::SERVED, GameParticleDef::PTCLK_SKILL_SHOCK_WAVE);
		EleneStat eestatSkill(cldat->getSkillOqlElene(), cldat->getSkillCurElene());
		Vector3F pos(*getThisUnit()->getCenterPos());
		mccprm._unitOwnrRef = getThisUnit();
		mccprm._unitMainTrgRef = unitTrg;
		mccprm._pos = &pos;
		mccprm._tstat.setupForSkill(getThisUnit(), &eestatSkill);
		mccprm._lifeframe = cldat->getSkillCurElene()->getWater() / Elene::ELENE_VALID_FIGURE;
		mccprm._isNoOnlyTrgColl = true;
		u16 mcidNew = mgcsys->appearCluster(&mccprm);
		if(mcidNew == 0)		{	return true;	}	// 成功ではないが終えるために次のステップへ
		MagicCluster* mcNew = mgcsys->getCluster(mcidNew);
		if(mcNew == 0L)			{	return true;	}	// 成功ではないが終えるために次のステップへ
		TFW_SET_FLAG(*mcNew->ctrlFlags(), MagicCluster::CTRLF_DIR_TO_ROTZ, true);	// 方向を Z 軸回転に反映させる

		// クラスタ発射
		/*
		f32 acc = cldat->getSkillCurElene()->getWind() * (0.1f / (f32)Elene::ELENE_VALID_FIGURE);
		if(acc < 0.033f)	{	acc = 0.033f;	}
		Vector3F accMc(0.0, 0.0, acc);
		Matrix4F mtxRot;
		mtxRot.rotateY(getThisUnit()->getDirection()->y());
		mtxRot.mult(&accMc, &accMc);
		mcNew->accelerate(&accMc);
		*/
		f32 speed = cldat->getSkillCurElene()->getWind() * (0.1f / (f32)Elene::ELENE_VALID_FIGURE);
		if(speed < 0.033f)	{ speed = 0.033f; }
		Vector3F velMc(0.0f, 0.0f, speed);
		Matrix4F mtxRot;
		mtxRot.rotateY(getThisUnit()->getDirection()->y());
		mtxRot.mult(&velMc, &velMc);
		mcNew->setInitialVelocity(&velMc);
		mcNew->reflectPosture();
#endif

		resetBefaviorFrame();		// 行動フレームリセット
		return true;
	}

	return false;	// 継続する
}
/*---------------------------------------------------------------------*//**
	バウンディングボックス等による描画対象判定
**//*---------------------------------------------------------------------*/
bool ShapeModel::testRenderingTarget(const RenderCtx* rc)
{
	// クリップ無しフラグが立っている場合は常に合格
	if(TFW_IS_FLAG(getModelFlag(), MFLAG_NO_CLIP))
	{
		return true;
	}

	// 現在のカメラを取得
	Camera* cam = rc->getRenderer()->getCurrentCamera();
	if(cam == 0L)	{	return true;	}

	if(TFW_IS_FLAG(getModelFlag(), MFLAG_NO_VIEWPOS))	// ビュー座標計算保存無しフラグが立っている場合
	{
		// シェイプよりバウンディングボックスを得る
		Vector3F vBbCenterWk;
		f32 rBb;
		getAllShapesBoundingBox(&vBbCenterWk, &rBb);	// 計算する

		// 自身の姿勢行列を適用
		if(_mtxPosture != 0L)
		{
			_mtxPosture->mult(&vBbCenterWk, &vBbCenterWk); 
		}

		// アニメーションによる移動も適用
		if(TFW_IS_FLAG(getModelFlag(), MFLAG_ANIM_VIEWPOS))
		{
			if((_asetRef != 0L) && (_asetRef->getObjRootNum() > 0))
			{
				Matrix4F mtxAnimRoot;
				_asetRef->calcObjRootMatrix(0, &mtxAnimRoot, _ascAsetCtx);
				mtxAnimRoot.mult(&vBbCenterWk, &vBbCenterWk); 
			}
		}

		#if 0	// クリップテストコード
		{
			bool isCorpo = false;
			for(int i = 0; i < (int)_numShape; i++)
			{
				if(_sarrShape[i]->getDebugName()->find("CLP", 0) != -1)
				{
					isCorpo = true;
					return cam->isClip(&vBbCenterWk, rBb);
				}
			}
		}
		#endif

		// 視錐台カリング判定
		return cam->isClipWithWorldPos(&vBbCenterWk, rBb);
	}
	else if(_viewpos != 0L)
	{
		// 視錐台カリング判定
		return cam->isClipWithViewPos(_viewpos, _rShapesBb);
	}

	return false;
}