📄 mgcbezierrectangle2.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 "MgcBezierRectangle2.h"
#include "MgcTriMesh.h"
MgcImplementRTTI(MgcBezierRectangle2,MgcBezierRectangle);
MgcImplementStream(MgcBezierRectangle2);
// 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]]
//----------------------------------------------------------------------------
MgcBezierRectangle2::MgcBezierRectangle2 (unsigned int* auiIndex)
:
MgcBezierRectangle(2,9,auiIndex)
{
}
//----------------------------------------------------------------------------
MgcBezierRectangle2::MgcBezierRectangle2 ()
{
}
//----------------------------------------------------------------------------
void MgcBezierRectangle2::InitializePoints (const MgcVector3* akCtrlPoint,
MgcVector3& rkXsstt, BlockParameters& rkBP)
{
// Xss
rkBP.m_akXss[0] = 2.0*(XA(0) - 2.0*XA(1) + XA(2));
rkBP.m_akXss[1] = 2.0*(XA(6) - 2.0*XA(7) + XA(8));
// Xtt
rkBP.m_akXtt[0] = 2.0*(XA(0) - 2.0*XA(3) + XA(6));
rkBP.m_akXtt[1] = 2.0*(XA(2) - 2.0*XA(5) + XA(8));
// Xsstt
rkXsstt = 4.0*(XA(0) + XA(2) + XA(6) + XA(8) - 2.0*(XA(1) + XA(3) + XA(5)
+ XA(7)) + 4.0*XA(4));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle2::InitializeNormals (const MgcVector3* akCtrlPoint,
BlockParameters& rkBP)
{
// Xsst
rkBP.m_akXsst[0] = 4.0*(XA(3)+XA(5)-XA(0)-XA(2)+2.0*(XA(1)-XA(4)));
rkBP.m_akXsst[1] = 4.0*(XA(6)+XA(8)-XA(3)-XA(5)+2.0*(XA(4)-XA(7)));
// Xstt
rkBP.m_akXstt[0] = 4.0*(XA(1)+XA(7)-XA(0)-XA(6)+2.0*(XA(3)-XA(4)));
rkBP.m_akXstt[1] = 4.0*(XA(2)+XA(8)-XA(1)-XA(7)+2.0*(XA(4)-XA(5)));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle2::InitializeColors (const MgcColor* akCtrlColor,
MgcColor& rkCsstt, BlockParameters& rkBP)
{
// Css
rkBP.m_akCss[0] = 2.0*(CA(0) - 2.0*CA(1) + CA(2));
rkBP.m_akCss[1] = 2.0*(CA(6) - 2.0*CA(7) + CA(8));
// Ctt
rkBP.m_akCtt[0] = 2.0*(CA(0) - 2.0*CA(3) + CA(6));
rkBP.m_akCtt[1] = 2.0*(CA(2) - 2.0*CA(5) + CA(8));
// Csstt
rkCsstt = 4.0*(CA(0) + CA(2) + CA(6) + CA(8) - 2.0*(CA(1) + CA(3) + CA(5)
+ CA(7)) + 4.0*CA(4));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle2::InitializeTextures (const MgcVector2* akCtrlTexture,
MgcVector2& rkTsstt, BlockParameters& rkBP)
{
// Tss
rkBP.m_akTss[0] = 2.0*(TA(0) - 2.0*TA(1) + TA(2));
rkBP.m_akTss[1] = 2.0*(TA(6) - 2.0*TA(7) + TA(8));
// Ttt
rkBP.m_akTtt[0] = 2.0*(TA(0) - 2.0*TA(3) + TA(6));
rkBP.m_akTtt[1] = 2.0*(TA(2) - 2.0*TA(5) + TA(8));
// Tsstt
rkTsstt = 4.0*(TA(0) + TA(2) + TA(6) + TA(8) - 2.0*(TA(1) + TA(3) + TA(5)
+ TA(7)) + 4.0*TA(4));
}
//----------------------------------------------------------------------------
void MgcBezierRectangle2::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(6);
akX[kBP.m_uiI10] = XA(2);
akX[kBP.m_uiI11] = XA(8);
// derivatives for subdivision (for normal vectors)
MgcVector3* akXs;
MgcVector3* akXt;
if ( pkMesh->Normals() )
{
akXs = new MgcVector3[uiQuantity];
akXs[kBP.m_uiI00] = 2.0*(XA(1) - XA(0));
akXs[kBP.m_uiI01] = 3.0*(XA(7) - XA(6));
akXs[kBP.m_uiI10] = 3.0*(XA(2) - XA(1));
akXs[kBP.m_uiI11] = 3.0*(XA(8) - XA(7));
akXt = new MgcVector3[uiQuantity];
akXt[kBP.m_uiI00] = 3.0*(XA(3) - XA(0));
akXt[kBP.m_uiI01] = 3.0*(XA(6) - XA(3));
akXt[kBP.m_uiI10] = 3.0*(XA(5) - XA(2));
akXt[kBP.m_uiI11] = 3.0*(XA(8) - XA(5));
}
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(6);
akColor[kBP.m_uiI10] = CA(2);
akColor[kBP.m_uiI11] = CA(8);
}
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(6);
akTexture[kBP.m_uiI10] = TA(2);
akTexture[kBP.m_uiI11] = TA(8);
}
else
{
akTexture = 0;
}
// recursive subdivision
if ( uiLevel > 0 )
{
MgcVector3 kXsstt;
MgcColor kCsstt;
MgcVector2 kTsstt;
InitializePoints(akCtrlPoint,kXsstt,kBP);
if ( akXs )
InitializeNormals(akCtrlPoint,kBP);
if ( akCtrlColor )
InitializeColors(akCtrlColor,kCsstt,kBP);
if ( akCtrlTexture )
InitializeTextures(akCtrlTexture,kTsstt,kBP);
Subdivide(--uiLevel,0.25,akX,akXs,akXt,akColor,akTexture,kXsstt,
kCsstt,kTsstt,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]);
delete[] akXs;
delete[] akXt;
}
ruiVertexStart += uiQuantity;
}
//----------------------------------------------------------------------------
void MgcBezierRectangle2::Subdivide (unsigned int uiLevel, MgcReal fDSqr,
MgcVector3* akX, MgcVector3* akXs, MgcVector3* akXt, MgcColor* akColor,
MgcVector2* akTexture, MgcVector3& rkXsstt, MgcColor& rkCsstt,
MgcVector2& rkTsstt, BlockParameters& rkBP)
{
// subdivision indices
unsigned int uiIM0 = (rkBP.m_uiI00 + rkBP.m_uiI10) >> 1;
unsigned int uiIM1 = (rkBP.m_uiI01 + rkBP.m_uiI11) >> 1;
unsigned int uiI0M = (rkBP.m_uiI00 + rkBP.m_uiI01) >> 1;
unsigned int uiI1M = (rkBP.m_uiI10 + rkBP.m_uiI11) >> 1;
unsigned int uiIMM = (uiI0M + uiI1M) >> 1;
// vertices
// top and bottom s-edge subdivision
MgcVector3 kXttM0 = 0.5*(rkBP.m_akXtt[0]+rkBP.m_akXtt[1]-fDSqr*rkXsstt);
akX[uiIM0] = 0.5*(akX[rkBP.m_uiI00] + akX[rkBP.m_uiI10] -
fDSqr*rkBP.m_akXss[0]);
akX[uiIM1] = 0.5*(akX[rkBP.m_uiI01] + akX[rkBP.m_uiI11] -
fDSqr*rkBP.m_akXss[1]);
// left and right t-edge subdivision
MgcVector3 kXss0M = 0.5*(rkBP.m_akXss[0]+rkBP.m_akXss[1]-fDSqr*rkXsstt);
akX[uiI0M] = 0.5*(akX[rkBP.m_uiI00] + akX[rkBP.m_uiI01] -
fDSqr*rkBP.m_akXtt[0]);
akX[uiI1M] = 0.5*(akX[rkBP.m_uiI10] + akX[rkBP.m_uiI11] -
fDSqr*rkBP.m_akXtt[1]);
// center subdivision
akX[uiIMM] = 0.5*(akX[uiI0M] + akX[uiI1M] - fDSqr*kXss0M);
// derivatives (for normal vectors)
MgcVector3 kXsst0M, kXsttM0;
if ( akXs )
{
// top and bottom s-edge subdivision
akXs[uiIM0] = 0.5*(akXs[rkBP.m_uiI00] + akXs[rkBP.m_uiI10]);
akXt[uiIM0] = 0.5*(akXt[rkBP.m_uiI00] + akXt[rkBP.m_uiI10] -
fDSqr*rkBP.m_akXsst[0]);
akXs[uiIM1] = 0.5*(akXs[rkBP.m_uiI01] + akXs[rkBP.m_uiI11]);
akXt[uiIM1] = 0.5*(akXt[rkBP.m_uiI01] + akXt[rkBP.m_uiI11] -
fDSqr*rkBP.m_akXsst[1]);
kXsttM0 = 0.5*(rkBP.m_akXstt[0] + rkBP.m_akXstt[1]);
// left and right t-edge subdivision
akXs[uiI0M] = 0.5*(akXs[rkBP.m_uiI00] + akXs[rkBP.m_uiI01] -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -