📄 mgcbezierrectangle3.cpp
字号:
// 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
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf
#include "MgcBezierRectangle3.h"
#include "MgcTriMesh.h"
MgcImplementRTTI(MgcBezierRectangle3,MgcBezierRectangle);
MgcImplementStream(MgcBezierRectangle3);
// macros for initialization in the subdivision
#define XA(i) akCtrlPoint[m_auiIndex[i]]
#define CA(i) akCtrlColor[m_auiIndex[i]]
#define TA(i) akCtrlTexture[m_auiIndex[i]]
//----------------------------------------------------------------------------
MgcBezierRectangle3::MgcBezierRectangle3 (unsigned int* auiIndex)
:
MgcBezierRectangle(3,16,auiIndex)
{
}
//----------------------------------------------------------------------------
MgcBezierRectangle3::MgcBezierRectangle3 ()
{
}
//----------------------------------------------------------------------------
void MgcBezierRectangle3::InitializePoints (const MgcVector3* akCtrlPoint,
BlockParameters& rkBP)
{
// Xss[s][t]
rkBP.m_aakXss[0][0] = 6.0*(XA( 0) - 2.0*XA( 1) + XA( 2));
rkBP.m_aakXss[0][1] = 6.0*(XA(12) - 2.0*XA(13) + XA(14));
rkBP.m_aakXss[1][0] = 6.0*(XA( 1) - 2.0*XA( 2) + XA( 3));
rkBP.m_aakXss[1][1] = 6.0*(XA(13) - 2.0*XA(14) + XA(15));
// Xtt[s][t]
rkBP.m_aakXtt[0][0] = 6.0*(XA( 0) - 2.0*XA( 4) + XA( 8));
rkBP.m_aakXtt[0][1] = 6.0*(XA( 4) - 2.0*XA( 8) + XA(12));
rkBP.m_aakXtt[1][0] = 6.0*(XA( 3) - 2.0*XA( 7) + XA(11));
rkBP.m_aakXtt[1][1] = 6.0*(XA( 7) - 2.0*XA(11) + XA(15));
// Xsstt[s][t]
rkBP.m_aakXsstt[0][0] = 36.0*(XA(0) + XA(2) + XA(8) + XA(10) -
2.0*(XA(1) + XA(4) + XA(6) + XA(9)) + 4.0*XA(5));
rkBP.m_aakXsstt[0][1] = 36.0*(XA(4) + XA(6) + XA(12) + XA(14) -
2.0*(XA(5) + XA(8) + XA(10) + XA(13)) + 4.0*XA(9));
rkBP.m_aakXsstt[1][0] = 36.0*(XA(1) + XA(3) + XA(9) + XA(11) -
2.0*(XA(2) + XA(5) + XA(7) + XA(10)) + 4.0*XA(6));
rkBP.m_aakXsstt[1][1] = 36.0*(XA(5) + XA(7) + XA(13) + XA(15) -
2.0*(XA(6) + XA(9) + XA(11) + XA(14)) + 4.0*XA(10));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle3::InitializeNormals (const MgcVector3* akCtrlPoint,
BlockParameters& rkBP)
{
// Xsst[s][t]
rkBP.m_aakXsst[0][0] = 18.0*(XA(4) + XA(6) - XA(0) - XA(2) +
2.0*(XA(1) - XA(5)));
rkBP.m_aakXsst[0][1] = 18.0*(XA(5) + XA(7) - XA(1) - XA(3) +
2.0*(XA(2) - XA(6)));
rkBP.m_aakXsst[1][0] = 18.0*(XA(12) + XA(14) - XA(8) - XA(10) +
2.0*(XA(9) - XA(13)));
rkBP.m_aakXsst[1][1] = 18.0*(XA(13) + XA(15) - XA(9) - XA(11) +
2.0*(XA(10) - XA(14)));
// Xstt[s][t]
rkBP.m_aakXstt[0][0] = 18.0*(XA(1) + XA(9) - XA(0) - XA(8) +
2.0*(XA(4) - XA(5)));
rkBP.m_aakXstt[0][1] = 18.0*(XA(5) + XA(13) - XA(4) - XA(12) +
2.0*(XA(8) - XA(9)));
rkBP.m_aakXstt[1][0] = 18.0*(XA(3) + XA(11) - XA(2) - XA(10) +
2.0*(XA(6) - XA(7)));
rkBP.m_aakXstt[1][1] = 18.0*(XA(7) + XA(15) - XA(6) - XA(14) +
2.0*(XA(10) - XA(11)));
// Xsss
rkBP.m_akXsss[0] = 6.0*(XA(3) + 3.0*(XA(1) - XA(2)) - XA(0));
rkBP.m_akXsss[1] = 6.0*(XA(15) + 3.0*(XA(13) - XA(14)) - XA(12));
// Xttt
rkBP.m_akXttt[0] = 6.0*(XA(12) + 3.0*(XA(4) - XA(8)) - XA(0));
rkBP.m_akXttt[1] = 6.0*(XA(15) + 3.0*(XA(7) - XA(11)) - XA(3));
// Xssstt
rkBP.m_akXssstt[0] = 36.0*(XA(3) + XA(11) - XA(0) - XA(8) +
2.0*(XA(4) - XA(7)) + 3.0*(XA(1) + XA(9) - XA(2) - XA(10)) +
6.0*(XA(6) - XA(5)));
rkBP.m_akXssstt[1] = 36.0*(XA(7) + XA(15) - XA(4) - XA(12) +
2.0*(XA(8) - XA(11)) + 3.0*(XA(5) + XA(13) - XA(6) - XA(14)) +
6.0*(XA(10) - XA(9)));
// Xtttss
rkBP.m_akXssttt[0] = 36.0*(XA(12) + XA(14) - XA(0) - XA(2) +
2.0*(XA(1) - XA(13)) + 3.0*(XA(4) + XA(6) - XA(8) - XA(10)) +
6.0*(XA(9) - XA(5)));
rkBP.m_akXssttt[1] = 36.0*(XA(13) + XA(15) - XA(1) - XA(3) +
2.0*(XA(2) - XA(14)) + 3.0*(XA(5) + XA(7) - XA(9) - XA(11)) +
6.0*(XA(10) - XA(6)));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle3::InitializeColors (const MgcColor* akCtrlColor,
BlockParameters& rkBP)
{
// Css[s][t]
rkBP.m_aakCss[0][0] = 6.0*(CA( 0) - 2.0*CA( 1) + CA( 2));
rkBP.m_aakCss[0][1] = 6.0*(CA(12) - 2.0*CA(13) + CA(14));
rkBP.m_aakCss[1][0] = 6.0*(CA( 1) - 2.0*CA( 2) + CA( 3));
rkBP.m_aakCss[1][1] = 6.0*(CA(13) - 2.0*CA(14) + CA(15));
// Ctt[s][t]
rkBP.m_aakCtt[0][0] = 6.0*(CA( 0) - 2.0*CA( 4) + CA( 8));
rkBP.m_aakCtt[0][1] = 6.0*(CA( 4) - 2.0*CA( 8) + CA(12));
rkBP.m_aakCtt[1][0] = 6.0*(CA( 3) - 2.0*CA( 7) + CA(11));
rkBP.m_aakCtt[1][1] = 6.0*(CA( 7) - 2.0*CA(11) + CA(15));
// Csstt[s][t]
rkBP.m_aakCsstt[0][0] = 36.0*(CA(0) + CA(2) + CA(8) + CA(10) -
2.0*(CA(1) + CA(4) + CA(6) + CA(9)) + 4.0*CA(5));
rkBP.m_aakCsstt[0][1] = 36.0*(CA(4) + CA(6) + CA(12) + CA(14) -
2.0*(CA(5) + CA(8) + CA(10) + CA(13)) + 4.0*CA(9));
rkBP.m_aakCsstt[1][0] = 36.0*(CA(1) + CA(3) + CA(9) + CA(11) -
2.0*(CA(2) + CA(5) + CA(7) + CA(10)) + 4.0*CA(6));
rkBP.m_aakCsstt[1][1] = 36.0*(CA(5) + CA(7) + CA(13) + CA(15) -
2.0*(CA(6) + CA(9) + CA(11) + CA(14)) + 4.0*CA(10));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle3::InitializeTextures (const MgcVector2* akCtrlTexture,
BlockParameters& rkBP)
{
// Tss[s][t]
rkBP.m_aakTss[0][0] = 6.0*(TA( 0) - 2.0*TA( 1) + TA( 2));
rkBP.m_aakTss[0][1] = 6.0*(TA(12) - 2.0*TA(13) + TA(14));
rkBP.m_aakTss[1][0] = 6.0*(TA( 1) - 2.0*TA( 2) + TA( 3));
rkBP.m_aakTss[1][1] = 6.0*(TA(13) - 2.0*TA(14) + TA(15));
// Ttt[s][t]
rkBP.m_aakTtt[0][0] = 6.0*(TA( 0) - 2.0*TA( 4) + TA( 8));
rkBP.m_aakTtt[0][1] = 6.0*(TA( 4) - 2.0*TA( 8) + TA(12));
rkBP.m_aakTtt[1][0] = 6.0*(TA( 3) - 2.0*TA( 7) + TA(11));
rkBP.m_aakTtt[1][1] = 6.0*(TA( 7) - 2.0*TA(11) + TA(15));
// Tsstt[s][t]
rkBP.m_aakTsstt[0][0] = 36.0*(TA(0) + TA(2) + TA(8) + TA(10) -
2.0*(TA(1) + TA(4) + TA(6) + TA(9)) + 4.0*TA(5));
rkBP.m_aakTsstt[0][1] = 36.0*(TA(4) + TA(6) + TA(12) + TA(14) -
2.0*(TA(5) + TA(8) + TA(10) + TA(13)) + 4.0*TA(9));
rkBP.m_aakTsstt[1][0] = 36.0*(TA(1) + TA(3) + TA(9) + TA(11) -
2.0*(TA(2) + TA(5) + TA(7) + TA(10)) + 4.0*TA(6));
rkBP.m_aakTsstt[1][1] = 36.0*(TA(5) + TA(7) + TA(13) + TA(15) -
2.0*(TA(6) + TA(9) + TA(11) + TA(14)) + 4.0*TA(10));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle3::Tessellate (unsigned int uiLevel,
const MgcVector3* akCtrlPoint, const MgcColor* akCtrlColor,
const MgcVector2* akCtrlTexture, MgcTriMesh* pkMesh,
unsigned int& ruiVertexStart, unsigned int& ruiTriangleStart)
{
GenerateConnectivity(uiLevel,pkMesh,ruiTriangleStart);
// number of vertices in the subdivision
unsigned int uiQuantity = GetVerticesPerRectanglePatch(uiLevel);
// indices of four corners of patch, I[s][t]
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 = pkMesh->Vertices() + ruiVertexStart;
akX[kBP.m_uiI00] = XA( 0);
akX[kBP.m_uiI01] = XA(12);
akX[kBP.m_uiI10] = XA( 3);
akX[kBP.m_uiI11] = XA(15);
// derivatives for subdivision (for normal vectors)
MgcVector3* akXs;
MgcVector3* akXt;
if ( pkMesh->Normals() )
{
akXs = new MgcVector3[uiQuantity];
akXs[kBP.m_uiI00] = 3.0*(XA( 1) - XA( 0));
akXs[kBP.m_uiI01] = 3.0*(XA(13) - XA(12));
akXs[kBP.m_uiI10] = 3.0*(XA( 3) - XA( 2));
akXs[kBP.m_uiI11] = 3.0*(XA(15) - XA(14));
akXt = new MgcVector3[uiQuantity];
akXt[kBP.m_uiI00] = 3.0*(XA( 4) - XA( 0));
akXt[kBP.m_uiI01] = 3.0*(XA(12) - XA( 8));
akXt[kBP.m_uiI10] = 3.0*(XA( 7) - XA( 3));
akXt[kBP.m_uiI11] = 3.0*(XA(15) - XA(11));
}
else
{
akXs = 0;
akXt = 0;
}
// colors for subdivision
MgcColor* akColor;
if ( pkMesh->Colors() )
{
akColor = pkMesh->Colors() + ruiVertexStart;
akColor[kBP.m_uiI00] = CA( 0);
akColor[kBP.m_uiI01] = CA(12);
akColor[kBP.m_uiI10] = CA( 3);
akColor[kBP.m_uiI11] = CA(15);
}
else
{
akColor = 0;
}
// textures for subdivision
MgcVector2* akTexture;
if ( pkMesh->Textures() )
{
akTexture = pkMesh->Textures() + ruiVertexStart;
akTexture[kBP.m_uiI00] = TA( 0);
akTexture[kBP.m_uiI01] = TA(12);
akTexture[kBP.m_uiI10] = TA( 3);
akTexture[kBP.m_uiI11] = TA(15);
}
else
{
akTexture = 0;
}
// recursive subdivision
if ( uiLevel > 0 )
{
InitializePoints(akCtrlPoint,kBP);
if ( akXs )
InitializeNormals(akCtrlPoint,kBP);
if ( akCtrlColor )
InitializeColors(akCtrlColor,kBP);
if ( akCtrlTexture )
InitializeTextures(akCtrlTexture,kBP);
Subdivide(--uiLevel,0.25,akX,akXs,akXt,akColor,akTexture,kBP);
}
// calculate unit-length normals from derivative vectors
if ( pkMesh->Normals() )
{
MgcVector3* akNormal = pkMesh->Normals() + ruiVertexStart;
for (unsigned int uiI = 0; uiI < uiQuantity; uiI++)
akNormal[uiI] = akXs[uiI].UnitCross(akXt[uiI]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -