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

📄 mgcbeziertriangle3g.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 "MgcBezierTriangle3G.h"

//----------------------------------------------------------------------------
MgcBezierTriangle3G::MgcBezierTriangle3G (MgcVector3* akCtrlPoint)
    :
    MgcBezierTriangleG(3,akCtrlPoint)
{
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle3G::GetPosition (MgcReal fU, MgcReal fV) const
{
    MgcReal fW = 1.0 - fU - fV;
    MgcReal fU2 = fU*fU, fV2 = fV*fV, fW2 = fW*fW;
    MgcReal fU3 = fU*fU2, fV3 = fV*fV2, fW3 = fW*fW2;
    MgcReal f3UV2 = 3.0*fU*fV2, f3UW2 = 3.0*fU*fW2, f3VW2 = 3.0*fV*fW2;
    MgcReal f3U2V = 3.0*fU2*fV, f3U2W = 3.0*fU2*fW, f3V2W = 3.0*fV2*fW;
    MgcReal f6UVW = 6.0*fU*fV*fW;

    return fW3*m_akCtrlPoint[0] + f3UW2*m_akCtrlPoint[1] +
        f3U2W*m_akCtrlPoint[2] + fU3*m_akCtrlPoint[3] +
        f3VW2*m_akCtrlPoint[4] + f6UVW*m_akCtrlPoint[5] +
        f3U2V*m_akCtrlPoint[6] + f3V2W*m_akCtrlPoint[7] +
        f3UV2*m_akCtrlPoint[8] + fV3*m_akCtrlPoint[9];
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle3G::GetDerivativeU (MgcReal fU, MgcReal fV) const
{
    MgcReal fW = 1.0 - fU - fV;
    MgcReal f3U2 = 3.0*fU*fU, f3V2 = 3.0*fV*fV, f3W2 = 3.0*fW*fW;
    MgcReal f6UV = 6.0*fU*fV, f6UW = 6.0*fU*fW, f6VW = 6.0*fV*fW;

    return -f3W2*m_akCtrlPoint[0] + (f3W2-f6UW)*m_akCtrlPoint[1] +
        (f6UW-f3U2)*m_akCtrlPoint[2] + f3U2*m_akCtrlPoint[3] -
        f6VW*m_akCtrlPoint[4] + (f6VW-f6UV)*m_akCtrlPoint[5] +
        f6UV*m_akCtrlPoint[6] - f3V2*m_akCtrlPoint[7] +
        f3V2*m_akCtrlPoint[8];
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle3G::GetDerivativeV (MgcReal fU, MgcReal fV) const
{
    MgcReal fW = 1.0 - fU - fV;
    MgcReal f3U2 = 3.0*fU*fU, f3V2 = 3.0*fV*fV, f3W2 = 3.0*fW*fW;
    MgcReal f6UV = 6.0*fU*fV, f6UW = 6.0*fU*fW, f6VW = 6.0*fV*fW;

    return -f3W2*m_akCtrlPoint[0] - f6UW*m_akCtrlPoint[1] -
        f3U2*m_akCtrlPoint[2] + (f3W2-f6VW)*m_akCtrlPoint[4] +
        (f6UW-f6UV)*m_akCtrlPoint[5] + f3U2*m_akCtrlPoint[6] +
        (f6VW-f3V2)*m_akCtrlPoint[7] + f6UV*m_akCtrlPoint[8] +
        f3V2*m_akCtrlPoint[9];
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle3G::GetDerivativeUU (MgcReal fU, MgcReal fV) const
{
    MgcReal fW = 1.0 - fU - fV;

    return 6.0*(fW*m_akCtrlPoint[0] + (fU-2.0*fW)*m_akCtrlPoint[1] +
        (fW-2.0*fU)*m_akCtrlPoint[2] + fU*m_akCtrlPoint[3] +
        fV*m_akCtrlPoint[4] - 2.0*m_akCtrlPoint[5] + fV*m_akCtrlPoint[6]);
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle3G::GetDerivativeUV (MgcReal fU, MgcReal fV) const
{
    MgcReal fW = 1.0 - fU - fV;

    return 6.0*(fW*m_akCtrlPoint[0] + (fU-fW)*m_akCtrlPoint[1] -
        fU*m_akCtrlPoint[2] + (fV-fW)*m_akCtrlPoint[4] +
        (fW-fU-fV)*m_akCtrlPoint[5] + fU*m_akCtrlPoint[6] -
        fV*m_akCtrlPoint[7] + fV*m_akCtrlPoint[8]);
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle3G::GetDerivativeVV (MgcReal fU, MgcReal fV) const
{
    MgcReal fW = 1.0 - fU - fV;

    return 6.0*(fW*m_akCtrlPoint[0] + fU*m_akCtrlPoint[1] +
        (fV-2.0*fW)*m_akCtrlPoint[4] - 2.0*fU*m_akCtrlPoint[5] +
        (fW-2.0*fV)*m_akCtrlPoint[7] + fU*m_akCtrlPoint[8] +
        fV*m_akCtrlPoint[9]);
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3G::Tessellate (unsigned int uiLevel, bool bWantNormals)
{
    // allocate arrays and compute connectivity
    Initialize(uiLevel,bWantNormals);

    // indices of three corners of patch, I0 (w=1), I1 (u=1), I2 (v=1)
    unsigned int uiTwoPowL = (1 << uiLevel);
    BlockParameters kBP;
    kBP.m_uiI0 = 0;
    kBP.m_uiI1 = uiTwoPowL;
    kBP.m_uiI2 = uiTwoPowL*(uiTwoPowL + 3) >> 1;

    // vertices for subdivision
    MgcVector3* akX = m_akVertex;
    akX[kBP.m_uiI0] = m_akCtrlPoint[0];
    akX[kBP.m_uiI1] = m_akCtrlPoint[3];
    akX[kBP.m_uiI2] = m_akCtrlPoint[9];

    // derivatives for subdivision (for normal vectors)
    MgcVector3* akXu;
    MgcVector3* akXv;
    if ( bWantNormals )
    {
        akXu = new MgcVector3[m_uiVertexQuantity];
        akXu[kBP.m_uiI0] = 3.0*(m_akCtrlPoint[1] - m_akCtrlPoint[0]);
        akXu[kBP.m_uiI1] = 3.0*(m_akCtrlPoint[3] - m_akCtrlPoint[2]);
        akXu[kBP.m_uiI2] = 3.0*(m_akCtrlPoint[8] - m_akCtrlPoint[7]);

        akXv = new MgcVector3[m_uiVertexQuantity];
        akXv[kBP.m_uiI0] = 3.0*(m_akCtrlPoint[4] - m_akCtrlPoint[0]);
        akXv[kBP.m_uiI1] = 3.0*(m_akCtrlPoint[6] - m_akCtrlPoint[2]);
        akXv[kBP.m_uiI2] = 3.0*(m_akCtrlPoint[9] - m_akCtrlPoint[7]);
    }
    else
    {
        akXu = 0;
        akXv = 0;
    }

    // recursive subdivision
    if ( uiLevel > 0 )
    {
        kBP.m_aakXuu[0] = 6.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[1] +
            m_akCtrlPoint[2]);
        kBP.m_aakXuu[1] = 6.0*(m_akCtrlPoint[1] - 2.0*m_akCtrlPoint[2] +
            m_akCtrlPoint[3]);
        kBP.m_aakXuu[2] = 6.0*(m_akCtrlPoint[4] - 2.0*m_akCtrlPoint[5] +
            m_akCtrlPoint[6]);
        kBP.m_aakXvv[0] = 6.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[4] +
            m_akCtrlPoint[7]);
        kBP.m_aakXvv[1] = 6.0*(m_akCtrlPoint[1] - 2.0*m_akCtrlPoint[5] +
            m_akCtrlPoint[8]);
        kBP.m_aakXvv[2] = 6.0*(m_akCtrlPoint[4] - 2.0*m_akCtrlPoint[7] +
            m_akCtrlPoint[9]);
        kBP.m_aakXhh[0] = 6.0*(m_akCtrlPoint[2] - 2.0*m_akCtrlPoint[5] +
            m_akCtrlPoint[7]);
        kBP.m_aakXhh[1] = 6.0*(m_akCtrlPoint[3] - 2.0*m_akCtrlPoint[6] +
            m_akCtrlPoint[8]);
        kBP.m_aakXhh[2] = 6.0*(m_akCtrlPoint[6] - 2.0*m_akCtrlPoint[8] +
            m_akCtrlPoint[9]);

        if ( bWantNormals )
        {
            kBP.m_kXuuu = 6.0*(m_akCtrlPoint[3] - m_akCtrlPoint[0] +
                2.0*(m_akCtrlPoint[1] - m_akCtrlPoint[2]));
            kBP.m_kXuuv = 6.0*(m_akCtrlPoint[4] + m_akCtrlPoint[6] -
                m_akCtrlPoint[0] - m_akCtrlPoint[2] + 2.0*(m_akCtrlPoint[1] -
                m_akCtrlPoint[5]));
            kBP.m_kXuvv = 6.0*(m_akCtrlPoint[1] + m_akCtrlPoint[8] -
                m_akCtrlPoint[0] - m_akCtrlPoint[7] + 2.0*(m_akCtrlPoint[4] -
                m_akCtrlPoint[5]));
            kBP.m_kXvvv = 6.0*(m_akCtrlPoint[9] - m_akCtrlPoint[0] +
                2.0*(m_akCtrlPoint[4] - m_akCtrlPoint[7]));
            kBP.m_kXhhu = 6.0*(m_akCtrlPoint[3] + m_akCtrlPoint[8] -
                m_akCtrlPoint[2] - m_akCtrlPoint[7] + 2.0*(m_akCtrlPoint[5] -
                m_akCtrlPoint[6]));
            kBP.m_kXhhv = 6.0*(m_akCtrlPoint[6] + m_akCtrlPoint[9] -
                m_akCtrlPoint[2] - m_akCtrlPoint[7] + 2.0*(m_akCtrlPoint[5] -
                m_akCtrlPoint[8]));
        }

        SubdivideLL(--uiLevel,0.25,akX,akXu,akXv,kBP);
    }

    // calculate unit-length normals from derivative vectors
    if ( bWantNormals )
    {
        for (unsigned int uiI = 0; uiI < m_uiVertexQuantity; uiI++)
            m_akNormal[uiI] = akXu[uiI].UnitCross(akXv[uiI]);
        delete[] akXu;
        delete[] akXv;
    }
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3G::SubdivideLL (unsigned int uiLevel, MgcReal fDSqr,
    MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv,
    BlockParameters& rkBP)
{
    /*
     i2
     +
     | \
     |   \
     +----+
     i0    i1
    */

    // subdivision indices
    unsigned int uiI01 = (rkBP.m_uiI0 + rkBP.m_uiI1) >> 1;
    unsigned int uiD10 = rkBP.m_uiI1 - rkBP.m_uiI0;
    unsigned int uiI02 = (((rkBP.m_uiI0+rkBP.m_uiI2) << 2)+uiD10*uiD10) >> 3;
    unsigned int uiI12 = uiI02 + (uiD10 >> 1);

    // vertices

    // bottom u-edge subdivision
    MgcVector3 kXuu01 = 0.5*(rkBP.m_aakXuu[0] + rkBP.m_aakXuu[1]);
    MgcVector3 kXvv01 = 0.5*(rkBP.m_aakXvv[0] + rkBP.m_aakXvv[1]);
    MgcVector3 kXhh01 = 0.5*(rkBP.m_aakXhh[0] + rkBP.m_aakXhh[1]);
    akX[uiI01] = 0.5*(akX[rkBP.m_uiI0] + akX[rkBP.m_uiI1] - fDSqr*kXuu01);

    // left v-edge subdivision
    MgcVector3 kXuu02 = 0.5*(rkBP.m_aakXuu[0] + rkBP.m_aakXuu[2]);
    MgcVector3 kXvv02 = 0.5*(rkBP.m_aakXvv[0] + rkBP.m_aakXvv[2]);
    MgcVector3 kXhh02 = 0.5*(rkBP.m_aakXhh[0] + rkBP.m_aakXhh[2]);
    akX[uiI02] = 0.5*(akX[rkBP.m_uiI0] + akX[rkBP.m_uiI2] - fDSqr*kXvv02);

    // hypotenuse edge subdivision
    MgcVector3 kXuu12 = 0.5*(rkBP.m_aakXuu[1] + rkBP.m_aakXuu[2]);
    MgcVector3 kXvv12 = 0.5*(rkBP.m_aakXvv[1] + rkBP.m_aakXvv[2]);
    MgcVector3 kXhh12 = 0.5*(rkBP.m_aakXhh[1] + rkBP.m_aakXhh[2]);
    akX[uiI12] = 0.5*(akX[rkBP.m_uiI1] + akX[rkBP.m_uiI2] - fDSqr*kXhh12);

    // derivatives (for normal vectors)
    if ( akXu )
    {
        // bottom u-edge subdivision

⌨️ 快捷键说明

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