/* Copyright (C) 1999-2007 id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant 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 General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ //----------------------------------------------------------------------------- // // DESCRIPTION: // implementation of isurfaceplugin-interface specifics #include "stdafx.h" void QERApp_GetTwoSelectedPatch( patchMesh_t **p1, patchMesh_t **p2 ) { *p1 = NULL; *p2 = NULL; for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) { if (pb->patchBrush) { if (!(*p1)) *p1 = pb->pPatch; else if (!(*p2)) { *p2 = pb->pPatch; return; } } } #ifdef _DEBUG Sys_Printf("WARNING: QERApp_GetTwoSelectedPatch failed (did not find two patches)\n"); #endif return; } // Nurail: The following functions are used by the Surface Inspector module // Queries the number of faces from selected brushes int SI_GetSelectedFaceCountfromBrushes(void) { face_t *f; brush_t *b; int num_of_faces = 0; if(selected_brushes.next == &selected_brushes) return(0); for(b=selected_brushes.next; b!=&selected_brushes; b=b->next) if (!(b->patchBrush)) for(f=b->brush_faces; f ; f=f->next, num_of_faces++); return num_of_faces; } void SI_GetSelFacesTexdef(texdef_to_face_t *allocd_block_texdef) { int i; face_t *f; brush_t *b; texdef_to_face_t *position, *prev_pos; if(selected_brushes.next != &selected_brushes) { prev_pos = position = allocd_block_texdef; for(b=selected_brushes.next; b!=&selected_brushes; b=b->next) { if ( !(b->patchBrush) ) { for(f=b->brush_faces; f ; f = f->next) { position->face = f; position->brush = b; position->texdef = f->texdef; position->orig_texdef = f->texdef; prev_pos->next = position; prev_pos = position; position++; } prev_pos->next = NULL; } } } else if(g_ptrSelectedFaces.GetSize() != 0) { f = (face_t *) g_ptrSelectedFaces.GetAt(0); b = (brush_t *) g_ptrSelectedFaceBrushes.GetAt(0); position = (texdef_to_face_t*) allocd_block_texdef; position->face = f; position->brush = b; position->texdef = f->texdef; position->orig_texdef = f->texdef; prev_pos = position; for(i=1; iface = f; position->brush = b; position->texdef = f->texdef; position->orig_texdef = f->texdef; prev_pos->next = position; prev_pos = position; } position->next = NULL; } } /* SetFaceTexdef_Q2 This doesn't mess with CONTENTS_DETAIL needed for Quake2 content flag */ void SetFaceTexdef_Q2 (face_t *f, texdef_t *texdef, bool bFitScale) { if(strcmp(f->texdef.GetName(), texdef->GetName()) != 0) // set shader here instead of Brush_Build Face_SetShader(f, texdef->GetName()); if (bFitScale) { f->texdef = *texdef; // fit the scaling of the texture on the actual plane vec3_t p1,p2,p3; // absolute coordinates // compute absolute coordinates ComputeAbsolute(f,p1,p2,p3); // compute the scale vec3_t vx,vy; VectorSubtract(p2,p1,vx); VectorNormalize(vx, vx); VectorSubtract(p3,p1,vy); VectorNormalize(vy, vy); // assign scale VectorScale(vx,texdef->scale[0],vx); VectorScale(vy,texdef->scale[1],vy); VectorAdd(p1,vx,p2); VectorAdd(p1,vy,p3); // compute back shift scale rot AbsoluteToLocal(f->plane,f,p1,p2,p3); } else { f->texdef = *texdef; } } void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoint, bool bFit_to_Scale) { texdef_to_face_t* texdef_to_face; bool b_isQuake2; if ( ( g_pGameDescription->mGameFile == "q2.game" ) || ( g_pGameDescription->mGameFile == "heretic2.game" ) ) b_isQuake2 = true; else b_isQuake2 = false; if (!texdef_face_list) return; if (b_SetUndoPoint) { if(g_ptrSelectedFaces.GetSize() > 1) Sys_FPrintf(SYS_WRN, "WARNING: Undo NOT supported for multiple face selections\n"); else if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1)) { // Give something to undo to for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) if (b_isQuake2) SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale); else SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, NULL); Undo_Start("set facelist texdefs"); if( selected_brushes.next != &selected_brushes ) Undo_AddBrushList(&selected_brushes); else Undo_AddBrush(texdef_face_list->brush); } } for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) { if (b_isQuake2) SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->texdef, bFit_to_Scale); else SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, NULL , bFit_to_Scale); Brush_Build(texdef_to_face->brush); if(bFit_to_Scale) texdef_to_face->texdef = texdef_to_face->face->texdef; } if ( b_SetUndoPoint ) { if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1) ) { if(selected_brushes.next != &selected_brushes) Undo_EndBrushList(&selected_brushes); else Undo_EndBrush(texdef_face_list->brush); Undo_End(); // Over-write the orig_texdef list, cementing the change. for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) texdef_to_face->orig_texdef = texdef_to_face->texdef; } } Sys_UpdateWindows (W_ALL); } void SI_FaceList_FitTexture(texdef_to_face_t* si_texdef_face_list, int nHeight, int nWidth) { texdef_to_face_t* temp_texdef_face_list; if (!si_texdef_face_list) return; for (temp_texdef_face_list = si_texdef_face_list; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next) { Face_FitTexture(temp_texdef_face_list->face, nHeight, nWidth); Brush_Build(temp_texdef_face_list->brush,true,true,false,false); // Write changes to our working Texdef list temp_texdef_face_list->texdef = temp_texdef_face_list->face->texdef; } Sys_UpdateWindows (W_CAMERA); } GtkWindow* SI_GetMainWindow(void) { return GTK_WINDOW(g_qeglobals_gui.d_main_window); } void SI_SetWinPos_from_Prefs(GtkWidget *win) { load_window_pos (win, g_PrefsDlg.mWindowInfo.posSurfaceWnd); }