📄 mgcbeziercylinder3g.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 "MgcBezierCylinder3G.h"
//----------------------------------------------------------------------------
MgcBezierCylinder3G::MgcBezierCylinder3G (MgcVector3* akCtrlPoint)
:
MgcBezierCylinderG(3,akCtrlPoint)
{
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder3G::GetPosition (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
MgcReal afUCoeff[4] =
{
fOmU*fOmU2,
3.0*fOmU2*fU,
3.0*fOmU*fU2,
fU*fU2
};
MgcReal fOmV = 1.0 - fV;
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 4; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 4];
}
MgcVector3 kResult = fOmV*kB0 + fV*kB1;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder3G::GetDerivativeU (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
MgcReal afUCoeff[4] =
{
-3.0*fOmU2,
3.0*fOmU*(fOmU - 2.0*fU),
3.0*fU*(2.0*fOmU - fU),
3.0*fU2
};
MgcReal fOmV = 1.0 - fV;
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 4; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 4];
}
MgcVector3 kResult = fOmV*kB0 + fV*kB1;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder3G::GetDerivativeV (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
MgcReal afUCoeff[4] =
{
fOmU*fOmU2,
3.0*fOmU2*fU,
3.0*fOmU*fU2,
fU*fU2
};
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 4; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 4];
}
MgcVector3 kResult = kB1 - kB0;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder3G::GetDerivativeUU (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU;
MgcReal afUCoeff[4] =
{
6.0*fOmU,
6.0*(fU - 2.0*fOmU),
6.0*(fOmU - 2.0*fU),
6.0*fU
};
MgcReal fOmV = 1.0 - fV;
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 4; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 4];
}
MgcVector3 kResult = fOmV*kB0 + fV*kB1;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder3G::GetDerivativeUV (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU, fU2 = fU*fU, fOmU2 = fOmU*fOmU;
MgcReal afUCoeff[4] =
{
-3.0*fOmU2,
3.0*fOmU*(fOmU - 2.0*fU),
3.0*fU*(2.0*fOmU - fU),
3.0*fU2
};
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 4; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 4];
}
MgcVector3 kResult = kB1 - kB0;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder3G::GetDerivativeVV (MgcReal fU, MgcReal fV) const
{
return MgcVector3::ZERO;
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3G::Tessellate (unsigned int uiLevel, bool bWantNormals)
{
// allocate arrays and compute connectivity
Initialize(uiLevel,bWantNormals);
// indices of four corners of patch, I[u][v]
unsigned int uiTwoPowL = (1 << uiLevel);
unsigned int uiTwoPowC = (1 << m_uiCylinderLevel);
IntervalParameters kIP;
kIP.m_uiI00 = 0;
kIP.m_uiI01 = uiTwoPowC*(uiTwoPowL + 1);
kIP.m_uiI10 = uiTwoPowL;
kIP.m_uiI11 = kIP.m_uiI01 + uiTwoPowL;
// vertices for subdivision
MgcVector3* akX = m_akVertex;
akX[kIP.m_uiI00] = m_akCtrlPoint[0];
akX[kIP.m_uiI01] = m_akCtrlPoint[4];
akX[kIP.m_uiI10] = m_akCtrlPoint[3];
akX[kIP.m_uiI11] = m_akCtrlPoint[7];
// derivatives for subdivision (for normal vectors)
MgcVector3* akXu;
MgcVector3* akXv;
if ( bWantNormals )
{
akXu = new MgcVector3[m_uiVertexQuantity];
akXu[kIP.m_uiI00] = 3.0*(m_akCtrlPoint[1] - m_akCtrlPoint[0]);
akXu[kIP.m_uiI01] = 3.0*(m_akCtrlPoint[5] - m_akCtrlPoint[4]);
akXu[kIP.m_uiI10] = 3.0*(m_akCtrlPoint[3] - m_akCtrlPoint[2]);
akXu[kIP.m_uiI11] = 3.0*(m_akCtrlPoint[7] - m_akCtrlPoint[6]);
akXv = new MgcVector3[m_uiVertexQuantity];
akXv[kIP.m_uiI00] = 3.0*(m_akCtrlPoint[4] - m_akCtrlPoint[0]);
akXv[kIP.m_uiI01] = akXv[kIP.m_uiI00];
akXv[kIP.m_uiI10] = 3.0*(m_akCtrlPoint[7] - m_akCtrlPoint[3]);
akXv[kIP.m_uiI11] = akXv[kIP.m_uiI10];
}
else
{
akXu = 0;
akXv = 0;
}
// recursive subdivision
MgcVector3 akXuuu[2];
if ( uiLevel > 0 || m_uiCylinderLevel > 0 )
{
kIP.m_aakXuu[0][0] = 6.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[1] +
m_akCtrlPoint[2]);
kIP.m_aakXuu[0][1] = 6.0*(m_akCtrlPoint[4] - 2.0*m_akCtrlPoint[5] +
m_akCtrlPoint[6]);
kIP.m_aakXuu[1][0] = 6.0*(m_akCtrlPoint[1] - 2.0*m_akCtrlPoint[2] +
m_akCtrlPoint[3]);
kIP.m_aakXuu[1][1] = 6.0*(m_akCtrlPoint[5] - 2.0*m_akCtrlPoint[6] +
m_akCtrlPoint[7]);
if ( akXu )
{
akXuuu[0] = 6.0*(m_akCtrlPoint[3] + 3.0*(m_akCtrlPoint[1] -
m_akCtrlPoint[2]) - m_akCtrlPoint[0]);
akXuuu[1] = 6.0*(m_akCtrlPoint[7] + 3.0*(m_akCtrlPoint[5] -
m_akCtrlPoint[6]) - m_akCtrlPoint[4]);
}
}
if ( uiLevel > 0 )
{
SubdivideBoundary(--uiLevel,0.25,akX,akXu,akXv,akXuuu,kIP);
}
if ( m_uiCylinderLevel > 0 )
{
SubdivideCylinder(m_uiCylinderLevel-1,akX,akXu,akXv,0,kIP.m_uiI01,
uiTwoPowL);
}
// 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 MgcBezierCylinder3G::SubdivideBoundary (unsigned int uiLevel,
MgcReal fDSqr, MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv,
MgcVector3 akXuuu[2], IntervalParameters& rkIP)
{
// subdivision indices
unsigned int uiIM0 = (rkIP.m_uiI00 + rkIP.m_uiI10) >> 1;
unsigned int uiIM1 = (rkIP.m_uiI01 + rkIP.m_uiI11) >> 1;
// vertices
MgcVector3 kXssM0 = 0.5*(rkIP.m_aakXuu[0][0] + rkIP.m_aakXuu[1][0]);
MgcVector3 kXssM1 = 0.5*(rkIP.m_aakXuu[0][1] + rkIP.m_aakXuu[1][1]);
akX[uiIM0] = 0.5*(akX[rkIP.m_uiI00] + akX[rkIP.m_uiI10] - fDSqr*kXssM0);
akX[uiIM1] = 0.5*(akX[rkIP.m_uiI01] + akX[rkIP.m_uiI11] - fDSqr*kXssM1);
// derivatives (for normal vectors)
if ( akXu )
{
akXu[uiIM0] = 0.5*(akXu[rkIP.m_uiI00] + akXu[rkIP.m_uiI10] -
fDSqr*akXuuu[0]);
akXu[uiIM1] = 0.5*(akXu[rkIP.m_uiI01] + akXu[rkIP.m_uiI11] -
fDSqr*akXuuu[1]);
akXv[uiIM0] = akX[uiIM1] - akX[uiIM0];
akXv[uiIM1] = akXv[uiIM0];
}
// recurse on two children
if ( uiLevel > 0 )
{
uiLevel--;
fDSqr *= 0.25;
IntervalParameters kSubIP;
// subinterval [u0,uM]
kSubIP.m_uiI00 = rkIP.m_uiI00;
kSubIP.m_uiI01 = rkIP.m_uiI01;
kSubIP.m_uiI10 = uiIM0;
kSubIP.m_uiI11 = uiIM1;
kSubIP.m_aakXuu[0][0] = rkIP.m_aakXuu[0][0];
kSubIP.m_aakXuu[0][1] = rkIP.m_aakXuu[0][1];
kSubIP.m_aakXuu[1][0] = kXssM0;
kSubIP.m_aakXuu[1][1] = kXssM1;
SubdivideBoundary(uiLevel,fDSqr,akX,akXu,akXv,akXuuu,kSubIP);
// subinterval [uM,u1]
kSubIP.m_uiI00 = uiIM0;
kSubIP.m_uiI01 = uiIM1;
kSubIP.m_uiI10 = rkIP.m_uiI10;
kSubIP.m_uiI11 = rkIP.m_uiI11;
kSubIP.m_aakXuu[0][0] = kXssM0;
kSubIP.m_aakXuu[0][1] = kXssM1;
kSubIP.m_aakXuu[1][0] = rkIP.m_aakXuu[1][0];
kSubIP.m_aakXuu[1][1] = rkIP.m_aakXuu[1][1];
SubdivideBoundary(uiLevel,fDSqr,akX,akXu,akXv,akXuuu,kSubIP);
}
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3G::SubdivideCylinder (unsigned int uiCLevel,
MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv, unsigned int uiI0,
unsigned int uiI1, unsigned int uiTwoPowL)
{
// subdivision index
unsigned int uiIM = (uiI0 + uiI1) >> 1;
unsigned int uiJ0 = uiI0, uiJM = uiIM, uiJ1 = uiI1;
unsigned int uiJLast = uiJM + uiTwoPowL;
for (/**/; uiJM <= uiJLast; uiJ0++, uiJM++, uiJ1++)
{
// vertices
akX[uiJM] = 0.5*(akX[uiJ0] + akX[uiJ1]);
// derivatives (for normal vectors)
if ( akXu )
{
akXu[uiJM] = 0.5*(akXu[uiJ0] + akXu[uiJ1]);
akXv[uiJM] = akXv[uiJ0];
}
}
// recurse on two children
if ( uiCLevel > 0 )
{
uiCLevel--;
// subinterval [v0,vM]
SubdivideCylinder(uiCLevel,akX,akXu,akXv,uiI0,uiIM,uiTwoPowL);
// subinterval [vM,v1]
SubdivideCylinder(uiCLevel,akX,akXu,akXv,uiIM,uiI1,uiTwoPowL);
}
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -