Experimental: add "XactCylinder" to make a better patch cylinder
authorRudolf Polzer <divverent@xonotic.org>
Fri, 7 Oct 2011 09:56:48 +0000 (11:56 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Fri, 7 Oct 2011 09:56:48 +0000 (11:56 +0200)
radiant/patch.cpp
radiant/patch.h
radiant/patchmanip.cpp

index ac96240..221d333 100644 (file)
@@ -1400,6 +1400,33 @@ void Patch::ConstructPrefab(const AABB& aabb, EPatchPrefab eType, int axis, std:
       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;
index d55e712..61ecba9 100644 (file)
@@ -102,6 +102,7 @@ enum EPatchPrefab
   eSqCylinder,
   eCone,
   eSphere,
+  eXactCylinder,
 };
 
 enum EMatrixMajor
index b8bccee..46818cf 100644 (file)
@@ -432,6 +432,13 @@ AABB PatchCreator_getBounds()
   return AABB(Vector3(0, 0, 0), Vector3(64, 64, 64));
 }
 
+void Patch_XactCylinder()
+{
+  UndoableCommand undo("patchCreateXactCylinder");
+
+  Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eXactCylinder, GlobalXYWnd_getCurrentViewType());
+}
+
 void Patch_Cylinder()
 {
   UndoableCommand undo("patchCreateCylinder");
@@ -743,6 +750,7 @@ void Patch_registerCommands()
   GlobalCommands_insert("DecPatchRow", FreeCaller<Patch_DeleteLastRow>(), Accelerator(GDK_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK));
   GlobalCommands_insert("NaturalizePatch", FreeCaller<Patch_NaturalTexture>(), Accelerator('N', (GdkModifierType)GDK_CONTROL_MASK));
   GlobalCommands_insert("PatchCylinder", FreeCaller<Patch_Cylinder>());
+  GlobalCommands_insert("PatchXactCylinder", FreeCaller<Patch_XactCylinder>());
   GlobalCommands_insert("PatchDenseCylinder", FreeCaller<Patch_DenseCylinder>());
   GlobalCommands_insert("PatchVeryDenseCylinder", FreeCaller<Patch_VeryDenseCylinder>());
   GlobalCommands_insert("PatchSquareCylinder", FreeCaller<Patch_SquareCylinder>());
@@ -788,6 +796,7 @@ void Patch_constructMenu(GtkMenu* menu)
     create_menu_item_with_mnemonic(menu_in_menu, "Dense Cylinder", "PatchDenseCylinder");
     create_menu_item_with_mnemonic(menu_in_menu, "Very Dense Cylinder", "PatchVeryDenseCylinder");
     create_menu_item_with_mnemonic(menu_in_menu, "Square Cylinder", "PatchSquareCylinder");
+    create_menu_item_with_mnemonic(menu_in_menu, "Exact Cylinder", "PatchXactCylinder");
   }
   menu_separator (menu);
   create_menu_item_with_mnemonic(menu, "End cap", "PatchEndCap");