summaryrefslogtreecommitdiff
path: root/hammer/createarch.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/createarch.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/createarch.cpp')
-rw-r--r--hammer/createarch.cpp657
1 files changed, 657 insertions, 0 deletions
diff --git a/hammer/createarch.cpp b/hammer/createarch.cpp
new file mode 100644
index 0000000..6e4e2c0
--- /dev/null
+++ b/hammer/createarch.cpp
@@ -0,0 +1,657 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#include "stdafx.h"
+#include "OPTGeneral.h"
+#include "Options.h"
+#include "hammer_mathlib.h"
+#include "MapFace.h"
+#include "MapGroup.h"
+#include "MapSolid.h"
+#include "hammer.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+//-----------------------------------------------------------------------------
+// Purpose: Create a segment using two polygons and a start and end position in
+// those polygons.
+// Input : fZMin -
+// fZMax -
+// fOuterPoints -
+// fInnerPoints -
+// iStart -
+// iEnd -
+// bCreateSouthFace -
+// Output :
+//-----------------------------------------------------------------------------
+static CMapSolid *CreateSegment(float fZMin, float fZMax, float fOuterPoints[][2], float fInnerPoints[][2], int iStart, int iEnd, BOOL bCreateSouthFace)
+{
+ CMapFace Face;
+ Vector points[4]; // all sides have four vertices
+
+ CMapSolid *pSolid = new CMapSolid;
+
+ int iNorthSouthPoints = 3 + (bCreateSouthFace ? 1 : 0);
+
+ // create top face
+ points[0][0] = fOuterPoints[iStart][0];
+ points[0][1] = fOuterPoints[iStart][1];
+ points[0][2] = fZMin;
+
+ points[1][0] = fOuterPoints[iEnd][0];
+ points[1][1] = fOuterPoints[iEnd][1];
+ points[1][2] = fZMin;
+
+ points[2][0] = fInnerPoints[iEnd][0];
+ points[2][1] = fInnerPoints[iEnd][1];
+ points[2][2] = fZMin;
+
+ points[3][0] = fInnerPoints[iStart][0];
+ points[3][1] = fInnerPoints[iStart][1];
+ points[3][2] = fZMin;
+
+ Face.CreateFace(points, iNorthSouthPoints);
+ pSolid->AddFace(&Face);
+
+ // bottom face - set other z value and reverse order
+ for (int i = 0; i < 4; i++)
+ {
+ points[i][2] = fZMax;
+ }
+
+ Face.CreateFace(points, -iNorthSouthPoints);
+ pSolid->AddFace(&Face);
+
+ // left side
+ points[0][0] = fOuterPoints[iStart][0];
+ points[0][1] = fOuterPoints[iStart][1];
+ points[0][2] = fZMax;
+
+ points[1][0] = fOuterPoints[iStart][0];
+ points[1][1] = fOuterPoints[iStart][1];
+ points[1][2] = fZMin;
+
+ points[2][0] = fInnerPoints[iStart][0];
+ points[2][1] = fInnerPoints[iStart][1];
+ points[2][2] = fZMin;
+
+ points[3][0] = fInnerPoints[iStart][0];
+ points[3][1] = fInnerPoints[iStart][1];
+ points[3][2] = fZMax;
+
+ Face.CreateFace(points, 4);
+ pSolid->AddFace(&Face);
+
+ // right side
+ points[0][0] = fOuterPoints[iEnd][0];
+ points[0][1] = fOuterPoints[iEnd][1];
+ points[0][2] = fZMin;
+
+ points[1][0] = fOuterPoints[iEnd][0];
+ points[1][1] = fOuterPoints[iEnd][1];
+ points[1][2] = fZMax;
+
+ points[2][0] = fInnerPoints[iEnd][0];
+ points[2][1] = fInnerPoints[iEnd][1];
+ points[2][2] = fZMax;
+
+ points[3][0] = fInnerPoints[iEnd][0];
+ points[3][1] = fInnerPoints[iEnd][1];
+ points[3][2] = fZMin;
+
+ Face.CreateFace(points, 4);
+ pSolid->AddFace(&Face);
+
+ // north face
+ points[0][0] = fOuterPoints[iEnd][0];
+ points[0][1] = fOuterPoints[iEnd][1];
+ points[0][2] = fZMin;
+
+ points[1][0] = fOuterPoints[iStart][0];
+ points[1][1] = fOuterPoints[iStart][1];
+ points[1][2] = fZMin;
+
+ points[2][0] = fOuterPoints[iStart][0];
+ points[2][1] = fOuterPoints[iStart][1];
+ points[2][2] = fZMax;
+
+ points[3][0] = fOuterPoints[iEnd][0];
+ points[3][1] = fOuterPoints[iEnd][1];
+ points[3][2] = fZMax;
+
+ Face.CreateFace(points, 4);
+ pSolid->AddFace(&Face);
+
+ // south face
+ if (bCreateSouthFace)
+ {
+ points[0][0] = fInnerPoints[iStart][0];
+ points[0][1] = fInnerPoints[iStart][1];
+ points[0][2] = fZMin;
+
+ points[1][0] = fInnerPoints[iEnd][0];
+ points[1][1] = fInnerPoints[iEnd][1];
+ points[1][2] = fZMin;
+
+ points[2][0] = fInnerPoints[iEnd][0];
+ points[2][1] = fInnerPoints[iEnd][1];
+ points[2][2] = fZMax;
+
+ points[3][0] = fInnerPoints[iStart][0];
+ points[3][1] = fInnerPoints[iStart][1];
+ points[3][2] = fZMax;
+
+ Face.CreateFace(points, 4);
+ pSolid->AddFace(&Face);
+ }
+
+ pSolid->InitializeTextureAxes(Options.GetTextureAlignment(), INIT_TEXTURE_ALL | INIT_TEXTURE_FORCE);
+
+ return(pSolid);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Create a segment using two polygons and a start and end position in
+// those polygons.
+// Input : fZMin -
+// fZMax -
+// fOuterPoints -
+// fInnerPoints -
+// iStart -
+// iEnd -
+// bCreateSouthFace -
+// Output :
+//-----------------------------------------------------------------------------
+static CMapSolid *CreateSegment(float fStartOuterPoints[][3], float fStartInnerPoints[][3],
+ float fEndOuterPoints[][3], float fEndInnerPoints[][3],
+ int iStart, int iEnd, BOOL bCreateSouthFace)
+{
+ CMapFace Face;
+ Vector points[4]; // all sides have four vertices
+
+ CMapSolid *pSolid = new CMapSolid;
+
+ // create top face
+ points[0][0] = fStartOuterPoints[iStart][0];
+ points[0][1] = fStartOuterPoints[iStart][1];
+ points[0][2] = fStartOuterPoints[iStart][2];
+
+ points[1][0] = fStartOuterPoints[iEnd][0];
+ points[1][1] = fStartOuterPoints[iEnd][1];
+ points[1][2] = fStartOuterPoints[iEnd][2];
+
+ points[2][0] = fStartInnerPoints[iEnd][0];
+ points[2][1] = fStartInnerPoints[iEnd][1];
+ points[2][2] = fStartInnerPoints[iEnd][2];
+
+ points[3][0] = fStartInnerPoints[iStart][0];
+ points[3][1] = fStartInnerPoints[iStart][1];
+ points[3][2] = fStartInnerPoints[iStart][2];
+
+ Face.CreateFace(points, -4);
+ pSolid->AddFace(&Face);
+
+ // bottom face - set other z value and reverse order
+ points[0][0] = fEndOuterPoints[iStart][0];
+ points[0][1] = fEndOuterPoints[iStart][1];
+ points[0][2] = fEndOuterPoints[iStart][2];
+
+ points[1][0] = fEndOuterPoints[iEnd][0];
+ points[1][1] = fEndOuterPoints[iEnd][1];
+ points[1][2] = fEndOuterPoints[iEnd][2];
+
+ points[2][0] = fEndInnerPoints[iEnd][0];
+ points[2][1] = fEndInnerPoints[iEnd][1];
+ points[2][2] = fEndInnerPoints[iEnd][2];
+
+ points[3][0] = fEndInnerPoints[iStart][0];
+ points[3][1] = fEndInnerPoints[iStart][1];
+ points[3][2] = fEndInnerPoints[iStart][2];
+
+ Face.CreateFace(points, 4);
+ pSolid->AddFace(&Face);
+
+ // left side
+ points[0][0] = fEndOuterPoints[iStart][0];
+ points[0][1] = fEndOuterPoints[iStart][1];
+ points[0][2] = fEndOuterPoints[iStart][2];
+
+ points[1][0] = fStartOuterPoints[iStart][0];
+ points[1][1] = fStartOuterPoints[iStart][1];
+ points[1][2] = fStartOuterPoints[iStart][2];
+
+ points[2][0] = fStartInnerPoints[iStart][0];
+ points[2][1] = fStartInnerPoints[iStart][1];
+ points[2][2] = fStartInnerPoints[iStart][2];
+
+ points[3][0] = fEndInnerPoints[iStart][0];
+ points[3][1] = fEndInnerPoints[iStart][1];
+ points[3][2] = fEndInnerPoints[iStart][2];
+
+ Face.CreateFace(points, -4);
+ pSolid->AddFace(&Face);
+
+ // right side
+ points[0][0] = fStartOuterPoints[iEnd][0];
+ points[0][1] = fStartOuterPoints[iEnd][1];
+ points[0][2] = fStartOuterPoints[iEnd][2];
+
+ points[1][0] = fEndOuterPoints[iEnd][0];
+ points[1][1] = fEndOuterPoints[iEnd][1];
+ points[1][2] = fEndOuterPoints[iEnd][2];
+
+ points[2][0] = fEndInnerPoints[iEnd][0];
+ points[2][1] = fEndInnerPoints[iEnd][1];
+ points[2][2] = fEndInnerPoints[iEnd][2];
+
+ points[3][0] = fStartInnerPoints[iEnd][0];
+ points[3][1] = fStartInnerPoints[iEnd][1];
+ points[3][2] = fStartInnerPoints[iEnd][2];
+
+ Face.CreateFace(points, -4);
+ pSolid->AddFace(&Face);
+
+ // north face
+ points[0][0] = fStartOuterPoints[iEnd][0];
+ points[0][1] = fStartOuterPoints[iEnd][1];
+ points[0][2] = fStartOuterPoints[iEnd][2];
+
+ points[1][0] = fStartOuterPoints[iStart][0];
+ points[1][1] = fStartOuterPoints[iStart][1];
+ points[1][2] = fStartOuterPoints[iStart][2];
+
+ points[2][0] = fEndOuterPoints[iStart][0];
+ points[2][1] = fEndOuterPoints[iStart][1];
+ points[2][2] = fEndOuterPoints[iStart][2];
+
+ points[3][0] = fEndOuterPoints[iEnd][0];
+ points[3][1] = fEndOuterPoints[iEnd][1];
+ points[3][2] = fEndOuterPoints[iEnd][2];
+
+ Face.CreateFace(points, -4);
+ pSolid->AddFace(&Face);
+
+ // south face
+ if (bCreateSouthFace)
+ {
+ points[0][0] = fStartInnerPoints[iStart][0];
+ points[0][1] = fStartInnerPoints[iStart][1];
+ points[0][2] = fStartInnerPoints[iStart][2];
+
+ points[1][0] = fStartInnerPoints[iEnd][0];
+ points[1][1] = fStartInnerPoints[iEnd][1];
+ points[1][2] = fStartInnerPoints[iEnd][2];
+
+ points[2][0] = fEndInnerPoints[iEnd][0];
+ points[2][1] = fEndInnerPoints[iEnd][1];
+ points[2][2] = fEndInnerPoints[iEnd][2];
+
+ points[3][0] = fEndInnerPoints[iStart][0];
+ points[3][1] = fEndInnerPoints[iStart][1];
+ points[3][2] = fEndInnerPoints[iStart][2];
+
+ Face.CreateFace(points, -4);
+ pSolid->AddFace(&Face);
+ }
+
+ pSolid->InitializeTextureAxes(Options.GetTextureAlignment(), INIT_TEXTURE_ALL | INIT_TEXTURE_FORCE);
+
+ return(pSolid);
+}
+
+
+//-----------------------------------------------------------------------------
+// Make a 2d arc
+//-----------------------------------------------------------------------------
+void MakeArcCenterRadius(float xCenter, float yCenter, float xrad, float yrad, int npoints, float start_ang, float fArc, float points[][2])
+{
+ int point;
+ float angle = start_ang;
+ float angle_delta;
+
+ angle_delta = fArc / (float)npoints;
+
+ // Add an additional points if we are not doing a full circle
+ if (fArc != 360.0)
+ {
+ ++npoints;
+ }
+
+ for( point = 0; point < npoints; point++ )
+ {
+ if ( angle > 360 )
+ {
+ angle -= 360;
+ }
+
+ points[point][0] = V_rint(xCenter + (float)cos(DEG2RAD(angle)) * xrad);
+ points[point][1] = V_rint(yCenter + (float)sin(DEG2RAD(angle)) * yrad);
+
+ angle += angle_delta;
+ }
+
+ // Full circle, recopy the first point as the closing point.
+ if (fArc == 360.0)
+ {
+ points[point][0] = points[0][0];
+ points[point][1] = points[0][1];
+ }
+}
+
+void MakeArc(float x1, float y1, float x2, float y2, int npoints, float start_ang, float fArc, float points[][2])
+{
+ float xrad = (x2 - x1) / 2.0f;
+ float yrad = (y2 - y1) / 2.0f;
+
+ // make centerpoint for polygon:
+ float xCenter = x1 + xrad;
+ float yCenter = y1 + yrad;
+
+ MakeArcCenterRadius( xCenter, yCenter, xrad, yrad, npoints, start_ang, fArc, points );
+}
+
+#define ARC_MAX_POINTS 4096
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pBox -
+// fStartAngle -
+// iSides -
+// fArc -
+// iWallWidth -
+// iAddHeight -
+// bPreview -
+// Output : Returns a group containing the arch solids.
+//-----------------------------------------------------------------------------
+CMapClass *CreateArch(BoundBox *pBox, float fStartAngle, int iSides, float fArc, int iWallWidth, int iAddHeight, BOOL bPreview)
+{
+ float fOuterPoints[ARC_MAX_POINTS][2];
+ float fInnerPoints[ARC_MAX_POINTS][2];
+
+ //
+ // create outer points
+ //
+ MakeArc(pBox->bmins[AXIS_X], pBox->bmins[AXIS_Y],
+ pBox->bmaxs[AXIS_X], pBox->bmaxs[AXIS_Y], iSides,
+ fStartAngle, fArc, fOuterPoints);
+
+ //
+ // create inner points
+ //
+ MakeArc(pBox->bmins[AXIS_X] + iWallWidth,
+ pBox->bmins[AXIS_Y] + iWallWidth,
+ pBox->bmaxs[AXIS_X] - iWallWidth,
+ pBox->bmaxs[AXIS_Y] - iWallWidth, iSides,
+ fStartAngle, fArc, fInnerPoints);
+
+
+ //
+ // check wall width - if it's half or more of the total,
+ // set the inner poinst to the center point of the box
+ // and turn off the CreateSouthFace flag
+ //
+ BOOL bCreateSouthFace = TRUE;
+ Vector Center;
+ pBox->GetBoundsCenter(Center);
+ if((iWallWidth*2+8) >= (pBox->bmaxs[AXIS_X] - pBox->bmins[AXIS_X]) ||
+ (iWallWidth*2+8) >= (pBox->bmaxs[AXIS_Y] - pBox->bmins[AXIS_Y]))
+ {
+ for(int i = 0; i < ARC_MAX_POINTS; i++)
+ {
+ fInnerPoints[i][AXIS_X] = Center[AXIS_X];
+ fInnerPoints[i][AXIS_Y] = Center[AXIS_Y];
+ }
+ bCreateSouthFace = FALSE;
+ }
+
+ // create group for segments
+ CMapGroup *pGroup = new CMapGroup;
+
+ Vector MoveAccum( 0.f, 0.f, 0.f );
+
+ float fMinZ, fMaxZ;
+
+ fMinZ = pBox->bmins[2];
+ fMaxZ = pBox->bmaxs[2];
+
+ if ((fMaxZ - fMinZ) < 1.0f)
+ fMaxZ = fMinZ + 1.0f;
+
+ for (int i = 0; i < iSides; i++)
+ {
+ int iNextPoint = i+1;
+ if (iNextPoint >= iSides + 1)
+ iNextPoint = 0;
+
+ CMapSolid *pSolid = CreateSegment(
+ fMinZ, fMaxZ,
+ fOuterPoints, fInnerPoints,
+ i, iNextPoint, bCreateSouthFace);
+
+ pGroup->AddChild(pSolid);
+
+ if (iAddHeight && i) // don't move first segment
+ {
+ MoveAccum[2] += iAddHeight;
+ pSolid->TransMove(MoveAccum);
+ }
+ }
+
+ pGroup->CalcBounds(TRUE);
+ if (Options.general.bStretchArches)
+ {
+ // make sure size of group's bounds are size of original bounds -
+ // if not, scale up. this can happen when we use rotation.
+ Vector objsize, boundsize;
+ pBox->GetBoundsSize(boundsize);
+ pGroup->GetBoundsSize(objsize);
+
+ if (boundsize[AXIS_X] > objsize[AXIS_X] ||
+ boundsize[AXIS_Y] > objsize[AXIS_Y])
+ {
+ Vector scale;
+ scale[AXIS_X] = boundsize[AXIS_X] / objsize[AXIS_X];
+ scale[AXIS_Y] = boundsize[AXIS_Y] / objsize[AXIS_Y];
+ scale[AXIS_Z] = 1.0f; // xxxYWB scaling by 0 causes veneers, so I changed to 1.0
+ Vector center;
+ pBox->GetBoundsCenter(center);
+ pGroup->TransScale(center, scale);
+ }
+ }
+
+ return pGroup;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pBox -
+// fStartAngle -
+// iSides -
+// fArc -
+// iWallWidth -
+// iAddHeight -
+// bPreview -
+// Output : Returns a group containing the arch solids.
+//-----------------------------------------------------------------------------
+typedef float TorusPointList_t[ARC_MAX_POINTS][3];
+
+CMapClass *CreateTorus(BoundBox *pBox, float fStartAngle, int iSides, float fArc, int iWallWidth, float flCrossSectionalRadius,
+ float fRotationStartAngle, int iRotationSides, float fRotationArc, int iAddHeight, BOOL bPreview)
+{
+ float xCenter = (pBox->bmaxs[AXIS_X] + pBox->bmins[AXIS_X]) * 0.5f;
+ float yCenter = (pBox->bmaxs[AXIS_Y] + pBox->bmins[AXIS_Y]) * 0.5f;
+ float xRad = (pBox->bmaxs[AXIS_X] - xCenter);
+ float yRad = (pBox->bmaxs[AXIS_Y] - yCenter);
+ if (xRad < 0.0f )
+ {
+ xRad = 0.0f;
+ }
+
+ if (yRad < 0.0f )
+ {
+ yRad = 0.0f;
+ }
+
+ if ( flCrossSectionalRadius > (xRad * 0.5f) )
+ {
+ flCrossSectionalRadius = (xRad * 0.5f);
+ }
+ if ( flCrossSectionalRadius > (yRad * 0.5f) )
+ {
+ flCrossSectionalRadius = (yRad * 0.5f);
+ }
+
+ if ( iWallWidth < flCrossSectionalRadius )
+ {
+ flCrossSectionalRadius -= iWallWidth;
+ }
+ else
+ {
+ iWallWidth = flCrossSectionalRadius;
+ flCrossSectionalRadius = 0.0f;
+ }
+
+ float flCrossSectionHalfWidth = flCrossSectionalRadius + iWallWidth;
+ xRad -= flCrossSectionHalfWidth;
+ yRad -= flCrossSectionHalfWidth;
+
+ float fOuterPoints[ARC_MAX_POINTS][2];
+ float fInnerPoints[ARC_MAX_POINTS][2];
+
+ // create outer points (unrotated)
+ MakeArcCenterRadius(0.0f, 0.0f,
+ flCrossSectionalRadius + iWallWidth, flCrossSectionalRadius + iWallWidth,
+ iSides, fStartAngle, fArc, fOuterPoints);
+
+ BOOL bCreateSouthFace = TRUE;
+ if ( flCrossSectionalRadius != 0.0f )
+ {
+ // create inner points (unrotated)
+ MakeArcCenterRadius(0.0f, 0.0f, flCrossSectionalRadius, flCrossSectionalRadius,
+ iSides, fStartAngle, fArc, fInnerPoints);
+ }
+ else
+ {
+ for( int i = 0; i < iSides; i++)
+ {
+ fInnerPoints[i][0] = fInnerPoints[i][1] = 0.0f;
+ }
+ bCreateSouthFace = FALSE;
+ }
+
+ // create group for segments
+ CMapGroup *pGroup = new CMapGroup;
+
+ TorusPointList_t innerPoints[2];
+ TorusPointList_t outerPoints[2];
+ TorusPointList_t *pStartInnerPoints;
+ TorusPointList_t *pStartOuterPoints;
+ TorusPointList_t *pEndInnerPoints = &innerPoints[1];
+ TorusPointList_t *pEndOuterPoints = &outerPoints[1];
+ int nCurrIndex = 0;
+
+ float flCurrentZ = pBox->bmins[AXIS_Z] + iWallWidth + flCrossSectionalRadius;
+ float flDeltaZ = (float)iAddHeight / (float)(iRotationSides);
+
+ float flRotationAngle = fRotationStartAngle;
+ float flRotationDeltaAngle = fRotationArc / iRotationSides;
+
+ bool bIsCircle = ( iAddHeight == 0.0f ) && ( fRotationArc == 360.0f );
+ ++iRotationSides;
+ for ( int i = 0; i != iRotationSides; ++i )
+ {
+ // This eliminates a seam in circular toruses
+ if ( bIsCircle && (i == iRotationSides - 1) )
+ {
+ flRotationAngle = fRotationStartAngle;
+ }
+
+ float xCurrCenter, yCurrCenter;
+
+ float flCosAngle = cos( DEG2RAD(flRotationAngle) );
+ float flSinAngle = sin( DEG2RAD(flRotationAngle) );
+ xCurrCenter = xCenter + xRad * flCosAngle;
+ yCurrCenter = yCenter + yRad * flSinAngle;
+
+ // Update buffers
+ pStartInnerPoints = pEndInnerPoints;
+ pStartOuterPoints = pEndOuterPoints;
+ pEndInnerPoints = &innerPoints[nCurrIndex];
+ pEndOuterPoints = &outerPoints[nCurrIndex];
+ nCurrIndex = 1 - nCurrIndex;
+
+ // Transform points into actual space.
+ int jPrevPoint = -1;
+ int j = 0;
+ do
+ {
+ // x original is transformed into x/y based on rotation
+ // y original is transformed into z
+ (*pEndInnerPoints)[j][0] = xCurrCenter + fInnerPoints[j][0] * flCosAngle;
+ (*pEndInnerPoints)[j][1] = yCurrCenter + fInnerPoints[j][0] * flSinAngle;
+ (*pEndInnerPoints)[j][2] = flCurrentZ + fInnerPoints[j][1];
+
+ (*pEndOuterPoints)[j][0] = xCurrCenter + fOuterPoints[j][0] * flCosAngle;
+ (*pEndOuterPoints)[j][1] = yCurrCenter + fOuterPoints[j][0] * flSinAngle;
+ (*pEndOuterPoints)[j][2] = flCurrentZ + fOuterPoints[j][1];
+
+ // We'll use the j == 0 data when iNextPoint = iSides - 1
+ if (( i != 0 ) && ( jPrevPoint != -1 ))
+ {
+ CMapSolid *pSolid = CreateSegment(
+ *pStartOuterPoints, *pStartInnerPoints,
+ *pEndOuterPoints, *pEndInnerPoints,
+ jPrevPoint, j, bCreateSouthFace);
+
+ pGroup->AddChild(pSolid);
+ }
+
+ jPrevPoint = j;
+ ++j;
+ } while( jPrevPoint != iSides );
+
+ flRotationAngle += flRotationDeltaAngle;
+ flCurrentZ += flDeltaZ;
+
+ if ( flRotationAngle >= 360.0f )
+ {
+ flRotationAngle -= 360.0f;
+ }
+ }
+
+ pGroup->CalcBounds(TRUE);
+
+ if (Options.general.bStretchArches)
+ {
+ // make sure size of group's bounds are size of original bounds -
+ // if not, scale up. this can happen when we use rotation.
+ Vector objsize, boundsize;
+ pBox->GetBoundsSize(boundsize);
+ pGroup->GetBoundsSize(objsize);
+
+ if (boundsize[AXIS_X] > objsize[AXIS_X] ||
+ boundsize[AXIS_Y] > objsize[AXIS_Y])
+ {
+ Vector scale;
+ scale[AXIS_X] = boundsize[AXIS_X] / objsize[AXIS_X];
+ scale[AXIS_Y] = boundsize[AXIS_Y] / objsize[AXIS_Y];
+ scale[AXIS_Z] = 1.0f; // xxxYWB scaling by 0 causes veneers, so I changed to 1.0
+ Vector center;
+ pBox->GetBoundsCenter(center);
+ pGroup->TransScale(center, scale);
+ }
+ }
+
+ return pGroup;
+}
+
+