-/*\r
-BobToolz plugin for GtkRadiant\r
-Copyright (C) 2001 Gordon Biggans\r
-\r
-This library is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU Lesser General Public\r
-License as published by the Free Software Foundation; either\r
-version 2.1 of the License, or (at your option) any later version.\r
-\r
-This library is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
-Lesser General Public License for more details.\r
-\r
-You should have received a copy of the GNU Lesser General Public\r
-License along with this library; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-*/\r
-\r
-\r
-#include "StdAfx.h"\r
-\r
-#include "shapes.h"\r
-\r
-#include "DPlane.h"\r
-\r
-#include "misc.h"\r
-#include "funchandlers.h"\r
-\r
-//#include "dialogs-gtk.h"\r
-\r
-/************************\r
- Cube Diagram\r
-************************/\r
-\r
-/*\r
-\r
- 7 ----- 5\r
- /| /|\r
- / | / |\r
- / | / |\r
- 4 ----- 6 |\r
- | 2|_|___|8\r
- | / | /\r
- | / | / ----> WEST, definitely\r
- |/ | /\r
- 1|_____|/3\r
-\r
-*/\r
-\r
-/************************\r
- Global Variables\r
-************************/\r
-\r
-vec3_t g_Origin = {0.0f, 0.0f, 0.0f};\r
-\r
-extern bool bFacesAll[];\r
-\r
-/************************\r
- Helper Functions\r
-************************/\r
-\r
-float Deg2Rad(float angle)\r
-{\r
- return (float)(angle*Q_PI/180);\r
-}\r
-\r
-void AddFaceWithTexture(brush_t* brush, vec3_t va, vec3_t vb, vec3_t vc, const char* texture, bool detail)\r
-{\r
- _QERFaceData faceData;\r
- FillDefaultTexture(&faceData, va, vb, vc, texture);\r
- if(detail)\r
- faceData.m_nContents |= FACE_DETAIL;\r
- \r
- g_FuncTable.m_pfnAddFaceData(brush, &faceData);\r
-}\r
-\r
-void AddFaceWithTextureScaled(brush_t* brush, vec3_t va, vec3_t vb, vec3_t vc, \r
- const char* texture, bool bVertScale, bool bHorScale, \r
- float minX, float minY, float maxX, float maxY)\r
-{\r
- g_ShadersTable.m_pfnShader_ForName(texture); // need to call frist to load?\r
-\r
- qtexture_t* pqtTexInfo;\r
-\r
- // TTimo: there used to be a call to pfnHasShader here\r
- // this was not necessary. In Radiant everything is shader.\r
- // If a texture doesn't have a shader script, a default shader object is used.\r
- // The IShader object was leaking also\r
- // collect texture info: sizes, etc\r
- IShader* i = g_ShadersTable.m_pfnShader_ForName(texture);\r
- pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly\r
-\r
- if(pqtTexInfo)\r
- {\r
- float scale[2] = {0.5f, 0.5f};\r
- float shift[2] = {0, 0};\r
-\r
- if(bHorScale)\r
- {\r
- int texWidth = pqtTexInfo->width;\r
- float width = maxX - minX;\r
-\r
- scale[0] = width/texWidth;\r
- shift[0] = -(float)((int)maxX%(int)width)/scale[0];\r
- }\r
-\r
- if(bVertScale)\r
- {\r
- int texHeight = pqtTexInfo->height;\r
- float height = maxY - minY;\r
-\r
- scale[1] = height/texHeight;\r
- shift[1] = (float)((int)minY%(int)height)/scale[1];\r
- }\r
-\r
- _QERFaceData addFace;\r
- FillDefaultTexture(&addFace, va, vb, vc, texture);\r
- addFace.m_fScale[0] = scale[0];\r
- addFace.m_fScale[1] = scale[1];\r
- addFace.m_fShift[0] = shift[0];\r
- addFace.m_fShift[1] = shift[1];\r
-\r
- g_FuncTable.m_pfnAddFaceData(brush, &addFace);\r
- }\r
- else\r
- {\r
- // shouldn't even get here, as default missing texture should be returned if\r
- // texture doesn't exist, but just in case\r
- AddFaceWithTexture(brush, va, vb, vc, texture, FALSE);\r
- Sys_ERROR("BobToolz::Invalid Texture Name-> %s", texture);\r
- }\r
- // the IShader is not kept referenced, DecRef it\r
- i->DecRef();\r
-}\r
-\r
-/************************\r
- --Main Functions--\r
-************************/\r
-\r
-void Build_Wedge(int dir, vec3_t min, vec3_t max, bool bUp)\r
-{\r
- brush_t* newBrush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();\r
-\r
- vec3_t v1, v2, v3, v5, v6, v7, v8;\r
- VectorCopy(min, v1);\r
- VectorCopy(min, v2);\r
- VectorCopy(min, v3);\r
- VectorCopy(max, v5);\r
- VectorCopy(max, v6);\r
- VectorCopy(max, v7);\r
- VectorCopy(max, v8);\r
-\r
- v2[0] = max[0];\r
- v3[1] = max[1];\r
-\r
- v6[0] = min[0];\r
- v7[1] = min[1];\r
- v8[2] = min[2];\r
-\r
- if(bUp)\r
- {\r
-\r
- if(dir != MOVE_EAST)\r
- AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", FALSE);\r
-\r
- if(dir != MOVE_WEST)\r
- AddFaceWithTexture(newBrush, v7, v5, v8, "textures/common/caulk", FALSE);\r
-\r
- if(dir != MOVE_NORTH)\r
- AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", FALSE);\r
-\r
- if(dir != MOVE_SOUTH)\r
- AddFaceWithTexture(newBrush, v3, v8, v6, "textures/common/caulk", FALSE);\r
-\r
- AddFaceWithTexture(newBrush, v1, v2, v3, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_EAST)\r
- AddFaceWithTexture(newBrush, v1, v3, v5, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_WEST)\r
- AddFaceWithTexture(newBrush, v2, v6, v8, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_NORTH)\r
- AddFaceWithTexture(newBrush, v1, v6, v5, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_SOUTH)\r
- AddFaceWithTexture(newBrush, v7, v3, v8, "textures/common/caulk", FALSE);\r
- }\r
- else\r
- {\r
- if(dir != MOVE_WEST)\r
- AddFaceWithTexture(newBrush, v7, v5, v8, "textures/common/caulk", FALSE);\r
-\r
- if(dir != MOVE_EAST)\r
- AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", FALSE);\r
-\r
- if(dir != MOVE_NORTH)\r
- AddFaceWithTexture(newBrush, v3, v8, v6, "textures/common/caulk", FALSE);\r
-\r
- if(dir != MOVE_SOUTH)\r
- AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", FALSE);\r
-\r
- \r
- AddFaceWithTexture(newBrush, v6, v5, v7, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_WEST)\r
- AddFaceWithTexture(newBrush, v1, v5, v3, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_EAST)\r
- AddFaceWithTexture(newBrush, v2, v8, v6, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_NORTH)\r
- AddFaceWithTexture(newBrush, v1, v5, v6, "textures/common/caulk", FALSE);\r
-\r
- if(dir == MOVE_SOUTH)\r
- AddFaceWithTexture(newBrush, v7, v8, v3, "textures/common/caulk", FALSE);\r
- }\r
-\r
- g_FuncTable.m_pfnCommitBrushHandle(newBrush);\r
-}\r
-\r
-//-----------------------------------------------------------------------------------\r
-//-----------------------------------------------------------------------------------\r
-\r
-void Build_StairStep_Wedge(int dir, vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, bool detail)\r
-{\r
- brush_t* newBrush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();\r
-\r
- //----- Build Outer Bounds ---------\r
-\r
- vec3_t v1, v2, v3, v5, v6, v7, v8;\r
- VectorCopy(min, v1);\r
- VectorCopy(min, v2);\r
- VectorCopy(min, v3);\r
- VectorCopy(max, v5);\r
- VectorCopy(max, v6);\r
- VectorCopy(max, v7);\r
- VectorCopy(max, v8);\r
-\r
- v2[0] = max[0];\r
- v3[1] = max[1];\r
-\r
- v6[0] = min[0];\r
- v7[1] = min[1];\r
-\r
- v8[2] = min[2];\r
- //v8 needed this time, becoz of sloping faces (2-4-6-8)\r
-\r
- //----------------------------------\r
-\r
- AddFaceWithTexture(newBrush, v6, v5, v7, mainTexture, detail);\r
-\r
- if(dir != MOVE_EAST)\r
- {\r
- if(dir == MOVE_WEST)\r
- AddFaceWithTexture(newBrush, v5, v2, v7, riserTexture, detail);\r
- else\r
- AddFaceWithTexture(newBrush, v5, v2, v7, "textures/common/caulk", detail);\r
- }\r
-\r
- if(dir != MOVE_WEST)\r
- {\r
- if(dir == MOVE_EAST)\r
- AddFaceWithTexture(newBrush, v1, v3, v6, riserTexture, detail);\r
- else\r
- AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", detail);\r
- }\r
-\r
- if(dir != MOVE_NORTH)\r
- {\r
- if(dir == MOVE_SOUTH)\r
- AddFaceWithTexture(newBrush, v3, v5, v6, riserTexture, detail);\r
- else\r
- AddFaceWithTexture(newBrush, v3, v5, v6, "textures/common/caulk", detail);\r
- }\r
-\r
- if(dir != MOVE_SOUTH)\r
- {\r
- if(dir == MOVE_NORTH)\r
- AddFaceWithTexture(newBrush, v1, v7, v2, riserTexture, detail);\r
- else\r
- AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", detail);\r
- }\r
-\r
- \r
- if(dir == MOVE_EAST)\r
- AddFaceWithTexture(newBrush, v1, v5, v3, "textures/common/caulk", detail);\r
-\r
- if(dir == MOVE_WEST)\r
- AddFaceWithTexture(newBrush, v2, v8, v6, "textures/common/caulk", detail);\r
-\r
- if(dir == MOVE_NORTH)\r
- AddFaceWithTexture(newBrush, v1, v5, v6, "textures/common/caulk", detail);\r
-\r
- if(dir == MOVE_SOUTH)\r
- AddFaceWithTexture(newBrush, v7, v8, v3, "textures/common/caulk", detail);\r
-\r
- g_FuncTable.m_pfnCommitBrushHandle(newBrush);\r
-}\r
-\r
-//-----------------------------------------------------------------------------------\r
-//-----------------------------------------------------------------------------------\r
-\r
-// internal use only, to get a box without finishing construction\r
-brush_t* Build_Get_BoundingCube_Selective(vec3_t min, vec3_t max, char* texture, bool* useFaces)\r
-{\r
- brush_t* newBrush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();\r
-\r
- //----- Build Outer Bounds ---------\r
-\r
- vec3_t v1, v2, v3, v5, v6, v7;\r
- VectorCopy(min, v1);\r
- VectorCopy(min, v2);\r
- VectorCopy(min, v3);\r
- VectorCopy(max, v5);\r
- VectorCopy(max, v6);\r
- VectorCopy(max, v7);\r
-\r
- v2[0] = max[0];\r
- v3[1] = max[1];\r
-\r
- v6[0] = min[0];\r
- v7[1] = min[1];\r
-\r
- //----------------------------------\r
-\r
- //----- Add Six Cube Faces ---------\r
-\r
- if(useFaces[0])\r
- AddFaceWithTexture(newBrush, v1, v2, v3, texture, FALSE);\r
- if(useFaces[1])\r
- AddFaceWithTexture(newBrush, v1, v3, v6, texture, FALSE);\r
- if(useFaces[2])\r
- AddFaceWithTexture(newBrush, v1, v7, v2, texture, FALSE);\r
-\r
- if(useFaces[3])\r
- AddFaceWithTexture(newBrush, v5, v6, v3, texture, FALSE);\r
- if(useFaces[4])\r
- AddFaceWithTexture(newBrush, v5, v2, v7, texture, FALSE);\r
- if(useFaces[5])\r
- AddFaceWithTexture(newBrush, v5, v7, v6, texture, FALSE);\r
-\r
- //----------------------------------\r
-\r
- return newBrush;\r
-}\r
-\r
-brush_t* Build_Get_BoundingCube(vec3_t min, vec3_t max, char* texture)\r
-{\r
- return Build_Get_BoundingCube_Selective(min, max, texture, bFacesAll);\r
-}\r
-\r
-//-----------------------------------------------------------------------------------\r
-//-----------------------------------------------------------------------------------\r
-\r
-void Build_StairStep(vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, int direction)\r
-{\r
- brush_t* newBrush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();\r
-\r
- //----- Build Outer Bounds ---------\r
-\r
- vec3_t v1, v2, v3, v5, v6, v7;\r
- VectorCopy(min, v1);\r
- VectorCopy(min, v2);\r
- VectorCopy(min, v3);\r
- VectorCopy(max, v5);\r
- VectorCopy(max, v6);\r
- VectorCopy(max, v7);\r
-\r
- v2[0] = max[0];\r
- v3[1] = max[1];\r
-\r
- v6[0] = min[0];\r
- v7[1] = min[1];\r
-\r
- //----------------------------------\r
-\r
- AddFaceWithTexture(newBrush, v6, v5, v7, mainTexture, FALSE);\r
- // top gets current texture\r
-\r
-\r
- if(direction == MOVE_EAST)\r
- AddFaceWithTexture(newBrush, v1, v3, v6, riserTexture, FALSE);\r
- else\r
- AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", FALSE);\r
- // west facing side, etc...\r
-\r
- \r
- if(direction == MOVE_NORTH)\r
- AddFaceWithTexture(newBrush, v1, v7, v2, riserTexture, FALSE);\r
- else\r
- AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", FALSE);\r
-\r
- if(direction == MOVE_SOUTH)\r
- AddFaceWithTexture(newBrush, v3, v5, v6, riserTexture, FALSE);\r
- else\r
- AddFaceWithTexture(newBrush, v3, v5, v6, "textures/common/caulk", FALSE);\r
- \r
- if(direction == MOVE_WEST)\r
- AddFaceWithTexture(newBrush, v7, v5, v2, riserTexture, FALSE);\r
- else\r
- AddFaceWithTexture(newBrush, v7, v5, v2, "textures/common/caulk", FALSE);\r
-\r
-\r
- AddFaceWithTexture(newBrush, v1, v2, v3, "textures/common/caulk", FALSE);\r
- // base is caulked\r
-\r
- g_FuncTable.m_pfnCommitBrushHandle(newBrush);\r
- // finish brush\r
-}\r
-\r
-//-----------------------------------------------------------------------------------\r
-//-----------------------------------------------------------------------------------\r
-\r
-void BuildDoorsX2(vec3_t min, vec3_t max, \r
- bool bSclMainHor, bool bSclMainVert, \r
- bool bSclTrimHor, bool bSclTrimVert,\r
- const char* mainTexture, const char* trimTexture,\r
- int direction)\r
-{\r
- int xy;\r
- if(direction == 0)\r
- xy = 0;\r
- else\r
- xy = 1;\r
-\r
- //----- Build Outer Bounds ---------\r
-\r
- vec3_t v1, v2, v3, v5, v6, v7, ve_1, ve_2, ve_3;\r
- VectorCopy(min, v1);\r
- VectorCopy(min, v2);\r
- VectorCopy(min, v3);\r
- VectorCopy(max, v5);\r
- VectorCopy(max, v6);\r
- VectorCopy(max, v7);\r
-\r
- v2[0] = max[0];\r
- v3[1] = max[1];\r
-\r
- v6[0] = min[0];\r
- v7[1] = min[1];\r
-\r
- float width = (max[xy] - min[xy])/2;\r
- \r
- if(direction == 0)\r
- {\r
- VectorCopy(v1, ve_1);\r
- VectorCopy(v3, ve_2);\r
- VectorCopy(v6, ve_3);\r
- }\r
- else\r
- {\r
- VectorCopy(v7, ve_1);\r
- VectorCopy(v1, ve_2);\r
- VectorCopy(v2, ve_3);\r
- }\r
-\r
- ve_1[xy] += width;\r
- ve_2[xy] += width;\r
- ve_3[xy] += width;\r
-\r
- //----------------------------------\r
-\r
- brush_t* newBrush1 = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();\r
- brush_t* newBrush2 = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();\r
-\r
- AddFaceWithTexture(newBrush1, v1, v2, v3, "textures/common/caulk", FALSE);\r
- AddFaceWithTexture(newBrush1, v5, v7, v6, "textures/common/caulk", FALSE);\r
-\r
- AddFaceWithTexture(newBrush2, v1, v2, v3, "textures/common/caulk", FALSE);\r
- AddFaceWithTexture(newBrush2, v5, v7, v6, "textures/common/caulk", FALSE);\r
-\r
- if(direction == 0)\r
- {\r
- AddFaceWithTexture(newBrush1, v1, v3, v6, "textures/common/caulk", FALSE);\r
- AddFaceWithTexture(newBrush2, v5, v2, v7, "textures/common/caulk", FALSE);\r
- }\r
- else\r
- {\r
- AddFaceWithTexture(newBrush1, v1, v7, v2, "textures/common/caulk", FALSE);\r
- AddFaceWithTexture(newBrush2, v5, v6, v3, "textures/common/caulk", FALSE);\r
- }\r
-\r
- if(direction == 0)\r
- {\r
- AddFaceWithTextureScaled(newBrush1, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,\r
- min[0], min[2], max[0], max[2]);\r
- AddFaceWithTextureScaled(newBrush1, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,\r
- max[0], min[2], min[0], max[2]);\r
-\r
- \r
- AddFaceWithTextureScaled(newBrush2, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,\r
- min[0], min[2], max[0], max[2]);\r
- AddFaceWithTextureScaled(newBrush2, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,\r
- max[0], min[2], min[0], max[2]); // flip max/min to reverse tex dir\r
-\r
-\r
- \r
- AddFaceWithTextureScaled(newBrush1, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,\r
- min[1], min[2], max[1], max[2]);\r
-\r
- AddFaceWithTextureScaled(newBrush2, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,\r
- max[1], min[2], min[1], max[2]);\r
- }\r
- else\r
- {\r
- AddFaceWithTextureScaled(newBrush1, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,\r
- min[1], min[2], max[1], max[2]);\r
- AddFaceWithTextureScaled(newBrush1, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,\r
- max[1], min[2], min[1], max[2]);\r
-\r
- \r
- AddFaceWithTextureScaled(newBrush2, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,\r
- min[1], min[2], max[1], max[2]);\r
- AddFaceWithTextureScaled(newBrush2, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,\r
- max[1], min[2], min[1], max[2]); // flip max/min to reverse tex dir\r
-\r
-\r
- AddFaceWithTextureScaled(newBrush1, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,\r
- min[0], min[2], max[0], max[2]);\r
-\r
- AddFaceWithTextureScaled(newBrush2, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,\r
- max[0], min[2], min[0], max[2]);\r
- }\r
-\r
- //----------------------------------\r
- \r
-\r
- entity_t* pEDoor1 = (entity_t*)g_FuncTable.m_pfnCreateEntityHandle();\r
- entity_t* pEDoor2 = (entity_t*)g_FuncTable.m_pfnCreateEntityHandle();\r
-\r
- epair_t* epDoor11 = GetNextChainItem(NULL, "classname", "func_door");\r
- epair_t* epDoor21 = GetNextChainItem(NULL, "classname", "func_door");\r
-\r
- epair_t* epDoor12;\r
- epair_t* epDoor22;\r
-\r
- if(direction == 0)\r
- {\r
- epDoor12 = GetNextChainItem(epDoor11, "angle", "180");\r
- epDoor22 = GetNextChainItem(epDoor21, "angle", "360");\r
- }\r
- else\r
- {\r
- epDoor12 = GetNextChainItem(epDoor11, "angle", "270");\r
- epDoor22 = GetNextChainItem(epDoor21, "angle", "90");\r
- }\r
-\r
- srand((unsigned)time(NULL));\r
-\r
- char teamname[256];\r
- sprintf(teamname, "t%i", rand());\r
- /*epair_t* epDoor13 = */ GetNextChainItem(epDoor12, "team", teamname);\r
- /*epair_t* epDoor23 = */ GetNextChainItem(epDoor22, "team", teamname);\r
-\r
- g_FuncTable.m_pfnCommitBrushHandleToEntity(newBrush1, pEDoor1);\r
- g_FuncTable.m_pfnCommitBrushHandleToEntity(newBrush2, pEDoor2);\r
-\r
- g_EntityTable.m_pfnSetEntityKeyValList(pEDoor1, epDoor11);\r
- g_EntityTable.m_pfnSetEntityKeyValList(pEDoor2, epDoor21);\r
-\r
- g_FuncTable.m_pfnCommitEntityHandleToMap(pEDoor1);\r
- g_FuncTable.m_pfnCommitEntityHandleToMap(pEDoor2);\r
-\r
-// ResetCurrentTexture();\r
-}\r
-\r
-//-----------------------------------------------------------------------------------\r
-//-----------------------------------------------------------------------------------\r
-\r
-void MakeBevel(vec3_t vMin, vec3_t vMax)\r
-{\r
- int nIndex = g_FuncTable.m_pfnCreatePatchHandle();\r
- //$ FIXME: m_pfnGetPatchHandle\r
- patchMesh_t* pm = g_FuncTable.m_pfnGetPatchData(nIndex);\r
-\r
- pm->height = 3;\r
- pm->width = 3;\r
-\r
- vec3_t x_3, y_3, z_3;\r
- x_3[0] = vMin[0]; x_3[1] = vMin[0]; x_3[2] = vMax[0];\r
- y_3[0] = vMin[1]; y_3[1] = vMax[1]; y_3[2] = vMax[1];\r
- z_3[0] = vMin[2]; z_3[1] = (vMax[2] + vMin[2])/2; z_3[2] = vMax[2];\r
-\r
-/* x_3[0] = 0; x_3[1] = 0; x_3[2] = 64;\r
- y_3[0] = 0; y_3[1] = 64; y_3[2] = 64;\r
- z_3[0] = 0; z_3[1] = 32; z_3[2] = 64;*/\r
-\r
- for(int i = 0; i < 3; i++)\r
- {\r
- for(int j = 0; j < 3; j++)\r
- {\r
- pm->ctrl[i][j].xyz[0] = x_3[i];\r
- pm->ctrl[i][j].xyz[1] = y_3[i];\r
- pm->ctrl[i][j].xyz[2] = z_3[j];\r
- }\r
- }\r
-\r
-\r
- g_FuncTable.m_pfnCommitPatchHandleToMap(nIndex, pm, "textures/common/caulk");\r
-}\r
-\r
-void BuildCornerStairs(vec3_t vMin, vec3_t vMax, int nSteps, const char* mainTexture, const char* riserTex)\r
-{\r
- vec3_t* topPoints = new vec3_t[nSteps+1];\r
- vec3_t* botPoints = new vec3_t[nSteps+1];\r
-\r
- bool bFacesUse[6] = {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE};\r
-\r
- vec3_t centre;\r
- VectorCopy(vMin, centre);\r
- centre[0] = vMax[0];\r
-\r
- int height = (int)(vMax[2] - vMin[2]) / nSteps;\r
-\r
- vec3_t vTop, vBot;\r
- VectorCopy(vMax, vTop);\r
- VectorCopy(vMin, vBot);\r
- vTop[2] = vMin[2] + height;\r
-\r
- int i;\r
- for(i = 0; i <= nSteps; i++)\r
- {\r
- VectorCopy(centre, topPoints[i]);\r
- VectorCopy(centre, botPoints[i]);\r
- \r
- topPoints[i][2] = vMax[2];\r
- botPoints[i][2] = vMin[2];\r
-\r
- topPoints[i][0] -= 10 * sinf( Q_PI * i / ( 2 * nSteps ) );\r
- topPoints[i][1] += 10 * cosf( Q_PI * i / ( 2 * nSteps ) );\r
-\r
- botPoints[i][0] = topPoints[i][0];\r
- botPoints[i][1] = topPoints[i][1];\r
- }\r
-\r
- vec3_t tp[3];\r
- for(int j = 0; j < 3; j++)\r
- VectorCopy(topPoints[j], tp[j]);\r
-\r
- for(i = 0; i < nSteps; i++)\r
- {\r
- brush_t* brush = Build_Get_BoundingCube_Selective(vBot, vTop, "textures/common/caulk", bFacesUse);\r
-\r
- for(int j = 0; j < 3; j++)\r
- tp[j][2] = vTop[2];\r
-\r
- AddFaceWithTexture(brush, tp[2], tp[1], tp[0], mainTexture, FALSE);\r
-\r
- AddFaceWithTexture(brush, centre, botPoints[i+1], topPoints[i+1], "textures/common/caulk", FALSE);\r
- AddFaceWithTexture(brush, centre, topPoints[i], botPoints[i], riserTex, FALSE);\r
-\r
- g_FuncTable.m_pfnCommitBrushHandle(brush);\r
-\r
- vTop[2] += height;\r
- vBot[2] += height;\r
- }\r
-\r
- delete[] topPoints;\r
- delete[] botPoints;\r
-\r
- vMin[2] += height;\r
- vMax[2] += height;\r
- MakeBevel(vMin, vMax);\r
-}\r
+/*
+ BobToolz plugin for GtkRadiant
+ Copyright (C) 2001 Gordon Biggans
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "shapes.h"
+
+#include <list>
+
+#include "DPoint.h"
+#include "DPlane.h"
+
+#include "str.h"
+#include "misc.h"
+#include "funchandlers.h"
+
+#include "iundo.h"
+#include "ishaders.h"
+#include "ientity.h"
+#include "ieclass.h"
+#include "ipatch.h"
+#include "qerplugin.h"
+
+#include <vector>
+#include <list>
+#include <map>
+#include <algorithm>
+#include <time.h>
+
+#include "scenelib.h"
+#include "texturelib.h"
+
+//#include "dialogs-gtk.h"
+
+/************************
+ Cube Diagram
+************************/
+
+/*
+
+ 7 ----- 5
+ /| /|
+ / | / |
+ / | / |
+ 4 ----- 6 |
+ | 2|_|___|8
+ | / | /
+ | / | / ----> WEST, definitely
+ ||/ | /
+ 1|_____|/3
+
+ */
+
+/************************
+ Global Variables
+************************/
+
+vec3_t g_Origin = {0.0f, 0.0f, 0.0f};
+
+extern bool bFacesAll[];
+
+/************************
+ Helper Functions
+************************/
+
+float Deg2Rad( float angle ){
+ return (float)( angle * Q_PI / 180 );
+}
+
+void AddFaceWithTexture( scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc, const char* texture, bool detail ){
+ _QERFaceData faceData;
+ FillDefaultTexture( &faceData, va, vb, vc, texture );
+ if ( detail ) {
+ faceData.contents |= FACE_DETAIL;
+ }
+ GlobalBrushCreator().Brush_addFace( brush, faceData );
+}
+
+void AddFaceWithTextureScaled( scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc,
+ const char* texture, bool bVertScale, bool bHorScale,
+ float minX, float minY, float maxX, float maxY ){
+ qtexture_t* pqtTexInfo;
+
+ // TTimo: there used to be a call to pfnHasShader here
+ // this was not necessary. In Radiant everything is shader.
+ // If a texture doesn't have a shader script, a default shader object is used.
+ // The IShader object was leaking also
+ // collect texture info: sizes, etc
+ IShader* i = GlobalShaderSystem().getShaderForName( texture );
+ pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly
+
+ if ( pqtTexInfo ) {
+ float scale[2] = {0.5f, 0.5f};
+ float shift[2] = {0, 0};
+
+ if ( bHorScale ) {
+ float width = maxX - minX;
+
+ scale[0] = width / pqtTexInfo->width;
+ shift[0] = -(float)( (int)maxX % (int)width ) / scale[0];
+ }
+
+ if ( bVertScale ) {
+ float height = maxY - minY;
+
+ scale[1] = height / pqtTexInfo->height;
+ shift[1] = (float)( (int)minY % (int)height ) / scale[1];
+ }
+
+ _QERFaceData addFace;
+ FillDefaultTexture( &addFace, va, vb, vc, texture );
+ addFace.m_texdef.scale[0] = scale[0];
+ addFace.m_texdef.scale[1] = scale[1];
+ addFace.m_texdef.shift[0] = shift[0];
+ addFace.m_texdef.shift[1] = shift[1];
+
+ GlobalBrushCreator().Brush_addFace( brush, addFace );
+ }
+ else
+ {
+ // shouldn't even get here, as default missing texture should be returned if
+ // texture doesn't exist, but just in case
+ AddFaceWithTexture( brush, va, vb, vc, texture, false );
+ globalErrorStream() << "BobToolz::Invalid Texture Name-> " << texture;
+ }
+ // the IShader is not kept referenced, DecRef it
+ i->DecRef();
+}
+
+/************************
+ --Main Functions--
+************************/
+
+void Build_Wedge( int dir, vec3_t min, vec3_t max, bool bUp ){
+ NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
+
+ vec3_t v1, v2, v3, v5, v6, v7, v8;
+ VectorCopy( min, v1 );
+ VectorCopy( min, v2 );
+ VectorCopy( min, v3 );
+ VectorCopy( max, v5 );
+ VectorCopy( max, v6 );
+ VectorCopy( max, v7 );
+ VectorCopy( max, v8 );
+
+ v2[0] = max[0];
+ v3[1] = max[1];
+
+ v6[0] = min[0];
+ v7[1] = min[1];
+ v8[2] = min[2];
+
+ if ( bUp ) {
+
+ if ( dir != MOVE_EAST ) {
+ AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
+ }
+
+ if ( dir != MOVE_WEST ) {
+ AddFaceWithTexture( newBrush, v7, v5, v8, "textures/common/caulk", false );
+ }
+
+ if ( dir != MOVE_NORTH ) {
+ AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
+ }
+
+ if ( dir != MOVE_SOUTH ) {
+ AddFaceWithTexture( newBrush, v3, v8, v6, "textures/common/caulk", false );
+ }
+
+ AddFaceWithTexture( newBrush, v1, v2, v3, "textures/common/caulk", false );
+
+ if ( dir == MOVE_EAST ) {
+ AddFaceWithTexture( newBrush, v1, v3, v5, "textures/common/caulk", false );
+ }
+
+ if ( dir == MOVE_WEST ) {
+ AddFaceWithTexture( newBrush, v2, v6, v8, "textures/common/caulk", false );
+ }
+
+ if ( dir == MOVE_NORTH ) {
+ AddFaceWithTexture( newBrush, v1, v6, v5, "textures/common/caulk", false );
+ }
+
+ if ( dir == MOVE_SOUTH ) {
+ AddFaceWithTexture( newBrush, v7, v3, v8, "textures/common/caulk", false );
+ }
+ }
+ else
+ {
+ if ( dir != MOVE_WEST ) {
+ AddFaceWithTexture( newBrush, v7, v5, v8, "textures/common/caulk", false );
+ }
+
+ if ( dir != MOVE_EAST ) {
+ AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
+ }
+
+ if ( dir != MOVE_NORTH ) {
+ AddFaceWithTexture( newBrush, v3, v8, v6, "textures/common/caulk", false );
+ }
+
+ if ( dir != MOVE_SOUTH ) {
+ AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
+ }
+
+
+ AddFaceWithTexture( newBrush, v6, v5, v7, "textures/common/caulk", false );
+
+ if ( dir == MOVE_WEST ) {
+ AddFaceWithTexture( newBrush, v1, v5, v3, "textures/common/caulk", false );
+ }
+
+ if ( dir == MOVE_EAST ) {
+ AddFaceWithTexture( newBrush, v2, v8, v6, "textures/common/caulk", false );
+ }
+
+ if ( dir == MOVE_NORTH ) {
+ AddFaceWithTexture( newBrush, v1, v5, v6, "textures/common/caulk", false );
+ }
+
+ if ( dir == MOVE_SOUTH ) {
+ AddFaceWithTexture( newBrush, v7, v8, v3, "textures/common/caulk", false );
+ }
+ }
+
+ Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
+}
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+void Build_StairStep_Wedge( int dir, vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, bool detail ){
+ NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
+
+ //----- Build Outer Bounds ---------
+
+ vec3_t v1, v2, v3, v5, v6, v7, v8;
+ VectorCopy( min, v1 );
+ VectorCopy( min, v2 );
+ VectorCopy( min, v3 );
+ VectorCopy( max, v5 );
+ VectorCopy( max, v6 );
+ VectorCopy( max, v7 );
+ VectorCopy( max, v8 );
+
+ v2[0] = max[0];
+ v3[1] = max[1];
+
+ v6[0] = min[0];
+ v7[1] = min[1];
+
+ v8[2] = min[2];
+ //v8 needed this time, becoz of sloping faces (2-4-6-8)
+
+ //----------------------------------
+
+ AddFaceWithTexture( newBrush, v6, v5, v7, mainTexture, detail );
+
+ if ( dir != MOVE_EAST ) {
+ if ( dir == MOVE_WEST ) {
+ AddFaceWithTexture( newBrush, v5, v2, v7, riserTexture, detail );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v5, v2, v7, "textures/common/caulk", detail );
+ }
+ }
+
+ if ( dir != MOVE_WEST ) {
+ if ( dir == MOVE_EAST ) {
+ AddFaceWithTexture( newBrush, v1, v3, v6, riserTexture, detail );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", detail );
+ }
+ }
+
+ if ( dir != MOVE_NORTH ) {
+ if ( dir == MOVE_SOUTH ) {
+ AddFaceWithTexture( newBrush, v3, v5, v6, riserTexture, detail );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", detail );
+ }
+ }
+
+ if ( dir != MOVE_SOUTH ) {
+ if ( dir == MOVE_NORTH ) {
+ AddFaceWithTexture( newBrush, v1, v7, v2, riserTexture, detail );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", detail );
+ }
+ }
+
+
+ if ( dir == MOVE_EAST ) {
+ AddFaceWithTexture( newBrush, v1, v5, v3, "textures/common/caulk", detail );
+ }
+
+ if ( dir == MOVE_WEST ) {
+ AddFaceWithTexture( newBrush, v2, v8, v6, "textures/common/caulk", detail );
+ }
+
+ if ( dir == MOVE_NORTH ) {
+ AddFaceWithTexture( newBrush, v1, v5, v6, "textures/common/caulk", detail );
+ }
+
+ if ( dir == MOVE_SOUTH ) {
+ AddFaceWithTexture( newBrush, v7, v8, v3, "textures/common/caulk", detail );
+ }
+
+ Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
+}
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+// internal use only, to get a box without finishing construction
+scene::Node& Build_Get_BoundingCube_Selective( vec3_t min, vec3_t max, char* texture, bool* useFaces ){
+ NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
+
+ //----- Build Outer Bounds ---------
+
+ vec3_t v1, v2, v3, v5, v6, v7;
+ VectorCopy( min, v1 );
+ VectorCopy( min, v2 );
+ VectorCopy( min, v3 );
+ VectorCopy( max, v5 );
+ VectorCopy( max, v6 );
+ VectorCopy( max, v7 );
+
+ v2[0] = max[0];
+ v3[1] = max[1];
+
+ v6[0] = min[0];
+ v7[1] = min[1];
+
+ //----------------------------------
+
+ //----- Add Six Cube Faces ---------
+
+ if ( useFaces[0] ) {
+ AddFaceWithTexture( newBrush, v1, v2, v3, texture, false );
+ }
+ if ( useFaces[1] ) {
+ AddFaceWithTexture( newBrush, v1, v3, v6, texture, false );
+ }
+ if ( useFaces[2] ) {
+ AddFaceWithTexture( newBrush, v1, v7, v2, texture, false );
+ }
+
+ if ( useFaces[3] ) {
+ AddFaceWithTexture( newBrush, v5, v6, v3, texture, false );
+ }
+ if ( useFaces[4] ) {
+ AddFaceWithTexture( newBrush, v5, v2, v7, texture, false );
+ }
+ if ( useFaces[5] ) {
+ AddFaceWithTexture( newBrush, v5, v7, v6, texture, false );
+ }
+
+ //----------------------------------
+
+ return newBrush;
+}
+
+scene::Node& Build_Get_BoundingCube( vec3_t min, vec3_t max, char* texture ){
+ return Build_Get_BoundingCube_Selective( min, max, texture, bFacesAll );
+}
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+void Build_StairStep( vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, int direction ){
+ NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
+
+ //----- Build Outer Bounds ---------
+
+ vec3_t v1, v2, v3, v5, v6, v7;
+ VectorCopy( min, v1 );
+ VectorCopy( min, v2 );
+ VectorCopy( min, v3 );
+ VectorCopy( max, v5 );
+ VectorCopy( max, v6 );
+ VectorCopy( max, v7 );
+
+ v2[0] = max[0];
+ v3[1] = max[1];
+
+ v6[0] = min[0];
+ v7[1] = min[1];
+
+ //----------------------------------
+
+ AddFaceWithTexture( newBrush, v6, v5, v7, mainTexture, false );
+ // top gets current texture
+
+
+ if ( direction == MOVE_EAST ) {
+ AddFaceWithTexture( newBrush, v1, v3, v6, riserTexture, false );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
+ }
+ // west facing side, etc...
+
+
+ if ( direction == MOVE_NORTH ) {
+ AddFaceWithTexture( newBrush, v1, v7, v2, riserTexture, false );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
+ }
+
+ if ( direction == MOVE_SOUTH ) {
+ AddFaceWithTexture( newBrush, v3, v5, v6, riserTexture, false );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", false );
+ }
+
+ if ( direction == MOVE_WEST ) {
+ AddFaceWithTexture( newBrush, v7, v5, v2, riserTexture, false );
+ }
+ else{
+ AddFaceWithTexture( newBrush, v7, v5, v2, "textures/common/caulk", false );
+ }
+
+
+ AddFaceWithTexture( newBrush, v1, v2, v3, "textures/common/caulk", false );
+ // base is caulked
+
+ Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
+ // finish brush
+}
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+void BuildDoorsX2( vec3_t min, vec3_t max,
+ bool bSclMainHor, bool bSclMainVert,
+ bool bSclTrimHor, bool bSclTrimVert,
+ const char* mainTexture, const char* trimTexture,
+ int direction ){
+ int xy;
+ if ( direction == 0 ) {
+ xy = 0;
+ }
+ else{
+ xy = 1;
+ }
+
+ //----- Build Outer Bounds ---------
+
+ vec3_t v1, v2, v3, v5, v6, v7, ve_1, ve_2, ve_3;
+ VectorCopy( min, v1 );
+ VectorCopy( min, v2 );
+ VectorCopy( min, v3 );
+ VectorCopy( max, v5 );
+ VectorCopy( max, v6 );
+ VectorCopy( max, v7 );
+
+ v2[0] = max[0];
+ v3[1] = max[1];
+
+ v6[0] = min[0];
+ v7[1] = min[1];
+
+ float width = ( max[xy] - min[xy] ) / 2;
+
+ if ( direction == 0 ) {
+ VectorCopy( v1, ve_1 );
+ VectorCopy( v3, ve_2 );
+ VectorCopy( v6, ve_3 );
+ }
+ else
+ {
+ VectorCopy( v7, ve_1 );
+ VectorCopy( v1, ve_2 );
+ VectorCopy( v2, ve_3 );
+ }
+
+ ve_1[xy] += width;
+ ve_2[xy] += width;
+ ve_3[xy] += width;
+
+ //----------------------------------
+
+ NodeSmartReference newBrush1( GlobalBrushCreator().createBrush() );
+ NodeSmartReference newBrush2( GlobalBrushCreator().createBrush() );
+
+ AddFaceWithTexture( newBrush1, v1, v2, v3, "textures/common/caulk", false );
+ AddFaceWithTexture( newBrush1, v5, v7, v6, "textures/common/caulk", false );
+
+ AddFaceWithTexture( newBrush2, v1, v2, v3, "textures/common/caulk", false );
+ AddFaceWithTexture( newBrush2, v5, v7, v6, "textures/common/caulk", false );
+
+ if ( direction == 0 ) {
+ AddFaceWithTexture( newBrush1, v1, v3, v6, "textures/common/caulk", false );
+ AddFaceWithTexture( newBrush2, v5, v2, v7, "textures/common/caulk", false );
+ }
+ else
+ {
+ AddFaceWithTexture( newBrush1, v1, v7, v2, "textures/common/caulk", false );
+ AddFaceWithTexture( newBrush2, v5, v6, v3, "textures/common/caulk", false );
+ }
+
+ if ( direction == 0 ) {
+ AddFaceWithTextureScaled( newBrush1, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
+ min[0], min[2], max[0], max[2] );
+ AddFaceWithTextureScaled( newBrush1, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
+ max[0], min[2], min[0], max[2] );
+
+
+ AddFaceWithTextureScaled( newBrush2, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
+ min[0], min[2], max[0], max[2] );
+ AddFaceWithTextureScaled( newBrush2, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
+ max[0], min[2], min[0], max[2] ); // flip max/min to reverse tex dir
+
+
+
+ AddFaceWithTextureScaled( newBrush1, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
+ min[1], min[2], max[1], max[2] );
+
+ AddFaceWithTextureScaled( newBrush2, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
+ max[1], min[2], min[1], max[2] );
+ }
+ else
+ {
+ AddFaceWithTextureScaled( newBrush1, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
+ min[1], min[2], max[1], max[2] );
+ AddFaceWithTextureScaled( newBrush1, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
+ max[1], min[2], min[1], max[2] );
+
+
+ AddFaceWithTextureScaled( newBrush2, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
+ min[1], min[2], max[1], max[2] );
+ AddFaceWithTextureScaled( newBrush2, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
+ max[1], min[2], min[1], max[2] ); // flip max/min to reverse tex dir
+
+
+ AddFaceWithTextureScaled( newBrush1, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
+ min[0], min[2], max[0], max[2] );
+
+ AddFaceWithTextureScaled( newBrush2, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
+ max[0], min[2], min[0], max[2] );
+ }
+
+ //----------------------------------
+
+
+ EntityClass* doorClass = GlobalEntityClassManager().findOrInsert( "func_door", true );
+ NodeSmartReference pEDoor1( GlobalEntityCreator().createEntity( doorClass ) );
+ NodeSmartReference pEDoor2( GlobalEntityCreator().createEntity( doorClass ) );
+
+ if ( direction == 0 ) {
+ Node_getEntity( pEDoor1 )->setKeyValue( "angle", "180" );
+ Node_getEntity( pEDoor2 )->setKeyValue( "angle", "360" );
+ }
+ else
+ {
+ Node_getEntity( pEDoor1 )->setKeyValue( "angle", "270" );
+ Node_getEntity( pEDoor2 )->setKeyValue( "angle", "90" );
+ }
+
+ srand( (unsigned)time( NULL ) );
+
+ char teamname[256];
+ sprintf( teamname, "t%i", rand() );
+ Node_getEntity( pEDoor1 )->setKeyValue( "team", teamname );
+ Node_getEntity( pEDoor2 )->setKeyValue( "team", teamname );
+
+ Node_getTraversable( pEDoor1 )->insert( newBrush1 );
+ Node_getTraversable( pEDoor2 )->insert( newBrush2 );
+
+ Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor1 );
+ Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor2 );
+
+// ResetCurrentTexture();
+}
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+void MakeBevel( vec3_t vMin, vec3_t vMax ){
+ NodeSmartReference patch( GlobalPatchCreator().createPatch() );
+ GlobalPatchCreator().Patch_resize( patch, 3, 3 );
+ GlobalPatchCreator().Patch_setShader( patch, "textures/common/caulk" );
+ PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch );
+ vec3_t x_3, y_3, z_3;
+ x_3[0] = vMin[0]; x_3[1] = vMin[0]; x_3[2] = vMax[0];
+ y_3[0] = vMin[1]; y_3[1] = vMax[1]; y_3[2] = vMax[1];
+ z_3[0] = vMin[2]; z_3[1] = ( vMax[2] + vMin[2] ) / 2; z_3[2] = vMax[2];
+ /*
+ x_3[0] = 0; x_3[1] = 0; x_3[2] = 64;
+ y_3[0] = 0; y_3[1] = 64; y_3[2] = 64;
+ z_3[0] = 0; z_3[1] = 32; z_3[2] = 64;*/
+ for ( int i = 0; i < 3; i++ )
+ {
+ for ( int j = 0; j < 3; j++ )
+ {
+ PatchControl& p = matrix( i, j );
+ p.m_vertex[0] = x_3[i];
+ p.m_vertex[1] = y_3[i];
+ p.m_vertex[2] = z_3[j];
+ }
+ }
+ //does invert the matrix, else the patch face is on wrong side.
+ for ( int i = 0 ; i < 3 ; i++ )
+ {
+ for ( int j = 0; j < 1; j++ )
+ {
+ PatchControl& p = matrix( i,2 - j );
+ PatchControl& q = matrix( i, j );
+ std::swap( p.m_vertex, q.m_vertex );
+ //std::swap(p.m_texcoord, q.m_texcoord);
+ }
+ }
+ GlobalPatchCreator().Patch_controlPointsChanged( patch );
+ //TODO - the patch has textures weird, patchmanip.h has all function it needs.. lots of duplicate code..
+ //NaturalTexture(patch);
+ Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( patch );
+}
+
+void BuildCornerStairs( vec3_t vMin, vec3_t vMax, int nSteps, const char* mainTexture, const char* riserTex ){
+ vec3_t* topPoints = new vec3_t[nSteps + 1];
+ vec3_t* botPoints = new vec3_t[nSteps + 1];
+
+ //bool bFacesUse[6] = {true, true, false, true, false, false};
+
+ vec3_t centre;
+ VectorCopy( vMin, centre );
+ centre[0] = vMax[0];
+
+ int height = (int)( vMax[2] - vMin[2] ) / nSteps;
+
+ vec3_t vTop, vBot;
+ VectorCopy( vMax, vTop );
+ VectorCopy( vMin, vBot );
+ vTop[2] = vMin[2] + height;
+
+ int i;
+ for ( i = 0; i <= nSteps; i++ )
+ {
+ VectorCopy( centre, topPoints[i] );
+ VectorCopy( centre, botPoints[i] );
+
+ topPoints[i][2] = vMax[2];
+ botPoints[i][2] = vMin[2];
+
+ topPoints[i][0] -= 10 * sinf( Q_PI * i / ( 2 * nSteps ) );
+ topPoints[i][1] += 10 * cosf( Q_PI * i / ( 2 * nSteps ) );
+
+ botPoints[i][0] = topPoints[i][0];
+ botPoints[i][1] = topPoints[i][1];
+ }
+
+ vec3_t tp[3];
+ for ( int j = 0; j < 3; j++ )
+ VectorCopy( topPoints[j], tp[j] );
+
+ for ( i = 0; i < nSteps; i++ )
+ {
+ NodeSmartReference brush( GlobalBrushCreator().createBrush() );
+ vec3_t v1, v2, v3, v5, v6, v7;
+ VectorCopy( vBot, v1 );
+ VectorCopy( vBot, v2 );
+ VectorCopy( vBot, v3 );
+ VectorCopy( vTop, v5 );
+ VectorCopy( vTop, v6 );
+ VectorCopy( vTop, v7 );
+
+ v2[0] = vTop[0];
+ v3[1] = vTop[1];
+
+ v6[0] = vBot[0];
+ v7[1] = vBot[1];
+
+ AddFaceWithTexture( brush, v1, v2, v3, "textures/common/caulk", false );
+ AddFaceWithTexture( brush, v1, v3, v6, "textures/common/caulk", false );
+ AddFaceWithTexture( brush, v5, v6, v3, "textures/common/caulk", false );
+
+ for ( int j = 0; j < 3; j++ )
+ tp[j][2] = vTop[2];
+
+ AddFaceWithTexture( brush, tp[2], tp[1], tp[0], mainTexture, false );
+
+ AddFaceWithTexture( brush, centre, botPoints[i + 1], topPoints[i + 1], "textures/common/caulk", false );
+ AddFaceWithTexture( brush, centre, topPoints[i], botPoints[i], riserTex, false );
+
+ Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( brush );
+
+ vTop[2] += height;
+ vBot[2] += height;
+ }
+
+ delete[] topPoints;
+ delete[] botPoints;
+
+ vMin[2] += height;
+ vMax[2] += height;
+ MakeBevel( vMin, vMax );
+}