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"
50 //#include "dialogs-gtk.h"
52 /************************
54 ************************/
65 | / | / ----> WEST, definitely
71 /************************
73 ************************/
75 vec3_t g_Origin = {0.0f, 0.0f, 0.0f};
77 extern bool bFacesAll[];
79 /************************
81 ************************/
83 float Deg2Rad( float angle ){
84 return (float)( angle * Q_PI / 180 );
87 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 ){
99 qtexture_t* pqtTexInfo;
101 // TTimo: there used to be a call to pfnHasShader here
102 // this was not necessary. In Radiant everything is shader.
103 // If a texture doesn't have a shader script, a default shader object is used.
104 // The IShader object was leaking also
105 // collect texture info: sizes, etc
106 IShader* i = GlobalShaderSystem().getShaderForName( texture );
107 pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly
110 float scale[2] = {0.5f, 0.5f};
111 float shift[2] = {0, 0};
114 float width = maxX - minX;
116 scale[0] = width / pqtTexInfo->width;
117 shift[0] = -(float)( (int)maxX % (int)width ) / scale[0];
121 float height = maxY - minY;
123 scale[1] = height / pqtTexInfo->height;
124 shift[1] = (float)( (int)minY % (int)height ) / scale[1];
127 _QERFaceData addFace;
128 FillDefaultTexture( &addFace, va, vb, vc, texture );
129 addFace.m_texdef.scale[0] = scale[0];
130 addFace.m_texdef.scale[1] = scale[1];
131 addFace.m_texdef.shift[0] = shift[0];
132 addFace.m_texdef.shift[1] = shift[1];
134 GlobalBrushCreator().Brush_addFace( brush, addFace );
138 // shouldn't even get here, as default missing texture should be returned if
139 // texture doesn't exist, but just in case
140 AddFaceWithTexture( brush, va, vb, vc, texture, false );
141 globalErrorStream() << "BobToolz::Invalid Texture Name-> " << texture;
143 // the IShader is not kept referenced, DecRef it
147 /************************
149 ************************/
151 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;
155 VectorCopy( min, v1 );
156 VectorCopy( min, v2 );
157 VectorCopy( min, v3 );
158 VectorCopy( max, v5 );
159 VectorCopy( max, v6 );
160 VectorCopy( max, v7 );
161 VectorCopy( max, 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 );
208 if ( dir != MOVE_WEST ) {
209 AddFaceWithTexture( newBrush, v7, v5, v8, "textures/common/caulk", false );
212 if ( dir != MOVE_EAST ) {
213 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
216 if ( dir != MOVE_NORTH ) {
217 AddFaceWithTexture( newBrush, v3, v8, v6, "textures/common/caulk", false );
220 if ( dir != MOVE_SOUTH ) {
221 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
225 AddFaceWithTexture( newBrush, v6, v5, v7, "textures/common/caulk", false );
227 if ( dir == MOVE_WEST ) {
228 AddFaceWithTexture( newBrush, v1, v5, v3, "textures/common/caulk", false );
231 if ( dir == MOVE_EAST ) {
232 AddFaceWithTexture( newBrush, v2, v8, v6, "textures/common/caulk", false );
235 if ( dir == MOVE_NORTH ) {
236 AddFaceWithTexture( newBrush, v1, v5, v6, "textures/common/caulk", false );
239 if ( dir == MOVE_SOUTH ) {
240 AddFaceWithTexture( newBrush, v7, v8, v3, "textures/common/caulk", false );
244 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
247 //-----------------------------------------------------------------------------------
248 //-----------------------------------------------------------------------------------
250 void 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;
256 VectorCopy( min, v1 );
257 VectorCopy( min, v2 );
258 VectorCopy( min, v3 );
259 VectorCopy( max, v5 );
260 VectorCopy( max, v6 );
261 VectorCopy( max, v7 );
262 VectorCopy( max, 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 );
282 AddFaceWithTexture( newBrush, v5, v2, v7, "textures/common/caulk", detail );
286 if ( dir != MOVE_WEST ) {
287 if ( dir == MOVE_EAST ) {
288 AddFaceWithTexture( newBrush, v1, v3, v6, riserTexture, detail );
291 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", detail );
295 if ( dir != MOVE_NORTH ) {
296 if ( dir == MOVE_SOUTH ) {
297 AddFaceWithTexture( newBrush, v3, v5, v6, riserTexture, detail );
300 AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", detail );
304 if ( dir != MOVE_SOUTH ) {
305 if ( dir == MOVE_NORTH ) {
306 AddFaceWithTexture( newBrush, v1, v7, v2, riserTexture, detail );
309 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", detail );
314 if ( dir == MOVE_EAST ) {
315 AddFaceWithTexture( newBrush, v1, v5, v3, "textures/common/caulk", detail );
318 if ( dir == MOVE_WEST ) {
319 AddFaceWithTexture( newBrush, v2, v8, v6, "textures/common/caulk", detail );
322 if ( dir == MOVE_NORTH ) {
323 AddFaceWithTexture( newBrush, v1, v5, v6, "textures/common/caulk", detail );
326 if ( dir == MOVE_SOUTH ) {
327 AddFaceWithTexture( newBrush, v7, v8, v3, "textures/common/caulk", detail );
330 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
333 //-----------------------------------------------------------------------------------
334 //-----------------------------------------------------------------------------------
336 // internal use only, to get a box without finishing construction
337 scene::Node& Build_Get_BoundingCube_Selective( vec3_t min, vec3_t max, char* texture, bool* useFaces ){
338 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
340 //----- Build Outer Bounds ---------
342 vec3_t v1, v2, v3, v5, v6, v7;
343 VectorCopy( min, v1 );
344 VectorCopy( min, v2 );
345 VectorCopy( min, v3 );
346 VectorCopy( max, v5 );
347 VectorCopy( max, v6 );
348 VectorCopy( max, v7 );
356 //----------------------------------
358 //----- Add Six Cube Faces ---------
361 AddFaceWithTexture( newBrush, v1, v2, v3, texture, false );
364 AddFaceWithTexture( newBrush, v1, v3, v6, texture, false );
367 AddFaceWithTexture( newBrush, v1, v7, v2, texture, false );
371 AddFaceWithTexture( newBrush, v5, v6, v3, texture, false );
374 AddFaceWithTexture( newBrush, v5, v2, v7, texture, false );
377 AddFaceWithTexture( newBrush, v5, v7, v6, texture, false );
380 //----------------------------------
385 scene::Node& Build_Get_BoundingCube( vec3_t min, vec3_t max, char* texture ){
386 return Build_Get_BoundingCube_Selective( min, max, texture, bFacesAll );
389 //-----------------------------------------------------------------------------------
390 //-----------------------------------------------------------------------------------
392 void Build_StairStep( vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, int direction ){
393 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
395 //----- Build Outer Bounds ---------
397 vec3_t v1, v2, v3, v5, v6, v7;
398 VectorCopy( min, v1 );
399 VectorCopy( min, v2 );
400 VectorCopy( min, v3 );
401 VectorCopy( max, v5 );
402 VectorCopy( max, v6 );
403 VectorCopy( max, v7 );
411 //----------------------------------
413 AddFaceWithTexture( newBrush, v6, v5, v7, mainTexture, false );
414 // top gets current texture
417 if ( direction == MOVE_EAST ) {
418 AddFaceWithTexture( newBrush, v1, v3, v6, riserTexture, false );
421 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
423 // west facing side, etc...
426 if ( direction == MOVE_NORTH ) {
427 AddFaceWithTexture( newBrush, v1, v7, v2, riserTexture, false );
430 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
433 if ( direction == MOVE_SOUTH ) {
434 AddFaceWithTexture( newBrush, v3, v5, v6, riserTexture, false );
437 AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", false );
440 if ( direction == MOVE_WEST ) {
441 AddFaceWithTexture( newBrush, v7, v5, v2, riserTexture, false );
444 AddFaceWithTexture( newBrush, v7, v5, v2, "textures/common/caulk", false );
448 AddFaceWithTexture( newBrush, v1, v2, v3, "textures/common/caulk", false );
451 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
455 //-----------------------------------------------------------------------------------
456 //-----------------------------------------------------------------------------------
458 void BuildDoorsX2( vec3_t min, vec3_t max,
459 bool bSclMainHor, bool bSclMainVert,
460 bool bSclTrimHor, bool bSclTrimVert,
461 const char* mainTexture, const char* trimTexture,
464 if ( direction == 0 ) {
471 //----- Build Outer Bounds ---------
473 vec3_t v1, v2, v3, v5, v6, v7, ve_1, ve_2, ve_3;
474 VectorCopy( min, v1 );
475 VectorCopy( min, v2 );
476 VectorCopy( min, v3 );
477 VectorCopy( max, v5 );
478 VectorCopy( max, v6 );
479 VectorCopy( max, v7 );
487 float width = ( max[xy] - min[xy] ) / 2;
489 if ( direction == 0 ) {
490 VectorCopy( v1, ve_1 );
491 VectorCopy( v3, ve_2 );
492 VectorCopy( v6, ve_3 );
496 VectorCopy( v7, ve_1 );
497 VectorCopy( v1, ve_2 );
498 VectorCopy( v2, ve_3 );
505 //----------------------------------
507 NodeSmartReference newBrush1( GlobalBrushCreator().createBrush() );
508 NodeSmartReference newBrush2( GlobalBrushCreator().createBrush() );
510 AddFaceWithTexture( newBrush1, v1, v2, v3, "textures/common/caulk", false );
511 AddFaceWithTexture( newBrush1, v5, v7, v6, "textures/common/caulk", false );
513 AddFaceWithTexture( newBrush2, v1, v2, v3, "textures/common/caulk", false );
514 AddFaceWithTexture( newBrush2, v5, v7, v6, "textures/common/caulk", false );
516 if ( direction == 0 ) {
517 AddFaceWithTexture( newBrush1, v1, v3, v6, "textures/common/caulk", false );
518 AddFaceWithTexture( newBrush2, v5, v2, v7, "textures/common/caulk", false );
522 AddFaceWithTexture( newBrush1, v1, v7, v2, "textures/common/caulk", false );
523 AddFaceWithTexture( newBrush2, v5, v6, v3, "textures/common/caulk", false );
526 if ( direction == 0 ) {
527 AddFaceWithTextureScaled( newBrush1, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
528 min[0], min[2], max[0], max[2] );
529 AddFaceWithTextureScaled( newBrush1, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
530 max[0], min[2], min[0], max[2] );
533 AddFaceWithTextureScaled( newBrush2, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
534 min[0], min[2], max[0], max[2] );
535 AddFaceWithTextureScaled( newBrush2, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
536 max[0], min[2], min[0], max[2] ); // flip max/min to reverse tex dir
540 AddFaceWithTextureScaled( newBrush1, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
541 min[1], min[2], max[1], max[2] );
543 AddFaceWithTextureScaled( newBrush2, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
544 max[1], min[2], min[1], max[2] );
548 AddFaceWithTextureScaled( newBrush1, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
549 min[1], min[2], max[1], max[2] );
550 AddFaceWithTextureScaled( newBrush1, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
551 max[1], min[2], min[1], max[2] );
554 AddFaceWithTextureScaled( newBrush2, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
555 min[1], min[2], max[1], max[2] );
556 AddFaceWithTextureScaled( newBrush2, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
557 max[1], min[2], min[1], max[2] ); // flip max/min to reverse tex dir
560 AddFaceWithTextureScaled( newBrush1, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
561 min[0], min[2], max[0], max[2] );
563 AddFaceWithTextureScaled( newBrush2, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
564 max[0], min[2], min[0], max[2] );
567 //----------------------------------
570 EntityClass* doorClass = GlobalEntityClassManager().findOrInsert( "func_door", true );
571 NodeSmartReference pEDoor1( GlobalEntityCreator().createEntity( doorClass ) );
572 NodeSmartReference pEDoor2( GlobalEntityCreator().createEntity( doorClass ) );
574 if ( direction == 0 ) {
575 Node_getEntity( pEDoor1 )->setKeyValue( "angle", "180" );
576 Node_getEntity( pEDoor2 )->setKeyValue( "angle", "360" );
580 Node_getEntity( pEDoor1 )->setKeyValue( "angle", "270" );
581 Node_getEntity( pEDoor2 )->setKeyValue( "angle", "90" );
584 srand( (unsigned)time( NULL ) );
587 sprintf( teamname, "t%i", rand() );
588 Node_getEntity( pEDoor1 )->setKeyValue( "team", teamname );
589 Node_getEntity( pEDoor2 )->setKeyValue( "team", teamname );
591 Node_getTraversable( pEDoor1 )->insert( newBrush1 );
592 Node_getTraversable( pEDoor2 )->insert( newBrush2 );
594 Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor1 );
595 Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor2 );
597 // ResetCurrentTexture();
600 //-----------------------------------------------------------------------------------
601 //-----------------------------------------------------------------------------------
603 void MakeBevel( vec3_t vMin, vec3_t vMax ){
604 NodeSmartReference patch( GlobalPatchCreator().createPatch() );
605 GlobalPatchCreator().Patch_resize( patch, 3, 3 );
606 GlobalPatchCreator().Patch_setShader( patch, "textures/common/caulk" );
607 PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch );
608 vec3_t x_3, y_3, z_3;
609 x_3[0] = vMin[0]; x_3[1] = vMin[0]; x_3[2] = vMax[0];
610 y_3[0] = vMin[1]; y_3[1] = vMax[1]; y_3[2] = vMax[1];
611 z_3[0] = vMin[2]; z_3[1] = ( vMax[2] + vMin[2] ) / 2; z_3[2] = vMax[2];
613 x_3[0] = 0; x_3[1] = 0; x_3[2] = 64;
614 y_3[0] = 0; y_3[1] = 64; y_3[2] = 64;
615 z_3[0] = 0; z_3[1] = 32; z_3[2] = 64;*/
616 for ( int i = 0; i < 3; i++ )
618 for ( int j = 0; j < 3; j++ )
620 PatchControl& p = matrix( i, j );
621 p.m_vertex[0] = x_3[i];
622 p.m_vertex[1] = y_3[i];
623 p.m_vertex[2] = z_3[j];
626 //does invert the matrix, else the patch face is on wrong side.
627 for ( int i = 0 ; i < 3 ; i++ )
629 for ( int j = 0; j < 1; j++ )
631 PatchControl& p = matrix( i,2 - j );
632 PatchControl& q = matrix( i, j );
633 std::swap( p.m_vertex, q.m_vertex );
634 //std::swap(p.m_texcoord, q.m_texcoord);
637 GlobalPatchCreator().Patch_controlPointsChanged( patch );
638 //TODO - the patch has textures weird, patchmanip.h has all function it needs.. lots of duplicate code..
639 //NaturalTexture(patch);
640 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( patch );
643 void BuildCornerStairs( vec3_t vMin, vec3_t vMax, int nSteps, const char* mainTexture, const char* riserTex ){
644 vec3_t* topPoints = new vec3_t[nSteps + 1];
645 vec3_t* botPoints = new vec3_t[nSteps + 1];
647 //bool bFacesUse[6] = {true, true, false, true, false, false};
650 VectorCopy( vMin, centre );
653 int height = (int)( vMax[2] - vMin[2] ) / nSteps;
656 VectorCopy( vMax, vTop );
657 VectorCopy( vMin, vBot );
658 vTop[2] = vMin[2] + height;
661 for ( i = 0; i <= nSteps; i++ )
663 VectorCopy( centre, topPoints[i] );
664 VectorCopy( centre, botPoints[i] );
666 topPoints[i][2] = vMax[2];
667 botPoints[i][2] = vMin[2];
669 topPoints[i][0] -= 10 * sinf( Q_PI * i / ( 2 * nSteps ) );
670 topPoints[i][1] += 10 * cosf( Q_PI * i / ( 2 * nSteps ) );
672 botPoints[i][0] = topPoints[i][0];
673 botPoints[i][1] = topPoints[i][1];
677 for ( int j = 0; j < 3; j++ )
678 VectorCopy( topPoints[j], tp[j] );
680 for ( i = 0; i < nSteps; i++ )
682 NodeSmartReference brush( GlobalBrushCreator().createBrush() );
683 vec3_t v1, v2, v3, v5, v6, v7;
684 VectorCopy( vBot, v1 );
685 VectorCopy( vBot, v2 );
686 VectorCopy( vBot, v3 );
687 VectorCopy( vTop, v5 );
688 VectorCopy( vTop, v6 );
689 VectorCopy( vTop, v7 );
697 AddFaceWithTexture( brush, v1, v2, v3, "textures/common/caulk", false );
698 AddFaceWithTexture( brush, v1, v3, v6, "textures/common/caulk", false );
699 AddFaceWithTexture( brush, v5, v6, v3, "textures/common/caulk", false );
701 for ( int j = 0; j < 3; j++ )
704 AddFaceWithTexture( brush, tp[2], tp[1], tp[0], mainTexture, false );
706 AddFaceWithTexture( brush, centre, botPoints[i + 1], topPoints[i + 1], "textures/common/caulk", false );
707 AddFaceWithTexture( brush, centre, topPoints[i], botPoints[i], riserTex, false );
709 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( brush );
720 MakeBevel( vMin, vMax );