diff --git a/source/SkyXEngine.h b/source/SkyXEngine.h
index 17c3b78428d385a0498ced1a3b77dc7714af249a..ac4aa28b0f46e2c71420e180e675e4ca5a5cae3d 100644
--- a/source/SkyXEngine.h
+++ b/source/SkyXEngine.h
@@ -292,7 +292,7 @@ QT стиль документирования (!) и QT_AUTOBRIEF - корот
 #ifndef __SKYXENGINE_H
 #define __SKYXENGINE_H
 
-#define SKYXENGINE_VERSION "X.1.2-dev"
+#define SKYXENGINE_VERSION "X.1.3-dev"
 
 #define SKYXENGINE_VERSION4EDITORS "SkyXEngine version " ## SKYXENGINE_VERSION
 
diff --git a/source/anim/AnimatedModel.cpp b/source/anim/AnimatedModel.cpp
index a3c0574a1c977d2e1567700b04f3d8ff7905972f..94e86e768baa097b4c5a7c599da192538e610a80 100644
--- a/source/anim/AnimatedModel.cpp
+++ b/source/anim/AnimatedModel.cpp
@@ -408,7 +408,7 @@ float3 XMETHODCALLTYPE CAnimatedModel::getBoneTransformPos(UINT id)
 		return(0);
 	}
 
-	return(getOrientation() * ((m_pRenderFrameBones[id].position - m_pRenderFrameBones[id].orient * (float3)m_pShared->getInvertedBindPose()[id].position)) + getPosition());
+	return(getOrientation() * ((m_pRenderFrameBones[id].position - m_pRenderFrameBones[id].orient * (float3)m_pShared->getInvertedBindPose()[id].position)) * m_fScale + getPosition());
 }
 SMQuaternion XMETHODCALLTYPE CAnimatedModel::getBoneTransformRot(UINT id)
 {
diff --git a/source/anim/AnimatedModelProvider.cpp b/source/anim/AnimatedModelProvider.cpp
index 03b6405f66a0c2f8d61c34a700f0b7c9db715a6a..2b5c106a205f70bd4ef06903e705bcd0cdd171d8 100644
--- a/source/anim/AnimatedModelProvider.cpp
+++ b/source/anim/AnimatedModelProvider.cpp
@@ -172,3 +172,30 @@ void CAnimatedModelProvider::computeVisibility(const IFrustum *pFrustum, CRender
 		}
 	}
 }
+
+void CAnimatedModelProvider::getLevelSize(const XEventLevelSize *pData)
+{
+	CAnimatedModel *pMdl;
+	float3 vMax, vMin;
+	for(UINT i = 0, l = m_apModels.size(); i < l; ++i)
+	{
+		pMdl = m_apModels[i];
+		if(pMdl->isEnabled())
+		{
+			float3 vDelta = pMdl->getPosition();
+			vMin = pMdl->getLocalBoundMin() + vDelta;
+			vMax = pMdl->getLocalBoundMax() + vDelta;
+
+			if(pData->vMax == pData->vMin)
+			{
+				pData->vMax = vMax;
+				pData->vMin = vMin;
+			}
+			else
+			{
+				pData->vMax = SMVectorMax(pData->vMax, vMax);
+				pData->vMin = SMVectorMin(pData->vMin, vMin);
+			}
+		}
+	}
+}
diff --git a/source/anim/AnimatedModelProvider.h b/source/anim/AnimatedModelProvider.h
index e8b64e8b7802525475afb462a14a1f77460c49cf..34a4cb0f67132fd16b2e8300c72ef650fc686a8a 100644
--- a/source/anim/AnimatedModelProvider.h
+++ b/source/anim/AnimatedModelProvider.h
@@ -28,6 +28,8 @@ public:
 	void render(CRenderableVisibility *pVisibility = NULL);
 	void computeVisibility(const IFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL);
 
+	void getLevelSize(const XEventLevelSize *pData);
+
 protected:
 	AssotiativeArray<IXResourceModelAnimated*, Array<CAnimatedModelShared*>> m_mModels;
 
diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp
index de848979bc95536eb0cf015c0b4cad1a371cb54b..c75ee49dcb9839676b43b6a50ff1acd6302dca59 100644
--- a/source/anim/DynamicModelProvider.cpp
+++ b/source/anim/DynamicModelProvider.cpp
@@ -134,3 +134,31 @@ void CDynamicModelProvider::computeVisibility(const IFrustum *pFrustum, CRendera
 		}
 	}
 }
+
+void CDynamicModelProvider::getLevelSize(const XEventLevelSize *pData)
+{
+	CDynamicModel *pMdl;
+	float3 vMax, vMin;
+	for(UINT i = 0, l = m_apModels.size(); i < l; ++i)
+	{
+		pMdl = m_apModels[i];
+		if(pMdl->isEnabled())
+		{
+			float3 vDelta = pMdl->getPosition();
+			vMin = pMdl->getLocalBoundMin() + vDelta;
+			vMax = pMdl->getLocalBoundMax() + vDelta;
+
+			if(pData->vMax == pData->vMin)
+			{
+				pData->vMax = vMax;
+				pData->vMin = vMin;
+			}
+			else
+			{
+				pData->vMax = SMVectorMax(pData->vMax, vMax);
+				pData->vMin = SMVectorMin(pData->vMin, vMin);
+			}
+
+		}
+	}
+}
diff --git a/source/anim/DynamicModelProvider.h b/source/anim/DynamicModelProvider.h
index 154919fad6228d2eeb186fd54016f5ac0c72fd0d..99b9f8edba6155d54a8858149864a16cdad6bda6 100644
--- a/source/anim/DynamicModelProvider.h
+++ b/source/anim/DynamicModelProvider.h
@@ -26,6 +26,8 @@ public:
 	void render(CRenderableVisibility *pVisibility = NULL);
 	void computeVisibility(const IFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL);
 
+	void getLevelSize(const XEventLevelSize *pData);
+
 protected:
 	AssotiativeArray<IXResourceModel*, CDynamicModelShared*> m_mModels;
 
diff --git a/source/anim/plugin_main.cpp b/source/anim/plugin_main.cpp
index b60c5827285714b8f4e4e662b51e1e4f8870e903..da7832bca5216cde9224261595b31a7ae9291de4 100644
--- a/source/anim/plugin_main.cpp
+++ b/source/anim/plugin_main.cpp
@@ -1,23 +1,48 @@
 #include <xcommon/IXPlugin.h>
+#include <xcommon/XEvents.h>
 #include "Renderable.h"
 #include "Updatable.h"
 #include "AnimatedModelProvider.h"
 #include "DynamicModelProvider.h"
 
+class CLevelSizeEventListener: public IEventListener<XEventLevelSize>
+{
+public:
+	CLevelSizeEventListener(CAnimatedModelProvider *pAnimatedModelProvider, CDynamicModelProvider *pDynamicModelProvider):
+		m_pAnimatedModelProvider(pAnimatedModelProvider),
+		m_pDynamicModelProvider(pDynamicModelProvider)
+	{
+	}
+	void onEvent(const XEventLevelSize *pData)
+	{
+		m_pDynamicModelProvider->getLevelSize(pData);
+		m_pAnimatedModelProvider->getLevelSize(pData);
+	}
+
+protected:
+	CAnimatedModelProvider *m_pAnimatedModelProvider;
+	CDynamicModelProvider *m_pDynamicModelProvider;
+};
 
 class CDSEPlugin: public IXPlugin
 {
 public:
 	void XMETHODCALLTYPE startup(IXCore *pCore) override
 	{
+		m_pCore = pCore;
 		m_pAnimatedModelProvider = new CAnimatedModelProvider(pCore);
 		m_pDynamicModelProvider = new CDynamicModelProvider(pCore);
 		m_pRenderable = new CRenderable(getID(), m_pAnimatedModelProvider, m_pDynamicModelProvider);
 		m_pUpdatable = new CUpdatable(m_pAnimatedModelProvider);
+		m_pLevelSizeEventListener = new CLevelSizeEventListener(m_pAnimatedModelProvider, m_pDynamicModelProvider);
+
+		m_pCore->getEventChannel<XEventLevelSize>(EVENT_LEVEL_GET_SIZE_GUID)->addListener(m_pLevelSizeEventListener);
 	}
 
 	void XMETHODCALLTYPE shutdown() override
 	{
+		m_pCore->getEventChannel<XEventLevelSize>(EVENT_LEVEL_GET_SIZE_GUID)->removeListener(m_pLevelSizeEventListener);
+		mem_delete(m_pLevelSizeEventListener);
 		mem_delete(m_pRenderable);
 		mem_delete(m_pUpdatable);
 		mem_delete(m_pAnimatedModelProvider);
@@ -74,8 +99,10 @@ public:
 protected:
 	CRenderable *m_pRenderable = NULL;
 	CUpdatable *m_pUpdatable = NULL;
+	IXCore *m_pCore = NULL;
 	CAnimatedModelProvider *m_pAnimatedModelProvider = NULL;
 	CDynamicModelProvider *m_pDynamicModelProvider = NULL;
+	CLevelSizeEventListener *m_pLevelSizeEventListener = NULL;
 };
 
 DECLARE_XPLUGIN(CDSEPlugin);
diff --git a/source/core/ResourceManager.cpp b/source/core/ResourceManager.cpp
index 1fc38c942dcfac3d0fd54c736a12481b41605b2c..b4995b525acb051c0c2490b8bffca982f49acd48 100644
--- a/source/core/ResourceManager.cpp
+++ b/source/core/ResourceManager.cpp
@@ -31,7 +31,7 @@ CResourceManager::CResourceManager(IXCore *pCore):
 				strlwr(const_cast<char*>(sExt.getName()));
 				sExt.setName(pLoader->getExt(i));
 				m_mapModelLoaders[sExt].push_back(pLoader);
-				m_aModelExts.push_back({pLoader->getDescription(), pLoader->getExt(i)});
+				m_aModelExts.push_back({pLoader->getExtText(i), pLoader->getExt(i)});
 			}
 		}
 	}
diff --git a/source/core/ResourceModel.cpp b/source/core/ResourceModel.cpp
index 57a08e624b5c7829dcc97322d653b567cb690609..a77870ff45ae5a4ebd6db19a9bc71197568d7cb8 100644
--- a/source/core/ResourceModel.cpp
+++ b/source/core/ResourceModel.cpp
@@ -204,3 +204,8 @@ IModelPhysboxCapsule * XMETHODCALLTYPE CResourceModel::newPhysboxCapsule() const
 {
 	return(new CModelPhysboxCapsule());
 }
+
+void XMETHODCALLTYPE CResourceModel::setLocalAABB(const float3 &vMin, const float3 &vMax)
+{
+	//! @todo: implement me!
+}
diff --git a/source/core/ResourceModel.h b/source/core/ResourceModel.h
index 3a668d6d57e8ad4b0e87cc0e6732499e3ef6822e..b18ff5f030cd18644d368d15f82fae684d904a2d 100644
--- a/source/core/ResourceModel.h
+++ b/source/core/ResourceModel.h
@@ -48,6 +48,8 @@ public:
 	IModelPhysboxCylinder * XMETHODCALLTYPE newPhysboxCylinder() const override;
 	IModelPhysboxCapsule * XMETHODCALLTYPE newPhysboxCapsule() const override;
 
+	void XMETHODCALLTYPE setLocalAABB(const float3 &vMin, const float3 &vMax) override;
+
 	void setFileName(const char *szFilename);
 	const char *getFileName() const;
 
diff --git a/source/dseplugin/ModelLoader.cpp b/source/dseplugin/ModelLoader.cpp
index 018f8c847eb836179f1ef3742953b86baa7f3eb4..7b5f283a087c820f248c5663dd3a7e3f1c500e4f 100644
--- a/source/dseplugin/ModelLoader.cpp
+++ b/source/dseplugin/ModelLoader.cpp
@@ -1,16 +1,16 @@
 #include "ModelLoader.h"
 #include "ModelFile.h"
 
-UINT CModelLoader::getVersion()
+UINT XMETHODCALLTYPE CModelLoader::getVersion()
 {
 	return(IXMODELLOADER_VERSION);
 }
 
-UINT CModelLoader::getExtCount() const
+UINT XMETHODCALLTYPE CModelLoader::getExtCount() const
 {
 	return(1);
 }
-const char *CModelLoader::getExt(UINT uIndex) const
+const char* XMETHODCALLTYPE CModelLoader::getExt(UINT uIndex) const
 {
 	assert(uIndex < getExtCount());
 	switch(uIndex)
@@ -20,20 +20,36 @@ const char *CModelLoader::getExt(UINT uIndex) const
 	}
 	return(NULL);
 }
-const char *CModelLoader::getAuthor() const
+const char* XMETHODCALLTYPE CModelLoader::getExtText(UINT uIndex) const
+{
+	assert(uIndex < getExtCount());
+	switch(uIndex)
+	{
+	case 0:
+		return("SkyXEngine model");
+	}
+	return(NULL);
+}
+const char* XMETHODCALLTYPE CModelLoader::getAuthor() const
 {
 	return("D-AIRY @ DogmaNet");
 }
-const char *CModelLoader::getCopyright() const
+const char* XMETHODCALLTYPE CModelLoader::getCopyright() const
 {
 	return("Copyright © Vitaliy Buturlin, Evgeny Danilovich, 2019");
 }
-const char *CModelLoader::getDescription() const
+const char* XMETHODCALLTYPE CModelLoader::getDescription() const
 {
 	return("DSE model loader");
 }
 
-bool CModelLoader::open(IFile *pFile)
+void XMETHODCALLTYPE CModelLoader::getInfo(XModelInfo *pModelInfo)
+{
+	assert(!"Not implemented!");
+	//! @todo Implement me!
+}
+
+bool XMETHODCALLTYPE CModelLoader::open(IFile *pFile)
 {
 	assert(!m_pCurrentFile && "File already opened!");
 	if(m_pCurrentFile)
@@ -66,11 +82,11 @@ bool CModelLoader::open(IFile *pFile)
 
 	return(true);
 }
-XMODELTYPE CModelLoader::getType() const
+XMODELTYPE XMETHODCALLTYPE CModelLoader::getType() const
 {
 	return((m_hdr.iFlags & MODEL_FLAG_STATIC) ? XMT_STATIC : XMT_ANIMATED);
 }
-bool CModelLoader::loadAsStatic(IXResourceModelStatic *pResource)
+bool XMETHODCALLTYPE CModelLoader::loadAsStatic(IXResourceModelStatic *pResource)
 {
 	if(!loadGeneric(pResource))
 	{
@@ -218,7 +234,7 @@ bool CModelLoader::loadAsStatic(IXResourceModelStatic *pResource)
 
 	return(true);
 }
-bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource)
+bool XMETHODCALLTYPE CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource)
 {
 	if(getType() != XMT_ANIMATED)
 	{
@@ -359,7 +375,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource)
 				}
 				for(UINT k = 0; k < pSubSet->iVertexCount; ++k)
 				{
-					pSubSet->pVertices[k].vPos = (float3)(pSubSet->pVertices[k].vPos * 0.0254f);
+					pSubSet->pVertices[k].vPos = /*(float3)(*/pSubSet->pVertices[k].vPos/* * 0.0254f)*/;
 				}
 			}
 		}
@@ -388,7 +404,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource)
 		{
 			m_pCurrentFile->readBin(&mbn, sizeof(ModelBoneName));
 			assert(i == mbn.bone.id);
-			pResource->setBoneInfo(i, mbn.szName, mbn.bone.pid, mbn.bone.position * 0.0254f, mbn.bone.orient);
+			pResource->setBoneInfo(i, mbn.szName, mbn.bone.pid, mbn.bone.position/* * 0.0254f*/, mbn.bone.orient);
 		}
 	}
 
@@ -459,7 +475,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource)
 					m_pCurrentFile->readBin(&mb, sizeof(ModelBone));
 
 					pSequence->m_ppSequenceData[j][k].orient = mb.orient;
-					pSequence->m_ppSequenceData[j][k].position = (float3)(mb.position * 0.0254f);
+					pSequence->m_ppSequenceData[j][k].position = /*(float3)(*/mb.position/* * 0.0254f)*/;
 				}
 			}
 		}
@@ -503,7 +519,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource)
 	return(true);
 }
 
-void CModelLoader::close()
+void XMETHODCALLTYPE CModelLoader::close()
 {
 	m_pCurrentFile = NULL;
 }
diff --git a/source/dseplugin/ModelLoader.h b/source/dseplugin/ModelLoader.h
index 28e60f5d4a66fee1b8f5ed8ef7156ea2c4e9e4b3..cd9eb07196dbef055465d99c69c75557168011de 100644
--- a/source/dseplugin/ModelLoader.h
+++ b/source/dseplugin/ModelLoader.h
@@ -10,16 +10,17 @@ public:
 	UINT XMETHODCALLTYPE getVersion() override;
 
 	UINT XMETHODCALLTYPE getExtCount() const override;
-	const char * XMETHODCALLTYPE getExt(UINT uIndex) const override;
-	const char * XMETHODCALLTYPE getAuthor() const override;
-	const char * XMETHODCALLTYPE getCopyright() const override;
-	const char * XMETHODCALLTYPE getDescription() const override;
+	const char* XMETHODCALLTYPE getExt(UINT uIndex) const override;
+	const char* XMETHODCALLTYPE getExtText(UINT uIndex) const override;
+	const char* XMETHODCALLTYPE getAuthor() const override;
+	const char* XMETHODCALLTYPE getCopyright() const override;
+	const char* XMETHODCALLTYPE getDescription() const override;
 
 	bool XMETHODCALLTYPE open(IFile *pFile) override;
 	XMODELTYPE XMETHODCALLTYPE getType() const override;
 	bool XMETHODCALLTYPE loadAsStatic(IXResourceModelStatic *pResource) override;
 	bool XMETHODCALLTYPE loadAsAnimated(IXResourceModelAnimated *pResource) override;
-	// void XMETHODCALLTYPE getInfo() override; // ??
+	void XMETHODCALLTYPE getInfo(XModelInfo *pModelInfo) override;
 	void XMETHODCALLTYPE close() override;
 
 
diff --git a/source/game/BaseAnimating.cpp b/source/game/BaseAnimating.cpp
index 3f220492344cafbdfb34ec4d4ed79a55a23abab0..a0da87e2c2c2f90b900d8b66a3cb45d76b59fd0c 100644
--- a/source/game/BaseAnimating.cpp
+++ b/source/game/BaseAnimating.cpp
@@ -16,25 +16,22 @@ See the license in LICENSE
 
 BEGIN_PROPTABLE(CBaseAnimating)
 	//! Файл модели. Поддерживаются статические и анимированные модели
-	DEFINE_FIELD_STRING(m_szModelFile, 0, "model", "Model file", EDITOR_FILEFIELD)
-		FILE_OPTION("Select model", "dse")
-	EDITOR_FILE_END()
+	DEFINE_FIELD_STRINGFN(m_szModelFile, 0, "model", "Model file", setModel, EDITOR_MODEL)
 
 	//! Масштаб модели
-	// DEFINE_FIELD_FLOAT(m_fBaseScale, 0, "scale", "Scale", EDITOR_TEXTFIELD)
+	DEFINE_FIELD_FLOATFN(m_fBaseScale, 0, "scale", "Scale", setScale, EDITOR_TEXTFIELD)
 
 	//! Объект референса для цвета свечения
 	DEFINE_FIELD_ENTITY(m_pEntColorRef, 0, "glow_color_ref", "Glow color reference", EDITOR_TEXTFIELD)
 	//! Цвет свечения
 	DEFINE_FIELD_VECTOR(m_vGlowColor, 0, "glow_color", "Glow color", EDITOR_TEXTFIELD)
 
-	DEFINE_FIELD_BOOLFN(m_isStatic, 0, "is_static", "Is static", onIsStaticChange, EDITOR_COMBOBOX)
-		COMBO_OPTION("Yes", "1")
-		COMBO_OPTION("No", "0")
-	EDITOR_COMBO_END()
+	DEFINE_FIELD_BOOLFN(m_isStatic, 0, "is_static", "Is static", onIsStaticChange, EDITOR_YESNO)
 
 	DEFINE_FIELD_INTFN(m_iSkin, 0, "skin", "Skin", setSkin, EDITOR_TEXTFIELD)
 
+	DEFINE_FIELD_BOOLFN(m_useAutoPhysbox, 0, "auto_physbox", "Auto generate physbox", onSetUseAutoPhysbox, EDITOR_YESNO)
+
 	DEFINE_INPUT(inputPlayAnim, "playAnim", "Play animation", PDF_STRING)
 	DEFINE_INPUT(inputPlayAnimNext, "playAnimNext", "Play animation next", PDF_STRING)
 
@@ -76,26 +73,14 @@ void CBaseAnimating::getMinMax(float3 * min, float3 * max)
 	}
 }*/
 
-bool CBaseAnimating::setKV(const char * name, const char * value)
+void CBaseAnimating::onSetUseAutoPhysbox(bool use)
 {
-	if(!BaseClass::setKV(name, value))
-	{
-		return(false);
-	}
-	if(!strcmp(name, "model"))
-	{
-		setModel(value);
-	}
-	/*else if(!strcmp(name, "scale"))
+	if(m_useAutoPhysbox != use)
 	{
+		m_useAutoPhysbox = use;
 		releasePhysics();
-		if(m_pAnimPlayer)
-		{
-			m_pAnimPlayer->setScale(m_fBaseScale);
-		}
 		initPhysics();
-	}*/
-	return(true);
+	}
 }
 
 void CBaseAnimating::setModel(const char * mdl)
@@ -119,10 +104,23 @@ void CBaseAnimating::setModel(const char * mdl)
 		{
 			m_pModel = pModel;
 			m_pModel->setSkin(m_iSkin);
+			m_pModel->setScale(m_fBaseScale);
 		}
 		mem_release(pResource);
 	}
-	
+
+	initPhysics();
+}
+
+void CBaseAnimating::setScale(float fScale)
+{
+	m_fBaseScale = fScale;
+
+	releasePhysics();
+	if(m_pModel)
+	{
+		m_pModel->setScale(m_fBaseScale);
+	}
 	initPhysics();
 }
 
@@ -218,16 +216,16 @@ void CBaseAnimating::initPhysics()
 		switch(pPhysbox->getType())
 		{
 		case XPBT_BOX:
-			pLocalShape = new btBoxShape(F3_BTVEC(pPhysbox->asBox()->getSize()));
+			pLocalShape = new btBoxShape(F3_BTVEC(pPhysbox->asBox()->getSize()) * m_fBaseScale);
 			break;
 		case XPBT_SPHERE:
-			pLocalShape = new btSphereShape(pPhysbox->asSphere()->getRadius());
+			pLocalShape = new btSphereShape(pPhysbox->asSphere()->getRadius() * m_fBaseScale);
 			break;
 		case XPBT_CAPSULE:
-			pLocalShape = new btCapsuleShape(pPhysbox->asCapsule()->getRadius(), pPhysbox->asCapsule()->getHeight());
+			pLocalShape = new btCapsuleShape(pPhysbox->asCapsule()->getRadius() * m_fBaseScale, pPhysbox->asCapsule()->getHeight() * m_fBaseScale);
 			break;
 		case XPBT_CYLINDER:
-			pLocalShape = new btCylinderShape(btVector3(pPhysbox->asCylinder()->getRadius(), pPhysbox->asCylinder()->getHeight() * 0.5f, pPhysbox->asCylinder()->getRadius()));
+			pLocalShape = new btCylinderShape(btVector3(pPhysbox->asCylinder()->getRadius(), pPhysbox->asCylinder()->getHeight() * 0.5f, pPhysbox->asCylinder()->getRadius()) * m_fBaseScale);
 			break;
 		case XPBT_CONVEX:
 			{
@@ -237,6 +235,10 @@ void CBaseAnimating::initPhysics()
 				btVector3 *pData;
 				int iVertexCount;
 				SPhysics_BuildHull(&tmpShape, &pData, &iVertexCount);
+				for(int i = 0; i < iVertexCount; ++i)
+				{
+					pData[i] *= m_fBaseScale;
+				}
 				pLocalShape = new btConvexHullShape((float*)pData, iVertexCount, sizeof(btVector3));
 				SPhysics_ReleaseHull(pData, iVertexCount);
 			}
@@ -245,11 +247,11 @@ void CBaseAnimating::initPhysics()
 
 		if(pLocalShape)
 		{
-			btTransform localTransform(Q4_BTQUAT(pPhysbox->getOrientation()), F3_BTVEC(pPhysbox->getPosition()));
+			btTransform localTransform(Q4_BTQUAT(pPhysbox->getOrientation()), F3_BTVEC(pPhysbox->getPosition()) * m_fBaseScale);
 			pShape->addChildShape(localTransform, pLocalShape);
 		}
 	}
-	if(!uShapesCount)
+	if(!uShapesCount && m_useAutoPhysbox)
 	{
 		{
 			auto pResource = m_pModel->getResource()->asStatic();
@@ -266,6 +268,10 @@ void CBaseAnimating::initPhysics()
 					btVector3 *pData;
 					int iVertexCount;
 					SPhysics_BuildHull(&tmpShape, &pData, &iVertexCount);
+					for(int i = 0; i < iVertexCount; ++i)
+					{
+						pData[i] *= m_fBaseScale;
+					}
 					pLocalShape = new btConvexHullShape((float*)pData, iVertexCount, sizeof(btVector3));
 					SPhysics_ReleaseHull(pData, iVertexCount);
 
@@ -294,6 +300,10 @@ void CBaseAnimating::initPhysics()
 					btVector3 *pData;
 					int iVertexCount;
 					SPhysics_BuildHull(&tmpShape, &pData, &iVertexCount);
+					for(int i = 0; i < iVertexCount; ++i)
+					{
+						pData[i] *= m_fBaseScale;
+					}
 					pLocalShape = new btConvexHullShape((float*)pData, iVertexCount, sizeof(btVector3));
 					SPhysics_ReleaseHull(pData, iVertexCount);
 
diff --git a/source/game/BaseAnimating.h b/source/game/BaseAnimating.h
index 1ce44957072aced7dabf4cc5b5606b1fb5e3c8a0..63fe6a72e4bd954b9b8bd158009efe75bb8aee3b 100644
--- a/source/game/BaseAnimating.h
+++ b/source/game/BaseAnimating.h
@@ -32,9 +32,8 @@ public:
 	void getMinMax(float3 * min, float3 * max);
 	// void getSphere(float3 * center, float * radius);
 
-	bool setKV(const char * name, const char * value);
-
-	virtual void setModel(const char * mdl);
+	virtual void setModel(const char *szMdl);
+	virtual void setScale(float fScale);
 
 	float3 getAttachmentPos(int id);
 	SMQuaternion getAttachmentRot(int id);
@@ -74,8 +73,9 @@ protected:
 
 	IXModel *m_pModel = NULL;
 	const char * m_szModelFile;
-	// float m_fBaseScale;
+	float m_fBaseScale = 1.0f;
 	bool m_isStatic = false;
+	bool m_useAutoPhysbox = true;
 
 	CBaseEntity *m_pEntColorRef = NULL;
 	float3_t m_vGlowColor;
@@ -93,7 +93,7 @@ protected:
 	virtual void onAnimationStateChanged(int slot, ANIM_STATE as);
 
 	void onIsStaticChange(bool isStatic);
-
+	void onSetUseAutoPhysbox(bool use);
 	int m_iSkin = 0;
 
 	struct
diff --git a/source/game/BaseItem.cpp b/source/game/BaseItem.cpp
index b99265a8d1666dbc3852057d19aa789a5a69645e..330603b52766bdb683cee1ba05a7dc2d304319ba 100644
--- a/source/game/BaseItem.cpp
+++ b/source/game/BaseItem.cpp
@@ -29,9 +29,7 @@ BEGIN_PROPTABLE(CBaseItem)
 	DEFINE_OUTPUT(m_onPickUp, "OnPickUp", "On pickup")
 	DEFINE_OUTPUT(m_onDrop, "OnDrop", "On drop")
 
-	DEFINE_FIELD_STRINGFN(m_szViewModelFile, 0, "model_view", "View model file", onSetViewModel, EDITOR_FILEFIELD)
-		FILE_OPTION("Select model", "dse")
-	EDITOR_FILE_END()
+	DEFINE_FIELD_STRINGFN(m_szViewModelFile, 0, "model_view", "View model file", onSetViewModel, EDITOR_MODEL)
 END_PROPTABLE()
 
 REGISTER_ENTITY_NOLISTING(CBaseItem, base_item);
@@ -116,6 +114,16 @@ void CBaseItem::onModeChanged(INVENTORY_ITEM_MODE oldMode, INVENTORY_ITEM_MODE n
 	}
 }
 
+void CBaseItem::setScale(float fScale)
+{
+	BaseClass::setScale(fScale);
+
+	if(m_pViewModel)
+	{
+		m_pViewModel->setScale(fScale);
+	}
+}
+
 void CBaseItem::onSetViewModel(const char *mdl)
 {
 	_setStrVal(&m_szViewModelFile, mdl);
@@ -168,6 +176,7 @@ void CBaseItem::onModelChanged()
 		{
 			m_pViewModel->play("IDLE");
 			m_pViewModel->enable(m_inventoryMode == IIM_EQUIPPED);
+			m_pViewModel->setScale(m_fBaseScale);
 		}
 	}
 }
diff --git a/source/game/BaseItem.h b/source/game/BaseItem.h
index 45cd17ee7268fbe6e465dcab0ec79c7b308021f8..e15bc0a41d11d6999f90d60583475db30afdfa36 100644
--- a/source/game/BaseItem.h
+++ b/source/game/BaseItem.h
@@ -50,6 +50,8 @@ protected:
 	void onModelChanged();
 	void onSync() override;
 
+	void setScale(float fScale) override;
+
 	const char * m_szInvName; //!< Имя, отображаемое в инвентаре
 	bool m_bInvStackable; //!< Можно ли хранить несколько итемов в одной ячейке
 	int m_iInvStackCurSize; //!< Количество итемов в стеке
diff --git a/source/game/PropStatic.cpp b/source/game/PropStatic.cpp
index 2d0a51f332a11073ab778c68d468207d456cba3a..af65c15cdd7248f7a77ad66d49cd17582608b463 100644
--- a/source/game/PropStatic.cpp
+++ b/source/game/PropStatic.cpp
@@ -11,14 +11,7 @@ See the license in LICENSE
 */
 
 BEGIN_PROPTABLE(CPropStatic)
-	//! Масштаб модели
-	DEFINE_FIELD_FLOATFN(m_fScale, 0, "scale", "Scale", onSetScale, EDITOR_TEXTFIELD)
-
-
-	DEFINE_FIELD_BOOLFN(m_useTrimeshPhysics, 0, "use_trimesh", "Use trimesh physics", onSetUseTrimesh, EDITOR_COMBOBOX)
-		COMBO_OPTION("Yes", "1")
-		COMBO_OPTION("No", "0")
-	EDITOR_COMBO_END()
+	DEFINE_FIELD_BOOLFN(m_useTrimeshPhysics, 0, "use_trimesh", "Use trimesh physics", onSetUseTrimesh, EDITOR_YESNO)
 END_PROPTABLE()
 
 REGISTER_ENTITY(CPropStatic, prop_static);
@@ -65,15 +58,6 @@ void CPropStatic::removePhysBody()
 	mem_delete(m_pRigidBody);
 }
 
-void CPropStatic::onSetScale(float fScale)
-{
-	m_fScale = fScale;
-	if(m_pModel)
-	{
-		m_pModel->setScale(fScale);
-	}
-}
-
 void CPropStatic::initPhysics()
 {
 	if(!m_pModel)
@@ -92,6 +76,11 @@ void CPropStatic::initPhysics()
 		return;
 	}
 
+	if(!m_useAutoPhysbox)
+	{
+		return;
+	}
+
 	btCompoundShape *pShape = new btCompoundShape(true, uShapesCount);
 
 	auto pResource = m_pModel->getResource()->asStatic();
@@ -105,6 +94,7 @@ void CPropStatic::initPhysics()
 		
 		if(pLocalShape)
 		{
+			pLocalShape->setLocalScaling(btVector3(m_fBaseScale, m_fBaseScale, m_fBaseScale));
 			btTransform localTransform;
 			localTransform.setIdentity();
 			pShape->addChildShape(localTransform, pLocalShape);
@@ -137,16 +127,6 @@ void CPropStatic::releasePhysics()
 	}
 }
 
-void CPropStatic::setModel(const char *mdl)
-{
-	BaseClass::setModel(mdl);
-
-	if(m_pModel)
-	{
-		m_pModel->setScale(m_fScale);
-	}
-}
-
 void CPropStatic::onSetUseTrimesh(bool use)
 {
 	if(m_useTrimeshPhysics != use)
diff --git a/source/game/PropStatic.h b/source/game/PropStatic.h
index c4daf11915aa0193e885e04724ce391bc63de3ed..5a658406a4e98177d767c5cb9b38f6f7dd2ededf 100644
--- a/source/game/PropStatic.h
+++ b/source/game/PropStatic.h
@@ -25,17 +25,14 @@ public:
 	DECLARE_CONSTRUCTOR();
 	~CPropStatic();
 
+protected:
 	void createPhysBody() override;
 	void removePhysBody() override;
 
 	void initPhysics() override;
 	void releasePhysics() override;
 
-	void setModel(const char *mdl) override;
-protected:
-	void onSetScale(float fScale);
 	void onSetUseTrimesh(bool use);
-	float m_fScale = 1.0f;
 	bool m_useTrimeshPhysics = false;
 };
 
diff --git a/source/game/proptable.h b/source/game/proptable.h
index 19049e341dc47019c611bc72ca9e585b43ac190b..1bb41c1a5c180d3057aabf959bdb243c6cc9e84d 100644
--- a/source/game/proptable.h
+++ b/source/game/proptable.h
@@ -364,6 +364,8 @@ const char * GetEmptyString();
 #define FILE_OPTION(name, value) , name, value
 #define EDITOR_FILE_END() , NULL)}
 
+#define EDITOR_YESNO EDITOR_COMBOBOX COMBO_OPTION("Yes", "1") COMBO_OPTION("No", "0") EDITOR_COMBO_END()
+#define EDITOR_MODEL EDITOR_FILEFIELD FILE_OPTION("Select model", "dse") EDITOR_FILE_END()
 
 #define DEFINE_FIELD_STRING(field, flags, keyname, edname, editor) , {(fieldtype)&DataClass::field, PDF_STRING, flags, keyname, edname, editor
 #define DEFINE_FIELD_VECTOR(field, flags, keyname, edname, editor) , {(fieldtype)&DataClass::field, PDF_VECTOR, flags, keyname, edname, editor
diff --git a/source/xcommon/IXModelLoader.h b/source/xcommon/IXModelLoader.h
index 957cf91994a295ff892fac9957c790ebdd212d61..ef3ef105e7b9ad62812aa9efb9ee8349a86c5399 100644
--- a/source/xcommon/IXModelLoader.h
+++ b/source/xcommon/IXModelLoader.h
@@ -9,11 +9,46 @@
 #define IXMODELLOADER_GUID DEFINE_XGUID(0x8e7da1d6, 0x7965, 0x41a1, 0xbf, 0xb4, 0x7, 0xb0, 0x87, 0xe8, 0x54, 0xa1)
 #define IXMODELLOADER_VERSION 1
 
+//! возможная информация о dse файле
+struct XModelInfo
+{
+	//! тип файла
+	XMODELTYPE type;
+
+	//! количество вершин
+	UINT uVertexCount;
+
+	//! количество индексов
+	UINT uIndexCount;
+
+	//! количество подгрупп
+	UINT uSubsetsCount;
+
+	//! количество скинов
+	UINT uSkinCount;
+
+	//! количество хитбоксов
+	UINT uHitboxCount;
+
+	//! количество костей
+	UINT uBoneCount;
+
+	//! количетсов анимаций
+	UINT uAnimationCount;
+
+	//! габариты в метрах
+	float3_t vDimensions;
+
+	//! центр модели в метрах
+	float3_t vCenter;
+};
+
 class IXModelLoader: public IXUnknown
 {
 public:
 	virtual UINT XMETHODCALLTYPE getExtCount() const = 0;
 	virtual const char* XMETHODCALLTYPE getExt(UINT uIndex) const = 0;
+	virtual const char* XMETHODCALLTYPE getExtText(UINT uIndex) const = 0;
 	virtual const char* XMETHODCALLTYPE getAuthor() const = 0;
 	virtual const char* XMETHODCALLTYPE getCopyright() const = 0;
 	virtual const char* XMETHODCALLTYPE getDescription() const = 0;
@@ -22,7 +57,7 @@ public:
 	virtual XMODELTYPE XMETHODCALLTYPE getType() const = 0;
 	virtual bool XMETHODCALLTYPE loadAsStatic(IXResourceModelStatic *pResource) = 0;
 	virtual bool XMETHODCALLTYPE loadAsAnimated(IXResourceModelAnimated *pResource) = 0;
-	// virtual void XMETHODCALLTYPE getInfo() = 0; // ??
+	virtual void XMETHODCALLTYPE getInfo(XModelInfo *pModelInfo) = 0;
 	virtual void XMETHODCALLTYPE close() = 0;
 };
 
diff --git a/source/xcommon/resource/IXResourceModel.h b/source/xcommon/resource/IXResourceModel.h
index 6bd94b674411997a01acb250eb16da669d14f256..0ed5a3925627406d5dc94956c21c2a80a4d38bde 100644
--- a/source/xcommon/resource/IXResourceModel.h
+++ b/source/xcommon/resource/IXResourceModel.h
@@ -280,6 +280,8 @@ public:
 	virtual UINT XMETHODCALLTYPE addLod(UINT uSubsetCount, UINT *puVertexCount, UINT *puIndexCount) = 0;
 	virtual UINT XMETHODCALLTYPE getLodCount() const = 0;
 
+	virtual void XMETHODCALLTYPE setLocalAABB(const float3 &vMin, const float3 &vMax) = 0;
+
 	virtual bool XMETHODCALLTYPE validate() const = 0;
 
 	virtual IModelPhysboxBox    * XMETHODCALLTYPE newPhysboxBox() const = 0;