diff --git a/source/terrax/mainWindow.cpp b/source/terrax/mainWindow.cpp
index 2b9b8270d6d0ea98f04ab754583d675e0cc27b04..ab6b568737a1f8b14722bf9d522b926ad95de81d 100644
--- a/source/terrax/mainWindow.cpp
+++ b/source/terrax/mainWindow.cpp
@@ -2085,6 +2085,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 			XSetXformType(X2DXF_ROTATE);
 			break;
 
+		case ID_XFORM_MODE_CENTER:
+			g_xConfig.m_bUsePivot = false;
+			CheckToolbarButton(ID_XFORM_MODE_PIVOT, g_xConfig.m_bUsePivot);
+			CheckToolbarButton(ID_XFORM_MODE_CENTER, !g_xConfig.m_bUsePivot);
+
+			break;
+		case ID_XFORM_MODE_PIVOT:
+			g_xConfig.m_bUsePivot = true;
+			CheckToolbarButton(ID_XFORM_MODE_PIVOT, g_xConfig.m_bUsePivot);
+			CheckToolbarButton(ID_XFORM_MODE_CENTER, !g_xConfig.m_bUsePivot);
+			break;
+
 		case IDC_TIE_TO_OBJECT:
 			if(IsWindowEnabled(g_hButtonToEntityWnd))
 			{
@@ -3418,7 +3430,7 @@ LRESULT CALLBACK RenderWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
 							{
 								// create rotate command
 								s_pRotateCmd = new CCommandRotate(GetKeyState(VK_SHIFT) < 0);
-								s_pRotateCmd->setStartOrigin((g_xState.vSelectionBoundMax + g_xState.vSelectionBoundMin) * 0.5f * vMask, float3(1.0f) - vMask);
+								s_pRotateCmd->setStartOrigin((g_xConfig.m_bUsePivot ? g_xState.vSelectionPivot : (g_xState.vSelectionBoundMax + g_xState.vSelectionBoundMin) * 0.5f) * vMask, float3(1.0f) - vMask);
 								s_pRotateCmd->setStartPos(vStartPos);
 								XEnumerateObjects([&](IXEditorObject *pObj, bool isProxy, ICompoundObject *pParent){
 									if(pObj->isSelected()/* && (g_xConfig.m_bIgnoreGroups ? !isProxy : !pParent)*/)
@@ -4729,7 +4741,7 @@ void XUpdateGizmos()
 {
 	if(Button_GetCheck(g_hABArrowButton) && g_xState.bHasSelection)
 	{
-		float3 vPos = (g_xState.vSelectionBoundMin + g_xState.vSelectionBoundMax) * 0.5f;
+		float3 vPos = g_xConfig.m_bUsePivot ? g_xState.vSelectionPivot : (g_xState.vSelectionBoundMin + g_xState.vSelectionBoundMax) * 0.5f;
 		g_pGizmoMove->setPos(vPos);
 		if(!g_gizmoRotateCallback.isActive())
 		{
@@ -4849,7 +4861,7 @@ HWND CreateToolbar(HWND hWndParent)
 {
 	// Declare and initialize local constants.
 	const int ImageListID = 0;
-	const int numButtons = 8;
+	const int numButtons = 10;
 	const int bitmapSize = 16;
 
 	const DWORD buttonStyles = BTNS_AUTOSIZE;
@@ -4909,6 +4921,9 @@ HWND CreateToolbar(HWND hWndParent)
 		{MAKELONG(1, ImageListID), ID_XFORM_TRANSLATE, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)"Move [W]"},
 		{MAKELONG(2, ImageListID), ID_XFORM_ROTATE, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)"Rotate [R]"},
 		{0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
+		{MAKELONG(8, ImageListID), ID_XFORM_MODE_CENTER, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)"Use center"},
+		{MAKELONG(9, ImageListID), ID_XFORM_MODE_PIVOT, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)"Use pivot"},
+		{0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
 		{MAKELONG(6, ImageListID), ID_TOOLS_GROUP, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)"Group selected [Ctrl+G]"},
 		{MAKELONG(7, ImageListID), ID_TOOLS_UNGROUP, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)"Ungroup selected [Ctrl+U]"},
 		{MAKELONG(5, ImageListID), ID_IGNORE_GROUPS, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)"Toggle group ignore [Ctrl+W]"},
diff --git a/source/terrax/resource.h b/source/terrax/resource.h
index bdbd2937659c1c2521c71074b5341ca191f4b3a6..8b0c2331f8a92e4071aab850ebda31aae84af055 100644
Binary files a/source/terrax/resource.h and b/source/terrax/resource.h differ
diff --git a/source/terrax/resource/toolbar1.bmp b/source/terrax/resource/toolbar1.bmp
index dbb1f0b437a3419ade41cafc9834107c00921d22..eb7529bf301a6746730ae4c975acc9601860c34a 100644
Binary files a/source/terrax/resource/toolbar1.bmp and b/source/terrax/resource/toolbar1.bmp differ
diff --git a/source/terrax/resource/toolbar2.bmp b/source/terrax/resource/toolbar2.bmp
index 5051572bc72dbbd0c0b1a1af2b48dcd827182f2d..e581a1f306259eb0cd1bb90037e55cad7a7a2a8e 100644
Binary files a/source/terrax/resource/toolbar2.bmp and b/source/terrax/resource/toolbar2.bmp differ
diff --git a/source/terrax/terrax.cpp b/source/terrax/terrax.cpp
index 3b1fa6d3fb060191c6c4b9660eeef39427c26d72..fe5e84feea376064c905a7c4a976e976873275ab 100644
--- a/source/terrax/terrax.cpp
+++ b/source/terrax/terrax.cpp
@@ -736,6 +736,8 @@ int main(int argc, char **argv)
 	g_pXformEventChannel = pEngine->getCore()->getEventChannel<XEventEditorXformType>(EVENT_EDITOR_XFORM_TYPE_GUID);
 
 	XSetXformType(X2DXF_SCALE);
+	CheckToolbarButton(ID_XFORM_MODE_PIVOT, g_xConfig.m_bUsePivot);
+	CheckToolbarButton(ID_XFORM_MODE_CENTER, !g_xConfig.m_bUsePivot);
 
 	RECT rcTopLeft;
 	GetClientRect(g_hTopLeftWnd, &rcTopLeft);
@@ -945,6 +947,20 @@ int main(int argc, char **argv)
 						}
 					}
 
+					szVal = pCfg->getKey("terrax", "xform_use_pivot");
+					if(szVal)
+					{
+						int iVal = 0;
+						if(sscanf(szVal, "%d", &iVal))
+						{
+							g_xConfig.m_bUsePivot = iVal != 0;
+							CheckToolbarButton(ID_XFORM_MODE_PIVOT, g_xConfig.m_bUsePivot);
+							CheckToolbarButton(ID_XFORM_MODE_CENTER, !g_xConfig.m_bUsePivot);
+						}
+					}
+
+					
+
 					for(UINT i = 0; i < 4; ++i)
 					{
 						float3 vec;
@@ -1094,6 +1110,9 @@ int main(int argc, char **argv)
 
 				sprintf_s(szVal, "%d", g_xConfig.m_bIgnoreGroups ? 1 : 0);
 				pCfg->set("terrax", "ignore_groups", szVal);
+
+				sprintf_s(szVal, "%d", g_xConfig.m_bUsePivot ? 1 : 0);
+				pCfg->set("terrax", "xform_use_pivot", szVal);
 				
 				pCfg->save();
 				mem_release(pCfg);
@@ -2633,21 +2652,53 @@ void XUpdateSelectionBound()
 	g_xState.bHasSelection = false;
 	float3 vMin, vMax;
 
+	extern HWND g_hABArrowButton;
+	bool bTrackPivotObject = g_xConfig.m_bUsePivot && g_xState.activeWindow == XWP_TOP_LEFT && Button_GetCheck(g_hABArrowButton);
+	float fBestDist = FLT_MAX;
+
 	XEnumerateObjects([&](IXEditorObject *pObj, bool isProxy, ICompoundObject *pParent){
 		if(pObj->isSelected()/* && !(g_xConfig.m_bIgnoreGroups && isProxy)*/)
 		{
 			pObj->getBound(&vMin, &vMax);
+
+			if(bTrackPivotObject)
+			{
+				// raytest
+				g_xState.vWorldRayStart;
+				g_xState.vWorldRayDir;
+				if(pObj->hasVisualModel())
+				{
+					float3 vPos;
+					if(pObj->rayTest(g_xState.vWorldRayStart, g_xState.vWorldRayStart + g_xState.vWorldRayDir * 1000.0f, &vPos))
+					{
+						float fDist2 = SMVector3Length2(g_xState.vWorldRayStart - vPos);
+						if(fDist2 < fBestDist)
+						{
+							fBestDist = fDist2;
+							g_xState.pPivotSource = pObj;
+						}
+					}
+				}
+			}
+
 			if(!g_xState.bHasSelection)
 			{
 				g_xState.bHasSelection = true;
 				g_xState.vSelectionBoundMax = vMax;
 				g_xState.vSelectionBoundMin = vMin;
+				g_xState.vSelectionPivot = pObj->getPos();
 			}
 			else
 			{
 				g_xState.vSelectionBoundMax = (float3)SMVectorMax(g_xState.vSelectionBoundMax, vMax);
 				g_xState.vSelectionBoundMin = (float3)SMVectorMin(g_xState.vSelectionBoundMin, vMin);
 			}
+
+			if(g_xState.pPivotSource == pObj)
+			{
+				g_xState.vSelectionPivot = pObj->getPos();
+			}
+
 			return(XEOR_SKIP_CHILDREN);
 		}
 		return(XEOR_CONTINUE);
diff --git a/source/terrax/terrax.h b/source/terrax/terrax.h
index 5b96dbd418c38ab00ac785374378010235d37cec..0185bbc4a1dc142404940dce31f3b53946d79143 100644
--- a/source/terrax/terrax.h
+++ b/source/terrax/terrax.h
@@ -92,6 +92,7 @@ struct CTerraXConfig
 	bool m_bDottedGrid = false;
 	float m_fGridOpacity = 0.5f;
 	bool m_bIgnoreGroups = false;
+	bool m_bUsePivot = false;
 
 	X_VIEWPORT_LAYOUT m_xViewportLayout = XVIEW_2X2;
 };
@@ -108,6 +109,8 @@ struct CTerraXState: public TerraXState
 	bool bHasSelection = false;
 	float3_t vSelectionBoundMin;
 	float3_t vSelectionBoundMax;
+	float3_t vSelectionPivot;
+	IXEditorObject *pPivotSource = NULL;
 
 	X_2DXFORM_TYPE xformType = X2DXF_SCALE;