2 BobToolz plugin for GtkRadiant
3 Copyright (C) 2001 Gordon Biggans
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "funchandlers.h"
37 #include "qerplugin.h"
46 #include "texturelib.h"
48 //#include "dialogs-gtk.h"
50 /************************
52 ************************/
63 | / | / ----> WEST, definitely
69 /************************
71 ************************/
73 vec3_t g_Origin = {0.0f, 0.0f, 0.0f};
75 extern bool bFacesAll[];
77 /************************
79 ************************/
81 float Deg2Rad(float angle)
83 return (float) (angle * Q_PI / 180);
86 void AddFaceWithTexture(scene::Node &brush, vec3_t va, vec3_t vb, vec3_t vc, const char *texture, bool detail)
88 _QERFaceData faceData;
89 FillDefaultTexture(&faceData, va, vb, vc, texture);
91 faceData.contents |= FACE_DETAIL;
93 GlobalBrushCreator().Brush_addFace(brush, faceData);
96 void AddFaceWithTextureScaled(scene::Node &brush, vec3_t va, vec3_t vb, vec3_t vc,
97 const char *texture, bool bVertScale, bool bHorScale,
98 float minX, float minY, float maxX, float maxY)
100 qtexture_t *pqtTexInfo;
102 // TTimo: there used to be a call to pfnHasShader here
103 // this was not necessary. In Radiant everything is shader.
104 // If a texture doesn't have a shader script, a default shader object is used.
105 // The IShader object was leaking also
106 // collect texture info: sizes, etc
107 IShader *i = GlobalShaderSystem().getShaderForName(texture);
108 pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly
111 float scale[2] = {0.5f, 0.5f};
112 float shift[2] = {0, 0};
115 float width = maxX - minX;
117 scale[0] = width / pqtTexInfo->width;
118 shift[0] = -(float) ((int) maxX % (int) width) / scale[0];
122 float height = maxY - minY;
124 scale[1] = height / pqtTexInfo->height;
125 shift[1] = (float) ((int) minY % (int) height) / scale[1];
128 _QERFaceData addFace;
129 FillDefaultTexture(&addFace, va, vb, vc, texture);
130 addFace.m_texdef.scale[0] = scale[0];
131 addFace.m_texdef.scale[1] = scale[1];
132 addFace.m_texdef.shift[0] = shift[0];
133 addFace.m_texdef.shift[1] = shift[1];
135 GlobalBrushCreator().Brush_addFace(brush, addFace);
137 // shouldn't even get here, as default missing texture should be returned if
138 // texture doesn't exist, but just in case
139 AddFaceWithTexture(brush, va, vb, vc, texture, false);
140 globalErrorStream() << "BobToolz::Invalid Texture Name-> " << texture;
142 // the IShader is not kept referenced, DecRef it
146 /************************
148 ************************/
150 void Build_Wedge(int dir, vec3_t min, vec3_t max, bool bUp)
152 NodeSmartReference newBrush(GlobalBrushCreator().createBrush());
154 vec3_t v1, v2, v3, v5, v6, v7, v8;
172 if (dir != MOVE_EAST) {
173 AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", false);
176 if (dir != MOVE_WEST) {
177 AddFaceWithTexture(newBrush, v7, v5, v8, "textures/common/caulk", false);
180 if (dir != MOVE_NORTH) {
181 AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", false);
184 if (dir != MOVE_SOUTH) {
185 AddFaceWithTexture(newBrush, v3, v8, v6, "textures/common/caulk", false);
188 AddFaceWithTexture(newBrush, v1, v2, v3, "textures/common/caulk", false);
190 if (dir == MOVE_EAST) {
191 AddFaceWithTexture(newBrush, v1, v3, v5, "textures/common/caulk", false);
194 if (dir == MOVE_WEST) {
195 AddFaceWithTexture(newBrush, v2, v6, v8, "textures/common/caulk", false);
198 if (dir == MOVE_NORTH) {
199 AddFaceWithTexture(newBrush, v1, v6, v5, "textures/common/caulk", false);
202 if (dir == MOVE_SOUTH) {
203 AddFaceWithTexture(newBrush, v7, v3, v8, "textures/common/caulk", false);
206 if (dir != MOVE_WEST) {
207 AddFaceWithTexture(newBrush, v7, v5, v8, "textures/common/caulk", false);
210 if (dir != MOVE_EAST) {
211 AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", false);
214 if (dir != MOVE_NORTH) {
215 AddFaceWithTexture(newBrush, v3, v8, v6, "textures/common/caulk", false);
218 if (dir != MOVE_SOUTH) {
219 AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", false);
223 AddFaceWithTexture(newBrush, v6, v5, v7, "textures/common/caulk", false);
225 if (dir == MOVE_WEST) {
226 AddFaceWithTexture(newBrush, v1, v5, v3, "textures/common/caulk", false);
229 if (dir == MOVE_EAST) {
230 AddFaceWithTexture(newBrush, v2, v8, v6, "textures/common/caulk", false);
233 if (dir == MOVE_NORTH) {
234 AddFaceWithTexture(newBrush, v1, v5, v6, "textures/common/caulk", false);
237 if (dir == MOVE_SOUTH) {
238 AddFaceWithTexture(newBrush, v7, v8, v3, "textures/common/caulk", false);
242 Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(newBrush);
245 //-----------------------------------------------------------------------------------
246 //-----------------------------------------------------------------------------------
249 Build_StairStep_Wedge(int dir, vec3_t min, vec3_t max, const char *mainTexture, const char *riserTexture, bool detail)
251 NodeSmartReference newBrush(GlobalBrushCreator().createBrush());
253 //----- Build Outer Bounds ---------
255 vec3_t v1, v2, v3, v5, v6, v7, v8;
271 //v8 needed this time, becoz of sloping faces (2-4-6-8)
273 //----------------------------------
275 AddFaceWithTexture(newBrush, v6, v5, v7, mainTexture, detail);
277 if (dir != MOVE_EAST) {
278 if (dir == MOVE_WEST) {
279 AddFaceWithTexture(newBrush, v5, v2, v7, riserTexture, detail);
281 AddFaceWithTexture(newBrush, v5, v2, v7, "textures/common/caulk", detail);
285 if (dir != MOVE_WEST) {
286 if (dir == MOVE_EAST) {
287 AddFaceWithTexture(newBrush, v1, v3, v6, riserTexture, detail);
289 AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", detail);
293 if (dir != MOVE_NORTH) {
294 if (dir == MOVE_SOUTH) {
295 AddFaceWithTexture(newBrush, v3, v5, v6, riserTexture, detail);
297 AddFaceWithTexture(newBrush, v3, v5, v6, "textures/common/caulk", detail);
301 if (dir != MOVE_SOUTH) {
302 if (dir == MOVE_NORTH) {
303 AddFaceWithTexture(newBrush, v1, v7, v2, riserTexture, detail);
305 AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", detail);
310 if (dir == MOVE_EAST) {
311 AddFaceWithTexture(newBrush, v1, v5, v3, "textures/common/caulk", detail);
314 if (dir == MOVE_WEST) {
315 AddFaceWithTexture(newBrush, v2, v8, v6, "textures/common/caulk", detail);
318 if (dir == MOVE_NORTH) {
319 AddFaceWithTexture(newBrush, v1, v5, v6, "textures/common/caulk", detail);
322 if (dir == MOVE_SOUTH) {
323 AddFaceWithTexture(newBrush, v7, v8, v3, "textures/common/caulk", detail);
326 Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(newBrush);
329 //-----------------------------------------------------------------------------------
330 //-----------------------------------------------------------------------------------
332 // internal use only, to get a box without finishing construction
333 scene::Node &Build_Get_BoundingCube_Selective(vec3_t min, vec3_t max, char *texture, bool *useFaces)
335 NodeSmartReference newBrush(GlobalBrushCreator().createBrush());
337 //----- Build Outer Bounds ---------
339 vec3_t v1, v2, v3, v5, v6, v7;
353 //----------------------------------
355 //----- Add Six Cube Faces ---------
358 AddFaceWithTexture(newBrush, v1, v2, v3, texture, false);
361 AddFaceWithTexture(newBrush, v1, v3, v6, texture, false);
364 AddFaceWithTexture(newBrush, v1, v7, v2, texture, false);
368 AddFaceWithTexture(newBrush, v5, v6, v3, texture, false);
371 AddFaceWithTexture(newBrush, v5, v2, v7, texture, false);
374 AddFaceWithTexture(newBrush, v5, v7, v6, texture, false);
377 //----------------------------------
382 scene::Node &Build_Get_BoundingCube(vec3_t min, vec3_t max, char *texture)
384 return Build_Get_BoundingCube_Selective(min, max, texture, bFacesAll);
387 //-----------------------------------------------------------------------------------
388 //-----------------------------------------------------------------------------------
390 void Build_StairStep(vec3_t min, vec3_t max, const char *mainTexture, const char *riserTexture, int direction)
392 NodeSmartReference newBrush(GlobalBrushCreator().createBrush());
394 //----- Build Outer Bounds ---------
396 vec3_t v1, v2, v3, v5, v6, v7;
410 //----------------------------------
412 AddFaceWithTexture(newBrush, v6, v5, v7, mainTexture, false);
413 // top gets current texture
416 if (direction == MOVE_EAST) {
417 AddFaceWithTexture(newBrush, v1, v3, v6, riserTexture, false);
419 AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", false);
421 // west facing side, etc...
424 if (direction == MOVE_NORTH) {
425 AddFaceWithTexture(newBrush, v1, v7, v2, riserTexture, false);
427 AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", false);
430 if (direction == MOVE_SOUTH) {
431 AddFaceWithTexture(newBrush, v3, v5, v6, riserTexture, false);
433 AddFaceWithTexture(newBrush, v3, v5, v6, "textures/common/caulk", false);
436 if (direction == MOVE_WEST) {
437 AddFaceWithTexture(newBrush, v7, v5, v2, riserTexture, false);
439 AddFaceWithTexture(newBrush, v7, v5, v2, "textures/common/caulk", false);
443 AddFaceWithTexture(newBrush, v1, v2, v3, "textures/common/caulk", false);
446 Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(newBrush);
450 //-----------------------------------------------------------------------------------
451 //-----------------------------------------------------------------------------------
453 void BuildDoorsX2(vec3_t min, vec3_t max,
454 bool bSclMainHor, bool bSclMainVert,
455 bool bSclTrimHor, bool bSclTrimVert,
456 const char *mainTexture, const char *trimTexture,
460 if (direction == 0) {
466 //----- Build Outer Bounds ---------
468 vec3_t v1, v2, v3, v5, v6, v7, ve_1, ve_2, ve_3;
482 float width = (max[xy] - min[xy]) / 2;
484 if (direction == 0) {
485 VectorCopy(v1, ve_1);
486 VectorCopy(v3, ve_2);
487 VectorCopy(v6, ve_3);
489 VectorCopy(v7, ve_1);
490 VectorCopy(v1, ve_2);
491 VectorCopy(v2, ve_3);
498 //----------------------------------
500 NodeSmartReference newBrush1(GlobalBrushCreator().createBrush());
501 NodeSmartReference newBrush2(GlobalBrushCreator().createBrush());
503 AddFaceWithTexture(newBrush1, v1, v2, v3, "textures/common/caulk", false);
504 AddFaceWithTexture(newBrush1, v5, v7, v6, "textures/common/caulk", false);
506 AddFaceWithTexture(newBrush2, v1, v2, v3, "textures/common/caulk", false);
507 AddFaceWithTexture(newBrush2, v5, v7, v6, "textures/common/caulk", false);
509 if (direction == 0) {
510 AddFaceWithTexture(newBrush1, v1, v3, v6, "textures/common/caulk", false);
511 AddFaceWithTexture(newBrush2, v5, v2, v7, "textures/common/caulk", false);
513 AddFaceWithTexture(newBrush1, v1, v7, v2, "textures/common/caulk", false);
514 AddFaceWithTexture(newBrush2, v5, v6, v3, "textures/common/caulk", false);
517 if (direction == 0) {
518 AddFaceWithTextureScaled(newBrush1, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
519 min[0], min[2], max[0], max[2]);
520 AddFaceWithTextureScaled(newBrush1, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
521 max[0], min[2], min[0], max[2]);
524 AddFaceWithTextureScaled(newBrush2, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
525 min[0], min[2], max[0], max[2]);
526 AddFaceWithTextureScaled(newBrush2, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
527 max[0], min[2], min[0], max[2]); // flip max/min to reverse tex dir
531 AddFaceWithTextureScaled(newBrush1, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
532 min[1], min[2], max[1], max[2]);
534 AddFaceWithTextureScaled(newBrush2, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
535 max[1], min[2], min[1], max[2]);
537 AddFaceWithTextureScaled(newBrush1, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
538 min[1], min[2], max[1], max[2]);
539 AddFaceWithTextureScaled(newBrush1, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
540 max[1], min[2], min[1], max[2]);
543 AddFaceWithTextureScaled(newBrush2, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
544 min[1], min[2], max[1], max[2]);
545 AddFaceWithTextureScaled(newBrush2, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
546 max[1], min[2], min[1], max[2]); // flip max/min to reverse tex dir
549 AddFaceWithTextureScaled(newBrush1, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
550 min[0], min[2], max[0], max[2]);
552 AddFaceWithTextureScaled(newBrush2, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
553 max[0], min[2], min[0], max[2]);
556 //----------------------------------
559 EntityClass *doorClass = GlobalEntityClassManager().findOrInsert("func_door", true);
560 NodeSmartReference pEDoor1(GlobalEntityCreator().createEntity(doorClass));
561 NodeSmartReference pEDoor2(GlobalEntityCreator().createEntity(doorClass));
563 if (direction == 0) {
564 Node_getEntity(pEDoor1)->setKeyValue("angle", "180");
565 Node_getEntity(pEDoor2)->setKeyValue("angle", "360");
567 Node_getEntity(pEDoor1)->setKeyValue("angle", "270");
568 Node_getEntity(pEDoor2)->setKeyValue("angle", "90");
571 srand((unsigned) time(NULL));
574 sprintf(teamname, "t%i", rand());
575 Node_getEntity(pEDoor1)->setKeyValue("team", teamname);
576 Node_getEntity(pEDoor2)->setKeyValue("team", teamname);
578 Node_getTraversable(pEDoor1)->insert(newBrush1);
579 Node_getTraversable(pEDoor2)->insert(newBrush2);
581 Node_getTraversable(GlobalSceneGraph().root())->insert(pEDoor1);
582 Node_getTraversable(GlobalSceneGraph().root())->insert(pEDoor2);
584 // ResetCurrentTexture();
587 //-----------------------------------------------------------------------------------
588 //-----------------------------------------------------------------------------------
590 void MakeBevel(vec3_t vMin, vec3_t vMax)
592 NodeSmartReference patch(GlobalPatchCreator().createPatch());
593 GlobalPatchCreator().Patch_resize(patch, 3, 3);
594 GlobalPatchCreator().Patch_setShader(patch, "textures/common/caulk");
595 PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints(patch);
596 vec3_t x_3, y_3, z_3;
604 z_3[1] = (vMax[2] + vMin[2]) / 2;
607 x_3[0] = 0; x_3[1] = 0; x_3[2] = 64;
608 y_3[0] = 0; y_3[1] = 64; y_3[2] = 64;
609 z_3[0] = 0; z_3[1] = 32; z_3[2] = 64;*/
610 for (int i = 0; i < 3; i++) {
611 for (int j = 0; j < 3; j++) {
612 PatchControl &p = matrix(i, j);
613 p.m_vertex[0] = x_3[i];
614 p.m_vertex[1] = y_3[i];
615 p.m_vertex[2] = z_3[j];
618 //does invert the matrix, else the patch face is on wrong side.
619 for (int i = 0; i < 3; i++) {
620 for (int j = 0; j < 1; j++) {
621 PatchControl &p = matrix(i, 2 - j);
622 PatchControl &q = matrix(i, j);
623 std::swap(p.m_vertex, q.m_vertex);
624 //std::swap(p.m_texcoord, q.m_texcoord);
627 GlobalPatchCreator().Patch_controlPointsChanged(patch);
628 //TODO - the patch has textures weird, patchmanip.h has all function it needs.. lots of duplicate code..
629 //NaturalTexture(patch);
630 Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(patch);
633 void BuildCornerStairs(vec3_t vMin, vec3_t vMax, int nSteps, const char *mainTexture, const char *riserTex)
635 vec3_t *topPoints = new vec3_t[nSteps + 1];
636 vec3_t *botPoints = new vec3_t[nSteps + 1];
638 //bool bFacesUse[6] = {true, true, false, true, false, false};
641 VectorCopy(vMin, centre);
644 int height = (int) (vMax[2] - vMin[2]) / nSteps;
647 VectorCopy(vMax, vTop);
648 VectorCopy(vMin, vBot);
649 vTop[2] = vMin[2] + height;
652 for (i = 0; i <= nSteps; i++) {
653 VectorCopy(centre, topPoints[i]);
654 VectorCopy(centre, botPoints[i]);
656 topPoints[i][2] = vMax[2];
657 botPoints[i][2] = vMin[2];
659 topPoints[i][0] -= 10 * sinf(Q_PI * i / (2 * nSteps));
660 topPoints[i][1] += 10 * cosf(Q_PI * i / (2 * nSteps));
662 botPoints[i][0] = topPoints[i][0];
663 botPoints[i][1] = topPoints[i][1];
667 for (int j = 0; j < 3; j++)
668 VectorCopy(topPoints[j], tp[j]);
670 for (i = 0; i < nSteps; i++) {
671 NodeSmartReference brush(GlobalBrushCreator().createBrush());
672 vec3_t v1, v2, v3, v5, v6, v7;
673 VectorCopy(vBot, v1);
674 VectorCopy(vBot, v2);
675 VectorCopy(vBot, v3);
676 VectorCopy(vTop, v5);
677 VectorCopy(vTop, v6);
678 VectorCopy(vTop, v7);
686 AddFaceWithTexture(brush, v1, v2, v3, "textures/common/caulk", false);
687 AddFaceWithTexture(brush, v1, v3, v6, "textures/common/caulk", false);
688 AddFaceWithTexture(brush, v5, v6, v3, "textures/common/caulk", false);
690 for (int j = 0; j < 3; j++) {
694 AddFaceWithTexture(brush, tp[2], tp[1], tp[0], mainTexture, false);
696 AddFaceWithTexture(brush, centre, botPoints[i + 1], topPoints[i + 1], "textures/common/caulk", false);
697 AddFaceWithTexture(brush, centre, topPoints[i], botPoints[i], riserTex, false);
699 Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(brush);
710 MakeBevel(vMin, vMax);