diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/stocksolids.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'hammer/stocksolids.cpp')
| -rw-r--r-- | hammer/stocksolids.cpp | 688 |
1 files changed, 688 insertions, 0 deletions
diff --git a/hammer/stocksolids.cpp b/hammer/stocksolids.cpp new file mode 100644 index 0000000..52e8355 --- /dev/null +++ b/hammer/stocksolids.cpp @@ -0,0 +1,688 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "stdafx.h" +#include "hammer.h" +#include "StockSolids.h" +#include "hammer_mathlib.h" +#include "MapSolid.h" + + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + + +#pragma warning(disable:4244) + +//Vector pmPoints[64]; + +StockSolid::StockSolid(int nFields) +{ + AllocateDataFields(nFields); + cofs.Init(); +} + + +StockSolid::~StockSolid() +{ + if ( pFields ) + { + delete[] pFields; + pFields = NULL; + } +} + + +void StockSolid::AllocateDataFields(int nFields_) +{ + pFields = new STSDATAFIELD[nFields_]; + Assert(pFields); + iMaxFields = nFields_; + this->nFields = 0; // none yet +} + + +void StockSolid::Serialize(std::fstream& file, BOOL bIsStoring) +{ +} + + +int StockSolid::GetFieldCount() const +{ + return nFields; +} + + +void StockSolid::SetFieldData(int iIndex, int iData) +{ + Assert(iIndex < nFields); + + STSDATAFIELD& field = pFields[iIndex]; + field.iValue = iData; + + if(field.flags & DFFLAG_RANGED) + { + Assert(!(iData < field.iRangeLower || iData > field.iRangeUpper)); + } +} + + +int StockSolid::GetFieldData(int iIndex, int *piData) const +{ + Assert(iIndex < nFields); + + STSDATAFIELD& field = pFields[iIndex]; + + if(piData) + piData[0] = field.iValue; + + return field.iValue; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void StockSolid::SetOrigin(const Vector &o) +{ + origin = o; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void StockSolid::SetCenterOffset(const Vector &ofs) +{ + cofs = ofs; +} + + +void StockSolid::AddDataField(STSDF_TYPE type, const char *pszName, int iRangeLower, int iRangeUpper) +{ + Assert(nFields < iMaxFields); + + STSDATAFIELD& field = pFields[nFields++]; + + field.type = type; + field.flags = 0; + strcpy(field.szName, pszName); + + if(iRangeLower != -1) + { + field.flags |= DFFLAG_RANGED; + field.iRangeLower = iRangeLower; + field.iRangeUpper = iRangeUpper; + } +} + + +// ---------------------------------------------------------------------------- +// StockBlock() +// ---------------------------------------------------------------------------- +StockBlock::StockBlock() : + StockSolid(3) +{ + AddDataField(DFTYPE_INTEGER, "Width (X)"); + AddDataField(DFTYPE_INTEGER, "Depth (Y)"); + AddDataField(DFTYPE_INTEGER, "Height (Z)"); +} + + +void StockBlock::SetFromBox(BoundBox *pBox) +{ + // round floats before converting to integers + SetFieldData(fieldWidth, (pBox->bmaxs[0] - pBox->bmins[0])+0.5f ); + SetFieldData(fieldDepth, (pBox->bmaxs[1] - pBox->bmins[1])+0.5f ); + SetFieldData(fieldHeight, (pBox->bmaxs[2] - pBox->bmins[2])+0.5f ); + + Vector o; + pBox->GetBoundsCenter(o); + + SetOrigin(o); +} + + +void StockBlock::CreateMapSolid(CMapSolid *pSolid, TextureAlignment_t eAlignment) +{ + CMapFace Face; + + float fDepth = float(GetFieldData(fieldDepth))/2; + float fWidth = float(GetFieldData(fieldWidth))/2; + float fHeight = float(GetFieldData(fieldHeight))/2; + + // create box + Vector bmins, bmaxs; + bmins[0] = origin[0] - fWidth + cofs[0]; + bmins[1] = origin[1] - fDepth + cofs[1]; + bmins[2] = origin[2] - fHeight + cofs[2]; + + bmaxs[0] = origin[0] + fWidth + cofs[0]; + bmaxs[1] = origin[1] + fDepth + cofs[1]; + bmaxs[2] = origin[2] + fHeight + cofs[2]; + + Vector Points[4]; + + // x planes - top first + Points[0][0] = bmins[0]; + Points[0][1] = bmaxs[1]; + Points[0][2] = bmaxs[2]; + + Points[1][0] = bmaxs[0]; + Points[1][1] = bmaxs[1]; + Points[1][2] = bmaxs[2]; + + Points[2][0] = bmaxs[0]; + Points[2][1] = bmins[1]; + Points[2][2] = bmaxs[2]; + + Points[3][0] = bmins[0]; + Points[3][1] = bmins[1]; + Points[3][2] = bmaxs[2]; + + Face.CreateFace(Points, 4, pSolid->IsCordonBrush()); + pSolid->AddFace(&Face); + + // top - modify heights + for(int i = 0; i < 4; i++) + { + Points[i][2] = bmins[2]; + } + + Face.CreateFace(Points, -4, pSolid->IsCordonBrush()); + pSolid->AddFace(&Face); + + // y planes - left + Points[0][0] = bmins[0]; + Points[0][1] = bmaxs[1]; + Points[0][2] = bmaxs[2]; + + Points[1][0] = bmins[0]; + Points[1][1] = bmins[1]; + Points[1][2] = bmaxs[2]; + + Points[2][0] = bmins[0]; + Points[2][1] = bmins[1]; + Points[2][2] = bmins[2]; + + Points[3][0] = bmins[0]; + Points[3][1] = bmaxs[1]; + Points[3][2] = bmins[2]; + + Face.CreateFace(Points, 4, pSolid->IsCordonBrush()); + pSolid->AddFace(&Face); + + // right - modify xloc + for(int i = 0; i < 4; i++) + { + Points[i][0] = bmaxs[0]; + } + + Face.CreateFace(Points, -4, pSolid->IsCordonBrush()); + pSolid->AddFace(&Face); + + // x planes - farthest + Points[0][0] = bmaxs[0]; + Points[0][1] = bmaxs[1]; + Points[0][2] = bmaxs[2]; + + Points[1][0] = bmins[0]; + Points[1][1] = bmaxs[1]; + Points[1][2] = bmaxs[2]; + + Points[2][0] = bmins[0]; + Points[2][1] = bmaxs[1]; + Points[2][2] = bmins[2]; + + Points[3][0] = bmaxs[0]; + Points[3][1] = bmaxs[1]; + Points[3][2] = bmins[2]; + + Face.CreateFace(Points, 4, pSolid->IsCordonBrush()); + pSolid->AddFace(&Face); + + // nearest - modify yloc + for(int i = 0; i < 4; i++) + { + Points[i][1] = bmins[1]; + } + + Face.CreateFace(Points, -4, pSolid->IsCordonBrush()); + pSolid->AddFace(&Face); + + pSolid->CalcBounds(); + pSolid->InitializeTextureAxes(eAlignment, INIT_TEXTURE_ALL | INIT_TEXTURE_FORCE); +} + + +// ---------------------------------------------------------------------------- +// StockWedge() +// ---------------------------------------------------------------------------- +StockWedge::StockWedge() : + StockSolid(3) +{ + AddDataField(DFTYPE_INTEGER, "Width (X)"); + AddDataField(DFTYPE_INTEGER, "Depth (Y)"); + AddDataField(DFTYPE_INTEGER, "Height (Z)"); +} + + +void StockWedge::SetFromBox(BoundBox *pBox) +{ + SetFieldData(fieldWidth, pBox->bmaxs[0] - pBox->bmins[0]); + SetFieldData(fieldDepth, pBox->bmaxs[1] - pBox->bmins[1]); + SetFieldData(fieldHeight, pBox->bmaxs[2] - pBox->bmins[2]); + + Vector o; + pBox->GetBoundsCenter(o); + + SetOrigin(o); +} + + +void StockWedge::CreateMapSolid(CMapSolid *pSolid, TextureAlignment_t eTextureAlignment) +{ + CMapFace Face; + + float fDepth = float(GetFieldData(fieldDepth))/2; + float fWidth = float(GetFieldData(fieldWidth))/2; + float fHeight = float(GetFieldData(fieldHeight))/2; + + Vector Points[4]; + + // x planes - top + Points[0][0] = origin[0] + fWidth; + Points[0][1] = origin[1] + fDepth; + Points[0][2] = origin[2] + fHeight; + + Points[1][0] = origin[0] + fWidth; + Points[1][1] = origin[1] - fDepth; + Points[1][2] = origin[2] + fHeight; + + Points[2][0] = origin[0] - fWidth; + Points[2][1] = origin[1] - fDepth; + Points[2][2] = origin[2] + fHeight; + + Face.CreateFace(Points, 3); + pSolid->AddFace(&Face); + + // bottom + for (int i = 0; i < 3; i++) + { + Points[i][2] = origin[2] - fHeight; + } + + Face.CreateFace(Points, -3); + pSolid->AddFace(&Face); + + // left (slant) + Points[0][0] = origin[0] + fWidth; + Points[0][1] = origin[1] + fDepth; + Points[0][2] = origin[2] - fHeight; + + Points[1][0] = origin[0] + fWidth; + Points[1][1] = origin[1] + fDepth; + Points[1][2] = origin[2] + fHeight; + + Points[2][0] = origin[0] - fWidth; + Points[2][1] = origin[1] - fDepth; + Points[2][2] = origin[2] + fHeight; + + Points[3][0] = origin[0] - fWidth; + Points[3][1] = origin[1] - fDepth; + Points[3][2] = origin[2] - fHeight; + + Face.CreateFace(Points, 4); + pSolid->AddFace(&Face); + + // south + Points[0][0] = origin[0] + fWidth; + Points[0][1] = origin[1] - fDepth; + Points[0][2] = origin[2] + fHeight; + + Points[1][0] = origin[0] + fWidth; + Points[1][1] = origin[1] - fDepth; + Points[1][2] = origin[2] - fHeight; + + Points[2][0] = origin[0] - fWidth; + Points[2][1] = origin[1] - fDepth; + Points[2][2] = origin[2] - fHeight; + + Points[3][0] = origin[0] - fWidth; + Points[3][1] = origin[1] - fDepth; + Points[3][2] = origin[2] + fHeight; + + Face.CreateFace(Points, 4); + pSolid->AddFace(&Face); + + // right + Points[0][0] = origin[0] + fWidth; + Points[0][1] = origin[1] + fDepth; + Points[0][2] = origin[2] + fHeight; + + Points[1][0] = origin[0] + fWidth; + Points[1][1] = origin[1] + fDepth; + Points[1][2] = origin[2] - fHeight; + + Points[2][0] = origin[0] + fWidth; + Points[2][1] = origin[1] - fDepth; + Points[2][2] = origin[2] - fHeight; + + Points[3][0] = origin[0] + fWidth; + Points[3][1] = origin[1] - fDepth; + Points[3][2] = origin[2] + fHeight; + + Face.CreateFace(Points, 4); + pSolid->AddFace(&Face); + + pSolid->CalcBounds(); + pSolid->InitializeTextureAxes(eTextureAlignment, INIT_TEXTURE_ALL | INIT_TEXTURE_FORCE); +} + + +// ---------------------------------------------------------------------------- +// StockCylinder() +// ---------------------------------------------------------------------------- +StockCylinder::StockCylinder() + : StockSolid(4) +{ + AddDataField(DFTYPE_INTEGER, "Width (X)"); + AddDataField(DFTYPE_INTEGER, "Depth (Y)"); + AddDataField(DFTYPE_INTEGER, "Height (Z)"); + AddDataField(DFTYPE_INTEGER, "Number of Sides"); + + SetFieldData(fieldSideCount, 8); +} + + +void StockCylinder::SetFromBox(BoundBox *pBox) +{ + SetFieldData(fieldWidth, pBox->bmaxs[0] - pBox->bmins[0]); + SetFieldData(fieldDepth, pBox->bmaxs[1] - pBox->bmins[1]); + SetFieldData(fieldHeight, pBox->bmaxs[2] - pBox->bmins[2]); + + Vector o; + pBox->GetBoundsCenter(o); + + SetOrigin(o); +} + + +void StockCylinder::CreateMapSolid(CMapSolid *pSolid, TextureAlignment_t eTextureAlignment) +{ + CMapFace Face; + + float fDepth = float(GetFieldData(fieldDepth))/2; + float fWidth = float(GetFieldData(fieldWidth))/2; + float fHeight = float(GetFieldData(fieldHeight))/2; + int nSides = GetFieldData(fieldSideCount); + + Vector pmPoints[64]; + polyMake(origin[0] - fWidth, origin[1] - fDepth, origin[0] + fWidth, origin[1] + fDepth, nSides, 0, pmPoints ); + + // face 0 - top face + for(int i = 0; i < nSides+1; i++) + { + pmPoints[i][2] = origin[2] - fHeight; + } + + Face.CreateFace( pmPoints, -nSides); + pSolid->AddFace(&Face); + + // bottom face + for(int i = 0; i < nSides+1; i++) + { + pmPoints[i][2] = origin[2] + fHeight; + } + + Face.CreateFace( pmPoints, nSides); + pSolid->AddFace(&Face); + + // other sides + Vector Points[4]; + + for(int i = 0; i < nSides; i++) + { + Points[0][0] = pmPoints[i][0]; + Points[0][1] = pmPoints[i][1]; + Points[0][2] = origin[2] - fHeight; + + Points[1][0] = pmPoints[i+1][0]; + Points[1][1] = pmPoints[i+1][1]; + Points[1][2] = origin[2] - fHeight; + + Points[2][0] = pmPoints[i+1][0]; + Points[2][1] = pmPoints[i+1][1]; + Points[2][2] = origin[2] + fHeight; + + Points[3][0] = pmPoints[i][0]; + Points[3][1] = pmPoints[i][1]; + Points[3][2] = origin[2] + fHeight; + + Face.CreateFace(Points, 4); + Face.texture.smooth = 1.f; + pSolid->AddFace(&Face); + } + + pSolid->CalcBounds(); + pSolid->InitializeTextureAxes(eTextureAlignment, INIT_TEXTURE_ALL | INIT_TEXTURE_FORCE); +} + + +// ---------------------------------------------------------------------------- +// StockSpike() +// ---------------------------------------------------------------------------- +StockSpike::StockSpike() + : StockSolid(4) +{ + AddDataField(DFTYPE_INTEGER, "Width (X)"); + AddDataField(DFTYPE_INTEGER, "Depth (Y)"); + AddDataField(DFTYPE_INTEGER, "Height (Z)"); + AddDataField(DFTYPE_INTEGER, "Number of Sides"); + + SetFieldData(fieldSideCount, 8); +} + + +void StockSpike::SetFromBox(BoundBox *pBox) +{ + SetFieldData(fieldWidth, pBox->bmaxs[0] - pBox->bmins[0]); + SetFieldData(fieldDepth, pBox->bmaxs[1] - pBox->bmins[1]); + SetFieldData(fieldHeight, pBox->bmaxs[2] - pBox->bmins[2]); + + Vector o; + pBox->GetBoundsCenter(o); + + SetOrigin(o); +} + + +void StockSpike::CreateMapSolid(CMapSolid *pSolid, TextureAlignment_t eTextureAlignment) +{ + float fDepth = float(GetFieldData(fieldDepth))/2; + float fWidth = float(GetFieldData(fieldWidth))/2; + float fHeight = float(GetFieldData(fieldHeight))/2; + int nSides = GetFieldData(fieldSideCount); + CMapFace NewFace; + + // create bottom poly + Vector pmPoints[64]; + polyMake(origin[0] - fWidth, origin[1] - fDepth, origin[0] + fWidth, origin[1] + fDepth, nSides, 0, pmPoints); + + // bottom face + for(int i = 0; i < nSides+1; i++) + { + // YWB rounding??? + pmPoints[i][2] = V_rint(origin[2] - fHeight); + } + + NewFace.CreateFace(pmPoints, -nSides); + pSolid->AddFace(&NewFace); + + // other sides + Vector Points[3]; + + // get centerpoint + Points[0][0] = origin[0]; + Points[0][1] = origin[1]; + // YWB rounding??? + Points[0][2] = V_rint(origin[2] + fHeight); + + for(int i = 0; i < nSides; i++) + { + Points[1][0] = pmPoints[i][0]; + Points[1][1] = pmPoints[i][1]; + Points[1][2] = pmPoints[i][2]; + + Points[2][0] = pmPoints[i+1][0]; + Points[2][1] = pmPoints[i+1][1]; + Points[2][2] = pmPoints[i+1][2]; + + NewFace.CreateFace(Points, 3); + pSolid->AddFace(&NewFace); + } + + pSolid->CalcBounds(); + pSolid->InitializeTextureAxes(eTextureAlignment, INIT_TEXTURE_ALL | INIT_TEXTURE_FORCE); +} + + +StockSphere::StockSphere() + : StockSolid(4) +{ + AddDataField(DFTYPE_INTEGER, "Width (X)"); + AddDataField(DFTYPE_INTEGER, "Depth (Y)"); + AddDataField(DFTYPE_INTEGER, "Height (Z)"); + AddDataField(DFTYPE_INTEGER, "Subdivisions"); + + SetFieldData(fieldSideCount, 8); +} + + +void StockSphere::SetFromBox(BoundBox *pBox) +{ + SetFieldData(fieldWidth, pBox->bmaxs[0] - pBox->bmins[0]); + SetFieldData(fieldDepth, pBox->bmaxs[1] - pBox->bmins[1]); + SetFieldData(fieldHeight, pBox->bmaxs[2] - pBox->bmins[2]); + + Vector o; + pBox->GetBoundsCenter(o); + + SetOrigin(o); +} + + +//----------------------------------------------------------------------------- +// Purpose: Builds a tesselated sphere. +// Input : pSolid - Pointer to a solid that will become a sphere. +//----------------------------------------------------------------------------- +void StockSphere::CreateMapSolid(CMapSolid *pSolid, TextureAlignment_t eTextureAlignment) +{ + CMapFace Face; + + float fDepth = (float)GetFieldData(fieldDepth) / 2; + float fWidth = (float)GetFieldData(fieldWidth) / 2; + float fHeight = (float)GetFieldData(fieldHeight) / 2; + int nSides = GetFieldData(fieldSideCount); + + float fAngle = 0; + float fAngleStep = 180.0 / nSides; + + // + // Build the sphere by building slices at constant angular intervals. + // + // Each slice is a ring of four-sided faces, except for the top and bottom slices, + // which are flattened cones. + // + // Unrolled, a sphere made with 5 'sides' has 25 faces and looks like this: + // + // /\ /\ /\ /\ /\ + // / 0\/ 1\/ 2\/ 3\/ 4\ + // | 5| 6| 7| 8| 9| + // | 10| 11| 12| 13| 14| + // | 15| 16| 17| 18| 19| + // \20/\21/\22/\23/\24/ + // \/ \/ \/ \/ \/ + // + for (int nSlice = 0; nSlice < nSides; nSlice++) + { + float fAngle1 = fAngle + fAngleStep; + + // + // Make the upper polygon. + // + Vector TopPoints[64]; + float fUpperWidth = fWidth * sin(DEG2RAD(fAngle)); + float fUpperDepth = fDepth * sin(DEG2RAD(fAngle)); + polyMake(origin[0] - fUpperWidth, origin[1] - fUpperDepth, origin[0] + fUpperWidth, origin[1] + fUpperDepth, nSides, 0, TopPoints); + + // + // Make the lower polygon. + // + Vector BottomPoints[64]; + float fLowerWidth = fWidth * sin(DEG2RAD(fAngle1)); + float fLowerDepth = fDepth * sin(DEG2RAD(fAngle1)); + polyMake(origin[0] - fLowerWidth, origin[1] - fLowerDepth, origin[0] + fLowerWidth, origin[1] + fLowerDepth, nSides, 0, BottomPoints); + + // + // Build the faces that connect the upper and lower polygons. + // + Vector Points[4]; + float fUpperHeight = origin[2] + fHeight * cos(DEG2RAD(fAngle)); + float fLowerHeight = origin[2] + fHeight * cos(DEG2RAD(fAngle1)); + + for (int i = 0; i < nSides; i++) + { + if (nSlice != 0) + { + Points[0][0] = TopPoints[i + 1][0]; + Points[0][1] = TopPoints[i + 1][1]; + Points[0][2] = fUpperHeight; + } + + Points[1][0] = TopPoints[i][0]; + Points[1][1] = TopPoints[i][1]; + Points[1][2] = fUpperHeight; + + Points[2][0] = BottomPoints[i][0]; + Points[2][1] = BottomPoints[i][1]; + Points[2][2] = fLowerHeight; + + if (nSlice != nSides - 1) + { + Points[3][0] = BottomPoints[i + 1][0]; + Points[3][1] = BottomPoints[i + 1][1]; + Points[3][2] = fLowerHeight; + } + + // + // Top and bottom are cones, not rings, so remove one vertex per face. + // + if (nSlice == 0) + { + Face.CreateFace(&Points[1], 3); + } + else if (nSlice == nSides - 1) + { + Face.CreateFace(Points, 3); + } + else + { + Face.CreateFace(Points, 4); + } + + Face.texture.smooth = 1.f; + pSolid->AddFace(&Face); + } + + fAngle += fAngleStep; + } + + pSolid->CalcBounds(); + pSolid->InitializeTextureAxes(eTextureAlignment, INIT_TEXTURE_ALL | INIT_TEXTURE_FORCE); +} + + |