📄 mgcbeziertriangle3g.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
//
// 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 + -