예제 #1
0
// 極座標から回転行列に変換.
void CEphemeris::ConvertPolarToMatrix(
    const SPolarCoord& polar,
    izanagi::math::SMatrix44& mtx)
{
    IZ_FLOAT latitude  = IZ_DEG2RAD(polar.latitude);
    IZ_FLOAT longitude = IZ_DEG2RAD(polar.longitude);

    izanagi::math::SMatrix44 tmp;
    izanagi::math::SMatrix44::GetRotByZ(tmp, latitude);

    // NOTE
    // 真上(y軸+方向)から見た場合 => x-z平面
    // z
    // |
    // |
    // +---->x 
    //
    // 極座標を考える場合は、x-z平面は数学的に2次元で考えられて、すると、それはよくある x-y平面 とみなすことができる
    // すると、回転の方向は x->y に向けて、つまり反時計まわりとなる。
    // しかし、左手座標系の回転は z->x に向けて、つまり時計まわりとなるため
    // 回転の方向に矛盾が生じる。
    // そこで、正規化をする必要がある。

    // TODO
    // 本来は、極座標を右手座標系に合わせる必要がある

    izanagi::math::SMatrix44::GetRotByY(mtx, IZ_MATH_PI2 - longitude);

    izanagi::math::SMatrix44::Mul(mtx, tmp, mtx);
}
예제 #2
0
// 赤道座標から地平座標に変換.
void CEphemeris::ConvertEquatorialToHorizontal(
    const izanagi::math::SVector4& equatorial, 
    IZ_FLOAT latitude,
    IZ_FLOAT hourAngle,
    izanagi::math::SVector4& horizontal)
{
    IZ_FLOAT lat = IZ_DEG2RAD(latitude);
    IZ_FLOAT hAngle = IZ_DEG2RAD(hourAngle);

    izanagi::math::SMatrix44 mtxLong;
    izanagi::math::SMatrix44::GetRotByY(mtxLong, -hAngle);

    izanagi::math::SMatrix44 mtxLat;
    izanagi::math::SMatrix44::GetRotByY(mtxLong, IZ_MATH_PI1_2 - lat);

    izanagi::math::SMatrix44::ApplyXYZ(horizontal, equatorial, mtxLong);
    izanagi::math::SMatrix44::ApplyXYZ(horizontal, horizontal, mtxLat);
}
예제 #3
0
IZ_BOOL CBillboardYAxis::Render(
    izanagi::graph::CGraphicsDevice* device,
    izanagi::sample::CSampleCamera& camera)
{
    izanagi::math::SMatrix44 mtx;
    izanagi::math::SMatrix44::SetUnit(mtx);
    izanagi::math::SMatrix44::RotByX(mtx, mtx, IZ_DEG2RAD(-90.0f));

    izanagi::math::SVector4 dir = camera.GetDir();

    if (dir.x == 0.0f) {
    }
    else {
        IZ_FLOAT deg = IZ_RAD2DEG(::atan2(dir.z, dir.x));
        izanagi::math::SMatrix44::RotByY(mtx, mtx, -1.0f * IZ_DEG2RAD(deg) + IZ_MATH_PI1_2);
    }

    m_Shader->Begin(device, 0, IZ_FALSE);
    {
        if (m_Shader->BeginPass(0)) {
            _SetShaderParam(
                m_Shader,
                "g_mL2W",
                (void*)&mtx,
                sizeof(mtx));

            _SetShaderParam(
                m_Shader,
                "g_mW2C",
                (void*)&camera.GetParam().mtxW2C,
                sizeof(camera.GetParam().mtxW2C));

            // シェーダ設定
            m_Shader->CommitChanges(device);

            m_Rect->Draw(device);
        }
    }
    m_Shader->End(device);

    return IZ_TRUE;
}
예제 #4
0
// 極座標から直行座標に変換.
void CEphemeris::ConvertPolarToRectangular(
    const SPolarCoord& polar,
    izanagi::math::SVector4& ortho)
{
    IZ_FLOAT latitude  = IZ_DEG2RAD(polar.latitude);
    IZ_FLOAT longitude = IZ_DEG2RAD(polar.longitude);

    IZ_FLOAT sinLat, cosLat;
    sinLat = izanagi::math::CMath::SinF(latitude);
    cosLat = izanagi::math::CMath::CosF(latitude);

    IZ_FLOAT sinLong, cosLong;
    sinLong = izanagi::math::CMath::SinF(longitude);
    cosLong = izanagi::math::CMath::CosF(longitude);

    ortho.x = polar.radius * cosLat * cosLong;
    ortho.y = polar.radius * sinLat;
    ortho.z = polar.radius * cosLat * sinLong;
    ortho.w = 0.0f;
}
예제 #5
0
// 黄道座標から赤道座標に変換.
void CEphemeris::ConvertElipticToEquatorial(
    const izanagi::math::SVector4& eliptic, 
    izanagi::math::SVector4& equatorial)
{
    izanagi::math::SMatrix44 mtx;
    izanagi::math::SMatrix44::GetRotByX(mtx, -IZ_DEG2RAD(23.43929f));

    izanagi::math::SMatrix44::ApplyXYZ(
        equatorial,
        eliptic,
        mtx);
}
예제 #6
0
IZ_BOOL CBillboard::Render(
    izanagi::graph::CGraphicsDevice* device,
    izanagi::sample::CSampleCamera& camera)
{
    izanagi::math::SMatrix44 mtx;
    izanagi::math::SMatrix44::SetUnit(mtx);

    // 軸と並行になる向きにする
    izanagi::math::SMatrix44::GetRotByX(mtx, IZ_DEG2RAD(-90.0f));

    // カメラに正対するようにする
    izanagi::math::SMatrix44 inv;
    {
        izanagi::math::SMatrix44::Copy(inv, camera.GetParam().mtxW2V);

        // 移動成分は消す
        inv.m[3][0] = inv.m[3][1] = inv.m[3][2] = 0.0f;

        // 逆行列にすることで、カメラのW2Vマトリクスと打ち消しあうようにする
        izanagi::math::SMatrix44::Inverse(inv, inv);
    }

    izanagi::math::SMatrix44::Mul(mtx, mtx, inv);

    m_Shader->Begin(device, 0, IZ_FALSE);
    {
        if (m_Shader->BeginPass(0)) {
            _SetShaderParam(
                m_Shader,
                "g_mL2W",
                (void*)&mtx,
                sizeof(mtx));

            _SetShaderParam(
                m_Shader,
                "g_mW2C",
                (void*)&camera.GetParam().mtxW2C,
                sizeof(camera.GetParam().mtxW2C));

            // シェーダ設定
            m_Shader->CommitChanges(device);

            m_Rect->Draw(device);
        }
    }
    m_Shader->End(device);

    return IZ_TRUE;
}
예제 #7
0
IZ_BOOL CColladaAnimation::CreateSlerp(IZ_UINT nNodeIdx)
{
    IZ_ASSERT(nNodeIdx < m_AnmNodes.size());
    SAnmNode& sAnmNode = m_AnmNodes[nNodeIdx];

    std::vector<SQuatParam> tvQuatList;

    std::vector<SAnmChannel>::iterator itAnmChannel = sAnmNode.channels.begin();

    for (; itAnmChannel != sAnmNode.channels.end(); ) {
        const SAnmChannel& sAnmChannel = *itAnmChannel;

        if (!(sAnmChannel.type & izanagi::E_ANM_TRANSFORM_TYPE_QUATERNION)) {
            itAnmChannel++;
            continue;
        }

        // TODO
        IZ_ASSERT((sAnmChannel.type & izanagi::E_ANM_TRANSFORM_TYPE_W) > 0);

        const SAnmInput* pKeyTime = sAnmChannel.FindInput(E_INPUT_SEMANTIC_INPUT);
        VRETURN(pKeyTime != IZ_NULL);

        const SAnmInput* pValue = sAnmChannel.FindInput(E_INPUT_SEMANTIC_OUTPUT);
        VRETURN(pValue != IZ_NULL);
        VRETURN((pValue->params.size() / pValue->stride) == pKeyTime->params.size());

        // TODO
        IZ_ASSERT(pValue->stride == 1);

        const SJoint& sJoint = m_Joints[sAnmNode.idxJoint];

        for (size_t nKey = 0; nKey < pKeyTime->params.size(); nKey++) {
            IZ_FLOAT fKeyTime = pKeyTime->params[nKey];

            // Find target transform's param.
            std::vector<SQuatParam>::iterator itQuatParam;
            itQuatParam = std::find(
                            tvQuatList.begin(),
                            tvQuatList.end(),
                            SQuatParam(sAnmChannel.transform.c_str(), fKeyTime));

            if (itQuatParam != tvQuatList.end()) {
                // Replace parameter.
                SQuatParam& sQuatParams = *itQuatParam;
                sQuatParams.params[3] = IZ_DEG2RAD(pValue->params[nKey]);
            }
            else {
                // Create new transform's param.
                std::vector<SJointTransform>::const_reverse_iterator rit = sJoint.transforms.rbegin();

                for (; rit != sJoint.transforms.rend(); rit++) {
                    const SJointTransform& sJointTransform = *rit;

                    SQuatParam sQuatParams(sJointTransform.name, fKeyTime);

                    if (sJointTransform.type == E_TRANSFROM_TYPE_QUARTANION) {
                        VRETURN(sJointTransform.param.size() == 4);

                        sQuatParams.params[0] = sJointTransform.param[0];
                        sQuatParams.params[1] = sJointTransform.param[1];
                        sQuatParams.params[2] = sJointTransform.param[2];

                        if (sJointTransform.name == sAnmChannel.transform) {
                            sQuatParams.params[3] = IZ_DEG2RAD(pValue->params[nKey]);
                        }
                        else {
                            sQuatParams.params[3] = IZ_DEG2RAD(sJointTransform.param[3]);
                        }

                        sQuatParams.idx = static_cast<IZ_UINT>(tvQuatList.size());
                        tvQuatList.push_back(sQuatParams);
                    }
                }
            }
        }

        // Remove sAnmChannel.
        itAnmChannel = sAnmNode.channels.erase(itAnmChannel);
    }

    if (!tvQuatList.empty()) {
        // Sort by time.
        std::sort(
            tvQuatList.begin(),
            tvQuatList.end(),
            SSortQuatParam());

        SAnmChannel sAnmChannel;
        {
            sAnmChannel.type = izanagi::E_ANM_TRANSFORM_TYPE_QUATERNION_XYZW;
            sAnmChannel.interp = izanagi::E_ANM_INTERP_TYPE_SLERP;

            // Inputs are times and quartanions.
            sAnmChannel.inputs.resize(2);

            // Get times.
            std::set<IZ_FLOAT> times;
            for (size_t i = 0; i < tvQuatList.size(); i++) {
                const SQuatParam& sQuatParam = tvQuatList[i];
                times.insert(sQuatParam.time);
            }

            SAnmInput& sAnmInput = sAnmChannel.inputs[0];
            {
                sAnmInput.semantic = E_INPUT_SEMANTIC_INPUT;
                sAnmInput.stride = 1;
            }

            for (std::set<IZ_FLOAT>::const_iterator it = times.begin(); it != times.end(); it++) {
                sAnmInput.params.push_back(*it);
            }
        }

        // For quartanion.
        SAnmInput& sAnmInput = sAnmChannel.inputs[1];
        {
            sAnmInput.semantic = E_INPUT_SEMANTIC_OUTPUT;
            sAnmInput.stride = 4;

            sAnmInput.params.reserve(4 * sAnmChannel.inputs[0].params.size());
        }

        // Compute new quartanion.
        IZ_FLOAT fPrevTime = IZ_FLOAT_MAX;

        izanagi::math::SMatrix44 mtx;

        for (size_t i = 0; i < tvQuatList.size(); i++) {
            const SQuatParam& sQuatParam = tvQuatList[i];

            IZ_FLOAT x = sQuatParam.params[0];
            IZ_FLOAT y = sQuatParam.params[1];
            IZ_FLOAT z = sQuatParam.params[2];
            IZ_FLOAT angle = sQuatParam.params[3];

            if (fPrevTime == sQuatParam.time) {
                _RotateAxis(
                    mtx, mtx,
                    x, y, z, angle);
            }
            else {
                if (i > 0) {
                    izanagi::math::SQuat quat;
                    izanagi::math::SQuat::QuatFromMatrix(quat, mtx);
                    izanagi::math::SQuat::Normalize(quat, quat);
                    sAnmInput.params.push_back(quat.x);
                    sAnmInput.params.push_back(quat.y);
                    sAnmInput.params.push_back(quat.z);
                    sAnmInput.params.push_back(quat.w);
                }

                izanagi::math::SMatrix44::SetUnit(mtx);
                _RotateAxis(
                    mtx, mtx,
                    x, y, z, angle);

                fPrevTime = sQuatParam.time;
            }
        }

        {
            izanagi::math::SQuat quat;
            izanagi::math::SQuat::QuatFromMatrix(quat, mtx);
            izanagi::math::SQuat::Normalize(quat, quat);
            sAnmInput.params.push_back(quat.x);
            sAnmInput.params.push_back(quat.y);
            sAnmInput.params.push_back(quat.z);
            sAnmInput.params.push_back(quat.w);
        }

        // Add new channel.
        sAnmNode.channels.push_back(sAnmChannel);
    }

    return IZ_TRUE;
}
예제 #8
0
StateChangeView::StateChangeView(izanagi::CVectorCamera& camera)
    : StateBase(camera)
{
    izanagi::CVectorCamera tmpCam;
    
    // Low
    {
#if 0
        tmpCam.Init(
            izanagi::math::CVector4(0.0f, 5.0f, -Configure::InnerRadius + Configure::CameraDistance, 1.0f),
            izanagi::math::CVector4(0.0f, 5.0f, -Configure::InnerRadius, 1.0f),
            1.0f,
            500.0f,
            izanagi::math::CMath::Deg2Rad(60.0f),
            1.0f);
        tmpCam.Update();

        izanagi::math::SMatrix44::Copy(m_ViewMtx[ViewState_Low], tmpCam.GetTransform());
#else
        izanagi::math::SMatrix44::Copy(m_ViewMtx[ViewState_Low], camera.GetTransform());
#endif
    }

    // Mid
    {
        izanagi::math::CVector4 v(0.0f, 0.0f, Configure::CameraDistance, 0.0f);
        izanagi::math::SMatrix44 mtx;
        izanagi::math::SMatrix44::GetRotByX(mtx, IZ_DEG2RAD(-30.0f));
        izanagi::math::SMatrix44::Apply(v, v, mtx);

        tmpCam.Init(
            izanagi::math::CVector4(0.0f, v.y, -Configure::InnerRadius + v.z, 1.0f),
            izanagi::math::CVector4(0.0f, 15.0f, -Configure::InnerRadius + Configure::RadiusDiff + Configure::RadiusDiff * 0.5f, 1.0f),
            1.0f,
            500.0f,
            izanagi::math::CMath::Deg2Rad(60.0f),
            1.0f);
        tmpCam.Update();

        izanagi::math::SMatrix44::Copy(m_ViewMtx[ViewState_Mid], tmpCam.GetTransform());
    }

    // High
    {
        izanagi::math::CVector4 v(0.0f, 0.0f, Configure::CameraDistance, 0.0f);
        izanagi::math::SMatrix44 mtx;
        izanagi::math::SMatrix44::GetRotByX(mtx, IZ_DEG2RAD(-55.0f));
        izanagi::math::SMatrix44::Apply(v, v, mtx);

        tmpCam.Init(
            izanagi::math::CVector4(0.0f, v.y, -Configure::InnerRadius + v.z, 1.0f),
            izanagi::math::CVector4(0.0f, 25.0f, -Configure::InnerRadius + Configure::RadiusDiff * 0.5f, 1.0f),
            1.0f,
            500.0f,
            izanagi::math::CMath::Deg2Rad(60.0f),
            1.0f);
        tmpCam.Update();

        izanagi::math::SMatrix44::Copy(m_ViewMtx[ViewState_High], tmpCam.GetTransform());
    }

    m_State = ViewState_Low;
    m_IsAnimating = IZ_FALSE;

    m_Timeline.Init(
        Configure::ChangeViewDuration,
        0.0f);
    m_Timeline.EnableLoop(IZ_FALSE);
    m_Timeline.AutoReverse(IZ_FALSE);
}