⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgcbezierrectangle3g.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// FREE SOURCE CODE
// http://www.magic-software.com/License/free.pdf

#include "MgcBezierRectangle3G.h"

//----------------------------------------------------------------------------
MgcBezierRectangle3G::MgcBezierRectangle3G (MgcVector3* akCtrlPoint)
    :
    MgcBezierRectangleG(3,akCtrlPoint)
{
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierRectangle3G::GetPosition (MgcReal fU, MgcReal fV) const
{
    MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
    MgcReal afUCoeff[4] =
    {
        fOmU*fOmU2,
        3.0*fOmU2*fU,
        3.0*fOmU*fU2,
        fU*fU2
    };

    MgcReal fOmV = 1.0 - fV, fV2 = fV*fV, fOmV2 = fOmV*fOmV;
    MgcReal afVCoeff[4] =
    {
        fOmV*fOmV2,
        3.0*fOmV2*fV,
        3.0*fOmV*fV2,
        fV*fV2
    };

    MgcVector3 kResult = MgcVector3::ZERO;
    for (int iY = 0; iY < 4; iY++)
    {
        for (int iX = 0; iX < 4; iX++)
            kResult += afUCoeff[iX]*afVCoeff[iY]*m_akCtrlPoint[iX + 4*iY];
    }

    return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierRectangle3G::GetDerivativeU (MgcReal fU, MgcReal fV) const
{
    MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
    MgcReal afUCoeff[4] =
    {
        -3.0*fOmU2,
        3.0*fOmU*(fOmU - 2.0*fU),
        3.0*fU*(2.0*fOmU - fU),
        3.0*fU2
    };

    MgcReal fOmV = 1.0 - fV, fV2 = fV*fV, fOmV2 = fOmV*fOmV;
    MgcReal afVCoeff[4] =
    {
        fOmV*fOmV2,
        3.0*fOmV2*fV,
        3.0*fOmV*fV2,
        fV*fV2
    };

    MgcVector3 kResult = MgcVector3::ZERO;
    for (int iY = 0; iY < 4; iY++)
    {
        for (int iX = 0; iX < 4; iX++)
            kResult += afUCoeff[iX]*afVCoeff[iY]*m_akCtrlPoint[iX + 4*iY];
    }

    return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierRectangle3G::GetDerivativeV (MgcReal fU, MgcReal fV) const
{
    MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
    MgcReal afUCoeff[4] =
    {
        fOmU*fOmU2,
        3.0*fOmU2*fU,
        3.0*fOmU*fU2,
        fU*fU2
    };

    MgcReal fOmV = 1.0 - fV, fV2 = fV*fV, fOmV2 = fOmV*fOmV;
    MgcReal afVCoeff[4] =
    {
        -3.0*fOmV2,
        3.0*fOmV*(fOmV - 2.0*fV),
        3.0*fV*(2.0*fOmV - fV),
        3.0*fV2
    };

    MgcVector3 kResult = MgcVector3::ZERO;
    for (int iY = 0; iY < 4; iY++)
    {
        for (int iX = 0; iX < 4; iX++)
            kResult += afUCoeff[iX]*afVCoeff[iY]*m_akCtrlPoint[iX + 4*iY];
    }

    return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierRectangle3G::GetDerivativeUU (MgcReal fU,
    MgcReal fV) const
{
    MgcReal fOmU = 1.0 - fU;
    MgcReal afUCoeff[4] =
    {
        6.0*fOmU,
        6.0*(fU - 2.0*fOmU),
        6.0*(fOmU - 2.0*fU),
        6.0*fU
    };

    MgcReal fOmV = 1.0 - fV, fV2 = fV*fV, fOmV2 = fOmV*fOmV;
    MgcReal afVCoeff[4] =
    {
        fOmV*fOmV2,
        3.0*fOmV2*fV,
        3.0*fOmV*fV2,
        fV*fV2
    };

    MgcVector3 kResult = MgcVector3::ZERO;
    for (int iY = 0; iY < 4; iY++)
    {
        for (int iX = 0; iX < 4; iX++)
            kResult += afUCoeff[iX]*afVCoeff[iY]*m_akCtrlPoint[iX + 4*iY];
    }

    return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierRectangle3G::GetDerivativeUV (MgcReal fU,
    MgcReal fV) const
{
    MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
    MgcReal afUCoeff[4] =
    {
        -3.0*fOmU2,
        3.0*fOmU*(fOmU - 2.0*fU),
        3.0*fU*(2.0*fOmU - fU),
        3.0*fU2
    };

    MgcReal fOmV = 1.0 - fV, fV2 = fV*fV, fOmV2 = fOmV*fOmV;
    MgcReal afVCoeff[4] =
    {
        -3.0*fOmV2,
        3.0*fOmV*(fOmV - 2.0*fV),
        3.0*fV*(2.0*fOmV - fV),
        3.0*fV2
    };

    MgcVector3 kResult = MgcVector3::ZERO;
    for (int iY = 0; iY < 4; iY++)
    {
        for (int iX = 0; iX < 4; iX++)
            kResult += afUCoeff[iX]*afVCoeff[iY]*m_akCtrlPoint[iX + 4*iY];
    }

    return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierRectangle3G::GetDerivativeVV (MgcReal fU,
    MgcReal fV) const
{
    MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
    MgcReal afUCoeff[4] =
    {
        fOmU*fOmU2,
        3.0*fOmU2*fU,
        3.0*fOmU*fU2,
        fU*fU2
    };

    MgcReal fOmV = 1.0 - fV;
    MgcReal afVCoeff[4] =
    {
        6.0*fOmV,
        6.0*(fV - 2.0*fOmV),
        6.0*(fOmV - 2.0*fV),
        6.0*fV
    };

    MgcVector3 kResult = MgcVector3::ZERO;
    for (int iY = 0; iY < 4; iY++)
    {
        for (int iX = 0; iX < 4; iX++)
            kResult += afUCoeff[iX]*afVCoeff[iY]*m_akCtrlPoint[iX + 4*iY];
    }

    return kResult;
}
//----------------------------------------------------------------------------
void MgcBezierRectangle3G::Tessellate (unsigned int uiLevel,
    bool bWantNormals)
{
    // allocate arrays and compute connectivity
    Initialize(uiLevel,bWantNormals);

    // indices of four corners of patch, I[u][v]
    unsigned int uiTwoPowL = (1 << uiLevel);
    BlockParameters kBP;
    kBP.m_uiI00 = 0;
    kBP.m_uiI01 = uiTwoPowL*(uiTwoPowL + 1);
    kBP.m_uiI10 = uiTwoPowL;
    kBP.m_uiI11 = kBP.m_uiI01 + uiTwoPowL;

    // vertices for subdivision
    MgcVector3* akX = m_akVertex;
    akX[kBP.m_uiI00] = m_akCtrlPoint[0];
    akX[kBP.m_uiI01] = m_akCtrlPoint[12];
    akX[kBP.m_uiI10] = m_akCtrlPoint[3];
    akX[kBP.m_uiI11] = m_akCtrlPoint[15];

    // derivatives for subdivision (for normal vectors)
    MgcVector3* akXu;
    MgcVector3* akXv;
    if ( bWantNormals )
    {
        akXu = new MgcVector3[m_uiVertexQuantity];
        akXu[kBP.m_uiI00] = 3.0*(m_akCtrlPoint[1] - m_akCtrlPoint[0]);
        akXu[kBP.m_uiI01] = 3.0*(m_akCtrlPoint[13] - m_akCtrlPoint[12]);
        akXu[kBP.m_uiI10] = 3.0*(m_akCtrlPoint[3] - m_akCtrlPoint[2]);
        akXu[kBP.m_uiI11] = 3.0*(m_akCtrlPoint[15] - m_akCtrlPoint[14]);

        akXv = new MgcVector3[m_uiVertexQuantity];
        akXv[kBP.m_uiI00] = 3.0*(m_akCtrlPoint[4] - m_akCtrlPoint[0]);
        akXv[kBP.m_uiI01] = 3.0*(m_akCtrlPoint[12] - m_akCtrlPoint[8]);
        akXv[kBP.m_uiI10] = 3.0*(m_akCtrlPoint[7] - m_akCtrlPoint[3]);
        akXv[kBP.m_uiI11] = 3.0*(m_akCtrlPoint[15] - m_akCtrlPoint[11]);
    }
    else
    {
        akXu = 0;
        akXv = 0;
    }

    // recursive subdivision
    if ( uiLevel > 0 )
    {
        kBP.m_aakXuu[0][0] = 6.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[1] +
            m_akCtrlPoint[2]);
        kBP.m_aakXuu[0][1] = 6.0*(m_akCtrlPoint[12] - 2.0*m_akCtrlPoint[13] +
            m_akCtrlPoint[14]);
        kBP.m_aakXuu[1][0] = 6.0*(m_akCtrlPoint[1] - 2.0*m_akCtrlPoint[2] +
            m_akCtrlPoint[3]);
        kBP.m_aakXuu[1][1] = 6.0*(m_akCtrlPoint[13] - 2.0*m_akCtrlPoint[14] +
            m_akCtrlPoint[15]);
        kBP.m_aakXvv[0][0] = 6.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[4] +
            m_akCtrlPoint[8]);
        kBP.m_aakXvv[0][1] = 6.0*(m_akCtrlPoint[4] - 2.0*m_akCtrlPoint[8] +
            m_akCtrlPoint[12]);
        kBP.m_aakXvv[1][0] = 6.0*(m_akCtrlPoint[3] - 2.0*m_akCtrlPoint[7] +
            m_akCtrlPoint[11]);
        kBP.m_aakXvv[1][1] = 6.0*(m_akCtrlPoint[7] - 2.0*m_akCtrlPoint[11] +
            m_akCtrlPoint[15]);
        kBP.m_aakXuuvv[0][0] = 36.0*(m_akCtrlPoint[0] + m_akCtrlPoint[2] +
            m_akCtrlPoint[8] + m_akCtrlPoint[10] -
            2.0*(m_akCtrlPoint[1] + m_akCtrlPoint[4] + m_akCtrlPoint[6] +
            m_akCtrlPoint[9]) + 4.0*m_akCtrlPoint[5]);
        kBP.m_aakXuuvv[0][1] = 36.0*(m_akCtrlPoint[4] + m_akCtrlPoint[6] +
            m_akCtrlPoint[12] + m_akCtrlPoint[14] -
            2.0*(m_akCtrlPoint[5] + m_akCtrlPoint[8] + m_akCtrlPoint[10] +
            m_akCtrlPoint[13]) + 4.0*m_akCtrlPoint[9]);
        kBP.m_aakXuuvv[1][0] = 36.0*(m_akCtrlPoint[1] + m_akCtrlPoint[3] +
            m_akCtrlPoint[9] + m_akCtrlPoint[11] -
            2.0*(m_akCtrlPoint[2] + m_akCtrlPoint[5] + m_akCtrlPoint[7] +
            m_akCtrlPoint[10]) + 4.0*m_akCtrlPoint[6]);
        kBP.m_aakXuuvv[1][1] = 36.0*(m_akCtrlPoint[5] + m_akCtrlPoint[7] +
            m_akCtrlPoint[13] + m_akCtrlPoint[15] -
            2.0*(m_akCtrlPoint[6] + m_akCtrlPoint[9] + m_akCtrlPoint[11] +
            m_akCtrlPoint[14]) + 4.0*m_akCtrlPoint[10]);

        if ( bWantNormals )
        {
            kBP.m_aakXuuv[0][0] = 18.0*(m_akCtrlPoint[4] + m_akCtrlPoint[6] -
                m_akCtrlPoint[0] - m_akCtrlPoint[2] + 2.0*(m_akCtrlPoint[1] -
                m_akCtrlPoint[5]));
            kBP.m_aakXuuv[0][1] = 18.0*(m_akCtrlPoint[5] + m_akCtrlPoint[7] -
                m_akCtrlPoint[1] - m_akCtrlPoint[3] + 2.0*(m_akCtrlPoint[2] -
                m_akCtrlPoint[6]));
            kBP.m_aakXuuv[1][0] = 18.0*(m_akCtrlPoint[12] + m_akCtrlPoint[14]
                - m_akCtrlPoint[8] - m_akCtrlPoint[10] +
                2.0*(m_akCtrlPoint[9] - m_akCtrlPoint[13]));
            kBP.m_aakXuuv[1][1] = 18.0*(m_akCtrlPoint[13] + m_akCtrlPoint[15]
                - m_akCtrlPoint[9] - m_akCtrlPoint[11] +
                2.0*(m_akCtrlPoint[10] - m_akCtrlPoint[14]));
            kBP.m_aakXuvv[0][0] = 18.0*(m_akCtrlPoint[1] + m_akCtrlPoint[9] -
                m_akCtrlPoint[0] - m_akCtrlPoint[8] + 2.0*(m_akCtrlPoint[4] -
                m_akCtrlPoint[5]));
            kBP.m_aakXuvv[0][1] = 18.0*(m_akCtrlPoint[5] + m_akCtrlPoint[13]
                - m_akCtrlPoint[4] - m_akCtrlPoint[12] +
                2.0*(m_akCtrlPoint[8] - m_akCtrlPoint[9]));
            kBP.m_aakXuvv[1][0] = 18.0*(m_akCtrlPoint[3] + m_akCtrlPoint[11]
                - m_akCtrlPoint[2] - m_akCtrlPoint[10] +
                2.0*(m_akCtrlPoint[6] - m_akCtrlPoint[7]));
            kBP.m_aakXuvv[1][1] = 18.0*(m_akCtrlPoint[7] + m_akCtrlPoint[15]
                - m_akCtrlPoint[6] - m_akCtrlPoint[14] +
                2.0*(m_akCtrlPoint[10] - m_akCtrlPoint[11]));
            kBP.m_akXuuu[0] = 6.0*(m_akCtrlPoint[3] + 3.0*(m_akCtrlPoint[1] -
                m_akCtrlPoint[2]) - m_akCtrlPoint[0]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -