📄 mgcbeziertriangle3.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 "MgcBezierTriangle3.h"
#include "MgcTriMesh.h"
MgcImplementRTTI(MgcBezierTriangle3,MgcBezierTriangle);
MgcImplementStream(MgcBezierTriangle3);
// 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]]
//----------------------------------------------------------------------------
MgcBezierTriangle3::MgcBezierTriangle3 (unsigned int* auiIndex)
:
MgcBezierTriangle(3,10,auiIndex)
{
}
//----------------------------------------------------------------------------
MgcBezierTriangle3::MgcBezierTriangle3 ()
{
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3::InitializePoints (const MgcVector3* akCtrlPoint,
BlockParameters& rkBP)
{
// Xuu
rkBP.m_aakXuu[0] = 6.0*(XA(0) - 2.0*XA(1) + XA(2));
rkBP.m_aakXuu[1] = 6.0*(XA(1) - 2.0*XA(2) + XA(3));
rkBP.m_aakXuu[2] = 6.0*(XA(4) - 2.0*XA(5) + XA(6));
// Xvv
rkBP.m_aakXvv[0] = 6.0*(XA(0) - 2.0*XA(4) + XA(7));
rkBP.m_aakXvv[1] = 6.0*(XA(1) - 2.0*XA(5) + XA(8));
rkBP.m_aakXvv[2] = 6.0*(XA(4) - 2.0*XA(7) + XA(9));
// Xhh = Xuu - 2*Xuv + Xvv (d/dh = d/ds - d/dt)
rkBP.m_aakXhh[0] = 6.0*(XA(2) - 2.0*XA(5) + XA(7));
rkBP.m_aakXhh[1] = 6.0*(XA(3) - 2.0*XA(6) + XA(8));
rkBP.m_aakXhh[2] = 6.0*(XA(6) - 2.0*XA(8) + XA(9));
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3::InitializeNormals (const MgcVector3* akCtrlPoint,
BlockParameters& rkBP)
{
// Xuuu
rkBP.m_kXuuu = 6.0*(XA(3) - XA(0) + 2.0*(XA(1) - XA(2)));
// Xuuv
rkBP.m_kXuuv = 6.0*(XA(4) + XA(6) - XA(0) - XA(2) + 2.0*(XA(1) - XA(5)));
// Xuvv
rkBP.m_kXuvv = 6.0*(XA(1) + XA(8) - XA(0) - XA(7) + 2.0*(XA(4) - XA(5)));
// Xvvv
rkBP.m_kXvvv = 6.0*(XA(9) - XA(0) + 2.0*(XA(4) - XA(7)));
// Xhhu
rkBP.m_kXhhu = 6.0*(XA(3) + XA(8) - XA(2) - XA(7) + 2.0*(XA(5) - XA(6)));
// Xhhv
rkBP.m_kXhhv = 6.0*(XA(6) + XA(9) - XA(2) - XA(7) + 2.0*(XA(5) - XA(8)));
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3::InitializeColors (const MgcColor* akCtrlColor,
BlockParameters& rkBP)
{
// Cuu
rkBP.m_aakCuu[0] = 6.0*(CA(0) - 2.0*CA(1) + CA(2));
rkBP.m_aakCuu[1] = 6.0*(CA(1) - 2.0*CA(2) + CA(3));
rkBP.m_aakCuu[2] = 6.0*(CA(4) - 2.0*CA(5) + CA(6));
// Cvv
rkBP.m_aakCvv[0] = 6.0*(CA(0) - 2.0*CA(4) + CA(7));
rkBP.m_aakCvv[1] = 6.0*(CA(1) - 2.0*CA(5) + CA(8));
rkBP.m_aakCvv[2] = 6.0*(CA(4) - 2.0*CA(7) + CA(9));
// Chh = Cuu - 2*Cuv + Cvv (d/dh = d/ds - d/dt)
rkBP.m_aakChh[0] = 6.0*(CA(2) - 2.0*CA(5) + CA(7));
rkBP.m_aakChh[1] = 6.0*(CA(3) - 2.0*CA(6) + CA(8));
rkBP.m_aakChh[2] = 6.0*(CA(6) - 2.0*CA(8) + CA(9));
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3::InitializeTextures (const MgcVector2* akCtrlTexture,
BlockParameters& rkBP)
{
// Tuu
rkBP.m_aakTuu[0] = 6.0*(TA(0) - 2.0*TA(1) + TA(2));
rkBP.m_aakTuu[1] = 6.0*(TA(1) - 2.0*TA(2) + TA(3));
rkBP.m_aakTuu[2] = 6.0*(TA(4) - 2.0*TA(5) + TA(6));
// Tvv
rkBP.m_aakTvv[0] = 6.0*(TA(0) - 2.0*TA(4) + TA(7));
rkBP.m_aakTvv[1] = 6.0*(TA(1) - 2.0*TA(5) + TA(8));
rkBP.m_aakTvv[2] = 6.0*(TA(4) - 2.0*TA(7) + TA(9));
// Thh = Tuu - 2*Tuv + Tvv (d/dh = d/ds - d/dt)
rkBP.m_aakThh[0] = 6.0*(TA(2) - 2.0*TA(5) + TA(7));
rkBP.m_aakThh[1] = 6.0*(TA(3) - 2.0*TA(6) + TA(8));
rkBP.m_aakThh[2] = 6.0*(TA(6) - 2.0*TA(8) + TA(9));
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3::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 = GetVerticesPerTrianglePatch(uiLevel);
// 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 = pkMesh->Vertices() + ruiVertexStart;
akX[kBP.m_uiI0] = XA(0);
akX[kBP.m_uiI1] = XA(3);
akX[kBP.m_uiI2] = XA(9);
// derivatives for subdivision (for normal vectors)
MgcVector3* akXu;
MgcVector3* akXv;
if ( pkMesh->Normals() )
{
akXu = new MgcVector3[uiQuantity];
akXu[kBP.m_uiI0] = 3.0*(XA(1) - XA(0));
akXu[kBP.m_uiI1] = 3.0*(XA(3) - XA(2));
akXu[kBP.m_uiI2] = 3.0*(XA(8) - XA(7));
akXv = new MgcVector3[uiQuantity];
akXv[kBP.m_uiI0] = 3.0*(XA(4) - XA(0));
akXv[kBP.m_uiI1] = 3.0*(XA(6) - XA(2));
akXv[kBP.m_uiI2] = 3.0*(XA(9) - XA(7));
}
else
{
akXu = 0;
akXv = 0;
}
// colors for subdivision
MgcColor* akColor;
if ( pkMesh->Colors() )
{
akColor = pkMesh->Colors() + ruiVertexStart;
akColor[kBP.m_uiI0] = CA(0);
akColor[kBP.m_uiI1] = CA(3);
akColor[kBP.m_uiI2] = CA(9);
}
else
{
akColor = 0;
}
// textures for subdivision
MgcVector2* akTexture;
if ( pkMesh->Textures() )
{
akTexture = pkMesh->Textures() + ruiVertexStart;
akTexture[kBP.m_uiI0] = TA(0);
akTexture[kBP.m_uiI1] = TA(3);
akTexture[kBP.m_uiI2] = TA(9);
}
else
{
akTexture = 0;
}
// recursive subdivision
if ( uiLevel > 0 )
{
InitializePoints(akCtrlPoint,kBP);
if ( akXu )
InitializeNormals(akCtrlPoint,kBP);
if ( akCtrlColor )
InitializeColors(akCtrlColor,kBP);
if ( akCtrlTexture )
InitializeTextures(akCtrlTexture,kBP);
SubdivideLL(--uiLevel,0.25,akX,akXu,akXv,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] = akXu[uiI].UnitCross(akXv[uiI]);
delete[] akXu;
delete[] akXv;
}
ruiVertexStart += uiQuantity;
}
//----------------------------------------------------------------------------
void MgcBezierTriangle3::SubdivideLL (unsigned int uiLevel, MgcReal fDSqr,
MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv, MgcColor* akColor,
MgcVector2* akTexture, 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
akXu[uiI01] = 0.5*(akXu[rkBP.m_uiI0] + akXu[rkBP.m_uiI1] -
fDSqr*rkBP.m_kXuuu);
akXv[uiI01] = 0.5*(akXv[rkBP.m_uiI0] + akXv[rkBP.m_uiI1] -
fDSqr*rkBP.m_kXuuv);
// left v-edge subdivision
akXu[uiI02] = 0.5*(akXu[rkBP.m_uiI0] + akXu[rkBP.m_uiI2] -
fDSqr*rkBP.m_kXuvv);
akXv[uiI02] = 0.5*(akXv[rkBP.m_uiI0] + akXv[rkBP.m_uiI2] -
fDSqr*rkBP.m_kXvvv);
// hypotenuse edge subdivision
akXu[uiI12] = 0.5*(akXu[rkBP.m_uiI1] + akXu[rkBP.m_uiI2] -
fDSqr*rkBP.m_kXhhu);
akXv[uiI12] = 0.5*(akXv[rkBP.m_uiI1] + akXv[rkBP.m_uiI2] -
fDSqr*rkBP.m_kXhhv);
}
// colors
MgcColor kCuu01, kCvv01, kChh01, kCuu02, kCvv02, kChh02, kCuu12, kCvv12,
kChh12;
if ( akColor )
{
// bottom u-edge subdivision
kCuu01 = 0.5*(rkBP.m_aakCuu[0] + rkBP.m_aakCuu[1]);
kCvv01 = 0.5*(rkBP.m_aakCvv[0] + rkBP.m_aakCvv[1]);
kChh01 = 0.5*(rkBP.m_aakChh[0] + rkBP.m_aakChh[1]);
akColor[uiI01] = 0.5*(akColor[rkBP.m_uiI0] + akColor[rkBP.m_uiI1] -
fDSqr*kCuu01);
// left v-edge subdivision
kCuu02 = 0.5*(rkBP.m_aakCuu[0] + rkBP.m_aakCuu[2]);
kCvv02 = 0.5*(rkBP.m_aakCvv[0] + rkBP.m_aakCvv[2]);
kChh02 = 0.5*(rkBP.m_aakChh[0] + rkBP.m_aakChh[2]);
akColor[uiI02] = 0.5*(akColor[rkBP.m_uiI0] + akColor[rkBP.m_uiI2] -
fDSqr*kCvv02);
// hypotenuse edge subdivision
kCuu12 = 0.5*(rkBP.m_aakCuu[1] + rkBP.m_aakCuu[2]);
kCvv12 = 0.5*(rkBP.m_aakCvv[1] + rkBP.m_aakCvv[2]);
kChh12 = 0.5*(rkBP.m_aakChh[1] + rkBP.m_aakChh[2]);
akColor[uiI12] = 0.5*(akColor[rkBP.m_uiI1] + akColor[rkBP.m_uiI2] -
fDSqr*kChh12);
}
// textures
MgcVector2 kTuu01, kTvv01, kThh01, kTuu02, kTvv02, kThh02, kTuu12, kTvv12,
kThh12;
if ( akTexture )
{
// bottom u-edge subdivision
kTuu01 = 0.5*(rkBP.m_aakTuu[0] + rkBP.m_aakTuu[1]);
kTvv01 = 0.5*(rkBP.m_aakTvv[0] + rkBP.m_aakTvv[1]);
kThh01 = 0.5*(rkBP.m_aakThh[0] + rkBP.m_aakThh[1]);
akTexture[uiI01] = 0.5*(akTexture[rkBP.m_uiI0]+akTexture[rkBP.m_uiI1]
- fDSqr*kTuu01);
// left v-edge subdivision
kTuu02 = 0.5*(rkBP.m_aakTuu[0] + rkBP.m_aakTuu[2]);
kTvv02 = 0.5*(rkBP.m_aakTvv[0] + rkBP.m_aakTvv[2]);
kThh02 = 0.5*(rkBP.m_aakThh[0] + rkBP.m_aakThh[2]);
akTexture[uiI02] = 0.5*(akTexture[rkBP.m_uiI0]+akTexture[rkBP.m_uiI2]
- fDSqr*kTvv02);
// hypotenuse edge subdivision
kTuu12 = 0.5*(rkBP.m_aakTuu[1] + rkBP.m_aakTuu[2]);
kTvv12 = 0.5*(rkBP.m_aakTvv[1] + rkBP.m_aakTvv[2]);
kThh12 = 0.5*(rkBP.m_aakThh[1] + rkBP.m_aakThh[2]);
akTexture[uiI12] = 0.5*(akTexture[rkBP.m_uiI1]+akTexture[rkBP.m_uiI2]
- fDSqr*kThh12);
}
// recurse on four children
if ( uiLevel > 0 )
{
uiLevel--;
fDSqr *= 0.25;
BlockParameters kSubBP;
// subtriangle <(s0,t0),(sm,t0),(s0,tm)>
kSubBP.m_uiI0 = rkBP.m_uiI0;
kSubBP.m_uiI1 = uiI01;
kSubBP.m_uiI2 = uiI02;
kSubBP.m_aakXuu[0] = rkBP.m_aakXuu[0];
kSubBP.m_aakXuu[1] = kXuu01;
kSubBP.m_aakXuu[2] = kXuu02;
kSubBP.m_aakXvv[0] = rkBP.m_aakXvv[0];
kSubBP.m_aakXvv[1] = kXvv01;
kSubBP.m_aakXvv[2] = kXvv02;
kSubBP.m_aakXhh[0] = rkBP.m_aakXhh[0];
kSubBP.m_aakXhh[1] = kXhh01;
kSubBP.m_aakXhh[2] = kXhh02;
if ( akColor )
{
kSubBP.m_aakCuu[0] = rkBP.m_aakCuu[0];
kSubBP.m_aakCuu[1] = kCuu01;
kSubBP.m_aakCuu[2] = kCuu02;
kSubBP.m_aakCvv[0] = rkBP.m_aakCvv[0];
kSubBP.m_aakCvv[1] = kCvv01;
kSubBP.m_aakCvv[2] = kCvv02;
kSubBP.m_aakChh[0] = rkBP.m_aakChh[0];
kSubBP.m_aakChh[1] = kChh01;
kSubBP.m_aakChh[2] = kChh02;
}
if ( akTexture )
{
kSubBP.m_aakTuu[0] = rkBP.m_aakTuu[0];
kSubBP.m_aakTuu[1] = kTuu01;
kSubBP.m_aakTuu[2] = kTuu02;
kSubBP.m_aakTvv[0] = rkBP.m_aakTvv[0];
kSubBP.m_aakTvv[1] = kTvv01;
kSubBP.m_aakTvv[2] = kTvv02;
kSubBP.m_aakThh[0] = rkBP.m_aakThh[0];
kSubBP.m_aakThh[1] = kThh01;
kSubBP.m_aakThh[2] = kThh02;
}
SubdivideLL(uiLevel,fDSqr,akX,akXu,akXv,akColor,akTexture,kSubBP);
// subtriangle <(sm,t0),(s1,t0),(sm,tm)>
kSubBP.m_uiI0 = uiI01;
kSubBP.m_uiI1 = rkBP.m_uiI1;
kSubBP.m_uiI2 = uiI12;
kSubBP.m_aakXuu[0] = kXuu01;
kSubBP.m_aakXuu[1] = rkBP.m_aakXuu[1];
kSubBP.m_aakXuu[2] = kXuu12;
kSubBP.m_aakXvv[0] = kXvv01;
kSubBP.m_aakXvv[1] = rkBP.m_aakXvv[1];
kSubBP.m_aakXvv[2] = kXvv12;
kSubBP.m_aakXhh[0] = kXhh01;
kSubBP.m_aakXhh[1] = rkBP.m_aakXhh[1];
kSubBP.m_aakXhh[2] = kXhh12;
if ( akColor )
{
kSubBP.m_aakCuu[0] = kCuu01;
kSubBP.m_aakCuu[1] = rkBP.m_aakCuu[1];
kSubBP.m_aakCuu[2] = kCuu12;
kSubBP.m_aakCvv[0] = kCvv01;
kSubBP.m_aakCvv[1] = rkBP.m_aakCvv[1];
kSubBP.m_aakCvv[2] = kCvv12;
kSubBP.m_aakChh[0] = kChh01;
kSubBP.m_aakChh[1] = rkBP.m_aakChh[1];
kSubBP.m_aakChh[2] = kChh12;
}
if ( akTexture )
{
kSubBP.m_aakTuu[0] = kTuu01;
kSubBP.m_aakTuu[1] = rkBP.m_aakTuu[1];
kSubBP.m_aakTuu[2] = kTuu12;
kSubBP.m_aakTvv[0] = kTvv01;
kSubBP.m_aakTvv[1] = rkBP.m_aakTvv[1];
kSubBP.m_aakTvv[2] = kTvv12;
kSubBP.m_aakThh[0] = kThh01;
kSubBP.m_aakThh[1] = rkBP.m_aakThh[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -