2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 //-----------------------------------------------------------------------------
25 // implementation of isurfaceplugin-interface specifics
29 void QERApp_GetTwoSelectedPatch( patchMesh_t **p1, patchMesh_t **p2 ){
30 *p1 = NULL; *p2 = NULL;
31 for ( brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next )
33 if ( pb->patchBrush ) {
37 else if ( !( *p2 ) ) {
44 Sys_Printf( "WARNING: QERApp_GetTwoSelectedPatch failed (did not find two patches)\n" );
49 // Nurail: The following functions are used by the Surface Inspector module
51 // Queries the number of faces from selected brushes
52 int SI_GetSelectedFaceCountfromBrushes( void ){
57 if ( selected_brushes.next == &selected_brushes ) {
61 for ( b = selected_brushes.next; b != &selected_brushes; b = b->next )
62 if ( !( b->patchBrush ) ) {
63 for ( f = b->brush_faces; f ; f = f->next, num_of_faces++ ) ;
69 void SI_GetSelFacesTexdef( texdef_to_face_t *allocd_block_texdef ){
73 texdef_to_face_t *position, *prev_pos;
74 brushprimit_texdef_t bp;
76 if ( selected_brushes.next != &selected_brushes ) {
77 prev_pos = position = allocd_block_texdef;
78 for ( b = selected_brushes.next; b != &selected_brushes; b = b->next )
80 if ( !( b->patchBrush ) ) {
81 for ( f = b->brush_faces; f ; f = f->next )
85 position->texdef = f->texdef;
86 if ( g_qeglobals.m_bBrushPrimitMode ) {
87 ConvertTexMatWithQTexture( &f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL );
88 TexMatToFakeTexCoords( bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale );
89 position->orig_bp_texdef = bp;
91 position->orig_texdef = position->texdef;
92 prev_pos->next = position;
96 prev_pos->next = NULL;
100 else if ( g_ptrSelectedFaces.GetSize() != 0 ) {
101 f = (face_t *) g_ptrSelectedFaces.GetAt( 0 );
102 b = (brush_t *) g_ptrSelectedFaceBrushes.GetAt( 0 );
103 position = (texdef_to_face_t*) allocd_block_texdef;
106 position->texdef = f->texdef;
107 if ( g_qeglobals.m_bBrushPrimitMode ) {
108 ConvertTexMatWithQTexture( &f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL );
109 TexMatToFakeTexCoords( bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale );
110 position->orig_bp_texdef = bp;
112 position->orig_texdef = position->texdef;
114 for ( i = 1; i < g_ptrSelectedFaces.GetSize(); i++ )
116 f = (face_t *) g_ptrSelectedFaces.GetAt( i );
117 b = (brush_t *) g_ptrSelectedFaceBrushes.GetAt( i );
118 position = allocd_block_texdef + i;
121 position->texdef = f->texdef;
122 if ( g_qeglobals.m_bBrushPrimitMode ) {
123 ConvertTexMatWithQTexture( &f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL );
124 TexMatToFakeTexCoords( bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale );
125 position->orig_bp_texdef = bp;
127 position->orig_texdef = position->texdef;
128 prev_pos->next = position;
131 position->next = NULL;
139 This doesn't mess with CONTENTS_DETAIL needed for Quake2 content flag
142 void SetFaceTexdef_Q2( face_t *f, texdef_t *texdef, bool bFitScale ){
144 if ( strcmp( f->texdef.GetName(), texdef->GetName() ) != 0 ) { // set shader here instead of Brush_Build
145 Face_SetShader( f, texdef->GetName() );
150 // fit the scaling of the texture on the actual plane
151 vec3_t p1,p2,p3; // absolute coordinates
152 // compute absolute coordinates
153 ComputeAbsolute( f,p1,p2,p3 );
156 VectorSubtract( p2,p1,vx );
157 VectorNormalize( vx, vx );
158 VectorSubtract( p3,p1,vy );
159 VectorNormalize( vy, vy );
161 VectorScale( vx,texdef->scale[0],vx );
162 VectorScale( vy,texdef->scale[1],vy );
163 VectorAdd( p1,vx,p2 );
164 VectorAdd( p1,vy,p3 );
165 // compute back shift scale rot
166 AbsoluteToLocal( f->plane,f,p1,p2,p3 );
176 void SI_SetTexdef_FaceList( texdef_to_face_t* texdef_face_list, bool b_SetUndoPoint, bool bFit_to_Scale ){
177 texdef_to_face_t* texdef_to_face;
180 if ( g_pGameDescription->quake2 ) {
187 if ( !texdef_face_list ) {
191 if ( b_SetUndoPoint ) {
192 if ( g_ptrSelectedFaces.GetSize() > 1 ) {
193 Sys_FPrintf( SYS_WRN, "WARNING: Undo NOT supported for multiple face selections\n" );
195 else if ( ( selected_brushes.next != &selected_brushes ) || ( g_ptrSelectedFaces.GetSize() == 1 ) ) {
196 // Give something to undo to
197 for ( texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next )
199 SetFaceTexdef_Q2( texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale );
202 SetFaceTexdef( texdef_to_face->face, &texdef_to_face->orig_texdef, &texdef_to_face->orig_bp_texdef, bFit_to_Scale );
205 Undo_Start( "set facelist texdefs" );
207 if ( selected_brushes.next != &selected_brushes ) {
208 Undo_AddBrushList( &selected_brushes );
211 Undo_AddBrush( texdef_face_list->brush );
217 for ( texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next )
220 SetFaceTexdef_Q2( texdef_to_face->face, &texdef_to_face->texdef, bFit_to_Scale );
224 brushprimit_texdef_t brushprimit_texdef;
225 FakeTexCoordsToTexMat( texdef_to_face->texdef.shift, texdef_to_face->texdef.rotate, texdef_to_face->texdef.scale, brushprimit_texdef.coords );
226 SetFaceTexdef( texdef_to_face->face, &texdef_to_face->texdef, &brushprimit_texdef, bFit_to_Scale );
228 Brush_Build( texdef_to_face->brush );
229 if ( bFit_to_Scale ) {
230 texdef_to_face->texdef = texdef_to_face->face->texdef;
234 if ( b_SetUndoPoint ) {
235 if ( ( selected_brushes.next != &selected_brushes ) || ( g_ptrSelectedFaces.GetSize() == 1 ) ) {
236 if ( selected_brushes.next != &selected_brushes ) {
237 Undo_EndBrushList( &selected_brushes );
240 Undo_EndBrush( texdef_face_list->brush );
244 // Over-write the orig_texdef list, cementing the change.
245 for ( texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next )
247 texdef_to_face->orig_texdef = texdef_to_face->texdef;
248 texdef_to_face->orig_bp_texdef = texdef_to_face->face->brushprimit_texdef;
253 Sys_UpdateWindows( W_ALL );
256 void SI_FaceList_FitTexture( texdef_to_face_t* si_texdef_face_list, int nHeight, int nWidth ){
257 texdef_to_face_t* temp_texdef_face_list;
258 brushprimit_texdef_t bp;
260 if ( !si_texdef_face_list ) {
264 for ( temp_texdef_face_list = si_texdef_face_list; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next )
266 Face_FitTexture( temp_texdef_face_list->face, nHeight, nWidth );
267 Brush_Build( temp_texdef_face_list->brush,true,true,false,false );
268 // Write changes to our working Texdef list
270 if ( g_qeglobals.m_bBrushPrimitMode ) {
271 ConvertTexMatWithQTexture( &temp_texdef_face_list->face->brushprimit_texdef, QERApp_Shader_ForName( temp_texdef_face_list->face->texdef.GetName() )->getTexture(), &bp, NULL );
272 TexMatToFakeTexCoords( bp.coords, temp_texdef_face_list->face->texdef.shift, &temp_texdef_face_list->face->texdef.rotate, temp_texdef_face_list->face->texdef.scale );
274 temp_texdef_face_list->texdef = temp_texdef_face_list->face->texdef;
277 Sys_UpdateWindows( W_CAMERA );
281 GtkWindow* SI_GetMainWindow( void ){
282 return GTK_WINDOW( g_qeglobals_gui.d_main_window );
285 void SI_SetWinPos_from_Prefs( GtkWidget *win ){
286 load_window_pos( win, g_PrefsDlg.mWindowInfo.posSurfaceWnd );