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

📄 wmlbezierrectangle2.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 "WmlBezierRectangle2.h"
#include "WmlTriMesh.h"
using namespace Wml;

WmlImplementRTTI(BezierRectangle2,BezierRectangle);
WmlImplementStream(BezierRectangle2);

// 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]]

//----------------------------------------------------------------------------
BezierRectangle2::BezierRectangle2 (int* aiIndex)
    :
    BezierRectangle(2,9,aiIndex)
{
}
//----------------------------------------------------------------------------
BezierRectangle2::BezierRectangle2 ()
{
}
//----------------------------------------------------------------------------
void BezierRectangle2::InitializePoints (const Vector3f* akCtrlPoint,
    Vector3f& rkXsstt, BlockParameters& rkBP)
{
    // Xss
    rkBP.m_akXss[0] = 2.0f*(XA(0) - 2.0f*XA(1) + XA(2));
    rkBP.m_akXss[1] = 2.0f*(XA(6) - 2.0f*XA(7) + XA(8));

    // Xtt
    rkBP.m_akXtt[0] = 2.0f*(XA(0) - 2.0f*XA(3) + XA(6));
    rkBP.m_akXtt[1] = 2.0f*(XA(2) - 2.0f*XA(5) + XA(8));

    // Xsstt
    rkXsstt = 4.0f*(XA(0) + XA(2) + XA(6) + XA(8) -
        2.0f*(XA(1) + XA(3) + XA(5) + XA(7)) + 4.0f*XA(4));
}
//----------------------------------------------------------------------------
void BezierRectangle2::InitializeNormals (const Vector3f* akCtrlPoint,
    BlockParameters& rkBP)
{
    // Xsst
    rkBP.m_akXsst[0] = 4.0f*(XA(3)+XA(5)-XA(0)-XA(2)+2.0f*(XA(1)-XA(4)));
    rkBP.m_akXsst[1] = 4.0f*(XA(6)+XA(8)-XA(3)-XA(5)+2.0f*(XA(4)-XA(7)));

    // Xstt
    rkBP.m_akXstt[0] = 4.0f*(XA(1)+XA(7)-XA(0)-XA(6)+2.0f*(XA(3)-XA(4)));
    rkBP.m_akXstt[1] = 4.0f*(XA(2)+XA(8)-XA(1)-XA(7)+2.0f*(XA(4)-XA(5)));
}
//----------------------------------------------------------------------------
void BezierRectangle2::InitializeColors (const ColorRGB* akCtrlColor,
    ColorRGB& rkCsstt, BlockParameters& rkBP)
{
    // Css
    rkBP.m_akCss[0] = 2.0f*(CA(0) - 2.0f*CA(1) + CA(2));
    rkBP.m_akCss[1] = 2.0f*(CA(6) - 2.0f*CA(7) + CA(8));

    // Ctt
    rkBP.m_akCtt[0] = 2.0f*(CA(0) - 2.0f*CA(3) + CA(6));
    rkBP.m_akCtt[1] = 2.0f*(CA(2) - 2.0f*CA(5) + CA(8));

    // Csstt
    rkCsstt = 4.0f*(CA(0) + CA(2) + CA(6) + CA(8) -
        2.0f*(CA(1) + CA(3) + CA(5) + CA(7)) + 4.0f*CA(4));
}
//----------------------------------------------------------------------------
void BezierRectangle2::InitializeTextures (const Vector2f* akCtrlTexture,
    Vector2f& rkTsstt, BlockParameters& rkBP)
{
    // Tss
    rkBP.m_akTss[0] = 2.0f*(TA(0) - 2.0f*TA(1) + TA(2));
    rkBP.m_akTss[1] = 2.0f*(TA(6) - 2.0f*TA(7) + TA(8));

    // Ttt
    rkBP.m_akTtt[0] = 2.0f*(TA(0) - 2.0f*TA(3) + TA(6));
    rkBP.m_akTtt[1] = 2.0f*(TA(2) - 2.0f*TA(5) + TA(8));

    // Tsstt
    rkTsstt = 4.0f*(TA(0) + TA(2) + TA(6) + TA(8) -
        2.0f*(TA(1) + TA(3) + TA(5) + TA(7)) + 4.0f*TA(4));
}
//----------------------------------------------------------------------------
void BezierRectangle2::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(6);
    akX[kBP.m_i10] = XA(2);
    akX[kBP.m_i11] = XA(8);

    // 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(7) - XA(6));
        akXs[kBP.m_i10] = 3.0f*(XA(2) - XA(1));
        akXs[kBP.m_i11] = 3.0f*(XA(8) - XA(7));

        akXt = new Vector3f[iQuantity];
        akXt[kBP.m_i00] = 3.0f*(XA(3) - XA(0));
        akXt[kBP.m_i01] = 3.0f*(XA(6) - XA(3));
        akXt[kBP.m_i10] = 3.0f*(XA(5) - XA(2));
        akXt[kBP.m_i11] = 3.0f*(XA(8) - XA(5));
    }
    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(6);
        akColor[kBP.m_i10] = CA(2);
        akColor[kBP.m_i11] = CA(8);
    }
    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(6);
        akTexture[kBP.m_i10] = TA(2);
        akTexture[kBP.m_i11] = TA(8);
    }
    else
    {
        akTexture = NULL;
    }

    // recursive subdivision
    if ( iLevel > 0 )
    {
        Vector3f kXsstt;
        ColorRGB kCsstt;
        Vector2f kTsstt;

        InitializePoints(akCtrlPoint,kXsstt,kBP);

        if ( akXs )
            InitializeNormals(akCtrlPoint,kBP);

        if ( akCtrlColor )
            InitializeColors(akCtrlColor,kCsstt,kBP);

        if ( akCtrlTexture )
            InitializeTextures(akCtrlTexture,kTsstt,kBP);

        Subdivide(--iLevel,0.25f,akX,akXs,akXt,akColor,akTexture,kXsstt,
            kCsstt,kTsstt,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 BezierRectangle2::Subdivide (int iLevel, float fDSqr, Vector3f* akX,
    Vector3f* akXs, Vector3f* akXt, ColorRGB* akColor, Vector2f* akTexture,
    Vector3f& rkXsstt, ColorRGB& rkCsstt, Vector2f& rkTsstt,
    BlockParameters& rkBP)
{
    // subdivision indices
    int iM0 = (rkBP.m_i00 + rkBP.m_i10) >> 1;
    int iM1 = (rkBP.m_i01 + rkBP.m_i11) >> 1;
    int i0M = (rkBP.m_i00 + rkBP.m_i01) >> 1;
    int i1M = (rkBP.m_i10 + rkBP.m_i11) >> 1;
    int iMM = (i0M + i1M) >> 1;

    // vertices

    // top and bottom s-edge subdivision
    Vector3f kXttM0 = 0.5f*(rkBP.m_akXtt[0]+rkBP.m_akXtt[1]-fDSqr*rkXsstt);
    akX[iM0] = 0.5f*(akX[rkBP.m_i00] + akX[rkBP.m_i10] -
        fDSqr*rkBP.m_akXss[0]);
    akX[iM1] = 0.5f*(akX[rkBP.m_i01] + akX[rkBP.m_i11] -
        fDSqr*rkBP.m_akXss[1]);

    // left and right t-edge subdivision
    Vector3f kXss0M = 0.5f*(rkBP.m_akXss[0]+rkBP.m_akXss[1]-fDSqr*rkXsstt);
    akX[i0M] = 0.5f*(akX[rkBP.m_i00] + akX[rkBP.m_i01] -
        fDSqr*rkBP.m_akXtt[0]);
    akX[i1M] = 0.5f*(akX[rkBP.m_i10] + akX[rkBP.m_i11] -
        fDSqr*rkBP.m_akXtt[1]);

    // center subdivision
    akX[iMM] = 0.5f*(akX[i0M] + akX[i1M] - fDSqr*kXss0M);

    // derivatives (for normal vectors)
    Vector3f kXsst0M, kXsttM0;
    if ( akXs )
    {
        // top and bottom s-edge subdivision
        akXs[iM0] = 0.5f*(akXs[rkBP.m_i00] + akXs[rkBP.m_i10]);
        akXt[iM0] = 0.5f*(akXt[rkBP.m_i00] + akXt[rkBP.m_i10] -
            fDSqr*rkBP.m_akXsst[0]);
        akXs[iM1] = 0.5f*(akXs[rkBP.m_i01] + akXs[rkBP.m_i11]);
        akXt[iM1] = 0.5f*(akXt[rkBP.m_i01] + akXt[rkBP.m_i11] -
            fDSqr*rkBP.m_akXsst[1]);

        kXsttM0 = 0.5f*(rkBP.m_akXstt[0] + rkBP.m_akXstt[1]);

        // left and right t-edge subdivision
        akXs[i0M] = 0.5f*(akXs[rkBP.m_i00] + akXs[rkBP.m_i01] -
            fDSqr*rkBP.m_akXstt[0]);
        akXt[i0M] = 0.5f*(akXt[rkBP.m_i00] + akXt[rkBP.m_i01]);
        akXs[i1M] = 0.5f*(akXs[rkBP.m_i10] + akXs[rkBP.m_i11] -
            fDSqr*rkBP.m_akXstt[1]);
        akXt[i1M] = 0.5f*(akXt[rkBP.m_i10] + akXt[rkBP.m_i11]);

        kXsst0M = 0.5f*(rkBP.m_akXsst[0] + rkBP.m_akXsst[1]);

        // center subdivision
        akXs[iMM] = 0.5f*(akXs[i0M] + akXs[i1M]);
        akXt[iMM] = 0.5f*(akXt[iM0] + akXt[iM1]);
    }

⌨️ 快捷键说明

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