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

📄 wmlbezierrectangle3.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003.  All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.

#include "WmlBezierRectangle3.h"
#include "WmlTriMesh.h"
using namespace Wml;

WmlImplementRTTI(BezierRectangle3,BezierRectangle);
WmlImplementStream(BezierRectangle3);

// macros for initialization in the subdivision
#define XA(i) akCtrlPoint[m_aiIndex[i]]
#define CA(i) akCtrlColor[m_aiIndex[i]]
#define TA(i) akCtrlTexture[m_aiIndex[i]]

//----------------------------------------------------------------------------
BezierRectangle3::BezierRectangle3 (int* aiIndex)
    :
    BezierRectangle(3,16,aiIndex)
{
}
//----------------------------------------------------------------------------
BezierRectangle3::BezierRectangle3 ()
{
}
//----------------------------------------------------------------------------
void BezierRectangle3::InitializePoints (const Vector3f* akCtrlPoint,
    BlockParameters& rkBP)
{
    // Xss[s][t]
    rkBP.m_aakXss[0][0] = 6.0f*(XA( 0) - 2.0f*XA( 1) + XA( 2));
    rkBP.m_aakXss[0][1] = 6.0f*(XA(12) - 2.0f*XA(13) + XA(14));
    rkBP.m_aakXss[1][0] = 6.0f*(XA( 1) - 2.0f*XA( 2) + XA( 3));
    rkBP.m_aakXss[1][1] = 6.0f*(XA(13) - 2.0f*XA(14) + XA(15));

    // Xtt[s][t]
    rkBP.m_aakXtt[0][0] = 6.0f*(XA( 0) - 2.0f*XA( 4) + XA( 8));
    rkBP.m_aakXtt[0][1] = 6.0f*(XA( 4) - 2.0f*XA( 8) + XA(12));
    rkBP.m_aakXtt[1][0] = 6.0f*(XA( 3) - 2.0f*XA( 7) + XA(11));
    rkBP.m_aakXtt[1][1] = 6.0f*(XA( 7) - 2.0f*XA(11) + XA(15));

    // Xsstt[s][t]
    rkBP.m_aakXsstt[0][0] = 36.0f*(XA(0) + XA(2) + XA(8) + XA(10) -
        2.0f*(XA(1) + XA(4) + XA(6) + XA(9)) + 4.0f*XA(5));
    rkBP.m_aakXsstt[0][1] = 36.0f*(XA(4) + XA(6) + XA(12) + XA(14) -
        2.0f*(XA(5) + XA(8) + XA(10) + XA(13)) + 4.0f*XA(9));
    rkBP.m_aakXsstt[1][0] = 36.0f*(XA(1) + XA(3) + XA(9) + XA(11) -
        2.0f*(XA(2) + XA(5) + XA(7) + XA(10)) + 4.0f*XA(6));
    rkBP.m_aakXsstt[1][1] = 36.0f*(XA(5) + XA(7) + XA(13) + XA(15) -
        2.0f*(XA(6) + XA(9) + XA(11) + XA(14)) + 4.0f*XA(10));
}
//----------------------------------------------------------------------------
void BezierRectangle3::InitializeNormals (const Vector3f* akCtrlPoint,
    BlockParameters& rkBP)
{
    // Xsst[s][t]
    rkBP.m_aakXsst[0][0] = 18.0f*(XA(4) + XA(6) - XA(0) - XA(2) +
        2.0f*(XA(1) - XA(5)));
    rkBP.m_aakXsst[0][1] = 18.0f*(XA(5) + XA(7) - XA(1) - XA(3) +
        2.0f*(XA(2) - XA(6)));
    rkBP.m_aakXsst[1][0] = 18.0f*(XA(12) + XA(14) - XA(8) - XA(10) +
        2.0f*(XA(9) - XA(13)));
    rkBP.m_aakXsst[1][1] = 18.0f*(XA(13) + XA(15) - XA(9) - XA(11) +
        2.0f*(XA(10) - XA(14)));

    // Xstt[s][t]
    rkBP.m_aakXstt[0][0] = 18.0f*(XA(1) + XA(9) - XA(0) - XA(8) +
        2.0f*(XA(4) - XA(5)));
    rkBP.m_aakXstt[0][1] = 18.0f*(XA(5) + XA(13) - XA(4) - XA(12) +
        2.0f*(XA(8) - XA(9)));
    rkBP.m_aakXstt[1][0] = 18.0f*(XA(3) + XA(11) - XA(2) - XA(10) +
        2.0f*(XA(6) - XA(7)));
    rkBP.m_aakXstt[1][1] = 18.0f*(XA(7) + XA(15) - XA(6) - XA(14) +
        2.0f*(XA(10) - XA(11)));

    // Xsss
    rkBP.m_akXsss[0] = 6.0f*(XA(3) + 3.0f*(XA(1) - XA(2)) - XA(0));
    rkBP.m_akXsss[1] = 6.0f*(XA(15) + 3.0f*(XA(13) - XA(14)) - XA(12));

    // Xttt
    rkBP.m_akXttt[0] = 6.0f*(XA(12) + 3.0f*(XA(4) - XA(8)) - XA(0));
    rkBP.m_akXttt[1] = 6.0f*(XA(15) + 3.0f*(XA(7) - XA(11)) - XA(3));

    // Xssstt
    rkBP.m_akXssstt[0] = 36.0f*(XA(3) + XA(11) - XA(0) - XA(8) +
        2.0f*(XA(4) - XA(7)) + 3.0f*(XA(1) + XA(9) - XA(2) - XA(10)) +
        6.0f*(XA(6) - XA(5)));
    rkBP.m_akXssstt[1] = 36.0f*(XA(7) + XA(15) - XA(4) - XA(12) +
        2.0f*(XA(8) - XA(11)) + 3.0f*(XA(5) + XA(13) - XA(6) - XA(14)) +
        6.0f*(XA(10) - XA(9)));

    // Xtttss
    rkBP.m_akXssttt[0] = 36.0f*(XA(12) + XA(14) - XA(0) - XA(2) +
        2.0f*(XA(1) - XA(13)) + 3.0f*(XA(4) + XA(6) - XA(8) - XA(10)) +
        6.0f*(XA(9) - XA(5)));
    rkBP.m_akXssttt[1] = 36.0f*(XA(13) + XA(15) - XA(1) - XA(3) +
        2.0f*(XA(2) - XA(14)) + 3.0f*(XA(5) + XA(7) - XA(9) - XA(11)) +
        6.0f*(XA(10) - XA(6)));
}
//----------------------------------------------------------------------------
void BezierRectangle3::InitializeColors (const ColorRGB* akCtrlColor,
    BlockParameters& rkBP)
{
    // Css[s][t]
    rkBP.m_aakCss[0][0] = 6.0f*(CA( 0) - 2.0f*CA( 1) + CA( 2));
    rkBP.m_aakCss[0][1] = 6.0f*(CA(12) - 2.0f*CA(13) + CA(14));
    rkBP.m_aakCss[1][0] = 6.0f*(CA( 1) - 2.0f*CA( 2) + CA( 3));
    rkBP.m_aakCss[1][1] = 6.0f*(CA(13) - 2.0f*CA(14) + CA(15));

    // Ctt[s][t]
    rkBP.m_aakCtt[0][0] = 6.0f*(CA( 0) - 2.0f*CA( 4) + CA( 8));
    rkBP.m_aakCtt[0][1] = 6.0f*(CA( 4) - 2.0f*CA( 8) + CA(12));
    rkBP.m_aakCtt[1][0] = 6.0f*(CA( 3) - 2.0f*CA( 7) + CA(11));
    rkBP.m_aakCtt[1][1] = 6.0f*(CA( 7) - 2.0f*CA(11) + CA(15));

    // Csstt[s][t]
    rkBP.m_aakCsstt[0][0] = 36.0f*(CA(0) + CA(2) + CA(8) + CA(10) -
        2.0f*(CA(1) + CA(4) + CA(6) + CA(9)) + 4.0f*CA(5));
    rkBP.m_aakCsstt[0][1] = 36.0f*(CA(4) + CA(6) + CA(12) + CA(14) -
        2.0f*(CA(5) + CA(8) + CA(10) + CA(13)) + 4.0f*CA(9));
    rkBP.m_aakCsstt[1][0] = 36.0f*(CA(1) + CA(3) + CA(9) + CA(11) -
        2.0f*(CA(2) + CA(5) + CA(7) + CA(10)) + 4.0f*CA(6));
    rkBP.m_aakCsstt[1][1] = 36.0f*(CA(5) + CA(7) + CA(13) + CA(15) -
        2.0f*(CA(6) + CA(9) + CA(11) + CA(14)) + 4.0f*CA(10));
}
//----------------------------------------------------------------------------
void BezierRectangle3::InitializeTextures (const Vector2f* akCtrlTexture,
    BlockParameters& rkBP)
{
    // Tss[s][t]
    rkBP.m_aakTss[0][0] = 6.0f*(TA( 0) - 2.0f*TA( 1) + TA( 2));
    rkBP.m_aakTss[0][1] = 6.0f*(TA(12) - 2.0f*TA(13) + TA(14));
    rkBP.m_aakTss[1][0] = 6.0f*(TA( 1) - 2.0f*TA( 2) + TA( 3));
    rkBP.m_aakTss[1][1] = 6.0f*(TA(13) - 2.0f*TA(14) + TA(15));

    // Ttt[s][t]
    rkBP.m_aakTtt[0][0] = 6.0f*(TA( 0) - 2.0f*TA( 4) + TA( 8));
    rkBP.m_aakTtt[0][1] = 6.0f*(TA( 4) - 2.0f*TA( 8) + TA(12));
    rkBP.m_aakTtt[1][0] = 6.0f*(TA( 3) - 2.0f*TA( 7) + TA(11));
    rkBP.m_aakTtt[1][1] = 6.0f*(TA( 7) - 2.0f*TA(11) + TA(15));

    // Tsstt[s][t]
    rkBP.m_aakTsstt[0][0] = 36.0f*(TA(0) + TA(2) + TA(8) + TA(10) -
        2.0f*(TA(1) + TA(4) + TA(6) + TA(9)) + 4.0f*TA(5));
    rkBP.m_aakTsstt[0][1] = 36.0f*(TA(4) + TA(6) + TA(12) + TA(14) -
        2.0f*(TA(5) + TA(8) + TA(10) + TA(13)) + 4.0f*TA(9));
    rkBP.m_aakTsstt[1][0] = 36.0f*(TA(1) + TA(3) + TA(9) + TA(11) -
        2.0f*(TA(2) + TA(5) + TA(7) + TA(10)) + 4.0f*TA(6));
    rkBP.m_aakTsstt[1][1] = 36.0f*(TA(5) + TA(7) + TA(13) + TA(15) -
        2.0f*(TA(6) + TA(9) + TA(11) + TA(14)) + 4.0f*TA(10));
}
//----------------------------------------------------------------------------
void BezierRectangle3::Tessellate (int iLevel, const Vector3f* akCtrlPoint,
    const ColorRGB* akCtrlColor, const Vector2f* akCtrlTexture,
    TriMesh* pkMesh, int& riVertexStart, int& riTriangleStart)
{
    GenerateConnectivity(iLevel,pkMesh,riTriangleStart);

    // number of vertices in the subdivision
    int iQuantity = GetVerticesPerPatch(iLevel);

    // indices of four corners of patch, I[s][t]
    int iTwoPowL = (1 << iLevel);
    BlockParameters kBP;
    kBP.m_i00 = 0;
    kBP.m_i01 = iTwoPowL*(iTwoPowL + 1);
    kBP.m_i10 = iTwoPowL;
    kBP.m_i11 = kBP.m_i01 + iTwoPowL;

    // vertices for subdivision
    Vector3f* akX = pkMesh->Vertices() + riVertexStart;
    akX[kBP.m_i00] = XA( 0);
    akX[kBP.m_i01] = XA(12);
    akX[kBP.m_i10] = XA( 3);
    akX[kBP.m_i11] = XA(15);

    // derivatives for subdivision (for normal vectors)
    Vector3f* akXs;
    Vector3f* akXt;
    if ( pkMesh->Normals() )
    {
        akXs = new Vector3f[iQuantity];
        akXs[kBP.m_i00] = 3.0f*(XA( 1) - XA( 0));
        akXs[kBP.m_i01] = 3.0f*(XA(13) - XA(12));
        akXs[kBP.m_i10] = 3.0f*(XA( 3) - XA( 2));
        akXs[kBP.m_i11] = 3.0f*(XA(15) - XA(14));

        akXt = new Vector3f[iQuantity];
        akXt[kBP.m_i00] = 3.0f*(XA( 4) - XA( 0));
        akXt[kBP.m_i01] = 3.0f*(XA(12) - XA( 8));
        akXt[kBP.m_i10] = 3.0f*(XA( 7) - XA( 3));
        akXt[kBP.m_i11] = 3.0f*(XA(15) - XA(11));
    }
    else
    {
        akXs = NULL;
        akXt = NULL;
    }

    // colors for subdivision
    ColorRGB* akColor;
    if ( pkMesh->Colors() )
    {
        akColor = pkMesh->Colors() + riVertexStart;
        akColor[kBP.m_i00] = CA( 0);
        akColor[kBP.m_i01] = CA(12);
        akColor[kBP.m_i10] = CA( 3);
        akColor[kBP.m_i11] = CA(15);
    }
    else
    {
        akColor = NULL;
    }

    // textures for subdivision
    Vector2f* akTexture;
    if ( pkMesh->Textures() )
    {
        akTexture = pkMesh->Textures() + riVertexStart;
        akTexture[kBP.m_i00] = TA( 0);
        akTexture[kBP.m_i01] = TA(12);
        akTexture[kBP.m_i10] = TA( 3);
        akTexture[kBP.m_i11] = TA(15);
    }
    else
    {
        akTexture = NULL;
    }

    // recursive subdivision
    if ( iLevel > 0 )
    {
        InitializePoints(akCtrlPoint,kBP);

        if ( akXs )
            InitializeNormals(akCtrlPoint,kBP);

        if ( akCtrlColor )
            InitializeColors(akCtrlColor,kBP);

        if ( akCtrlTexture )
            InitializeTextures(akCtrlTexture,kBP);

        Subdivide(--iLevel,0.25f,akX,akXs,akXt,akColor,akTexture,kBP);
    }

    // calculate unit-length normals from derivative vectors
    if ( pkMesh->Normals() )
    {
        Vector3f* akNormal = pkMesh->Normals() + riVertexStart;
        for (int i = 0; i < iQuantity; i++)
            akNormal[i] = akXs[i].UnitCross(akXt[i]);
        delete[] akXs;
        delete[] akXt;
    }

    riVertexStart += iQuantity;
}
//----------------------------------------------------------------------------
void BezierRectangle3::Subdivide (int iLevel, float fDSqr, Vector3f* akX,
    Vector3f* akXs, Vector3f* akXt, ColorRGB* akColor, Vector2f* akTexture,

⌨️ 快捷键说明

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