2 BobToolz plugin for GtkRadiant
\r
3 Copyright (C) 2001 Gordon Biggans
\r
5 This library is free software; you can redistribute it and/or
\r
6 modify it under the terms of the GNU Lesser General Public
\r
7 License as published by the Free Software Foundation; either
\r
8 version 2.1 of the License, or (at your option) any later version.
\r
10 This library is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
13 Lesser General Public License for more details.
\r
15 You should have received a copy of the GNU Lesser General Public
\r
16 License along with this library; if not, write to the Free Software
\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 // DPatch.cpp: implementation of the DPatch class.
\r
22 //////////////////////////////////////////////////////////////////////
\r
27 #include "./dialogs/dialogs-gtk.h"
\r
29 //////////////////////////////////////////////////////////////////////
\r
30 // Construction/Destruction
\r
31 //////////////////////////////////////////////////////////////////////
\r
33 // Added patch merging, wahey!
\r
36 // problem is, you cant put patches into entities as yet :(
\r
41 width = MIN_PATCH_WIDTH;
\r
42 height = MIN_PATCH_HEIGHT;
\r
52 void DPatch::SetTexture(const char *textureName)
\r
54 strcpy(texture, textureName);
\r
57 void CopyDrawVert(const drawVert_t* in, drawVert_t* out)
\r
59 out->lightmap[0] = in->lightmap[0];
\r
60 out->lightmap[1] = in->lightmap[1];
\r
61 out->st[0] = in->st[0];
\r
62 out->st[1] = in->st[1];
\r
63 VectorCopy(in->normal, out->normal);
\r
64 VectorCopy(in->xyz, out->xyz);
\r
67 void DPatch::BuildInRadiant(void* entity)
\r
69 int nIndex = g_FuncTable.m_pfnCreatePatchHandle();
\r
70 //$ FIXME: m_pfnGetPatchHandle
\r
71 patchMesh_t* pm = g_FuncTable.m_pfnGetPatchData(nIndex);
\r
73 pm->height = height;
\r
76 for(int x = 0; x < width; x++)
\r
77 for(int y = 0; y < height; y++)
\r
78 CopyDrawVert(&points[x][y], &pm->ctrl[x][y]);
\r
84 // strcpy(pm->d_texture->name, texture);
\r
86 brush_t* brush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();
\r
87 brush->patchBrush = TRUE;
\r
88 brush->pPatch = pm;
\r
90 pm->pSymbiot = brush;
\r
91 pm->bSelected = false;
\r
92 pm->bOverlay = false; // bleh, f*cks up, just have to wait for a proper function
\r
93 pm->bDirty = true; // or get my own patch out....
\r
96 g_FuncTable.m_pfnCommitBrushHandleToEntity(brush, entity);
\r
98 else*/ // patch to entity just plain dont work atm
\r
101 g_FuncTable.m_pfnCommitPatchHandleToEntity(nIndex, pm, texture, entity);
\r
103 g_FuncTable.m_pfnCommitPatchHandleToMap(nIndex, pm, texture);
\r
105 QER_brush = pm->pSymbiot;
\r
108 void DPatch::LoadFromBrush_t(brush_t* brush)
\r
111 QER_patch = brush->pPatch;
\r
113 SetTexture(QER_patch->pShader->getName());
\r
115 for(int x = 0; x < QER_patch->width; x++)
\r
116 for(int y = 0; y < QER_patch->height; y++)
\r
117 CopyDrawVert(&QER_patch->ctrl[x][y], &points[x][y]);
\r
119 width = QER_patch->width;
\r
120 height = QER_patch->height;
\r
123 void DPatch::RemoveFromRadiant()
\r
126 g_FuncTable.m_pfnDeleteBrushHandle(QER_brush);
\r
129 bool DPatch::ResetTextures(const char *oldTextureName, const char *newTextureName)
\r
131 if( !oldTextureName || !strcmp(texture, oldTextureName))
\r
133 strcpy(texture, newTextureName);
\r
140 void Build1dArray(vec3_t* array, drawVert_t points[MAX_PATCH_WIDTH][MAX_PATCH_HEIGHT],
\r
141 int startX, int startY, int number, bool horizontal, bool inverse)
\r
143 int x = startX, y = startY, i, step;
\r
150 for(i = 0; i < number; i++)
\r
152 VectorCopy(points[x][y].xyz, array[i]);
\r
161 void Print1dArray(vec3_t* array, int size)
\r
163 for(int i = 0; i < size; i++)
\r
164 Sys_Printf("(%.0f %.0f %.0f)\t", array[i][0], array[i][1], array[i][2]);
\r
168 bool Compare1dArrays(vec3_t* a1, vec3_t* a2, int size)
\r
173 for(i = 0; i < size; i++)
\r
175 if(!VectorCompare(a1[i], a2[size-i-1]))
\r
184 patch_merge_t DPatch::IsMergable(DPatch *other)
\r
187 vec3_t p1Array[4][MAX_PATCH_HEIGHT];
\r
188 vec3_t p2Array[4][MAX_PATCH_HEIGHT];
\r
190 int p1ArraySizes[4];
\r
191 int p2ArraySizes[4];
\r
193 patch_merge_t merge_info;
\r
195 Build1dArray(p1Array[0], this->points, 0, 0, this->width, true, false);
\r
196 Build1dArray(p1Array[1], this->points, this->width-1, 0, this->height, false, false);
\r
197 Build1dArray(p1Array[2], this->points, this->width-1, this->height-1, this->width, true, true);
\r
198 Build1dArray(p1Array[3], this->points, 0, this->height-1, this->height, false, true);
\r
200 Build1dArray(p2Array[0], other->points, 0, 0, other->width, true, false);
\r
201 Build1dArray(p2Array[1], other->points, other->width-1, 0, other->height, false, false);
\r
202 Build1dArray(p2Array[2], other->points, other->width-1, other->height-1, other->width, true, true);
\r
203 Build1dArray(p2Array[3], other->points, 0, other->height-1, other->height, false, true);
\r
205 p1ArraySizes[0] = this->width;
\r
206 p1ArraySizes[1] = this->height;
\r
207 p1ArraySizes[2] = this->width;
\r
208 p1ArraySizes[3] = this->height;
\r
210 p2ArraySizes[0] = other->width;
\r
211 p2ArraySizes[1] = other->height;
\r
212 p2ArraySizes[2] = other->width;
\r
213 p2ArraySizes[3] = other->height;
\r
215 for(i = 0; i < 4; i++)
\r
217 for(j = 0; j < 4; j++)
\r
219 if(p1ArraySizes[i] == p2ArraySizes[j])
\r
221 if(Compare1dArrays(p1Array[i], p2Array[j], p1ArraySizes[i]))
\r
223 merge_info.pos1 = i;
\r
224 merge_info.pos2 = j;
\r
225 merge_info.mergable = true;
\r
232 merge_info.mergable = false;
\r
236 DPatch* DPatch::MergePatches(patch_merge_t merge_info, DPatch *p1, DPatch *p2)
\r
238 while(merge_info.pos1 != 2)
\r
242 if(merge_info.pos1 < 0)
\r
243 merge_info.pos1 += 4;
\r
246 while(merge_info.pos2 != 0)
\r
250 if(merge_info.pos2 < 0)
\r
251 merge_info.pos2 += 3;
\r
254 int newHeight = p1->height + p2->height - 1;
\r
255 if(newHeight > MAX_PATCH_HEIGHT)
\r
258 DPatch* newPatch = new DPatch();
\r
260 newPatch->height = newHeight;
\r
261 newPatch->width = p1->width;
\r
262 newPatch->SetTexture(p1->texture);
\r
266 for(i = 0; i < p1->height; i++, y++)
\r
267 for(int x = 0; x < p1->width; x++)
\r
268 memcpy(&newPatch->points[x][y], &p1->points[x][i], sizeof(drawVert_t));
\r
270 for(i = 1; i < p2->height; i++, y++)
\r
271 for(int x = 0; x < p2->width; x++)
\r
272 memcpy(&newPatch->points[x][y], &p2->points[x][i], sizeof(drawVert_t));
\r
274 // newPatch->Invert();
\r
279 void DPatch::Invert()
\r
281 drawVert_t vertTemp;
\r
284 for(i = 0 ; i < width ; i++ )
\r
286 for(j = 0; j < height / 2; j++)
\r
288 memcpy(&vertTemp, &points[i][height - 1- j], sizeof (drawVert_t));
\r
289 memcpy(&points[i][height - 1 - j], &points[i][j], sizeof(drawVert_t));
\r
290 memcpy(&points[i][j], &vertTemp, sizeof(drawVert_t));
\r
295 void DPatch::Transpose()
\r
300 if ( width > height )
\r
302 for ( i = 0 ; i < height ; i++ )
\r
304 for ( j = i + 1 ; j < width ; j++ )
\r
309 memcpy(&dv, &points[j][i], sizeof(drawVert_t));
\r
310 memcpy(&points[j][i], &points[i][j], sizeof(drawVert_t));
\r
311 memcpy(&points[i][j], &dv, sizeof(drawVert_t));
\r
316 memcpy(&points[i][j], &points[j][i], sizeof(drawVert_t));
\r
323 for ( i = 0 ; i < width ; i++ )
\r
325 for ( j = i + 1 ; j < height ; j++ )
\r
330 memcpy(&dv, &points[i][j], sizeof(drawVert_t));
\r
331 memcpy(&points[i][j], &points[j][i], sizeof(drawVert_t));
\r
332 memcpy(&points[j][i], &dv, sizeof(drawVert_t));
\r
337 memcpy(&points[j][i], &points[i][j], sizeof(drawVert_t));
\r
350 list<DPatch> DPatch::Split(bool rows, bool cols)
\r
352 list<DPatch> patchList;
\r
356 if(rows && height >= 5)
\r
358 for(i = 0; i < (height-1)/2; i++)
\r
364 p.SetTexture(texture);
\r
366 for(y = 0; y < 3; y++)
\r
368 for(x = 0; x < p.width; x++)
\r
370 memcpy(&p.points[x][y], &points[x][(i*2)+y], sizeof(drawVert_t));
\r
373 patchList.push_back(p);
\r
376 if(cols && width >= 5)
\r
378 list<DPatch> patchList2;
\r
380 for(list<DPatch>::iterator patches = patchList.begin(); patches != patchList.end(); patches++)
\r
382 list<DPatch> patchList3 = (*patches).Split(false, true);
\r
384 for(list<DPatch>::iterator patches2 = patchList3.begin(); patches2 != patchList3.end(); patches2++)
\r
385 patchList2.push_front(*patches2);
\r
391 else if(cols && width >= 5)
\r
393 for(i = 0; i < (width-1)/2; i++)
\r
399 p.SetTexture(texture);
\r
401 for(x = 0; x < 3; x++)
\r
403 for(y = 0; y < p.height; y++)
\r
405 memcpy(&p.points[x][y], &points[(i*2)+x][y], sizeof(drawVert_t));
\r
409 patchList.push_back(p);
\r