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
20 // DPatch.cpp: implementation of the DPatch class.
22 //////////////////////////////////////////////////////////////////////
26 #include "gtkr_list.h"
34 //#include "DEntity.h"
37 #include "./dialogs/dialogs-gtk.h"
39 //////////////////////////////////////////////////////////////////////
40 // Construction/Destruction
41 //////////////////////////////////////////////////////////////////////
43 // Added patch merging, wahey!
46 // problem is, you cant put patches into entities as yet :(
51 width = MIN_PATCH_WIDTH;
52 height = MIN_PATCH_HEIGHT;
61 void DPatch::SetTexture(const char *textureName)
63 strcpy(texture, textureName);
66 void CopyDrawVert(const drawVert_t* in, drawVert_t* out)
68 out->lightmap[0] = in->lightmap[0];
69 out->lightmap[1] = in->lightmap[1];
70 out->st[0] = in->st[0];
71 out->st[1] = in->st[1];
72 VectorCopy(in->normal, out->normal);
73 VectorCopy(in->xyz, out->xyz);
76 void DPatch::BuildInRadiant(void* entity)
79 int nIndex = g_FuncTable.m_pfnCreatePatchHandle();
80 //$ FIXME: m_pfnGetPatchHandle
81 patchMesh_t* pm = g_FuncTable.m_pfnGetPatchData(nIndex);
84 b->pPatch = Patch_Alloc();
85 b->pPatch->setDims(width,height);
87 for(int x = 0; x < height; x++)
89 for(int y = 0; y < width; y++)
91 float *p = b->pPatch->ctrlAt(ROW,x,y);
92 p[0] = points[x][y].xyz[0];
93 p[1] = points[x][y].xyz[1];
94 p[2] = points[x][y].xyz[2];
95 p[3] = points[x][y].st[0];
96 p[4] = points[x][y].st[1];
101 g_FuncTable.m_pfnCommitBrushHandleToEntity(QER_brush, entity);
103 g_FuncTable.m_pfnCommitBrushHandle(QER_brush);
105 for(int x = 0; x < width; x++)
106 for(int y = 0; y < height; y++)
107 CopyDrawVert(&points[x][y], &pm->ctrl[x][y]);
113 // strcpy(pm->d_texture->name, texture);
115 brush_t* brush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();
116 brush->patchBrush = TRUE;
119 pm->pSymbiot = brush;
120 pm->bSelected = false;
121 pm->bOverlay = false; // bleh, f*cks up, just have to wait for a proper function
122 pm->bDirty = true; // or get my own patch out....
125 g_FuncTable.m_pfnCommitBrushHandleToEntity(brush, entity);
127 else*/ // patch to entity just plain dont work atm
130 g_FuncTable.m_pfnCommitPatchHandleToEntity(nIndex, pm, texture, entity);
132 g_FuncTable.m_pfnCommitPatchHandleToMap(nIndex, pm, texture);
134 QER_brush = pm->pSymbiot;
138 void DPatch::LoadFromBrush(scene::Node* brush)
143 SetTexture(brush->pPatch->GetShader());
145 width = brush->pPatch->getWidth();
146 height = brush->pPatch->getHeight();
148 for(int x = 0; x < height; x++)
150 for(int y = 0; y < width; y++)
152 float *p = brush->pPatch->ctrlAt(ROW,x,y);
153 p[0] = points[x][y].xyz[0];
154 p[1] = points[x][y].xyz[1];
155 p[2] = points[x][y].xyz[2];
156 p[3] = points[x][y].st[0];
157 p[4] = points[x][y].st[1];
163 void DPatch::RemoveFromRadiant()
168 g_FuncTable.m_pfnDeleteBrushHandle(QER_brush);
173 bool DPatch::ResetTextures(const char *oldTextureName, const char *newTextureName)
175 if( !oldTextureName || !strcmp(texture, oldTextureName))
177 strcpy(texture, newTextureName);
184 void Build1dArray(vec3_t* array, drawVert_t points[MAX_PATCH_WIDTH][MAX_PATCH_HEIGHT],
185 int startX, int startY, int number, bool horizontal, bool inverse)
187 int x = startX, y = startY, i, step;
194 for(i = 0; i < number; i++)
196 VectorCopy(points[x][y].xyz, array[i]);
205 void Print1dArray(vec3_t* array, int size)
207 for(int i = 0; i < size; i++)
208 Sys_Printf("(%.0f %.0f %.0f)\t", array[i][0], array[i][1], array[i][2]);
212 bool Compare1dArrays(vec3_t* a1, vec3_t* a2, int size)
217 for(i = 0; i < size; i++)
219 if(!VectorCompare(a1[i], a2[size-i-1]))
228 patch_merge_t DPatch::IsMergable(DPatch *other)
231 vec3_t p1Array[4][MAX_PATCH_HEIGHT];
232 vec3_t p2Array[4][MAX_PATCH_HEIGHT];
237 patch_merge_t merge_info;
239 Build1dArray(p1Array[0], this->points, 0, 0, this->width, true, false);
240 Build1dArray(p1Array[1], this->points, this->width-1, 0, this->height, false, false);
241 Build1dArray(p1Array[2], this->points, this->width-1, this->height-1, this->width, true, true);
242 Build1dArray(p1Array[3], this->points, 0, this->height-1, this->height, false, true);
244 Build1dArray(p2Array[0], other->points, 0, 0, other->width, true, false);
245 Build1dArray(p2Array[1], other->points, other->width-1, 0, other->height, false, false);
246 Build1dArray(p2Array[2], other->points, other->width-1, other->height-1, other->width, true, true);
247 Build1dArray(p2Array[3], other->points, 0, other->height-1, other->height, false, true);
249 p1ArraySizes[0] = this->width;
250 p1ArraySizes[1] = this->height;
251 p1ArraySizes[2] = this->width;
252 p1ArraySizes[3] = this->height;
254 p2ArraySizes[0] = other->width;
255 p2ArraySizes[1] = other->height;
256 p2ArraySizes[2] = other->width;
257 p2ArraySizes[3] = other->height;
259 for(i = 0; i < 4; i++)
261 for(j = 0; j < 4; j++)
263 if(p1ArraySizes[i] == p2ArraySizes[j])
265 if(Compare1dArrays(p1Array[i], p2Array[j], p1ArraySizes[i]))
269 merge_info.mergable = true;
276 merge_info.mergable = false;
280 DPatch* DPatch::MergePatches(patch_merge_t merge_info, DPatch *p1, DPatch *p2)
282 while(merge_info.pos1 != 2)
286 if(merge_info.pos1 < 0)
287 merge_info.pos1 += 4;
290 while(merge_info.pos2 != 0)
294 if(merge_info.pos2 < 0)
295 merge_info.pos2 += 3;
298 int newHeight = p1->height + p2->height - 1;
299 if(newHeight > MAX_PATCH_HEIGHT)
302 DPatch* newPatch = new DPatch();
304 newPatch->height = newHeight;
305 newPatch->width = p1->width;
306 newPatch->SetTexture(p1->texture);
310 for(i = 0; i < p1->height; i++, y++)
311 for(int x = 0; x < p1->width; x++)
312 memcpy(&newPatch->points[x][y], &p1->points[x][i], sizeof(drawVert_t));
314 for(i = 1; i < p2->height; i++, y++)
315 for(int x = 0; x < p2->width; x++)
316 memcpy(&newPatch->points[x][y], &p2->points[x][i], sizeof(drawVert_t));
318 // newPatch->Invert();
323 void DPatch::Invert()
328 for(i = 0 ; i < width ; i++ )
330 for(j = 0; j < height / 2; j++)
332 memcpy(&vertTemp, &points[i][height - 1- j], sizeof (drawVert_t));
333 memcpy(&points[i][height - 1 - j], &points[i][j], sizeof(drawVert_t));
334 memcpy(&points[i][j], &vertTemp, sizeof(drawVert_t));
339 void DPatch::Transpose()
344 if ( width > height )
346 for ( i = 0 ; i < height ; i++ )
348 for ( j = i + 1 ; j < width ; j++ )
353 memcpy(&dv, &points[j][i], sizeof(drawVert_t));
354 memcpy(&points[j][i], &points[i][j], sizeof(drawVert_t));
355 memcpy(&points[i][j], &dv, sizeof(drawVert_t));
360 memcpy(&points[i][j], &points[j][i], sizeof(drawVert_t));
367 for ( i = 0 ; i < width ; i++ )
369 for ( j = i + 1 ; j < height ; j++ )
374 memcpy(&dv, &points[i][j], sizeof(drawVert_t));
375 memcpy(&points[i][j], &points[j][i], sizeof(drawVert_t));
376 memcpy(&points[j][i], &dv, sizeof(drawVert_t));
381 memcpy(&points[j][i], &points[i][j], sizeof(drawVert_t));
394 list<DPatch> DPatch::Split(bool rows, bool cols)
396 list<DPatch> patchList;
400 if(rows && height >= 5)
402 for(i = 0; i < (height-1)/2; i++)
408 p.SetTexture(texture);
410 for(y = 0; y < 3; y++)
412 for(x = 0; x < p.width; x++)
414 memcpy(&p.points[x][y], &points[x][(i*2)+y], sizeof(drawVert_t));
417 patchList.push_back(p);
420 if(cols && width >= 5)
422 list<DPatch> patchList2;
424 for(list<DPatch>::iterator patches = patchList.begin(); patches != patchList.end(); patches++)
426 list<DPatch> patchList3 = (*patches).Split(false, true);
428 for(list<DPatch>::iterator patches2 = patchList3.begin(); patches2 != patchList3.end(); patches2++)
429 patchList2.push_front(*patches2);
435 else if(cols && width >= 5)
437 for(i = 0; i < (width-1)/2; i++)
443 p.SetTexture(texture);
445 for(x = 0; x < 3; x++)
447 for(y = 0; y < p.height; y++)
449 memcpy(&p.points[x][y], &points[(i*2)+x][y], sizeof(drawVert_t));
453 patchList.push_back(p);