/*---------------------------------------------------------------------*//** オイラー角度からクォータニオンへ変換 **//*---------------------------------------------------------------------*/ void Quaternion::convFromEulerAngles(Vector4F* q, const Vector3F* angle) { Matrix4F mtxRot; mtxRot.rotateX(angle->x()); mtxRot.rotateY(angle->y()); mtxRot.rotateZ(angle->z()); convFromMatrix(q, &mtxRot); }
void renderCamSetupGL ( Scene& scene, int prog ) { // Set model, view, projection matrices Camera3D* cam = scene.getCamera (); Matrix4F ident; ident.Identity(); glProgramUniformMatrix4fv( prog, scene.getParam(prog, UMODEL), 1, GL_FALSE, ident.GetDataF() ); glProgramUniformMatrix4fv( prog, scene.getParam(prog, UVIEW), 1, GL_FALSE, cam->getViewMatrix().GetDataF() ); glProgramUniformMatrix4fv( prog, scene.getParam(prog, UPROJ), 1, GL_FALSE, cam->getProjMatrix().GetDataF() ); }
void Camera3D::updateFrustum () { Matrix4F mv; mv = tileproj_matrix; // Compute the model-view-projection matrix mv *= view_matrix; float* mvm = mv.GetDataF(); float t; // Right plane frustum[0][0] = mvm[ 3] - mvm[ 0]; frustum[0][1] = mvm[ 7] - mvm[ 4]; frustum[0][2] = mvm[11] - mvm[ 8]; frustum[0][3] = mvm[15] - mvm[12]; t = sqrt( frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2] ); frustum[0][0] /= t; frustum[0][1] /= t; frustum[0][2] /= t; frustum[0][3] /= t; // Left plane frustum[1][0] = mvm[ 3] + mvm[ 0]; frustum[1][1] = mvm[ 7] + mvm[ 4]; frustum[1][2] = mvm[11] + mvm[ 8]; frustum[1][3] = mvm[15] + mvm[12]; t = sqrt( frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2] ); frustum[1][0] /= t; frustum[1][1] /= t; frustum[1][2] /= t; frustum[1][3] /= t; // Bottom plane frustum[2][0] = mvm[ 3] + mvm[ 1]; frustum[2][1] = mvm[ 7] + mvm[ 5]; frustum[2][2] = mvm[11] + mvm[ 9]; frustum[2][3] = mvm[15] + mvm[13]; t = sqrt( frustum[2][0] * frustum[2][0] + frustum[2][1] * frustum[2][1] + frustum[2][2] * frustum[2][2] ); frustum[2][0] /= t; frustum[2][1] /= t; frustum[2][2] /= t; frustum[2][3] /= t; // Top plane frustum[3][0] = mvm[ 3] - mvm[ 1]; frustum[3][1] = mvm[ 7] - mvm[ 5]; frustum[3][2] = mvm[11] - mvm[ 9]; frustum[3][3] = mvm[15] - mvm[13]; t = sqrt( frustum[3][0] * frustum[3][0] + frustum[3][1] * frustum[3][1] + frustum[3][2] * frustum[3][2] ); frustum[3][0] /= t; frustum[3][1] /= t; frustum[3][2] /= t; frustum[3][3] /= t; // Far plane frustum[4][0] = mvm[ 3] - mvm[ 2]; frustum[4][1] = mvm[ 7] - mvm[ 6]; frustum[4][2] = mvm[11] - mvm[10]; frustum[4][3] = mvm[15] - mvm[14]; t = sqrt( frustum[4][0] * frustum[4][0] + frustum[4][1] * frustum[4][1] + frustum[4][2] * frustum[4][2] ); frustum[4][0] /= t; frustum[4][1] /= t; frustum[4][2] /= t; frustum[4][3] /= t; // Near plane frustum[5][0] = mvm[ 3] + mvm[ 2]; frustum[5][1] = mvm[ 7] + mvm[ 6]; frustum[5][2] = mvm[11] + mvm[10]; frustum[5][3] = mvm[15] + mvm[14]; t = sqrt( frustum[5][0] * frustum[5][0] + frustum[5][1] * frustum[5][1] + frustum[5][2] * frustum[5][2] ); frustum[5][0] /= t; frustum[5][1] /= t; frustum[5][2] /= t; frustum[5][3] /= t; }
/*---------------------------------------------------------------------*//** 描画前処理 **//*---------------------------------------------------------------------*/ 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; // 継続する }
/*---------------------------------------------------------------------*//** 2D の基本行列を設定 **//*---------------------------------------------------------------------*/ void View::apply2dDrawSetting() { ::glMatrixMode(GL_PROJECTION); ::glLoadIdentity(); ::glMatrixMode(GL_MODELVIEW); ::glLoadIdentity(); Matrix4F mtx; f32 left, right, top, bottom, znear, zfar; // 左上を原点にし、ウインドウ座標系に設定 ///STRACELN("view: %d", _dispflags & TFW_DISPF_RANG_MASK); switch (_dispflags & TFW_DISPF_RANG_MASK) { case TFW_DISPF_RANG_0: // 0 度回転した glOrtho + α left = _xLeft; right = _xRight; bottom = _yBottom; top = _yTop; znear = -1.0f; zfar = 1.0f; mtx.set( 2.0f / (right - left), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / (zfar - znear), 0.0f, -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(zfar + znear) / (zfar - znear), 1.0f); // 論理サイズに対するスケールを掛け合わせる mtx._v[0][0] *= _xscaleLgc; mtx._v[1][1] *= _yscaleLgc; ::glMultMatrixf(mtx.ptr()); ::glTranslatef(left * _xscaleLgcInv, top * _yscaleLgcInv, 0.0f); break; case TFW_DISPF_RANG_90: // -90 度回転した glOrtho + α left = _yBottom; right = _yTop; bottom = _xRight; top = _xLeft; znear = -1.0f; zfar = 1.0f; mtx.set( 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, 2.0f / (right - left), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / (zfar - znear), 0.0f, -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(zfar + znear) / (zfar - znear), 1.0f); // 論理サイズに対するスケールを掛け合わせる mtx._v[1][0] *= _yscaleLgc; mtx._v[0][1] *= _xscaleLgc; ::glMultMatrixf(mtx.ptr()); ::glTranslatef(top * _yscaleLgcInv, right * _xscaleLgcInv, 0.0f); break; case TFW_DISPF_RANG_180: // -180 度回転した glOrtho + α left = _xRight; right = _xLeft; bottom = _yTop; top = _yBottom; znear = -1.0f; zfar = 1.0f; mtx.set( 2.0f / (right - left), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / (zfar - znear), 0.0f, -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(zfar + znear) / (zfar - znear), 1.0f); // 論理サイズに対するスケールを掛け合わせる mtx._v[0][0] *= _xscaleLgc; mtx._v[1][1] *= _yscaleLgc; ::glMultMatrixf(mtx.ptr()); ::glTranslatef(right * _xscaleLgcInv, bottom * _yscaleLgcInv, 0.0f); break; case TFW_DISPF_RANG_270: // -270 度回転した glOrtho + α left = _yTop; right = _yBottom; bottom = _xLeft; top = _xRight; znear = -1.0f; zfar = 1.0f; mtx.set( 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, 2.0f / (right - left), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / (zfar - znear), 0.0f, -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(zfar + znear) / (zfar - znear), 1.0f); // 論理サイズに対するスケールを掛け合わせる mtx._v[1][0] *= _yscaleLgc; mtx._v[0][1] *= _xscaleLgc; ::glMultMatrixf(mtx.ptr()); ::glTranslatef(bottom * _yscaleLgcInv, left * _xscaleLgcInv, 0.0f); break; } // mtx._v[0][3] = left * _xscaleLgc; // ::glMultMatrixf(mtx.ptr()); // ::glTranslatef(left * _xscaleLgcInv, top * _yscaleLgcInv, 0.0f); // STRACE("w=%d,h=%d,sx=%f,sy=%f\n", , _xscaleLgc, _yscaleLgc); }
/*---------------------------------------------------------------------*//** バウンディングボックス等による描画対象判定 **//*---------------------------------------------------------------------*/ 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; }