📄 wmlstandardmesh.cpp
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003. All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.
#include "WmlStandardMesh.h"
using namespace Wml;
//----------------------------------------------------------------------------
void Wml::CreateRectangleMesh (TriMesh*& rpkMesh, const Vector3f& rkCenter,
const Vector3f& rkU, const Vector3f& rkV, const Vector3f& rkAxis,
float fUExtent, float fVExtent, bool bWantNormals, bool bWantColors,
bool bWantUVs)
{
// allocate vertices
int iVQuantity = 4;
Vector3f* akVertex = new Vector3f[iVQuantity];
// allocate normals if requested
Vector3f* akNormal = NULL;
if ( bWantNormals )
akNormal = new Vector3f[iVQuantity];
// allocate colors if requested
ColorRGB* akColor = NULL;
if ( bWantColors )
{
akColor = new ColorRGB[iVQuantity];
memset(akColor,0,iVQuantity*sizeof(ColorRGB));
}
// allocate texture coordinates if requested
Vector2f* akUV = NULL;
if ( bWantUVs )
akUV = new Vector2f[iVQuantity];
// allocate connectivity
int iTQuantity = 2;
int* aiConnect = new int[3*iTQuantity];
// generate geometry
Vector3f kUTerm = fUExtent*rkU;
Vector3f kVTerm = fVExtent*rkV;
akVertex[0] = rkCenter - kUTerm - kVTerm;
akVertex[1] = rkCenter + kUTerm - kVTerm;
akVertex[2] = rkCenter + kUTerm + kVTerm;
akVertex[3] = rkCenter - kUTerm + kVTerm;
if ( bWantNormals )
{
for (int i = 0; i < iVQuantity; i++)
akNormal[i] = rkAxis;
}
if ( bWantUVs )
{
akUV[0] = Vector2f(0.0f,0.0f);
akUV[1] = Vector2f(1.0f,0.0f);
akUV[2] = Vector2f(1.0f,1.0f);
akUV[3] = Vector2f(0.0f,1.0f);
}
// generate connectivity
aiConnect[0] = 0; aiConnect[1] = 1; aiConnect[2] = 2;
aiConnect[3] = 0; aiConnect[4] = 2; aiConnect[5] = 3;
if ( rpkMesh )
{
rpkMesh->Reconstruct(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
else
{
rpkMesh = new TriMesh(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
}
//----------------------------------------------------------------------------
void Wml::CreateDiskMesh (TriMesh*& rpkMesh, int iShellSamples,
int iRadialSamples, const Vector3f& rkCenter, float fRadius,
const Vector3f& rkU, const Vector3f& rkV, const Vector3f& rkAxis,
bool bWantNormals, bool bWantColors, bool bWantUVs)
{
int iRSm1 = iRadialSamples - 1, iSSm1 = iShellSamples - 1;
// allocate vertices
int iVQuantity = 1 + iRadialSamples*iSSm1;
Vector3f* akVertex = new Vector3f[iVQuantity];
// allocate normals if requested
Vector3f* akNormal = NULL;
if ( bWantNormals )
akNormal = new Vector3f[iVQuantity];
// allocate colors if requested
ColorRGB* akColor = NULL;
if ( bWantColors )
{
akColor = new ColorRGB[iVQuantity];
memset(akColor,0,iVQuantity*sizeof(ColorRGB));
}
// allocate texture coordinates if requested
Vector2f* akUV = NULL;
if ( bWantUVs )
akUV = new Vector2f[iVQuantity];
// allocate connectivity
int iTQuantity = iRadialSamples*(2*iSSm1-1);
int* aiConnect = new int[3*iTQuantity];
// generate geometry
int iR, iS, i;
// center of disk
akVertex[0] = Vector3f::ZERO;
if ( bWantNormals )
{
akNormal[0] = rkAxis;
}
if ( bWantUVs )
{
akUV[0].X() = 0.5f;
akUV[0].Y() = 0.5f;
}
float fInvSSm1 = 1.0f/(float)iSSm1;
float fInvRS = 1.0f/(float)iRadialSamples;
for (iR = 0; iR < iRadialSamples; iR++)
{
float fAngle = Mathf::TWO_PI*fInvRS*iR;
float fCos = Mathf::Cos(fAngle);
float fSin = Mathf::Sin(fAngle);
Vector3f kRadial = fCos*rkU + fSin*rkV;
for (iS = 1; iS < iShellSamples; iS++)
{
float fFraction = fInvSSm1*iS; // in (0,R]
Vector3f kFracRadial = fFraction*kRadial;
i = iS+iSSm1*iR;
akVertex[i] = fRadius*kFracRadial;
if ( bWantNormals )
{
akNormal[i] = rkAxis;
}
if ( bWantUVs )
{
akUV[i].X() = 0.5f*(1.0f+kFracRadial.X());
akUV[i].Y() = 0.5f*(1.0f+kFracRadial.Y());
}
}
}
// rotate and translate disk to specified center
for (i = 0; i < iVQuantity; i++)
akVertex[i] += rkCenter;
// generate connectivity
int* aiLocalConnect = aiConnect;
int iT = 0;
for (int iR0 = iRSm1, iR1 = 0; iR1 < iRadialSamples; iR0 = iR1++)
{
aiLocalConnect[0] = 0;
aiLocalConnect[1] = 1+iSSm1*iR0;
aiLocalConnect[2] = 1+iSSm1*iR1;
aiLocalConnect += 3;
iT++;
for (int iS = 1; iS < iSSm1; iS++, aiLocalConnect += 6)
{
int i00 = iS+iSSm1*iR0;
int i01 = iS+iSSm1*iR1;
int i10 = i00+1;
int i11 = i01+1;
aiLocalConnect[0] = i00;
aiLocalConnect[1] = i10;
aiLocalConnect[2] = i11;
aiLocalConnect[3] = i00;
aiLocalConnect[4] = i11;
aiLocalConnect[5] = i01;
iT += 2;
}
}
assert( iT == iTQuantity );
if ( rpkMesh )
{
rpkMesh->Reconstruct(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
else
{
rpkMesh = new TriMesh(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
}
//----------------------------------------------------------------------------
void Wml::CreateBoxMesh (TriMesh*& rpkMesh, const Vector3f& rkCenter,
const Vector3f& rkU, const Vector3f& rkV, const Vector3f& rkW,
float fUExtent, float fVExtent, float fWExtent, bool bWantNormals,
bool bWantColors, bool bWantUVs, bool bOutsideView)
{
// allocate vertices
int iVQuantity = 8;
Vector3f* akVertex = new Vector3f[iVQuantity];
// allocate normals if requested
Vector3f* akNormal = NULL;
if ( bWantNormals )
akNormal = new Vector3f[iVQuantity];
// allocate colors if requested
ColorRGB* akColor = NULL;
if ( bWantColors )
{
akColor = new ColorRGB[iVQuantity];
memset(akColor,0,iVQuantity*sizeof(ColorRGB));
}
// allocate texture coordinates if requested
Vector2f* akUV = NULL;
if ( bWantUVs )
akUV = new Vector2f[iVQuantity];
// allocate connectivity
int iTQuantity = 12;
int* aiConnect = new int[3*iTQuantity];
// generate geometry
Vector3f kUTerm = fUExtent*rkU;
Vector3f kVTerm = fVExtent*rkV;
Vector3f kWTerm = fWExtent*rkW;
akVertex[0] = rkCenter - kUTerm - kVTerm - kWTerm;
akVertex[1] = rkCenter + kUTerm - kVTerm - kWTerm;
akVertex[2] = rkCenter + kUTerm + kVTerm - kWTerm;
akVertex[3] = rkCenter - kUTerm + kVTerm - kWTerm;
akVertex[4] = rkCenter - kUTerm - kVTerm + kWTerm;
akVertex[5] = rkCenter + kUTerm - kVTerm + kWTerm;
akVertex[6] = rkCenter + kUTerm + kVTerm + kWTerm;
akVertex[7] = rkCenter - kUTerm + kVTerm + kWTerm;
if ( bWantUVs )
{
akUV[0] = Vector2f(0.25f,0.75f);
akUV[1] = Vector2f(0.75f,0.75f);
akUV[2] = Vector2f(0.75f,0.25f);
akUV[3] = Vector2f(0.25f,0.25f);
akUV[4] = Vector2f(0.0f,1.0f);
akUV[5] = Vector2f(1.0f,1.0f);
akUV[6] = Vector2f(1.0f,0.0f);
akUV[7] = Vector2f(0.0f,0.0f);
}
// generate connectivity (outside view)
aiConnect[ 0] = 0; aiConnect[ 1] = 2; aiConnect[ 2] = 1;
aiConnect[ 3] = 0; aiConnect[ 4] = 3; aiConnect[ 5] = 2;
aiConnect[ 6] = 0; aiConnect[ 7] = 1; aiConnect[ 8] = 5;
aiConnect[ 9] = 0; aiConnect[10] = 5; aiConnect[11] = 4;
aiConnect[12] = 0; aiConnect[13] = 4; aiConnect[14] = 7;
aiConnect[15] = 0; aiConnect[16] = 7; aiConnect[17] = 3;
aiConnect[18] = 6; aiConnect[19] = 4; aiConnect[20] = 5;
aiConnect[21] = 6; aiConnect[22] = 7; aiConnect[23] = 4;
aiConnect[24] = 6; aiConnect[25] = 5; aiConnect[26] = 1;
aiConnect[27] = 6; aiConnect[28] = 1; aiConnect[29] = 2;
aiConnect[30] = 6; aiConnect[31] = 2; aiConnect[32] = 3;
aiConnect[33] = 6; aiConnect[34] = 3; aiConnect[35] = 7;
if ( !bOutsideView )
{
int* aiLocalConnect = aiConnect;
for (int iT = 0; iT < iTQuantity; iT++, aiLocalConnect +=3)
{
int iSave = aiLocalConnect[1];
aiLocalConnect[1] = aiLocalConnect[2];
aiLocalConnect[2] = iSave;
}
}
if ( rpkMesh )
{
rpkMesh->Reconstruct(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
else
{
rpkMesh = new TriMesh(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
if ( bWantNormals )
rpkMesh->UpdateModelNormals();
}
//----------------------------------------------------------------------------
void Wml::CreateCylinderMesh (TriMesh*& rpkMesh, int iAxisSamples,
int iRadialSamples, const Vector3f& rkCenter, const Vector3f& rkU,
const Vector3f& rkV, const Vector3f& rkAxis, float fRadius,
float fHeight, bool bWantNormals, bool bWantColors, bool bWantUVs,
bool bOutsideView)
{
// allocate vertices
int iVQuantity = iAxisSamples*(iRadialSamples+1);
Vector3f* akVertex = new Vector3f[iVQuantity];
// allocate normals if requested
Vector3f* akNormal = NULL;
if ( bWantNormals )
akNormal = new Vector3f[iVQuantity];
// allocate colors if requested
ColorRGB* akColor = NULL;
if ( bWantColors )
{
akColor = new ColorRGB[iVQuantity];
memset(akColor,0,iVQuantity*sizeof(ColorRGB));
}
// allocate texture coordinates if requested
Vector2f* akUV = NULL;
if ( bWantUVs )
akUV = new Vector2f[iVQuantity];
// allocate connectivity
int iTQuantity = 2*(iAxisSamples-1)*iRadialSamples;
int* aiConnect = new int[3*iTQuantity];
// generate geometry
float fInvRS = 1.0f/(float)iRadialSamples;
float fInvASm1 = 1.0f/(float)(iAxisSamples-1);
float fHalfHeight = 0.5f*fHeight;
int iR, iA, iAStart, i;
// Generate points on the unit circle to be used in computing the mesh
// points on a cylinder slice.
float* afSin = new float[iRadialSamples+1];
float* afCos = new float[iRadialSamples+1];
for (iR = 0; iR < iRadialSamples; iR++)
{
float fAngle = Mathf::TWO_PI*fInvRS*iR;
afCos[iR] = Mathf::Cos(fAngle);
afSin[iR] = Mathf::Sin(fAngle);
}
afSin[iRadialSamples] = afSin[0];
afCos[iRadialSamples] = afCos[0];
// generate the cylinder itself
for (iA = 0, i = 0; iA < iAxisSamples; iA++)
{
float fAxisFraction = iA*fInvASm1; // in [0,1]
float fZ = -fHalfHeight + fHeight*fAxisFraction;
// compute center of slice
Vector3f kSliceCenter = rkCenter + fZ*rkAxis;
// compute slice vertices with duplication at end point
int iSave = i;
for (iR = 0; iR < iRadialSamples; iR++)
{
float fRadialFraction = iR*fInvRS; // in [0,1)
Vector3f kNormal = afCos[iR]*rkU + afSin[iR]*rkV;
akVertex[i] = kSliceCenter + fRadius*kNormal;
if ( bWantNormals )
{
if ( bOutsideView )
akNormal[i] = kNormal;
else
akNormal[i] = -kNormal;
}
if ( bWantUVs )
{
akUV[i].X() = fRadialFraction;
akUV[i].Y() = fAxisFraction;
}
i++;
}
akVertex[i] = akVertex[iSave];
if ( bWantNormals )
{
akNormal[i] = akNormal[iSave];
}
if ( bWantUVs )
{
akUV[i].X() = 1.0f;
akUV[i].Y() = fAxisFraction;
}
i++;
}
// generate connectivity
int* aiLocalConnect = aiConnect;
for (iA = 0, iAStart = 0; iA < iAxisSamples-1; iA++)
{
int i0 = iAStart;
int i1 = i0 + 1;
iAStart += iRadialSamples + 1;
int i2 = iAStart;
int i3 = i2 + 1;
for (i = 0; i < iRadialSamples; i++, aiLocalConnect += 6)
{
if ( bOutsideView )
{
aiLocalConnect[0] = i0++;
aiLocalConnect[1] = i1;
aiLocalConnect[2] = i2;
aiLocalConnect[3] = i1++;
aiLocalConnect[4] = i3++;
aiLocalConnect[5] = i2++;
}
else // inside view
{
aiLocalConnect[0] = i0++;
aiLocalConnect[1] = i2;
aiLocalConnect[2] = i1;
aiLocalConnect[3] = i1++;
aiLocalConnect[4] = i2++;
aiLocalConnect[5] = i3++;
}
}
}
delete[] afCos;
delete[] afSin;
if ( rpkMesh )
{
rpkMesh->Reconstruct(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
else
{
rpkMesh = new TriMesh(iVQuantity,akVertex,akNormal,akColor,akUV,
iTQuantity,aiConnect);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -