-/*\r
-BobToolz plugin for GtkRadiant\r
-Copyright (C) 2001 Gordon Biggans\r
-\r
-This library is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU Lesser General Public\r
-License as published by the Free Software Foundation; either\r
-version 2.1 of the License, or (at your option) any later version.\r
-\r
-This library is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
-Lesser General Public License for more details.\r
-\r
-You should have received a copy of the GNU Lesser General Public\r
-License along with this library; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-*/\r
-\r
-// DPatch.cpp: implementation of the DPatch class.\r
-//\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-#include "StdAfx.h"\r
-#include "DPatch.h"\r
-#include "misc.h"\r
-#include "./dialogs/dialogs-gtk.h"\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Construction/Destruction\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-// Added patch merging, wahey!\r
-\r
-//\r
-// problem is, you cant put patches into entities as yet :(\r
-//\r
-\r
-DPatch::DPatch()\r
-{\r
- width = MIN_PATCH_WIDTH;\r
- height = MIN_PATCH_HEIGHT;\r
- QER_patch = NULL;\r
- QER_brush = NULL;\r
-}\r
-\r
-DPatch::~DPatch()\r
-{\r
-\r
-}\r
-\r
-void DPatch::SetTexture(const char *textureName)\r
-{\r
- strcpy(texture, textureName);\r
-}\r
-\r
-void CopyDrawVert(const drawVert_t* in, drawVert_t* out)\r
-{\r
- out->lightmap[0] = in->lightmap[0];\r
- out->lightmap[1] = in->lightmap[1];\r
- out->st[0] = in->st[0];\r
- out->st[1] = in->st[1];\r
- VectorCopy(in->normal, out->normal);\r
- VectorCopy(in->xyz, out->xyz);\r
-}\r
-\r
-void DPatch::BuildInRadiant(void* entity)\r
-{\r
- int nIndex = g_FuncTable.m_pfnCreatePatchHandle();\r
- //$ FIXME: m_pfnGetPatchHandle\r
- patchMesh_t* pm = g_FuncTable.m_pfnGetPatchData(nIndex);\r
-\r
- pm->height = height;\r
- pm->width = width;\r
-\r
- for(int x = 0; x < width; x++)\r
- for(int y = 0; y < height; y++)\r
- CopyDrawVert(&points[x][y], &pm->ctrl[x][y]);\r
-\r
- QER_patch = pm;\r
-\r
-/* if(entity)\r
- {\r
-// strcpy(pm->d_texture->name, texture);\r
-\r
- brush_t* brush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();\r
- brush->patchBrush = TRUE;\r
- brush->pPatch = pm; \r
-\r
- pm->pSymbiot = brush;\r
- pm->bSelected = false;\r
- pm->bOverlay = false; // bleh, f*cks up, just have to wait for a proper function\r
- pm->bDirty = true; // or get my own patch out....\r
- pm->nListID = -1;\r
-\r
- g_FuncTable.m_pfnCommitBrushHandleToEntity(brush, entity);\r
- }\r
- else*/ // patch to entity just plain dont work atm\r
-\r
- if(entity)\r
- g_FuncTable.m_pfnCommitPatchHandleToEntity(nIndex, pm, texture, entity);\r
- else\r
- g_FuncTable.m_pfnCommitPatchHandleToMap(nIndex, pm, texture);\r
-\r
- QER_brush = pm->pSymbiot;\r
-}\r
-\r
-void DPatch::LoadFromBrush_t(brush_t* brush)\r
-{\r
- QER_brush = brush;\r
- QER_patch = brush->pPatch;\r
-\r
- SetTexture(QER_patch->pShader->getName());\r
-\r
- for(int x = 0; x < QER_patch->width; x++)\r
- for(int y = 0; y < QER_patch->height; y++)\r
- CopyDrawVert(&QER_patch->ctrl[x][y], &points[x][y]);\r
-\r
- width = QER_patch->width;\r
- height = QER_patch->height;\r
-}\r
-\r
-void DPatch::RemoveFromRadiant()\r
-{\r
- if(QER_brush)\r
- g_FuncTable.m_pfnDeleteBrushHandle(QER_brush);\r
-}\r
-\r
-bool DPatch::ResetTextures(const char *oldTextureName, const char *newTextureName)\r
-{\r
- if( !oldTextureName || !strcmp(texture, oldTextureName))\r
- {\r
- strcpy(texture, newTextureName);\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-void Build1dArray(vec3_t* array, drawVert_t points[MAX_PATCH_WIDTH][MAX_PATCH_HEIGHT], \r
- int startX, int startY, int number, bool horizontal, bool inverse)\r
-{\r
- int x = startX, y = startY, i, step;\r
-\r
- if(inverse)\r
- step = -1;\r
- else\r
- step = 1;\r
-\r
- for(i = 0; i < number; i++)\r
- {\r
- VectorCopy(points[x][y].xyz, array[i]);\r
-\r
- if(horizontal)\r
- x+=step;\r
- else\r
- y+=step;\r
- }\r
-}\r
-\r
-void Print1dArray(vec3_t* array, int size)\r
-{\r
- for(int i = 0; i < size; i++)\r
- Sys_Printf("(%.0f %.0f %.0f)\t", array[i][0], array[i][1], array[i][2]);\r
- Sys_Printf("\n");\r
-}\r
-\r
-bool Compare1dArrays(vec3_t* a1, vec3_t* a2, int size)\r
-{\r
- int i;\r
- bool equal = true;\r
-\r
- for(i = 0; i < size; i++)\r
- {\r
- if(!VectorCompare(a1[i], a2[size-i-1]))\r
- {\r
- equal = false;\r
- break;\r
- }\r
- }\r
- return equal;\r
-}\r
-\r
-patch_merge_t DPatch::IsMergable(DPatch *other)\r
-{\r
- int i, j;\r
- vec3_t p1Array[4][MAX_PATCH_HEIGHT];\r
- vec3_t p2Array[4][MAX_PATCH_HEIGHT];\r
-\r
- int p1ArraySizes[4];\r
- int p2ArraySizes[4];\r
-\r
- patch_merge_t merge_info;\r
-\r
- Build1dArray(p1Array[0], this->points, 0, 0, this->width, true, false);\r
- Build1dArray(p1Array[1], this->points, this->width-1, 0, this->height, false, false);\r
- Build1dArray(p1Array[2], this->points, this->width-1, this->height-1, this->width, true, true);\r
- Build1dArray(p1Array[3], this->points, 0, this->height-1, this->height, false, true);\r
-\r
- Build1dArray(p2Array[0], other->points, 0, 0, other->width, true, false);\r
- Build1dArray(p2Array[1], other->points, other->width-1, 0, other->height, false, false);\r
- Build1dArray(p2Array[2], other->points, other->width-1, other->height-1, other->width, true, true);\r
- Build1dArray(p2Array[3], other->points, 0, other->height-1, other->height, false, true);\r
-\r
- p1ArraySizes[0] = this->width;\r
- p1ArraySizes[1] = this->height;\r
- p1ArraySizes[2] = this->width;\r
- p1ArraySizes[3] = this->height;\r
-\r
- p2ArraySizes[0] = other->width;\r
- p2ArraySizes[1] = other->height;\r
- p2ArraySizes[2] = other->width;\r
- p2ArraySizes[3] = other->height;\r
-\r
- for(i = 0; i < 4; i++)\r
- {\r
- for(j = 0; j < 4; j++)\r
- {\r
- if(p1ArraySizes[i] == p2ArraySizes[j])\r
- {\r
- if(Compare1dArrays(p1Array[i], p2Array[j], p1ArraySizes[i]))\r
- {\r
- merge_info.pos1 = i;\r
- merge_info.pos2 = j;\r
- merge_info.mergable = true;\r
- return merge_info;\r
- }\r
- }\r
- }\r
- }\r
- \r
- merge_info.mergable = false;\r
- return merge_info;\r
-}\r
-\r
-DPatch* DPatch::MergePatches(patch_merge_t merge_info, DPatch *p1, DPatch *p2)\r
-{\r
- while(merge_info.pos1 != 2)\r
- {\r
- p1->Transpose();\r
- merge_info.pos1--;\r
- if(merge_info.pos1 < 0)\r
- merge_info.pos1 += 4;\r
- }\r
-\r
- while(merge_info.pos2 != 0)\r
- {\r
- p2->Transpose();\r
- merge_info.pos2--;\r
- if(merge_info.pos2 < 0)\r
- merge_info.pos2 += 3;\r
- }\r
-\r
- int newHeight = p1->height + p2->height - 1;\r
- if(newHeight > MAX_PATCH_HEIGHT)\r
- return NULL;\r
-\r
- DPatch* newPatch = new DPatch();\r
-\r
- newPatch->height = newHeight;\r
- newPatch->width = p1->width;\r
- newPatch->SetTexture(p1->texture);\r
-\r
- int y = 0;\r
- int i;\r
- for(i = 0; i < p1->height; i++, y++)\r
- for(int x = 0; x < p1->width; x++)\r
- memcpy(&newPatch->points[x][y], &p1->points[x][i], sizeof(drawVert_t));\r
-\r
- for(i = 1; i < p2->height; i++, y++)\r
- for(int x = 0; x < p2->width; x++)\r
- memcpy(&newPatch->points[x][y], &p2->points[x][i], sizeof(drawVert_t));\r
-\r
-// newPatch->Invert();\r
-\r
- return newPatch;\r
-}\r
-\r
-void DPatch::Invert()\r
-{\r
- drawVert_t vertTemp;\r
- int i, j;\r
-\r
- for(i = 0 ; i < width ; i++ ) \r
- {\r
- for(j = 0; j < height / 2; j++)\r
- {\r
- memcpy(&vertTemp, &points[i][height - 1- j], sizeof (drawVert_t));\r
- memcpy(&points[i][height - 1 - j], &points[i][j], sizeof(drawVert_t));\r
- memcpy(&points[i][j], &vertTemp, sizeof(drawVert_t));\r
- }\r
- }\r
-}\r
-\r
-void DPatch::Transpose()\r
-{\r
- int i, j, w;\r
- drawVert_t dv;\r
-\r
- if ( width > height ) \r
- {\r
- for ( i = 0 ; i < height ; i++ ) \r
- {\r
- for ( j = i + 1 ; j < width ; j++ ) \r
- {\r
- if ( j < height ) \r
- {\r
- // swap the value\r
- memcpy(&dv, &points[j][i], sizeof(drawVert_t));\r
- memcpy(&points[j][i], &points[i][j], sizeof(drawVert_t));\r
- memcpy(&points[i][j], &dv, sizeof(drawVert_t));\r
- } \r
- else \r
- {\r
- // just copy\r
- memcpy(&points[i][j], &points[j][i], sizeof(drawVert_t));\r
- }\r
- }\r
- }\r
- } \r
- else \r
- {\r
- for ( i = 0 ; i < width ; i++ ) \r
- {\r
- for ( j = i + 1 ; j < height ; j++ ) \r
- {\r
- if ( j < width ) \r
- {\r
- // swap the value\r
- memcpy(&dv, &points[i][j], sizeof(drawVert_t));\r
- memcpy(&points[i][j], &points[j][i], sizeof(drawVert_t));\r
- memcpy(&points[j][i], &dv, sizeof(drawVert_t));\r
- } \r
- else \r
- {\r
- // just copy\r
- memcpy(&points[j][i], &points[i][j], sizeof(drawVert_t));\r
- }\r
- }\r
- }\r
- }\r
-\r
- w = width;\r
- width = height;\r
- height = w;\r
-\r
- Invert();\r
-}\r
-\r
-list<DPatch> DPatch::Split(bool rows, bool cols)\r
-{\r
- list<DPatch> patchList;\r
- int i;\r
- int x, y;\r
-\r
- if(rows && height >= 5)\r
- {\r
- for(i = 0; i < (height-1)/2; i++)\r
- {\r
- DPatch p;\r
-\r
- p.width = width;\r
- p.height = 3;\r
- p.SetTexture(texture);\r
-\r
- for(y = 0; y < 3; y++)\r
- {\r
- for(x = 0; x < p.width; x++)\r
- {\r
- memcpy(&p.points[x][y], &points[x][(i*2)+y], sizeof(drawVert_t));\r
- }\r
- }\r
- patchList.push_back(p);\r
- }\r
-\r
- if(cols && width >= 5)\r
- {\r
- list<DPatch> patchList2;\r
-\r
- for(list<DPatch>::iterator patches = patchList.begin(); patches != patchList.end(); patches++)\r
- {\r
- list<DPatch> patchList3 = (*patches).Split(false, true);\r
- \r
- for(list<DPatch>::iterator patches2 = patchList3.begin(); patches2 != patchList3.end(); patches2++)\r
- patchList2.push_front(*patches2);\r
- }\r
-\r
- return patchList2;\r
- }\r
- }\r
- else if(cols && width >= 5)\r
- {\r
- for(i = 0; i < (width-1)/2; i++)\r
- {\r
- DPatch p;\r
-\r
- p.height = height;\r
- p.width = 3;\r
- p.SetTexture(texture);\r
-\r
- for(x = 0; x < 3; x++)\r
- {\r
- for(y = 0; y < p.height; y++)\r
- {\r
- memcpy(&p.points[x][y], &points[(i*2)+x][y], sizeof(drawVert_t));\r
- }\r
- }\r
-\r
- patchList.push_back(p);\r
- }\r
- }\r
-\r
- return patchList;\r
-}\r
+/*
+ BobToolz plugin for GtkRadiant
+ Copyright (C) 2001 Gordon Biggans
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// DPatch.cpp: implementation of the DPatch class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "DPatch.h"
+
+#include <list>
+#include "str.h"
+#include "scenelib.h"
+
+#include "ipatch.h"
+
+#include "misc.h"
+#include "./dialogs/dialogs-gtk.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+// Added patch merging, wahey!
+
+//
+// problem is, you cant put patches into entities as yet :(
+//
+
+DPatch::DPatch(){
+ width = MIN_PATCH_WIDTH;
+ height = MIN_PATCH_HEIGHT;
+ QER_entity = NULL;
+ QER_brush = NULL;
+}
+
+DPatch::~DPatch(){
+
+}
+
+void DPatch::SetTexture( const char *textureName ){
+ strcpy( texture, textureName );
+}
+
+void CopyDrawVert( const drawVert_t* in, drawVert_t* out ){
+ out->lightmap[0] = in->lightmap[0];
+ out->lightmap[1] = in->lightmap[1];
+ out->st[0] = in->st[0];
+ out->st[1] = in->st[1];
+ VectorCopy( in->normal, out->normal );
+ VectorCopy( in->xyz, out->xyz );
+}
+
+void DPatch::BuildInRadiant( scene::Node* entity ){
+ NodeSmartReference patch( GlobalPatchCreator().createPatch() );
+
+ scene::Node& parent = entity != 0 ? *entity : GlobalRadiant().getMapWorldEntity();
+ Node_getTraversable( parent )->insert( patch );
+
+ GlobalPatchCreator().Patch_setShader( patch, texture );
+ GlobalPatchCreator().Patch_resize( patch, height, width );
+ PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch );
+ for ( int x = 0; x < width; x++ )
+ {
+ for ( int y = 0; y < height; y++ )
+ {
+ PatchControl& p = matrix( x, y );
+ p.m_vertex[0] = points[x][y].xyz[0];
+ p.m_vertex[1] = points[x][y].xyz[1];
+ p.m_vertex[2] = points[x][y].xyz[2];
+ p.m_texcoord[0] = points[x][y].st[0];
+ p.m_texcoord[1] = points[x][y].st[1];
+ }
+ }
+ GlobalPatchCreator().Patch_controlPointsChanged( patch );
+
+ QER_entity = entity;
+ QER_brush = patch.get_pointer();
+
+
+#if 0
+ int nIndex = g_FuncTable.m_pfnCreatePatchHandle();
+ //$ FIXME: m_pfnGetPatchHandle
+ patchMesh_t* pm = g_FuncTable.m_pfnGetPatchData( nIndex );
+
+ b->patchBrush = true;
+ b->pPatch = Patch_Alloc();
+ b->pPatch->setDims( width,height );
+
+ for ( int x = 0; x < width; x++ )
+ for ( int y = 0; y < height; y++ )
+ CopyDrawVert( &points[x][y], &pm->ctrl[x][y] );
+
+/* if(entity)
+ {
+ // strcpy(pm->d_texture->name, texture);
+
+ brush_t* brush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle();
+ brush->patchBrush = true;
+ brush->pPatch = pm;
+
+ pm->pSymbiot = brush;
+ pm->bSelected = false;
+ pm->bOverlay = false; // bleh, f*cks up, just have to wait for a proper function
+ pm->bDirty = true; // or get my own patch out....
+ pm->nListID = -1;
+
+ g_FuncTable.m_pfnCommitBrushHandleToEntity(brush, entity);
+ }
+ else*/ // patch to entity just plain dont work atm
+
+ if ( entity ) {
+ g_FuncTable.m_pfnCommitPatchHandleToEntity( nIndex, pm, texture, entity );
+ }
+ else{
+ g_FuncTable.m_pfnCommitPatchHandleToMap( nIndex, pm, texture );
+ }
+
+ QER_brush = pm->pSymbiot;
+#endif
+}
+
+void DPatch::LoadFromPatch( scene::Instance& patch ){
+ QER_entity = patch.path().parent().get_pointer();
+ QER_brush = patch.path().top().get_pointer();
+
+ PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch.path().top() );
+
+ width = static_cast<int>( matrix.x() );
+ height = static_cast<int>( matrix.y() );
+
+ for ( int x = 0; x < width; x++ )
+ {
+ for ( int y = 0; y < height; y++ )
+ {
+ PatchControl& p = matrix( x, y );
+ points[x][y].xyz[0] = p.m_vertex[0];
+ points[x][y].xyz[1] = p.m_vertex[1];
+ points[x][y].xyz[2] = p.m_vertex[2];
+ points[x][y].st[0] = p.m_texcoord[0];
+ points[x][y].st[1] = p.m_texcoord[1];
+ }
+ }
+ SetTexture( GlobalPatchCreator().Patch_getShader( patch.path().top() ) );
+
+#if 0
+ SetTexture( brush->pPatch->GetShader() );
+
+ width = brush->pPatch->getWidth();
+ height = brush->pPatch->getHeight();
+
+ for ( int x = 0; x < height; x++ )
+ {
+ for ( int y = 0; y < width; y++ )
+ {
+ float *p = brush->pPatch->ctrlAt( ROW,x,y );
+ p[0] = points[x][y].xyz[0];
+ p[1] = points[x][y].xyz[1];
+ p[2] = points[x][y].xyz[2];
+ p[3] = points[x][y].st[0];
+ p[4] = points[x][y].st[1];
+ }
+ }
+#endif
+}
+
+bool DPatch::ResetTextures( const char *oldTextureName, const char *newTextureName ){
+ if ( !oldTextureName || !strcmp( texture, oldTextureName ) ) {
+ strcpy( texture, newTextureName );
+ return true;
+ }
+
+ return false;
+}
+
+void Build1dArray( vec3_t* array, drawVert_t points[MAX_PATCH_WIDTH][MAX_PATCH_HEIGHT],
+ int startX, int startY, int number, bool horizontal, bool inverse ){
+ int x = startX, y = startY, i, step;
+
+ if ( inverse ) {
+ step = -1;
+ }
+ else{
+ step = 1;
+ }
+
+ for ( i = 0; i < number; i++ )
+ {
+ VectorCopy( points[x][y].xyz, array[i] );
+
+ if ( horizontal ) {
+ x += step;
+ }
+ else{
+ y += step;
+ }
+ }
+}
+
+void Print1dArray( vec3_t* array, int size ){
+ for ( int i = 0; i < size; i++ )
+ globalOutputStream() << "(" << array[i][0] << " " << array[i][1] << " " << array[i][2] << ")\t";
+ globalOutputStream() << "\n";
+}
+
+bool Compare1dArrays( vec3_t* a1, vec3_t* a2, int size ){
+ int i;
+ bool equal = true;
+
+ for ( i = 0; i < size; i++ )
+ {
+ if ( !VectorCompare( a1[i], a2[size - i - 1] ) ) {
+ equal = false;
+ break;
+ }
+ }
+ return equal;
+}
+
+patch_merge_t DPatch::IsMergable( DPatch *other ){
+ int i, j;
+ vec3_t p1Array[4][MAX_PATCH_HEIGHT];
+ vec3_t p2Array[4][MAX_PATCH_HEIGHT];
+
+ int p1ArraySizes[4];
+ int p2ArraySizes[4];
+
+ patch_merge_t merge_info;
+
+ Build1dArray( p1Array[0], this->points, 0, 0, this->width, true, false );
+ Build1dArray( p1Array[1], this->points, this->width - 1, 0, this->height, false, false );
+ Build1dArray( p1Array[2], this->points, this->width - 1, this->height - 1, this->width, true, true );
+ Build1dArray( p1Array[3], this->points, 0, this->height - 1, this->height, false, true );
+
+ Build1dArray( p2Array[0], other->points, 0, 0, other->width, true, false );
+ Build1dArray( p2Array[1], other->points, other->width - 1, 0, other->height, false, false );
+ Build1dArray( p2Array[2], other->points, other->width - 1, other->height - 1, other->width, true, true );
+ Build1dArray( p2Array[3], other->points, 0, other->height - 1, other->height, false, true );
+
+ p1ArraySizes[0] = this->width;
+ p1ArraySizes[1] = this->height;
+ p1ArraySizes[2] = this->width;
+ p1ArraySizes[3] = this->height;
+
+ p2ArraySizes[0] = other->width;
+ p2ArraySizes[1] = other->height;
+ p2ArraySizes[2] = other->width;
+ p2ArraySizes[3] = other->height;
+
+ for ( i = 0; i < 4; i++ )
+ {
+ for ( j = 0; j < 4; j++ )
+ {
+ if ( p1ArraySizes[i] == p2ArraySizes[j] ) {
+ if ( Compare1dArrays( p1Array[i], p2Array[j], p1ArraySizes[i] ) ) {
+ merge_info.pos1 = i;
+ merge_info.pos2 = j;
+ merge_info.mergable = true;
+ return merge_info;
+ }
+ }
+ }
+ }
+
+ merge_info.mergable = false;
+ return merge_info;
+}
+
+DPatch* DPatch::MergePatches( patch_merge_t merge_info, DPatch *p1, DPatch *p2 ){
+ while ( merge_info.pos1 != 2 )
+ {
+ p1->Transpose();
+ merge_info.pos1--;
+ if ( merge_info.pos1 < 0 ) {
+ merge_info.pos1 += 4;
+ }
+ }
+
+ while ( merge_info.pos2 != 0 )
+ {
+ p2->Transpose();
+ merge_info.pos2--;
+ if ( merge_info.pos2 < 0 ) {
+ merge_info.pos2 += 3;
+ }
+ }
+
+ int newHeight = p1->height + p2->height - 1;
+ if ( newHeight > MAX_PATCH_HEIGHT ) {
+ return NULL;
+ }
+
+ DPatch* newPatch = new DPatch();
+
+ newPatch->height = newHeight;
+ newPatch->width = p1->width;
+ newPatch->SetTexture( p1->texture );
+
+ for ( int y = 0; y < p1->height; y++ )
+ for ( int x = 0; x < p1->width; x++ )
+ newPatch->points[x][y] = p1->points[x][y];
+
+ for ( int y = 1; y < p2->height; y++ )
+ for ( int x = 0; x < p2->width; x++ )
+ newPatch->points[x][( y + p1->height - 1 )] = p2->points[x][y];
+
+// newPatch->Invert();
+ return newPatch;
+}
+
+void DPatch::Invert(){
+ int i, j;
+
+ for ( i = 0 ; i < width ; i++ )
+ {
+ for ( j = 0; j < height / 2; j++ )
+ {
+ std::swap( points[i][height - 1 - j], points[i][j] );
+ }
+ }
+}
+/*
+ //Was used for debugging, obsolete function
+ DPatch* DPatch::TransposePatch(DPatch *p1)
+ {
+ globalOutputStream() << "Source patch ";
+ p1->DebugPrint();
+ p1->Transpose();
+ globalOutputStream() << "Transposed";
+ p1->DebugPrint();
+
+ DPatch* newPatch = new DPatch();
+ newPatch->height = p1->height;
+ newPatch->width = p1->width;
+ newPatch->SetTexture(p1->texture);
+
+ for(int x = 0; x < p1->height; x++)
+ {
+ for(int y = 0; y < p1->width; y++)
+ {
+ newPatch->points[x][y] = p1->points[x][y];
+ }
+ }
+ return newPatch;
+ }
+
+ //Function to figure out what is actually going wrong.
+ void DPatch::DebugPrint()
+ {
+ globalOutputStream() << "width: " << width << "\theight: " << height << "\n";
+ for(int x = 0; x < height; x++)
+ {
+ for(int y = 0; y < width; y++)
+ {
+ globalOutputStream() << "\t(" << points[x][y].xyz[0] << " " << points[x][y].xyz[1] << " " << points[x][y].xyz[2] << ")\t";
+ }
+ globalOutputStream() << "\n";
+ }
+ }
+ */
+
+void DPatch::Transpose(){
+ int i, j, w;
+
+ if ( width > height ) {
+ for ( i = 0 ; i < height ; i++ )
+ {
+ for ( j = i + 1 ; j < width ; j++ )
+ {
+ if ( j < height ) {
+ // swap the value
+ std::swap( points[j][i], points[i][j] );
+ }
+ else
+ {
+ // just copy
+ points[i][j] = points[j][i];
+ }
+ }
+ }
+ }
+ else
+ {
+ for ( i = 0 ; i < width ; i++ )
+ {
+ for ( j = i + 1 ; j < height ; j++ )
+ {
+ if ( j < width ) {
+ // swap the value
+ std::swap( points[i][j], points[j][i] );
+ }
+ else
+ {
+ // just copy
+ points[j][i] = points[i][j];
+ }
+ }
+ }
+ }
+
+ w = width;
+ width = height;
+ height = w;
+
+ Invert();
+}
+
+std::list<DPatch> DPatch::SplitCols(){
+ std::list<DPatch> patchList;
+ int i;
+ int x, y;
+
+ if ( height >= 5 ) {
+ for ( i = 0; i < ( height - 1 ) / 2; i++ )
+ {
+ DPatch p;
+
+ p.width = width;
+ p.height = MIN_PATCH_HEIGHT;
+ p.SetTexture( texture );
+ for ( x = 0; x < p.width; x++ )
+ {
+ for ( y = 0; y < MIN_PATCH_HEIGHT; y++ )
+ {
+ p.points[x][y] = points[x][( i * 2 ) + y];
+ }
+ }
+ patchList.push_back( p );
+ }
+ }
+ else {
+ //globalErrorStream() << "bobToolz SplitPatchRows: Patch has not enough rows for splitting.\n";
+ patchList.push_back( *this );
+ }
+ return patchList;
+}
+
+std::list<DPatch> DPatch::SplitRows(){
+ std::list<DPatch> patchList;
+ int i;
+ int x, y;
+
+ if ( width >= 5 ) {
+ for ( i = 0; i < ( width - 1 ) / 2; i++ )
+ {
+ DPatch p;
+
+ p.width = MIN_PATCH_WIDTH;
+ p.height = height;
+ p.SetTexture( texture );
+
+ for ( x = 0; x < MIN_PATCH_WIDTH; x++ )
+ {
+ for ( y = 0; y < p.height; y++ )
+ {
+ p.points[x][y] = points[( i * 2 ) + x][y];
+ }
+ }
+ patchList.push_back( p );
+ }
+ }
+ else
+ {
+ patchList.push_back( *this );
+ }
+ return patchList;
+}
+
+std::list<DPatch> DPatch::Split(){
+ std::list<DPatch> patchList;
+ int i;
+ int x, y;
+
+ if ( width >= 5 ) {
+ std::list<DPatch> patchColList = SplitCols();
+ for ( std::list<DPatch>::iterator patchesCol = patchColList.begin(); patchesCol != patchColList.end(); patchesCol++ )
+ {
+ std::list<DPatch> patchRowList = ( *patchesCol ).SplitRows();
+ for ( std::list<DPatch>::iterator patchesRow = patchRowList.begin(); patchesRow != patchRowList.end(); patchesRow++ )
+ {
+ patchList.push_front( *patchesRow );
+ }
+ }
+ }
+ else if ( height >= 5 ) {
+ std::list<DPatch> patchRowList = SplitRows();
+ for ( std::list<DPatch>::iterator patchesRow = patchRowList.begin(); patchesRow != patchRowList.end(); patchesRow++ )
+ {
+ patchList.push_front( *patchesRow );
+ }
+ }
+ else
+ {
+ //globalErrorStream() << "bobToolz SplitPatchRows: Patch has not enough rows for splitting.\n";
+ patchList.push_back( *this );
+ }
+ return patchList;
+}