]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/patch.cpp
Experimental: add "XactCylinder" to make a better patch cylinder
[xonotic/netradiant.git] / radiant / patch.cpp
index 59be212ee50f6226371ccfb466be714b597758a3..221d333350b3326d504fdb3eae31e5accc25b938 100644 (file)
@@ -399,7 +399,8 @@ void Patch::Redisperse(EMatrixMajor mt)
 void Patch::Smooth(EMatrixMajor mt)
 {
   std::size_t w, h, width, height, row_stride, col_stride;
 void Patch::Smooth(EMatrixMajor mt)
 {
   std::size_t w, h, width, height, row_stride, col_stride;
-  PatchControl* p1, * p2, * p3;
+  bool wrap;
+  PatchControl* p1, * p2, * p3, * p2b;
 
   undoSave();
 
 
   undoSave();
 
@@ -422,6 +423,20 @@ void Patch::Smooth(EMatrixMajor mt)
     return;
   }
 
     return;
   }
 
+  wrap = true;
+  for(h=0;h<height;h++)
+  {
+       p1 = m_ctrl.data()+(h*row_stride);
+       p2 = p1+(2*width)*col_stride;
+       //globalErrorStream() << "compare " << p1->m_vertex << " and " << p2->m_vertex << "\n";
+       if(vector3_length_squared(vector3_subtracted(p1->m_vertex, p2->m_vertex)) > 1.0)
+       {
+         //globalErrorStream() << "too far\n";
+         wrap = false;
+         break;
+       }
+  }
+
   for(h=0;h<height;h++)
   {
     p1 = m_ctrl.data()+(h*row_stride)+col_stride;
   for(h=0;h<height;h++)
   {
     p1 = m_ctrl.data()+(h*row_stride)+col_stride;
@@ -432,6 +447,14 @@ void Patch::Smooth(EMatrixMajor mt)
       p2->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex);
       p1 = p3;
     }
       p2->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex);
       p1 = p3;
     }
+       if(wrap)
+       {
+         p1 = m_ctrl.data()+(h*row_stride)+(2*width-1)*col_stride;
+         p2 = m_ctrl.data()+(h*row_stride);
+         p2b = m_ctrl.data()+(h*row_stride)+(2*width)*col_stride;
+         p3 = m_ctrl.data()+(h*row_stride)+col_stride;
+         p2->m_vertex = p2b->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex);
+       }
   }
   
   controlPointsChanged();
   }
   
   controlPointsChanged();
@@ -753,7 +776,15 @@ void Patch::InsertPoints(EMatrixMajor mt, bool bFirst)
   std::size_t pos = 0;
   {
     PatchControl* p1 = m_ctrl.data();
   std::size_t pos = 0;
   {
     PatchControl* p1 = m_ctrl.data();
-    for(std::size_t w = 0; w != width; ++w, p1 += col_stride)
+       /*
+         if(GlobalSelectionSystem().countSelected() != 0) 
+         {  
+                 scene::Instance& instance = GlobalSelectionSystem().ultimateSelected();
+                 PatchInstance* patch = Instance_getPatch(instance);
+                 patch->m_selectable.isSelected();
+         }
+       */
+       for(std::size_t w = 0; w != width; ++w, p1 += col_stride)
     {
       {
         PatchControl* p2 = p1;
     {
       {
         PatchControl* p2 = p1;
@@ -808,7 +839,15 @@ void Patch::InsertPoints(EMatrixMajor mt, bool bFirst)
     ERROR_MESSAGE("neither row-major nor column-major");
     return;
   }
     ERROR_MESSAGE("neither row-major nor column-major");
     return;
   }
-
+    if(bFirst)
+    {
+               pos = height - 1;
+    }
+    else
+    {
+               pos = 2;
+    }
+       
   if(pos >= height)
   {
     if(bFirst)
   if(pos >= height)
   {
     if(bFirst)
@@ -955,7 +994,14 @@ void Patch::RemovePoints(EMatrixMajor mt, bool bFirst)
     ERROR_MESSAGE("neither row-major nor column-major");
     return;
   }
     ERROR_MESSAGE("neither row-major nor column-major");
     return;
   }
-
+    if(bFirst)
+    {
+               pos=height-3;
+    }
+    else
+    {
+               pos=2;
+    }
   if(pos >= height)
   {
     if(bFirst)
   if(pos >= height)
   {
     if(bFirst)
@@ -1336,7 +1382,7 @@ void Patch::ConstructPrefab(const AABB& aabb, EPatchPrefab eType, int axis, std:
         {
           pCtrl->m_vertex[0] = vPos[1][0];
           pCtrl->m_vertex[1] = vPos[1][1];
         {
           pCtrl->m_vertex[0] = vPos[1][0];
           pCtrl->m_vertex[1] = vPos[1][1];
-          pCtrl->m_vertex[2] = vPos[2][2];
+          pCtrl->m_vertex[2] = vPos[0][2];
         }
       }
       {
         }
       }
       {
@@ -1348,11 +1394,39 @@ void Patch::ConstructPrefab(const AABB& aabb, EPatchPrefab eType, int axis, std:
           pCtrl->m_vertex[2] = vPos[2][2];
         }
       }
           pCtrl->m_vertex[2] = vPos[2][2];
         }
       }
+         break;
     default:
       ERROR_MESSAGE("this should be unreachable");
       return;
     }
   }
     default:
       ERROR_MESSAGE("this should be unreachable");
       return;
     }
   }
+  else if (eType == eXactCylinder)
+  {
+       int n = 6; // n = number of segments
+       setDims(2 * n + 1, 3);
+
+       // vPos[0] = vector3_subtracted(aabb.origin, aabb.extents);
+       // vPos[1] = aabb.origin;
+       // vPos[2] = vector3_added(aabb.origin, aabb.extents);
+
+       int i, j;
+       float f = 1 / cos(M_PI / n);
+       for(i = 0; i < 2*n+1; ++i)
+       {
+               float angle  = (M_PI * i) / n;
+               float x = vPos[1][0] + cos(angle) * (vPos[2][0] - vPos[1][0]) * ((i&1) ? f : 1.0f);
+               float y = vPos[1][1] + sin(angle) * (vPos[2][1] - vPos[1][1]) * ((i&1) ? f : 1.0f);
+               for(j = 0; j < 3; ++j)
+               {
+                       float z = vPos[j][2];
+                       PatchControl *v;
+                       v = &m_ctrl.data()[j*(2*n+1)+i];
+                       v->m_vertex[0] = x;
+                       v->m_vertex[1] = y;
+                       v->m_vertex[2] = z;
+               }
+       }
+  }
   else if  (eType == eBevel)
   {
     unsigned char *pIndex;
   else if  (eType == eBevel)
   {
     unsigned char *pIndex;