📄 mgcbeziercylinder3.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 "MgcBezierCylinder3.h"
#include "MgcTriMesh.h"
MgcImplementRTTI(MgcBezierCylinder3,MgcBezierCylinder);
MgcImplementStream(MgcBezierCylinder3);
// 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]]
//----------------------------------------------------------------------------
MgcBezierCylinder3::MgcBezierCylinder3 (unsigned int* auiIndex)
:
MgcBezierCylinder(3,8,auiIndex)
{
}
//----------------------------------------------------------------------------
MgcBezierCylinder3::MgcBezierCylinder3 ()
{
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::InitializePoints (const MgcVector3* akCtrlPoint,
IntervalParameters& rkIP)
{
// Xss[s][t]
rkIP.m_aakXss[0][0] = 6.0*(XA(0) - 2.0*XA(1) + XA(2));
rkIP.m_aakXss[0][1] = 6.0*(XA(4) - 2.0*XA(5) + XA(6));
rkIP.m_aakXss[1][0] = 6.0*(XA(1) - 2.0*XA(2) + XA(3));
rkIP.m_aakXss[1][1] = 6.0*(XA(5) - 2.0*XA(6) + XA(7));
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::InitializeNormals (const MgcVector3* akCtrlPoint,
MgcVector3 akXsss[2])
{
// Xsss[t]
akXsss[0] = 6.0*(XA(3) + 3.0*(XA(1) - XA(2)) - XA(0));
akXsss[1] = 6.0*(XA(7) + 3.0*(XA(5) - XA(6)) - XA(4));
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::InitializeColors (const MgcColor* akCtrlColor,
IntervalParameters& rkIP)
{
// Css[s][t]
rkIP.m_aakCss[0][0] = 6.0*(CA(0) - 2.0*CA(1) + CA(2));
rkIP.m_aakCss[0][1] = 6.0*(CA(4) - 2.0*CA(5) + CA(6));
rkIP.m_aakCss[1][0] = 6.0*(CA(1) - 2.0*CA(2) + CA(3));
rkIP.m_aakCss[1][1] = 6.0*(CA(5) - 2.0*CA(6) + CA(7));
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::InitializeTextures (const MgcVector2* akCtrlTexture,
IntervalParameters& rkIP)
{
// Tss[s][t]
rkIP.m_aakTss[0][0] = 6.0*(TA(0) - 2.0*TA(1) + TA(2));
rkIP.m_aakTss[0][1] = 6.0*(TA(4) - 2.0*TA(5) + TA(6));
rkIP.m_aakTss[1][0] = 6.0*(TA(1) - 2.0*TA(2) + TA(3));
rkIP.m_aakTss[1][1] = 6.0*(TA(5) - 2.0*TA(6) + TA(7));
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::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 = GetVerticesPerCylinderPatch(uiLevel,
m_uiCylinderLevel);
// indices of four corners of patch, I[s][t]
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 = pkMesh->Vertices() + ruiVertexStart;
akX[kIP.m_uiI00] = XA(0);
akX[kIP.m_uiI01] = XA(4);
akX[kIP.m_uiI10] = XA(3);
akX[kIP.m_uiI11] = XA(7);
// derivatives for subdivision (for normal vectors)
MgcVector3* akXs;
MgcVector3* akXt;
if ( pkMesh->Normals() )
{
akXs = new MgcVector3[uiQuantity];
akXs[kIP.m_uiI00] = 3.0*(XA(1) - XA(0));
akXs[kIP.m_uiI01] = 3.0*(XA(5) - XA(4));
akXs[kIP.m_uiI10] = 3.0*(XA(3) - XA(2));
akXs[kIP.m_uiI11] = 3.0*(XA(7) - XA(6));
akXt = new MgcVector3[uiQuantity];
akXt[kIP.m_uiI00] = 3.0*(XA(4) - XA(0));
akXt[kIP.m_uiI01] = akXt[kIP.m_uiI00];
akXt[kIP.m_uiI10] = 3.0*(XA(7) - XA(3));
akXt[kIP.m_uiI11] = akXt[kIP.m_uiI10];
}
else
{
akXs = 0;
akXt = 0;
}
// colors for subdivision
MgcColor* akColor;
if ( pkMesh->Colors() )
{
akColor = pkMesh->Colors() + ruiVertexStart;
akColor[kIP.m_uiI00] = CA(0);
akColor[kIP.m_uiI01] = CA(4);
akColor[kIP.m_uiI10] = CA(3);
akColor[kIP.m_uiI11] = CA(7);
}
else
{
akColor = 0;
}
// textures for subdivision
MgcVector2* akTexture;
if ( pkMesh->Textures() )
{
akTexture = pkMesh->Textures() + ruiVertexStart;
akTexture[kIP.m_uiI00] = TA(0);
akTexture[kIP.m_uiI01] = TA(4);
akTexture[kIP.m_uiI10] = TA(3);
akTexture[kIP.m_uiI11] = TA(7);
}
else
{
akTexture = 0;
}
// recursive subdivision
MgcVector3 akXsss[2];
if ( uiLevel > 0 || m_uiCylinderLevel > 0 )
{
InitializePoints(akCtrlPoint,kIP);
if ( akXs )
InitializeNormals(akCtrlPoint,akXsss);
if ( akCtrlColor )
InitializeColors(akCtrlColor,kIP);
if ( akCtrlTexture )
InitializeTextures(akCtrlTexture,kIP);
}
if ( uiLevel > 0 )
{
SubdivideBoundary(--uiLevel,0.25,akX,akXs,akXt,akXsss,akColor,
akTexture,kIP);
}
if ( m_uiCylinderLevel > 0 )
{
SubdivideCylinder(m_uiCylinderLevel-1,akX,akXs,akXt,akColor,
akTexture,0,kIP.m_uiI01,uiTwoPowL);
}
// 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 MgcBezierCylinder3::SubdivideBoundary (unsigned int uiLevel,
MgcReal fDSqr, MgcVector3* akX, MgcVector3* akXs, MgcVector3* akXt,
MgcVector3 akXsss[2], MgcColor* akColor, MgcVector2* akTexture,
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_aakXss[0][0] + rkIP.m_aakXss[1][0]);
MgcVector3 kXssM1 = 0.5*(rkIP.m_aakXss[0][1] + rkIP.m_aakXss[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 ( akXs )
{
akXs[uiIM0] = 0.5*(akXs[rkIP.m_uiI00] + akXs[rkIP.m_uiI10] -
fDSqr*akXsss[0]);
akXs[uiIM1] = 0.5*(akXs[rkIP.m_uiI01] + akXs[rkIP.m_uiI11] -
fDSqr*akXsss[1]);
akXt[uiIM0] = akX[uiIM1] - akX[uiIM0];
akXt[uiIM1] = akXt[uiIM0];
}
// colors
MgcColor kCssM0, kCssM1;
if ( akColor )
{
kCssM0 = 0.5*(rkIP.m_aakCss[0][0] + rkIP.m_aakCss[1][0]);
kCssM1 = 0.5*(rkIP.m_aakCss[0][1] + rkIP.m_aakCss[1][1]);
akColor[uiIM0] = 0.5*(akColor[rkIP.m_uiI00] + akColor[rkIP.m_uiI10] -
fDSqr*kCssM0);
akColor[uiIM1] = 0.5*(akColor[rkIP.m_uiI01] + akColor[rkIP.m_uiI11] -
fDSqr*kCssM1);
}
// textures
MgcVector2 kTssM0, kTssM1;
if ( akTexture )
{
kTssM0 = 0.5*(rkIP.m_aakTss[0][0] + rkIP.m_aakTss[1][0]);
kTssM1 = 0.5*(rkIP.m_aakTss[0][1] + rkIP.m_aakTss[1][1]);
akTexture[uiIM0] = 0.5*(akTexture[rkIP.m_uiI00] +
akTexture[rkIP.m_uiI10] - fDSqr*kTssM0);
akTexture[uiIM1] = 0.5*(akTexture[rkIP.m_uiI01] +
akTexture[rkIP.m_uiI11] - fDSqr*kTssM1);
}
// recurse on two children
if ( uiLevel > 0 )
{
uiLevel--;
fDSqr *= 0.25;
IntervalParameters kSubIP;
// subinterval [s0,sM]
kSubIP.m_uiI00 = rkIP.m_uiI00;
kSubIP.m_uiI01 = rkIP.m_uiI01;
kSubIP.m_uiI10 = uiIM0;
kSubIP.m_uiI11 = uiIM1;
kSubIP.m_aakXss[0][0] = rkIP.m_aakXss[0][0];
kSubIP.m_aakXss[0][1] = rkIP.m_aakXss[0][1];
kSubIP.m_aakXss[1][0] = kXssM0;
kSubIP.m_aakXss[1][1] = kXssM1;
if ( akColor )
{
kSubIP.m_aakCss[0][0] = rkIP.m_aakCss[0][0];
kSubIP.m_aakCss[0][1] = rkIP.m_aakCss[0][1];
kSubIP.m_aakCss[1][0] = kCssM0;
kSubIP.m_aakCss[1][1] = kCssM1;
}
if ( akTexture )
{
kSubIP.m_aakTss[0][0] = rkIP.m_aakTss[0][0];
kSubIP.m_aakTss[0][1] = rkIP.m_aakTss[0][1];
kSubIP.m_aakTss[1][0] = kTssM0;
kSubIP.m_aakTss[1][1] = kTssM1;
}
SubdivideBoundary(uiLevel,fDSqr,akX,akXs,akXt,akXsss,akColor,
akTexture,kSubIP);
// subinterval [sM,s1]
kSubIP.m_uiI00 = uiIM0;
kSubIP.m_uiI01 = uiIM1;
kSubIP.m_uiI10 = rkIP.m_uiI10;
kSubIP.m_uiI11 = rkIP.m_uiI11;
kSubIP.m_aakXss[0][0] = kXssM0;
kSubIP.m_aakXss[0][1] = kXssM1;
kSubIP.m_aakXss[1][0] = rkIP.m_aakXss[1][0];
kSubIP.m_aakXss[1][1] = rkIP.m_aakXss[1][1];
if ( akColor )
{
kSubIP.m_aakCss[0][0] = kCssM0;
kSubIP.m_aakCss[0][1] = kCssM1;
kSubIP.m_aakCss[1][0] = rkIP.m_aakCss[1][0];
kSubIP.m_aakCss[1][1] = rkIP.m_aakCss[1][1];
}
if ( akTexture )
{
kSubIP.m_aakTss[0][0] = kTssM0;
kSubIP.m_aakTss[0][1] = kTssM1;
kSubIP.m_aakTss[1][0] = rkIP.m_aakTss[1][0];
kSubIP.m_aakTss[1][1] = rkIP.m_aakTss[1][1];
}
SubdivideBoundary(uiLevel,fDSqr,akX,akXs,akXt,akXsss,akColor,
akTexture,kSubIP);
}
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::SubdivideCylinder (unsigned int uiCLevel,
MgcVector3* akX, MgcVector3* akXs, MgcVector3* akXt, MgcColor* akColor,
MgcVector2* akTexture, 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 ( akXs )
{
akXs[uiJM] = 0.5*(akXs[uiJ0] + akXs[uiJ1]);
akXt[uiJM] = akXt[uiJ0];
}
// colors
if ( akColor )
akColor[uiJM] = 0.5*(akColor[uiJ0] + akColor[uiJ1]);
// textures
if ( akTexture )
akTexture[uiJM] = 0.5*(akTexture[uiJ0] + akTexture[uiJ1]);
}
// recurse on two children
if ( uiCLevel > 0 )
{
uiCLevel--;
// subinterval [t0,tM]
SubdivideCylinder(uiCLevel,akX,akXs,akXt,akColor,akTexture,uiI0,
uiIM,uiTwoPowL);
// subinterval [tM,t1]
SubdivideCylinder(uiCLevel,akX,akXs,akXt,akColor,akTexture,uiIM,
uiI1,uiTwoPowL);
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// streaming
//----------------------------------------------------------------------------
MgcObject* MgcBezierCylinder3::Factory (MgcStream& rkStream)
{
MgcBezierCylinder3* pkObject = new MgcBezierCylinder3;
MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
pkObject->Load(rkStream,pkLink);
return pkObject;
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcBezierCylinder::Load(rkStream,pkLink);
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcBezierCylinder::Link(rkStream,pkLink);
}
//----------------------------------------------------------------------------
bool MgcBezierCylinder3::Register (MgcStream& rkStream)
{
return MgcBezierCylinder::Register(rkStream);
}
//----------------------------------------------------------------------------
void MgcBezierCylinder3::Save (MgcStream& rkStream)
{
MgcBezierCylinder::Save(rkStream);
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -