also support XactCone and XactSphere
authorRudolf Polzer <divverent@xonotic.org>
Fri, 7 Oct 2011 10:15:18 +0000 (12:15 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Fri, 7 Oct 2011 10:15:18 +0000 (12:15 +0200)
radiant/patch.cpp
radiant/patch.h
radiant/patchmanip.cpp

index 221d333..9ecb649 100644 (file)
@@ -1413,9 +1413,9 @@ void Patch::ConstructPrefab(const AABB& aabb, EPatchPrefab eType, int axis, std:
        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);
+               float angle = (M_PI * i) / n;
+               float x = vPos[1][0] + (vPos[2][0] - vPos[1][0]) * cos(angle) * ((i&1) ? f : 1.0f);
+               float y = vPos[1][1] + (vPos[2][1] - vPos[1][1]) * sin(angle) * ((i&1) ? f : 1.0f);
                for(j = 0; j < 3; ++j)
                {
                        float z = vPos[j][2];
@@ -1427,6 +1427,63 @@ void Patch::ConstructPrefab(const AABB& aabb, EPatchPrefab eType, int axis, std:
                }
        }
   }
+  else if (eType == eXactCone)
+  {
+       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;
+               for(j = 0; j < 3; ++j)
+               {
+                       float x = vPos[1][0] + ((2-j)/2.0f) * (vPos[2][0] - vPos[1][0]) * cos(angle) * ((i&1) ? f : 1.0f);
+                       float y = vPos[1][1] + ((2-j)/2.0f) * (vPos[2][1] - vPos[1][1]) * sin(angle) * ((i&1) ? f : 1.0f);
+                       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 == eXactSphere)
+  {
+       int n = 6; // n = number of segments
+       int m = 3; // m = number of segments
+       setDims(2 * n + 1, 2 * m + 1);
+
+       // 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);
+       float g = 1 / cos(M_PI / (2*m));
+       for(i = 0; i < 2*n+1; ++i)
+       {
+               float angle = (M_PI * i) / n;
+               for(j = 0; j < 2*m+1; ++j)
+               {
+                       float angle2 = (M_PI * j) / (2*m);
+                       float x = vPos[1][0] + (vPos[2][0] - vPos[1][0]) *  sin(angle2) * ((j&1) ? g : 1.0f) * cos(angle) * ((i&1) ? f : 1.0f);
+                       float y = vPos[1][1] + (vPos[2][1] - vPos[1][1]) *  sin(angle2) * ((j&1) ? g : 1.0f) * sin(angle) * ((i&1) ? f : 1.0f);
+                       float z = vPos[1][2] + (vPos[2][2] - vPos[1][2]) * -cos(angle2) * ((j&1) ? g : 1.0f);
+                       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 61ecba9..403c43b 100644 (file)
@@ -103,6 +103,8 @@ enum EPatchPrefab
   eCone,
   eSphere,
   eXactCylinder,
+  eXactSphere,
+  eXactCone,
 };
 
 enum EMatrixMajor
index 46818cf..744f29a 100644 (file)
@@ -439,6 +439,20 @@ void Patch_XactCylinder()
   Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eXactCylinder, GlobalXYWnd_getCurrentViewType());
 }
 
+void Patch_XactSphere()
+{
+  UndoableCommand undo("patchCreateXactSphere");
+
+  Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eXactSphere, GlobalXYWnd_getCurrentViewType());
+}
+
+void Patch_XactCone()
+{
+  UndoableCommand undo("patchCreateXactCone");
+
+  Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eXactCone, GlobalXYWnd_getCurrentViewType());
+}
+
 void Patch_Cylinder()
 {
   UndoableCommand undo("patchCreateCylinder");
@@ -750,10 +764,12 @@ 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>());
+  GlobalCommands_insert("PatchXactCylinder", FreeCaller<Patch_XactCylinder>());
+  GlobalCommands_insert("PatchXactSphere", FreeCaller<Patch_XactSphere>());
+  GlobalCommands_insert("PatchXactCone", FreeCaller<Patch_XactCone>());
   GlobalCommands_insert("PatchEndCap", FreeCaller<Patch_Endcap>());
   GlobalCommands_insert("PatchBevel", FreeCaller<Patch_Bevel>());
   GlobalCommands_insert("PatchSquareBevel", FreeCaller<Patch_SquareBevel>());
@@ -796,7 +812,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");
+    create_menu_item_with_mnemonic(menu_in_menu, "Exact Cylinder...", "PatchXactCylinder");
   }
   menu_separator (menu);
   create_menu_item_with_mnemonic(menu, "End cap", "PatchEndCap");
@@ -810,7 +826,10 @@ void Patch_constructMenu(GtkMenu* menu)
   }
   menu_separator (menu);
   create_menu_item_with_mnemonic(menu, "Cone", "PatchCone");
+  create_menu_item_with_mnemonic(menu, "Exact Cone...", "PatchXactCone");
+  menu_separator (menu);
   create_menu_item_with_mnemonic(menu, "Sphere", "PatchSphere");
+  create_menu_item_with_mnemonic(menu, "Exact Sphere...", "PatchXactSphere");
   menu_separator (menu);
   create_menu_item_with_mnemonic(menu, "Simple Patch Mesh...", "SimplePatchMesh");
   menu_separator (menu);