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 ){
82 return (float)( angle * Q_PI / 180 );
85 void AddFaceWithTexture( scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc, const char* texture, bool detail ){
86 _QERFaceData faceData;
87 FillDefaultTexture( &faceData, va, vb, vc, texture );
89 faceData.contents |= FACE_DETAIL;
91 GlobalBrushCreator().Brush_addFace( brush, faceData );
94 void AddFaceWithTextureScaled( scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc,
95 const char* texture, bool bVertScale, bool bHorScale,
96 float minX, float minY, float maxX, float maxY ){
97 qtexture_t* pqtTexInfo;
99 // TTimo: there used to be a call to pfnHasShader here
100 // this was not necessary. In Radiant everything is shader.
101 // If a texture doesn't have a shader script, a default shader object is used.
102 // The IShader object was leaking also
103 // collect texture info: sizes, etc
104 IShader* i = GlobalShaderSystem().getShaderForName( texture );
105 pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly
108 float scale[2] = {0.5f, 0.5f};
109 float shift[2] = {0, 0};
112 float width = maxX - minX;
114 scale[0] = width / pqtTexInfo->width;
115 shift[0] = -(float)( (int)maxX % (int)width ) / scale[0];
119 float height = maxY - minY;
121 scale[1] = height / pqtTexInfo->height;
122 shift[1] = (float)( (int)minY % (int)height ) / scale[1];
125 _QERFaceData addFace;
126 FillDefaultTexture( &addFace, va, vb, vc, texture );
127 addFace.m_texdef.scale[0] = scale[0];
128 addFace.m_texdef.scale[1] = scale[1];
129 addFace.m_texdef.shift[0] = shift[0];
130 addFace.m_texdef.shift[1] = shift[1];
132 GlobalBrushCreator().Brush_addFace( brush, addFace );
136 // shouldn't even get here, as default missing texture should be returned if
137 // texture doesn't exist, but just in case
138 AddFaceWithTexture( brush, va, vb, vc, texture, false );
139 globalErrorStream() << "BobToolz::Invalid Texture Name-> " << texture;
141 // the IShader is not kept referenced, DecRef it
145 /************************
147 ************************/
149 void Build_Wedge( int dir, vec3_t min, vec3_t max, bool bUp ){
150 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
152 vec3_t v1, v2, v3, v5, v6, v7, v8;
153 VectorCopy( min, v1 );
154 VectorCopy( min, v2 );
155 VectorCopy( min, v3 );
156 VectorCopy( max, v5 );
157 VectorCopy( max, v6 );
158 VectorCopy( max, v7 );
159 VectorCopy( max, v8 );
170 if ( dir != MOVE_EAST ) {
171 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
174 if ( dir != MOVE_WEST ) {
175 AddFaceWithTexture( newBrush, v7, v5, v8, "textures/common/caulk", false );
178 if ( dir != MOVE_NORTH ) {
179 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
182 if ( dir != MOVE_SOUTH ) {
183 AddFaceWithTexture( newBrush, v3, v8, v6, "textures/common/caulk", false );
186 AddFaceWithTexture( newBrush, v1, v2, v3, "textures/common/caulk", false );
188 if ( dir == MOVE_EAST ) {
189 AddFaceWithTexture( newBrush, v1, v3, v5, "textures/common/caulk", false );
192 if ( dir == MOVE_WEST ) {
193 AddFaceWithTexture( newBrush, v2, v6, v8, "textures/common/caulk", false );
196 if ( dir == MOVE_NORTH ) {
197 AddFaceWithTexture( newBrush, v1, v6, v5, "textures/common/caulk", false );
200 if ( dir == MOVE_SOUTH ) {
201 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 //-----------------------------------------------------------------------------------
248 void Build_StairStep_Wedge( int dir, vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, bool detail ){
249 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
251 //----- Build Outer Bounds ---------
253 vec3_t v1, v2, v3, v5, v6, v7, v8;
254 VectorCopy( min, v1 );
255 VectorCopy( min, v2 );
256 VectorCopy( min, v3 );
257 VectorCopy( max, v5 );
258 VectorCopy( max, v6 );
259 VectorCopy( max, v7 );
260 VectorCopy( max, v8 );
269 //v8 needed this time, becoz of sloping faces (2-4-6-8)
271 //----------------------------------
273 AddFaceWithTexture( newBrush, v6, v5, v7, mainTexture, detail );
275 if ( dir != MOVE_EAST ) {
276 if ( dir == MOVE_WEST ) {
277 AddFaceWithTexture( newBrush, v5, v2, v7, riserTexture, detail );
280 AddFaceWithTexture( newBrush, v5, v2, v7, "textures/common/caulk", detail );
284 if ( dir != MOVE_WEST ) {
285 if ( dir == MOVE_EAST ) {
286 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 );
298 AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", detail );
302 if ( dir != MOVE_SOUTH ) {
303 if ( dir == MOVE_NORTH ) {
304 AddFaceWithTexture( newBrush, v1, v7, v2, riserTexture, detail );
307 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", detail );
312 if ( dir == MOVE_EAST ) {
313 AddFaceWithTexture( newBrush, v1, v5, v3, "textures/common/caulk", detail );
316 if ( dir == MOVE_WEST ) {
317 AddFaceWithTexture( newBrush, v2, v8, v6, "textures/common/caulk", detail );
320 if ( dir == MOVE_NORTH ) {
321 AddFaceWithTexture( newBrush, v1, v5, v6, "textures/common/caulk", detail );
324 if ( dir == MOVE_SOUTH ) {
325 AddFaceWithTexture( newBrush, v7, v8, v3, "textures/common/caulk", detail );
328 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
331 //-----------------------------------------------------------------------------------
332 //-----------------------------------------------------------------------------------
334 // internal use only, to get a box without finishing construction
335 scene::Node& Build_Get_BoundingCube_Selective( vec3_t min, vec3_t max, char* texture, bool* useFaces ){
336 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
338 //----- Build Outer Bounds ---------
340 vec3_t v1, v2, v3, v5, v6, v7;
341 VectorCopy( min, v1 );
342 VectorCopy( min, v2 );
343 VectorCopy( min, v3 );
344 VectorCopy( max, v5 );
345 VectorCopy( max, v6 );
346 VectorCopy( max, v7 );
354 //----------------------------------
356 //----- Add Six Cube Faces ---------
359 AddFaceWithTexture( newBrush, v1, v2, v3, texture, false );
362 AddFaceWithTexture( newBrush, v1, v3, v6, texture, false );
365 AddFaceWithTexture( newBrush, v1, v7, v2, texture, false );
369 AddFaceWithTexture( newBrush, v5, v6, v3, texture, false );
372 AddFaceWithTexture( newBrush, v5, v2, v7, texture, false );
375 AddFaceWithTexture( newBrush, v5, v7, v6, texture, false );
378 //----------------------------------
383 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 ){
391 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
393 //----- Build Outer Bounds ---------
395 vec3_t v1, v2, v3, v5, v6, v7;
396 VectorCopy( min, v1 );
397 VectorCopy( min, v2 );
398 VectorCopy( min, v3 );
399 VectorCopy( max, v5 );
400 VectorCopy( max, v6 );
401 VectorCopy( max, v7 );
409 //----------------------------------
411 AddFaceWithTexture( newBrush, v6, v5, v7, mainTexture, false );
412 // top gets current texture
415 if ( direction == MOVE_EAST ) {
416 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 );
428 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
431 if ( direction == MOVE_SOUTH ) {
432 AddFaceWithTexture( newBrush, v3, v5, v6, riserTexture, false );
435 AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", false );
438 if ( direction == MOVE_WEST ) {
439 AddFaceWithTexture( newBrush, v7, v5, v2, riserTexture, false );
442 AddFaceWithTexture( newBrush, v7, v5, v2, "textures/common/caulk", false );
446 AddFaceWithTexture( newBrush, v1, v2, v3, "textures/common/caulk", false );
449 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
453 //-----------------------------------------------------------------------------------
454 //-----------------------------------------------------------------------------------
456 void BuildDoorsX2( vec3_t min, vec3_t max,
457 bool bSclMainHor, bool bSclMainVert,
458 bool bSclTrimHor, bool bSclTrimVert,
459 const char* mainTexture, const char* trimTexture,
462 if ( direction == 0 ) {
469 //----- Build Outer Bounds ---------
471 vec3_t v1, v2, v3, v5, v6, v7, ve_1, ve_2, ve_3;
472 VectorCopy( min, v1 );
473 VectorCopy( min, v2 );
474 VectorCopy( min, v3 );
475 VectorCopy( max, v5 );
476 VectorCopy( max, v6 );
477 VectorCopy( max, v7 );
485 float width = ( max[xy] - min[xy] ) / 2;
487 if ( direction == 0 ) {
488 VectorCopy( v1, ve_1 );
489 VectorCopy( v3, ve_2 );
490 VectorCopy( v6, ve_3 );
494 VectorCopy( v7, ve_1 );
495 VectorCopy( v1, ve_2 );
496 VectorCopy( v2, ve_3 );
503 //----------------------------------
505 NodeSmartReference newBrush1( GlobalBrushCreator().createBrush() );
506 NodeSmartReference newBrush2( GlobalBrushCreator().createBrush() );
508 AddFaceWithTexture( newBrush1, v1, v2, v3, "textures/common/caulk", false );
509 AddFaceWithTexture( newBrush1, v5, v7, v6, "textures/common/caulk", false );
511 AddFaceWithTexture( newBrush2, v1, v2, v3, "textures/common/caulk", false );
512 AddFaceWithTexture( newBrush2, v5, v7, v6, "textures/common/caulk", false );
514 if ( direction == 0 ) {
515 AddFaceWithTexture( newBrush1, v1, v3, v6, "textures/common/caulk", false );
516 AddFaceWithTexture( newBrush2, v5, v2, v7, "textures/common/caulk", false );
520 AddFaceWithTexture( newBrush1, v1, v7, v2, "textures/common/caulk", false );
521 AddFaceWithTexture( newBrush2, v5, v6, v3, "textures/common/caulk", false );
524 if ( direction == 0 ) {
525 AddFaceWithTextureScaled( newBrush1, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
526 min[0], min[2], max[0], max[2] );
527 AddFaceWithTextureScaled( newBrush1, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
528 max[0], min[2], min[0], max[2] );
531 AddFaceWithTextureScaled( newBrush2, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
532 min[0], min[2], max[0], max[2] );
533 AddFaceWithTextureScaled( newBrush2, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
534 max[0], min[2], min[0], max[2] ); // flip max/min to reverse tex dir
538 AddFaceWithTextureScaled( newBrush1, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
539 min[1], min[2], max[1], max[2] );
541 AddFaceWithTextureScaled( newBrush2, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
542 max[1], min[2], min[1], max[2] );
546 AddFaceWithTextureScaled( newBrush1, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
547 min[1], min[2], max[1], max[2] );
548 AddFaceWithTextureScaled( newBrush1, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
549 max[1], min[2], min[1], max[2] );
552 AddFaceWithTextureScaled( newBrush2, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
553 min[1], min[2], max[1], max[2] );
554 AddFaceWithTextureScaled( newBrush2, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
555 max[1], min[2], min[1], max[2] ); // flip max/min to reverse tex dir
558 AddFaceWithTextureScaled( newBrush1, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
559 min[0], min[2], max[0], max[2] );
561 AddFaceWithTextureScaled( newBrush2, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
562 max[0], min[2], min[0], max[2] );
565 //----------------------------------
568 EntityClass* doorClass = GlobalEntityClassManager().findOrInsert( "func_door", true );
569 NodeSmartReference pEDoor1( GlobalEntityCreator().createEntity( doorClass ) );
570 NodeSmartReference pEDoor2( GlobalEntityCreator().createEntity( doorClass ) );
572 if ( direction == 0 ) {
573 Node_getEntity( pEDoor1 )->setKeyValue( "angle", "180" );
574 Node_getEntity( pEDoor2 )->setKeyValue( "angle", "360" );
578 Node_getEntity( pEDoor1 )->setKeyValue( "angle", "270" );
579 Node_getEntity( pEDoor2 )->setKeyValue( "angle", "90" );
582 srand( (unsigned)time( NULL ) );
585 sprintf( teamname, "t%i", rand() );
586 Node_getEntity( pEDoor1 )->setKeyValue( "team", teamname );
587 Node_getEntity( pEDoor2 )->setKeyValue( "team", teamname );
589 Node_getTraversable( pEDoor1 )->insert( newBrush1 );
590 Node_getTraversable( pEDoor2 )->insert( newBrush2 );
592 Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor1 );
593 Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor2 );
595 // ResetCurrentTexture();
598 //-----------------------------------------------------------------------------------
599 //-----------------------------------------------------------------------------------
601 void MakeBevel( vec3_t vMin, vec3_t vMax ){
602 NodeSmartReference patch( GlobalPatchCreator().createPatch() );
603 GlobalPatchCreator().Patch_resize( patch, 3, 3 );
604 GlobalPatchCreator().Patch_setShader( patch, "textures/common/caulk" );
605 PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch );
606 vec3_t x_3, y_3, z_3;
607 x_3[0] = vMin[0]; x_3[1] = vMin[0]; x_3[2] = vMax[0];
608 y_3[0] = vMin[1]; y_3[1] = vMax[1]; y_3[2] = vMax[1];
609 z_3[0] = vMin[2]; z_3[1] = ( vMax[2] + vMin[2] ) / 2; z_3[2] = vMax[2];
611 x_3[0] = 0; x_3[1] = 0; x_3[2] = 64;
612 y_3[0] = 0; y_3[1] = 64; y_3[2] = 64;
613 z_3[0] = 0; z_3[1] = 32; z_3[2] = 64;*/
614 for ( int i = 0; i < 3; i++ )
616 for ( int j = 0; j < 3; j++ )
618 PatchControl& p = matrix( i, j );
619 p.m_vertex[0] = x_3[i];
620 p.m_vertex[1] = y_3[i];
621 p.m_vertex[2] = z_3[j];
624 //does invert the matrix, else the patch face is on wrong side.
625 for ( int i = 0 ; i < 3 ; i++ )
627 for ( int j = 0; j < 1; j++ )
629 PatchControl& p = matrix( i,2 - j );
630 PatchControl& q = matrix( i, j );
631 std::swap( p.m_vertex, q.m_vertex );
632 //std::swap(p.m_texcoord, q.m_texcoord);
635 GlobalPatchCreator().Patch_controlPointsChanged( patch );
636 //TODO - the patch has textures weird, patchmanip.h has all function it needs.. lots of duplicate code..
637 //NaturalTexture(patch);
638 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( patch );
641 void BuildCornerStairs( vec3_t vMin, vec3_t vMax, int nSteps, const char* mainTexture, const char* riserTex ){
642 vec3_t* topPoints = new vec3_t[nSteps + 1];
643 vec3_t* botPoints = new vec3_t[nSteps + 1];
645 //bool bFacesUse[6] = {true, true, false, true, false, false};
648 VectorCopy( vMin, centre );
651 int height = (int)( vMax[2] - vMin[2] ) / nSteps;
654 VectorCopy( vMax, vTop );
655 VectorCopy( vMin, vBot );
656 vTop[2] = vMin[2] + height;
659 for ( i = 0; i <= nSteps; i++ )
661 VectorCopy( centre, topPoints[i] );
662 VectorCopy( centre, botPoints[i] );
664 topPoints[i][2] = vMax[2];
665 botPoints[i][2] = vMin[2];
667 topPoints[i][0] -= 10 * sinf( Q_PI * i / ( 2 * nSteps ) );
668 topPoints[i][1] += 10 * cosf( Q_PI * i / ( 2 * nSteps ) );
670 botPoints[i][0] = topPoints[i][0];
671 botPoints[i][1] = topPoints[i][1];
675 for ( int j = 0; j < 3; j++ )
676 VectorCopy( topPoints[j], tp[j] );
678 for ( i = 0; i < nSteps; i++ )
680 NodeSmartReference brush( GlobalBrushCreator().createBrush() );
681 vec3_t v1, v2, v3, v5, v6, v7;
682 VectorCopy( vBot, v1 );
683 VectorCopy( vBot, v2 );
684 VectorCopy( vBot, v3 );
685 VectorCopy( vTop, v5 );
686 VectorCopy( vTop, v6 );
687 VectorCopy( vTop, v7 );
695 AddFaceWithTexture( brush, v1, v2, v3, "textures/common/caulk", false );
696 AddFaceWithTexture( brush, v1, v3, v6, "textures/common/caulk", false );
697 AddFaceWithTexture( brush, v5, v6, v3, "textures/common/caulk", false );
699 for ( int j = 0; j < 3; j++ )
702 AddFaceWithTexture( brush, tp[2], tp[1], tp[0], mainTexture, false );
704 AddFaceWithTexture( brush, centre, botPoints[i + 1], topPoints[i + 1], "textures/common/caulk", false );
705 AddFaceWithTexture( brush, centre, topPoints[i], botPoints[i], riserTex, false );
707 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( brush );
718 MakeBevel( vMin, vMax );