From c245de3fe946a9874157143fa02adf391d845a27 Mon Sep 17 00:00:00 2001
From: Byurrer <byurrer@mail.ru>
Date: Thu, 7 Jun 2018 21:01:53 +0400
Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?=
 =?UTF-8?q?=D0=BB=D0=B8=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20=D0=B2=20?=
 =?UTF-8?q?=D1=81=D0=BC=D0=B5=D0=BD=D0=B5=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC?=
 =?UTF-8?q?=D0=B0,=20=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB=20=D0=B4?=
 =?UTF-8?q?=D0=B2=D0=B8=D0=B6=D0=BA=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BD=D0=B0?=
 =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B8,=20=D0=B4=D0=BE?=
 =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=84=D1=80=D1=83=D1=81=D1=82?=
 =?UTF-8?q?=D1=83=D0=BC=20=D0=BA=D1=83=D0=BB=D0=BB=D0=B8=D0=BD=D0=B3=20?=
 =?UTF-8?q?=D0=B2=20OC,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?=
 =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=20=D1=84=D1=80=D1=83=D1=81=D1=82=D1=83?=
 =?UTF-8?q?=D0=BC=20=D0=BA=D1=83=D0=BB=D0=BB=D0=B8=D0=BD=D0=B3=D0=B0=20?=
 =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=82=D1=80=D0=B5=D1=83=D0=B3=D0=BE=D0=BB?=
 =?UTF-8?q?=D1=8C=D0=BD=D0=B8=D0=BA=D0=B0,=20=D0=B4=D0=BE=D0=B1=D0=B0?=
 =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=82=D0=BE=D1=8B?=
 =?UTF-8?q?=D1=80=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20?=
 =?UTF-8?q?=D0=B2=20=D0=B0=D0=B8=D1=81=D0=B5=D1=82=D0=BA=D1=83,=20=D0=BF?=
 =?UTF-8?q?=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B1=D0=B0=D0=B3?=
 =?UTF-8?q?=20=D1=81=20=D1=82=D0=B5=D0=BD=D1=8F=D0=BC=D0=B8=20=D0=BF=D1=80?=
 =?UTF-8?q?=D0=BE=D0=B7=D1=80=D0=B0=D1=87=D0=BD=D0=BE=D0=B9=20=D0=B3=D0=B5?=
 =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                    |   2 +
 build/editor.cfg                              |   7 -
 .../mtrlgeom/mtrlgeom_water_reflect.ps        |   2 +-
 .../shaders/sm/sm_depth_geom_cube.ps          |   4 +
 .../shaders/sm/sm_depth_geom_pssm_direct.ps   |   4 +
 .../shaders/sm/sm_depth_skin_cube.ps          |   4 +
 .../shaders/sm/sm_depth_skin_pssm_direct.ps   |   4 +
 build/sysconfig.cfg                           |  62 ------
 source/SkyXEngine_Build/SkyXEngine_Build.cpp  |   4 +-
 source/aigrid/aigrid.cpp                      |  42 +++-
 source/aigrid/aigrid.h                        |   3 +
 source/aigrid/sxaigrid.cpp                    |  14 ++
 source/aigrid/sxaigrid.h                      |   9 +-
 source/game/GameData.cpp                      |  16 ++
 source/gcore/camera.cpp                       |  29 ++-
 source/gcore/sxgcore.cpp                      | 201 +++++++++++-------
 source/gcore/sxgcore.h                        |   4 +-
 source/physics/PhyWorld.cpp                   |  41 +++-
 source/physics/PhyWorld.h                     |   7 +
 source/render/render_func.cpp                 |  29 ++-
 source/render/render_func.h                   |   2 +-
 source/render/sxrender.cpp                    |   6 +-
 source/render/sxrender.h                      |   4 +-
 source/skyxengine.cpp                         |  78 ++++---
 source/sxmaterialeditor/sxmaterialeditor.cpp  |   2 +
 25 files changed, 365 insertions(+), 215 deletions(-)
 delete mode 100644 build/editor.cfg
 delete mode 100644 build/sysconfig.cfg

diff --git a/.gitignore b/.gitignore
index 0d3bcfe42..034d9eb9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -207,3 +207,5 @@ docs/html/*
 !docs/html/particles_editor/
 
 /source/game/ents_doc.h
+
+/build/config_game_user.cfg
diff --git a/build/editor.cfg b/build/editor.cfg
deleted file mode 100644
index 8d3d90280..000000000
--- a/build/editor.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-echo "Executing editor config file"
-
-
-unbind f10
-cl_mode_editor 1
-
-r_stats 1
\ No newline at end of file
diff --git a/build/gamesource/shaders/mtrlgeom/mtrlgeom_water_reflect.ps b/build/gamesource/shaders/mtrlgeom/mtrlgeom_water_reflect.ps
index 42899ad60..7ca2250e3 100644
--- a/build/gamesource/shaders/mtrlgeom/mtrlgeom_water_reflect.ps
+++ b/build/gamesource/shaders/mtrlgeom/mtrlgeom_water_reflect.ps
@@ -45,7 +45,7 @@ ps_out_ds_mrt main(vs_out_water IN)
 	half3 normaloffset = normalize(tc_offset+tc_offset2)*Param.x;
 
 	half4 TexUVRefractProj = mul(IN.Pos,MatrixRefraction);
-	half depth = LinearizeDepth(tex2D(DepthTex, TexUVRefractProj.xy/TexUVRefractProj.w + half2(0.5f/WinSize.x,0.5f/WinSize.y)).r, NearFarIsUnlit.xy);
+	half depth = tex2D(DepthTex, TexUVRefractProj.xy/TexUVRefractProj.w + half2(0.5f/WinSize.x,0.5f/WinSize.y)).r;
 	half intens = saturate(abs(((IN.Pos.z/NearFarIsUnlit.y) - depth)*NearFarIsUnlit.y) / (Param.y * 100.f));
 	
 	normaloffset *= intens;
diff --git a/build/gamesource/shaders/sm/sm_depth_geom_cube.ps b/build/gamesource/shaders/sm/sm_depth_geom_cube.ps
index efc615187..eee466996 100644
--- a/build/gamesource/shaders/sm/sm_depth_geom_cube.ps
+++ b/build/gamesource/shaders/sm/sm_depth_geom_cube.ps
@@ -10,5 +10,9 @@ sampler2D BaseSampler:register(s0);
 
 half4 main(vs_out_gcommon IN):COLOR0
 {
+	half4 tmpColor = tex2D(BaseSampler,IN.TexUV);
+	clip(tmpColor.a - GREEN_ALPHATEST_VALUE);
+	tmpColor.a = 1.f;
+	
 	return length(IN.Pos);
 }
\ No newline at end of file
diff --git a/build/gamesource/shaders/sm/sm_depth_geom_pssm_direct.ps b/build/gamesource/shaders/sm/sm_depth_geom_pssm_direct.ps
index e5c1c5871..849a71f32 100644
--- a/build/gamesource/shaders/sm/sm_depth_geom_pssm_direct.ps
+++ b/build/gamesource/shaders/sm/sm_depth_geom_pssm_direct.ps
@@ -10,5 +10,9 @@ sampler2D BaseSampler:register(s0);
 
 half4 main(vs_out_gcommon IN):COLOR0
 {
+	half4 tmpColor = tex2D(BaseSampler,IN.TexUV);
+	clip(tmpColor.a - GREEN_ALPHATEST_VALUE);
+	tmpColor.a = 1.f;
+	
 	return IN.Pos.z/IN.Pos.w;
 }
\ No newline at end of file
diff --git a/build/gamesource/shaders/sm/sm_depth_skin_cube.ps b/build/gamesource/shaders/sm/sm_depth_skin_cube.ps
index 088c94b88..c6307220a 100644
--- a/build/gamesource/shaders/sm/sm_depth_skin_cube.ps
+++ b/build/gamesource/shaders/sm/sm_depth_skin_cube.ps
@@ -10,5 +10,9 @@ sampler2D BaseSampler:register(s0);
 
 half4 main(vs_out_gcommon IN) : COLOR0
 {
+	half4 tmpColor = tex2D(BaseSampler,IN.TexUV);
+	clip(tmpColor.a - GREEN_ALPHATEST_VALUE);
+	tmpColor.a = 1.f;
+	
 	return length(IN.Pos);
 }
\ No newline at end of file
diff --git a/build/gamesource/shaders/sm/sm_depth_skin_pssm_direct.ps b/build/gamesource/shaders/sm/sm_depth_skin_pssm_direct.ps
index 81d8d7c55..109cf662f 100644
--- a/build/gamesource/shaders/sm/sm_depth_skin_pssm_direct.ps
+++ b/build/gamesource/shaders/sm/sm_depth_skin_pssm_direct.ps
@@ -10,5 +10,9 @@ sampler2D BaseSampler:register(s0);
 
 half4 main(vs_out_gcommon IN) : COLOR0
 {
+	half4 tmpColor = tex2D(BaseSampler,IN.TexUV);
+	clip(tmpColor.a - GREEN_ALPHATEST_VALUE);
+	tmpColor.a = 1.f;
+	
 	return IN.Pos.z/IN.Pos.w;
 }
\ No newline at end of file
diff --git a/build/sysconfig.cfg b/build/sysconfig.cfg
deleted file mode 100644
index 5139338d2..000000000
--- a/build/sysconfig.cfg
+++ /dev/null
@@ -1,62 +0,0 @@
-echo "Executing config file"
-
-bind escape exit
-
-bind w +forward
-bind s +backward
-bind a +left
-bind d +right
-bind shift +boost
-bind ctrl +crouch
-bind alt +crawl
-bind space +jump
-bind mouse1 +attack
-bind mouse3 +attack2
-bind r reload
-bind t flashlight
-
-bind f12 screenshot
-bind f11 save_worktex
-bind f10 change_mode_window
-bind f9 shader_reload
-bind f8 change_mode_window_abs
-
-cl_mode_editor 1
-
-r_default_fov 1.046
-r_stats 1
-r_win_width 800
-r_win_height 600
-
-pp_ssao 1
-pp_bloom true
-pp_lensflare true
-pp_lensflare_usebloom true
-pp_dlaa 0
-pp_nfaa 0
-pp_motionblur true
-pp_motionblur_coef 0.05
-
-pssm_4or3 true
-
-pssm_q 1.0
-lsm_q 1.0
-
-grass_frec 100
-green_lod0 50
-green_lod1 100
-green_less 20
-r_far 400
-
-r_s_filter 2
-r_s_max_anisotropy 16
-r_s_max_miplevel 0
-
-main_rain_density 1
-main_thunderbolt true
-
-g_time_speed 1
-
-spawn
-
-//cl_grab_cursor 0
diff --git a/source/SkyXEngine_Build/SkyXEngine_Build.cpp b/source/SkyXEngine_Build/SkyXEngine_Build.cpp
index 0c1a37113..076d1509f 100644
--- a/source/SkyXEngine_Build/SkyXEngine_Build.cpp
+++ b/source/SkyXEngine_Build/SkyXEngine_Build.cpp
@@ -37,12 +37,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLin
 		bEnt->setKV("origin", "0 0 0");
 	}*/
 
-	for (int i = 0; i < 100; ++i)
+	/*for (int i = 0; i < 100; ++i)
 	{
 		CBaseEntity* bEnt = SXGame_CreateEntity("npc_zombie");
 		bEnt->setFlags(bEnt->getFlags() | EF_EXPORT | EF_LEVEL);
 		bEnt->setKV("origin", "0 1 0");
-	}
+	}*/
 	/*for (int i = 0; i < 10; ++i)
 	{
 	for (int k = 0; k < 10; ++k)
diff --git a/source/aigrid/aigrid.cpp b/source/aigrid/aigrid.cpp
index c9533b7e3..bb46b75cf 100644
--- a/source/aigrid/aigrid.cpp
+++ b/source/aigrid/aigrid.cpp
@@ -1036,6 +1036,11 @@ void AIGrid::Clear()
 	mem_release_del(BoundBox);
 }
 
+bool AIGrid::existsQuads()
+{
+	return (ArrQuads.size() > 0);
+}
+
 void AIGrid::GridClear()
 {
 	AllocAIQuad.clear();
@@ -2724,6 +2729,9 @@ ID AIGrid::GraphPointGetNear(ID beginq, ID endq)
 
 bool AIGrid::gridFindPath(ID idQueueObject)
 {
+	if (!existsQuads())
+		return false;
+
 	ID idStart = m_aQueueFind[idQueueObject].m_idStart;
 	ID idFinish = m_aQueueFind[idQueueObject].m_idFinish;
 	Array<ID> &aQuads = m_aQueueFind[idQueueObject].m_aQuads;
@@ -2923,6 +2931,9 @@ bool AIGrid::gridFindPath(ID idQueueObject)
 
 int AIGrid::gridGetSizePath(ID idQueueObject)
 {
+	if (!existsQuads())
+		return -1;
+
 	if (idQueueObject >= 0 && idQueueObject < m_aQueueFind.size() && m_aQueueFind[idQueueObject].m_state == QUEUE_OBJ_STATE_COMPLITE)
 		return m_aQueueFind[idQueueObject].m_aQuads.size();
 
@@ -2931,6 +2942,9 @@ int AIGrid::gridGetSizePath(ID idQueueObject)
 
 bool AIGrid::gridGetPath(ID idQueueObject, ID *pMemory, UINT uiCount, bool canReverse)
 {
+	if (!existsQuads())
+		return false;
+
 	if (idQueueObject >= 0 && idQueueObject < m_aQueueFind.size() && m_aQueueFind[idQueueObject].m_state == QUEUE_OBJ_STATE_COMPLITE)
 	{
 		if (pMemory)
@@ -2956,7 +2970,7 @@ bool AIGrid::gridGetPath(ID idQueueObject, ID *pMemory, UINT uiCount, bool canRe
 
 void AIGrid::GridSetColorArr(const ID * pmem, DWORD color, UINT count)
 {
-	if (!pmem)
+	if (ArrColor.size() > 0 || !pmem)
 		return;
 
 	for (int i = 0; i < count; ++i)
@@ -2968,7 +2982,8 @@ void AIGrid::GridSetColorArr(const ID * pmem, DWORD color, UINT count)
 
 void AIGrid::GridSetNullColor()
 {
-	memset(&(ArrColor[0]), 0, sizeof(uint32_t)* ArrColor.size());
+	if (ArrColor.size() > 0)
+		memset(&(ArrColor[0]), 0, sizeof(uint32_t)* ArrColor.size());
 }
 
 //##########################################################################
@@ -3022,6 +3037,9 @@ ID AIGrid::getQueueIdle()
 
 ID AIGrid::gridQueryFindPath(ID idStart, ID idFinish)
 {
+	if (!existsQuads())
+		return -1;
+
 	if (ArrQuads.size() <= 1)
 	{
 		LibReport(REPORT_MSG_LEVEL_WARNING, "AI grid not found\n");
@@ -3068,8 +3086,26 @@ ID AIGrid::gridQueryFindPath(ID idStart, ID idFinish)
 	return idQueueObject;
 }
 
+bool AIGrid::gridCancelQueryFindPath(ID idQuery)
+{
+	if (!existsQuads())
+		return false;
+
+	if (idQuery >= 0 && idQuery < m_aQueueFind.size())
+	{
+		m_aQueueFind[idQuery].m_state = QUEUE_OBJ_STATE_IDLE;
+		m_aQueueFind[idQuery].m_idStart = m_aQueueFind[idQuery].m_idFinish = -1;
+		return true;
+	}
+
+	return false;
+}
+
 void AIGrid::gridQueryFindPathUpdate(UINT uiLimitMls)
 {
+	if (!existsQuads())
+		return;
+
 	UINT uiStartTime = GetTickCount();
 
 	while ((GetTickCount() - uiStartTime < uiLimitMls) || uiLimitMls == 0)
@@ -3083,5 +3119,7 @@ void AIGrid::gridQueryFindPathUpdate(UINT uiLimitMls)
 			else
 				m_aQueueFind[idQueueObject].m_state = QUEUE_OBJ_STATE_ERROR;
 		}
+		else
+			break;
 	}
 }
\ No newline at end of file
diff --git a/source/aigrid/aigrid.h b/source/aigrid/aigrid.h
index d735f72a5..b93b17aa0 100644
--- a/source/aigrid/aigrid.h
+++ b/source/aigrid/aigrid.h
@@ -149,6 +149,8 @@ public:
 	void GraphicsInit();//инициализация графических данных, если надо
 	void Clear();		//очистка всех данных
 
+	bool existsQuads();
+
 	//сохранение/загрузка
 	void GridSave(const char* path);
 	void GridLoad(const char* path);
@@ -213,6 +215,7 @@ public:
 	bool gridGetPath(ID idQueueObject, ID *pMemory, UINT uiCount, bool canReverse);	//запись найденного пути в уже выделенную память
 
 	ID gridQueryFindPath(ID idStart, ID idFinish);
+	bool gridCancelQueryFindPath(ID idQuery);
 	void gridQueryFindPathUpdate(UINT uiLimitMls);
 
 	void GridSetColorArr(const ID * pmem, DWORD color, UINT count);
diff --git a/source/aigrid/sxaigrid.cpp b/source/aigrid/sxaigrid.cpp
index dd79a4e40..be1281ccd 100644
--- a/source/aigrid/sxaigrid.cpp
+++ b/source/aigrid/sxaigrid.cpp
@@ -90,6 +90,13 @@ SX_LIB_API void SAIG_Clear()
 	g_pAIGrid->Clear();
 }
 
+SX_LIB_API bool SAIG_ExistsQuads()
+{
+	AIG_PRECOND(false);
+
+	return g_pAIGrid->existsQuads();
+}
+
 SX_LIB_API void SAIG_GridSave(const char *szPath)
 {
 	AIG_PRECOND(_VOID);
@@ -343,6 +350,13 @@ SX_LIB_API ID SAIG_GridQueryFindPath(ID idBegin, ID idEnd)
 	return g_pAIGrid->gridQueryFindPath(idBegin, idEnd);
 }
 
+SX_LIB_API bool SAIG_GridCancelQueryFindPath(ID idQuery)
+{
+	AIG_PRECOND(false);
+
+	return g_pAIGrid->gridCancelQueryFindPath(idQuery);
+}
+
 SX_LIB_API int SAIG_GridGetSizePath(ID idQueueObject)
 {
 	AIG_PRECOND(0);
diff --git a/source/aigrid/sxaigrid.h b/source/aigrid/sxaigrid.h
index e27a76ec3..67bfaac4f 100644
--- a/source/aigrid/sxaigrid.h
+++ b/source/aigrid/sxaigrid.h
@@ -113,7 +113,11 @@ typedef bool(*g_aiquad_phy_navigate) (float3_t *pPos);
 SX_LIB_API void SAIG_SetFunc_QuadPhyNavigate(g_aiquad_phy_navigate func);
 
 //! очистка всех данных
-SX_LIB_API void SAIG_Clear();						
+SX_LIB_API void SAIG_Clear();
+
+
+//! есть ли валидные квады на аи сетке
+SX_LIB_API bool SAIG_ExistsQuads();
 
 
 //! сохранение сетки
@@ -186,6 +190,9 @@ SX_LIB_API void SAIG_GridQueryFindPathUpdate(UINT uiLimitMls);
 //! поиск пути, (beginq,beginq]
 SX_LIB_API ID SAIG_GridQueryFindPath(ID idBegin, ID idEnd);
 
+//! отмена запроса поиска пути, idQuery - идентификатор запроса, возвращает удалось ли отменить
+SX_LIB_API bool SAIG_GridCancelQueryFindPath(ID idQuery);
+
 //! размер найденного пути в количестве квадратов
 SX_LIB_API int SAIG_GridGetSizePath(ID idQueueObject);
 
diff --git a/source/game/GameData.cpp b/source/game/GameData.cpp
index a0f27ee6c..1f24c028d 100644
--- a/source/game/GameData.cpp
+++ b/source/game/GameData.cpp
@@ -69,6 +69,22 @@ GameData::GameData()
 	Core_0RegisterCVarFloat("cl_bob_walk", 0.5f, "View bobbing walk period");
 	Core_0RegisterCVarFloat("cl_bob_run", 1.0f, "View bobbing run period");
 
+
+	Core_0RegisterConcmdArg("ent_dump_info", [](int argc, const char ** argv)
+	{
+		if (argc != 2)
+		{
+			printf("Usage: ent_dump_info <hexaddress>");
+			return;
+		}
+
+		CBaseEntity *pEnt;
+		if (sscanf(argv[1], "%x", &pEnt))
+		{
+			LibReport(REPORT_MSG_LEVEL_WARNING, "Ent: id:%d; cls:'%s'; name:'%s'\n", pEnt->getId(), pEnt->getClassName(), pEnt->getName());
+		}
+	});
+
 	CCrosshairManager::loadConfig("config/game/crosshairs.cfg");
 
 	m_pPlayer = (CPlayer*)CREATE_ENTITY("player", m_pMgr);
diff --git a/source/gcore/camera.cpp b/source/gcore/camera.cpp
index e2e4fc50c..2532e2c2b 100644
--- a/source/gcore/camera.cpp
+++ b/source/gcore/camera.cpp
@@ -66,23 +66,30 @@ void CFrustum::update(const float4x4* view,const float4x4* proj)
 
 bool CFrustum::pointInFrustum(const float3 *point) const
 {
-		for (int i=0; i<6; i++)
+	for (int i=0; i<6; ++i)
+	{
+		float tmp = m_aFrustumPlanes[i].m_vNormal.x*(point->x) + m_aFrustumPlanes[i].m_vNormal.y*(point->y) +  m_aFrustumPlanes[i].m_vNormal.z*(point->z) + m_aFrustumPlanes[i].m_fDistance;
+		if(int(tmp * 1000.0f) <= 0)
 		{
-			float tmp = m_aFrustumPlanes[i].m_vNormal.x*(point->x) + m_aFrustumPlanes[i].m_vNormal.y*(point->y) +  m_aFrustumPlanes[i].m_vNormal.z*(point->z) + m_aFrustumPlanes[i].m_fDistance;
-				if(long(tmp * 1000.0f) <= long(0 * 1000.0f))
-				{
-					return false;
-				}
+			return false;
 		}
+	}
     return true;
 }
 
 bool CFrustum::polyInFrustum(const float3* p1, const float3* p2, const float3* p3) const
 {
-		if(pointInFrustum(p1) || pointInFrustum(p2) || pointInFrustum(p3))
-			return true;
+	/*if(pointInFrustum(p1) || pointInFrustum(p2) || pointInFrustum(p3))
+		return true;*/
 
-	return false;
+	for (int i = 0; i<6; i++)
+	{
+		if (int((m_aFrustumPlanes[i].m_vNormal.x * (p1->x) + m_aFrustumPlanes[i].m_vNormal.y * (p1->y) + m_aFrustumPlanes[i].m_vNormal.z * (p1->z) + m_aFrustumPlanes[i].m_fDistance) * 1000.f) > 0) continue;
+		if (int((m_aFrustumPlanes[i].m_vNormal.x * (p2->x) + m_aFrustumPlanes[i].m_vNormal.y * (p2->y) + m_aFrustumPlanes[i].m_vNormal.z * (p2->z) + m_aFrustumPlanes[i].m_fDistance) * 1000.f) > 0) continue;
+		if (int((m_aFrustumPlanes[i].m_vNormal.x * (p3->x) + m_aFrustumPlanes[i].m_vNormal.y * (p3->y) + m_aFrustumPlanes[i].m_vNormal.z * (p3->z) + m_aFrustumPlanes[i].m_fDistance) * 1000.f) > 0) continue;
+		return false;
+	}
+	return true;
 }
 
 bool CFrustum::polyInFrustumAbs(const float3* p1, const float3* p2, const float3* p3) const
@@ -107,8 +114,8 @@ bool CFrustum::sphereInFrustumAbs(const float3 *point, float radius) const
 {
 		for (int i=0; i<6; i++)
 		{
-				if (m_aFrustumPlanes[i].m_vNormal.x*point->x + m_aFrustumPlanes[i].m_vNormal.y*point->y + m_aFrustumPlanes[i].m_vNormal.z*point->z + m_aFrustumPlanes[i].m_fDistance > -radius)
-					return false;
+			if (m_aFrustumPlanes[i].m_vNormal.x*point->x + m_aFrustumPlanes[i].m_vNormal.y*point->y + m_aFrustumPlanes[i].m_vNormal.z*point->z + m_aFrustumPlanes[i].m_fDistance > -radius)
+				return false;
 		}
 	return true;
 }
diff --git a/source/gcore/sxgcore.cpp b/source/gcore/sxgcore.cpp
index 088fb3d0d..ecd001b14 100644
--- a/source/gcore/sxgcore.cpp
+++ b/source/gcore/sxgcore.cpp
@@ -46,6 +46,9 @@ float *g_pOCarrDepthBufferRasterize = 0;
 bool g_isOCenable = false;
 float4x4 g_mOColdView;
 float4x4 g_mOColdProj;
+int g_iOCcountPixels = 0;
+int g_iOCWidth = 0;
+int g_iOCHeight = 0;
 ID RT_DepthOC[2];
 int g_iOCcurrDepth = 0;
 ID VS_ScreenOut = -1;
@@ -53,7 +56,10 @@ ID PS_ScreenOut = -1;
 ID PS_FindMax9 = -1;
 
 //! ����������� ������ ������ ��� ����� occlusion culling
-#define OC_CMP_BIAS 0.0001f
+float g_fOCbiasDEpth = 0.0001f;
+
+//! ���������� �������� ���������� ������������� ��� 
+float g_fOCextTriangle = 2.f;
 
 //! ���������� ������� ������ ������� occlusion culling
 #define OC_SIZE_COEF 0.25f
@@ -251,16 +257,21 @@ void GCoreInit(HWND hWnd, int iWidth, int iHeight, bool isWindowed, DWORD dwFlag
 		}
 	}
 
-	g_pDXDevice->CreateOffscreenPlainSurface(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[0], 0);
-	g_pDXDevice->CreateOffscreenPlainSurface(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[1], 0);
-	g_pDXDevice->CreateOffscreenPlainSurface(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[2], 0);
-	g_pOCarrDepthBuffer = new float[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
-	g_pOCarrWorldPos = new float4[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
-	g_pOCarrDepthBufferReProjection = new float[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
-	g_pOCarrDepthBufferRasterize = new float[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
-
-	RT_DepthOC[0] = SGCore_RTAdd(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, "depth_oc", 0.25f);
-	RT_DepthOC[1] = SGCore_RTAdd(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, "depth_oc2", 0.25f);
+	
+	g_iOCWidth = float(iWidth * OC_SIZE_COEF);
+	g_iOCHeight = float(iHeight * OC_SIZE_COEF);
+	g_iOCcountPixels = g_iOCWidth * g_iOCHeight;
+
+	g_pDXDevice->CreateOffscreenPlainSurface(g_iOCWidth, g_iOCHeight, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[0], 0);
+	g_pDXDevice->CreateOffscreenPlainSurface(g_iOCWidth, g_iOCHeight, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[1], 0);
+	g_pDXDevice->CreateOffscreenPlainSurface(g_iOCWidth, g_iOCHeight, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[2], 0);
+	g_pOCarrDepthBuffer = new float[g_iOCcountPixels+1];
+	g_pOCarrWorldPos = new float4[g_iOCcountPixels+1];
+	g_pOCarrDepthBufferReProjection = new float[g_iOCcountPixels+1];
+	g_pOCarrDepthBufferRasterize = new float[g_iOCcountPixels];
+
+	RT_DepthOC[0] = SGCore_RTAdd(g_iOCWidth, g_iOCHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, "depth_oc", 0.25f);
+	RT_DepthOC[1] = SGCore_RTAdd(g_iOCWidth, g_iOCHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, "depth_oc2", 0.25f);
 	
 	VS_ScreenOut = SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "pp_quad_render.vs", "pp_quad_render.vs", SHADER_CHECKDOUBLE_PATH);
 	PS_ScreenOut = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "pp_quad_render.ps", "pp_quad_render.ps", SHADER_CHECKDOUBLE_PATH);
@@ -381,13 +392,17 @@ SX_LIB_API bool SGCore_OnDeviceReset(int iWidth, int iHeight, bool windowed)
 {
 	SG_PRECOND(false);
 
-	g_pDXDevice->CreateOffscreenPlainSurface(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[0], 0);
-	g_pDXDevice->CreateOffscreenPlainSurface(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[1], 0);
-	g_pDXDevice->CreateOffscreenPlainSurface(float(iWidth) * OC_SIZE_COEF, float(iHeight) * OC_SIZE_COEF, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[2], 0);
-	g_pOCarrDepthBuffer = new float[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
-	g_pOCarrWorldPos = new float4[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
-	g_pOCarrDepthBufferReProjection = new float[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
-	g_pOCarrDepthBufferRasterize = new float[int(float(iWidth) * OC_SIZE_COEF * float(iHeight) * OC_SIZE_COEF) + 1];
+	g_iOCWidth = float(iWidth * OC_SIZE_COEF);
+	g_iOCHeight = float(iHeight * OC_SIZE_COEF);
+	g_iOCcountPixels = g_iOCWidth * g_iOCHeight;
+
+	g_pDXDevice->CreateOffscreenPlainSurface(g_iOCWidth, g_iOCHeight, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[0], 0);
+	g_pDXDevice->CreateOffscreenPlainSurface(g_iOCWidth, g_iOCHeight, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[1], 0);
+	g_pDXDevice->CreateOffscreenPlainSurface(g_iOCWidth, g_iOCHeight, D3DFMT_R32F, D3DPOOL_SYSTEMMEM, &g_pOCsurfDepthBuffer[2], 0);
+	g_pOCarrDepthBuffer = new float[g_iOCcountPixels + 1];
+	g_pOCarrWorldPos = new float4[g_iOCcountPixels + 1];
+	g_pOCarrDepthBufferReProjection = new float[g_iOCcountPixels + 1];
+	g_pOCarrDepthBufferRasterize = new float[g_iOCcountPixels];
 
 	g_oD3DAPP.BackBufferWidth = iWidth;
 	g_oD3DAPP.BackBufferHeight = iHeight;
@@ -520,13 +535,23 @@ SX_LIB_API void SGCore_OC_SetEnable(bool isEnable)
 	g_isOCenable = isEnable;
 }
 
-SX_LIB_API void SGCore_OC_Update(ID idDepthMap)
+const ISXFrustum *g_pFrustum = 0;
+int g_iOCcountFC = 0;
+int g_iOCcountFCfail = 0;
+
+SX_LIB_API void SGCore_OC_Update(ID idDepthMap, const ISXFrustum *pFrustum)
 {
 	SG_PRECOND(_VOID);
 
 	if (!g_isOCenable)
 		return;
 
+	g_pFrustum = pFrustum;
+	g_iOCcountFC = 0;
+	g_iOCcountFCfail = 0;
+
+	
+
 	static const float *r_near = GET_PCVAR_FLOAT("r_near");
 	static const float *r_far = GET_PCVAR_FLOAT("r_far");
 
@@ -546,8 +571,10 @@ SX_LIB_API void SGCore_OC_Update(ID idDepthMap)
 		return;
 	}
 
-	float fWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
-	float fHeight = g_oD3DAPP.BackBufferHeight * OC_SIZE_COEF;
+	g_fOCbiasDEpth = 1.f / (*r_far);
+
+	/*float fWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
+	float fHeight = g_oD3DAPP.BackBufferHeight * OC_SIZE_COEF;*/
 
 	IDirect3DTexture9 *pTexDepth = SGCore_RTGetTexture(idDepthMap);
 	IDirect3DTexture9 *pTexDepthOC = SGCore_RTGetTexture(RT_DepthOC[g_iOCcurrDepth]);
@@ -597,15 +624,13 @@ SX_LIB_API void SGCore_OC_Update(ID idDepthMap)
 	D3DLOCKED_RECT  srect;
 	g_pOCsurfDepthBuffer[iCurrOld]->LockRect(&srect, 0, D3DLOCK_READONLY | D3DLOCK_DONOTWAIT);
 	
-	memcpy(g_pOCarrDepthBuffer, srect.pBits, sizeof(float)* fWidth * fHeight);
+	memcpy(g_pOCarrDepthBuffer, srect.pBits, sizeof(float)* g_iOCcountPixels);
 	g_pOCsurfDepthBuffer[iCurrOld]->UnlockRect();
 
 	mem_release(pDepthSurf);
 
 	//**********************************************************************
 	
-	int iCountPixels = fWidth * fHeight;
-
 	float fPosX = 0, fPosY = 0;
 	
 	float4 vWorldPos;
@@ -641,23 +666,23 @@ SX_LIB_API void SGCore_OC_Update(ID idDepthMap)
 	Core_RFloat3Get(G_RI_FLOAT3_OBSERVER_POSITION, &vObserverPos);
 
 	float fTanHalfFOV = tan((*r_default_fov) * 0.5f);
-	float fAspectRatio = fWidth / fHeight;
+	float fAspectRatio = float(g_iOCWidth) / float(g_iOCHeight);
 	float fFarY = fTanHalfFOV * (*r_far);
 	float fFarX = fFarY * fAspectRatio;
 
 	float4 vEyeRay, vWorldRay;
 	float4x4 mInvView = SMMatrixInverse(&fD, g_mOColdView);
 
-	/*for (int i = 0; i < iCountPixels; ++i)
+	/*for (int i = 0; i < g_iOCcountPixels; ++i)
 	{
 		//float linearDepth = (2.0 * (*r_near)) / ((*r_far) + (*r_near) - g_pArrDepthBufferOC[i] * ((*r_far) - (*r_near)));
 		//g_pArrDepthBufferOC[i] = linearDepth;
 
-		fPosY = int(float(i) / fWidth);
-		fPosX = int(i - (fPosY * fWidth));
+		fPosY = int(float(i) / g_iOCWidth);
+		fPosX = int(i - (fPosY * g_iOCWidth));
 
-		fPosX = fPosX / fWidth;
-		fPosY = fPosY / fHeight;
+		fPosX = fPosX / g_iOCWidth;
+		fPosY = fPosY / g_iOCHeight;
 
 		fPosX = 2.f * fPosX - 1.f;
 		fPosY = 2.f * (1.f - fPosY) - 1.f;
@@ -677,14 +702,14 @@ SX_LIB_API void SGCore_OC_Update(ID idDepthMap)
 
 	float4 vWorldRay0, vWorldRay1;
 
-	for (int x = 0; x < fWidth; ++x)
+	for (int x = 0; x < g_iOCWidth; ++x)
 	{
-		vWorldRay0 = SMVectorLerp(aWorldRays[0], aWorldRays[1], float(x) / fWidth);
-		vWorldRay1 = SMVectorLerp(aWorldRays[3], aWorldRays[2], float(x) / fWidth);
-		for (int y = 0; y < fHeight; ++y)
+		vWorldRay0 = SMVectorLerp(aWorldRays[0], aWorldRays[1], float(x) / g_iOCWidth);
+		vWorldRay1 = SMVectorLerp(aWorldRays[3], aWorldRays[2], float(x) / g_iOCWidth);
+		for (int y = 0; y < g_iOCHeight; ++y)
 		{
-			int iPosPixel = (y * fWidth) + x;
-			vWorldRay = SMVectorLerp(vWorldRay1, vWorldRay0,float(y) / fHeight);
+			int iPosPixel = (y * g_iOCWidth) + x;
+			vWorldRay = SMVectorLerp(vWorldRay1, vWorldRay0, float(y) / g_iOCHeight);
 			vWorldPos = vObserverPos + vWorldRay * g_pOCarrDepthBuffer[iPosPixel];
 			vWorldPos.w = 1.f;
 			g_pOCarrWorldPos[iPosPixel] = vWorldPos;
@@ -704,7 +729,7 @@ SX_LIB_API void SGCore_OC_Update(ID idDepthMap)
 	{
 		g_pOCsurfDepthBuffer[2]->LockRect(&srect, 0, D3DLOCK_READONLY);
 
-		memcpy(srect.pBits, g_pOCarrDepthBuffer, sizeof(float)* float(g_oD3DAPP.BackBufferWidth)*0.25 * float(g_oD3DAPP.BackBufferHeight)*0.25);
+		memcpy(srect.pBits, g_pOCarrDepthBuffer, sizeof(float) * g_iOCcountPixels);
 		g_pOCsurfDepthBuffer[2]->UnlockRect();
 
 		D3DXSaveSurfaceToFile("C:/1/g_pOCsurfDepthBuffer.jpg", D3DXIFF_JPG, g_pOCsurfDepthBuffer[2], NULL, NULL);
@@ -740,8 +765,8 @@ SX_LIB_API void SGCore_OC_Reprojection()
 		return;
 	}
 
-	float fWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
-	float fHeight = g_oD3DAPP.BackBufferHeight * OC_SIZE_COEF;
+	/*float fWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
+	float fHeight = g_oD3DAPP.BackBufferHeight * OC_SIZE_COEF;*/
 
 	float4x4 mView, mProjection;
 	Core_RMatrixGet(G_RI_MATRIX_OBSERVER_VIEW, &mView);
@@ -749,11 +774,11 @@ SX_LIB_API void SGCore_OC_Reprojection()
 
 	float4x4 mViewProj = mView * mProjection;
 
-	int iCountPixels = fWidth * fHeight;
+	//int iCountPixels = fWidth * fHeight;
 
 	float4 vNewPos;
 
-	for (int i = 0; i < iCountPixels; ++i)
+	for (int i = 0; i < g_iOCcountPixels; ++i)
 	{
 		g_pOCarrDepthBufferReProjection[i] = 1.f;
 		g_pOCarrDepthBufferRasterize[i] = 1.f;
@@ -765,7 +790,7 @@ SX_LIB_API void SGCore_OC_Reprojection()
 	float2 vNewPos2;
 
 	//���� ���������� ������� �������, ������ ����� ������� � screen-space � ����� �������
-	for (int i = 0; i < iCountPixels; ++i)
+	for (int i = 0; i < g_iOCcountPixels; ++i)
 	{
 		vNewPos = SMVector4Transform(g_pOCarrWorldPos[i], mViewProj);
 
@@ -794,11 +819,11 @@ SX_LIB_API void SGCore_OC_Reprojection()
 
 		if ((vNewPos.x <= 1.f && vNewPos.x >= 0.f) && (vNewPos.y <= 1.f && vNewPos.y >= 0.f))
 		{
-			int x = floor(vNewPos.x * fWidth + 0.5f);
-			int y = floor(vNewPos.y * fHeight + 0.5f);
-			int iPosPixel = int(y * fWidth) + x;
+			int x = floor(vNewPos.x * float(g_iOCWidth) + 0.5f);
+			int y = floor(vNewPos.y * g_iOCHeight + 0.5f);
+			int iPosPixel = int(y * g_iOCWidth) + x;
 
-			if (iPosPixel > iCountPixels)
+			if (iPosPixel > g_iOCcountPixels)
 				int qwerty = 0;
 			else
 			{
@@ -815,7 +840,7 @@ SX_LIB_API void SGCore_OC_Reprojection()
 		D3DLOCKED_RECT  srect;
 		g_pOCsurfDepthBuffer[2]->LockRect(&srect, 0, D3DLOCK_READONLY);
 
-		memcpy(srect.pBits, g_pOCarrDepthBufferReProjection, sizeof(float)* float(g_oD3DAPP.BackBufferWidth)*0.25 * float(g_oD3DAPP.BackBufferHeight)*0.25);
+		memcpy(srect.pBits, g_pOCarrDepthBufferReProjection, sizeof(float) * g_iOCcountPixels);
 		g_pOCsurfDepthBuffer[2]->UnlockRect();
 		D3DXSaveSurfaceToFile("C:/1/g_pSurfDepthBufferOCreproj.jpg", D3DXIFF_JPG, g_pOCsurfDepthBuffer[2], NULL, NULL);
 	}
@@ -872,10 +897,10 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 	float3 vPointB = vB;
 	float3 vPointC = vC;
 
-	int iWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
-	int iHeight = g_oD3DAPP.BackBufferHeight * OC_SIZE_COEF;
+	/*int iWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
+	int iHeight = g_oD3DAPP.BackBufferHeight * OC_SIZE_COEF;*/
 
-	int iCountPixels = iWidth * iHeight;
+	//int iCountPixels = iWidth * iHeight;
 
 	//��� ���������� D ���������� ������������ ������������� ����� ������������
 	float fD = -(vNormal.x * vPointA.x + vNormal.y * vPointA.y + vNormal.z * vPointA.z);
@@ -900,8 +925,8 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 	bool isVisible = false;
 
 	//���������� ������������, �� ������ ����������� ����������, ������� ����� �����
-	vPointA.y -= 1.f;
-	vPointC.y += 1.f;
+	vPointA.y -= g_fOCextTriangle;
+	vPointC.y += g_fOCextTriangle;
 
 	int iTotalHeight = vPointC.y - vPointA.y;
 
@@ -913,8 +938,8 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 	if (iSegmentHeight == 0)
 		return false;
 
-	int iStartY = clampf(vPointA.y, 0, iHeight-1);
-	int iFinishY = clampf(vPointB.y, 0, iHeight-1);
+	int iStartY = clampf(vPointA.y, 0, g_iOCHeight - 1);
+	int iFinishY = clampf(vPointB.y, 0, g_iOCHeight - 1);
 
 	for (int y = iStartY; y <= iFinishY; ++y)
 	{
@@ -929,8 +954,8 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 		if (fA > fB)
 			std::swap(fA, fB);
 
-		fA = clampf(fA - 1, 0, iWidth - 1);
-		fB = clampf(fB + 1, 0, iWidth - 1);
+		fA = clampf(fA - g_fOCextTriangle, 0, g_iOCWidth - 1);
+		fB = clampf(fB + g_fOCextTriangle, 0, g_iOCWidth - 1);
 
 		//� ��������� �������� � ���������� ������� �� ����, �� �������� ������� ����� ������� ���� ���������
 		for (int x = fA; x <= fB; ++x)
@@ -938,15 +963,15 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 			/*if (x < 0 || x > iWidth - 1)
 				continue;*/
 
-			int iPosPixel = (y * iWidth) + x;
-			if (iPosPixel < iCountPixels)
+			int iPosPixel = (y * g_iOCWidth) + x;
+			if (iPosPixel < g_iOCcountPixels)
 			{
 				float fCurrDepth = (-(vNormal.x * float(x) + vNormal.y * float(y) + fD) / vNormal.z);
 				
 				/*if (isRasterize)
 					g_pOCarrDepthBufferRasterize[iPosPixel] = 0;*/
 
-				if (fCurrDepth >= 0.f && g_pOCarrDepthBufferReProjection[iPosPixel] >= (fCurrDepth - OC_CMP_BIAS))
+				if (fCurrDepth >= 0.f && g_pOCarrDepthBufferReProjection[iPosPixel] >= (fCurrDepth - g_fOCbiasDEpth))
 				{
 					//if (!isRasterize)
 						return true;
@@ -963,8 +988,8 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 	if (iSegmentHeight == 0)
 		return false;
 
-	iStartY = clampf(vPointB.y, 0, iHeight-1);
-	iFinishY = clampf(vPointC.y, 0, iHeight-1);
+	iStartY = clampf(vPointB.y, 0, g_iOCHeight - 1);
+	iFinishY = clampf(vPointC.y, 0, g_iOCHeight - 1);
 
 	for (int y = iStartY; y <= iFinishY; ++y)
 	{
@@ -979,8 +1004,8 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 		if (fA > fB)
 			std::swap(fA, fB);
 
-		fA = clampf(fA - 1, 0, iWidth - 1);
-		fB = clampf(fB + 1, 0, iWidth - 1);
+		fA = clampf(fA - g_fOCextTriangle, 0, g_iOCWidth - 1);
+		fB = clampf(fB + g_fOCextTriangle, 0, g_iOCWidth - 1);
 
 		//� ��������� �������� � ���������� ������� �� ����, �� �������� ������� ����� ������� ���� ���������
 		for (int x = fA; x <= fB; ++x)
@@ -988,15 +1013,15 @@ inline bool OC_TriangleRasterize(const float4 &vA, const float4 &vB, const float
 			/*if (x < 0 || x > iWidth - 1)
 				continue;*/
 
-			int iPosPixel = (y * iWidth) + x;
-			if (iPosPixel < iCountPixels)
+			int iPosPixel = (y * g_iOCWidth) + x;
+			if (iPosPixel < g_iOCcountPixels)
 			{
 				float fCurrDepth = (-(vNormal.x * float(x) + vNormal.y * float(y) + fD) / vNormal.z);
 				
 				/*if (isRasterize)
 					g_pOCarrDepthBufferRasterize[iPosPixel] = 0;*/
 
-				if (fCurrDepth >= 0.f && g_pOCarrDepthBufferReProjection[iPosPixel] >= (fCurrDepth - OC_CMP_BIAS))
+				if (fCurrDepth >= 0.f && g_pOCarrDepthBufferReProjection[iPosPixel] >= (fCurrDepth - g_fOCbiasDEpth))
 				{
 					//if (!isRasterize)
 						return true;
@@ -1018,6 +1043,18 @@ inline bool OC_RasterizeQuad(const float3 &vA, const float3 &vB, const float3 &v
 
 
 
+inline bool OC_FrustumCulling(const float3 &vA, const float3 &vB, const float3 &vC)
+{
+	if (GetAsyncKeyState('P'))
+		return true;
+	++g_iOCcountFC;
+	bool isVisible = (!g_pFrustum || g_pFrustum->polyInFrustum(&vA, &vB, &vC));
+	if (!isVisible)
+		++g_iOCcountFCfail;
+	return isVisible;
+}
+
+
 SX_LIB_API bool SGCore_OC_IsVisible(const float3 *pMax, const float3 *pMin)
 {
 	SG_PRECOND(false);
@@ -1068,10 +1105,10 @@ SX_LIB_API bool SGCore_OC_IsVisible(const float3 *pMax, const float3 *pMin)
 	vMin -= g_cvOCext;
 
 
-	float fWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
+	/*float fWidth = g_oD3DAPP.BackBufferWidth * OC_SIZE_COEF;
 	float fHeight = g_oD3DAPP.BackBufferHeight * OC_SIZE_COEF;
 
-	int iCountPixels = fWidth * fHeight;
+	int iCountPixels = fWidth * fHeight;*/
 
 	float4x4 mWorld, mView, mProjection;
 	Core_RMatrixGet(G_RI_MATRIX_WORLD, &mWorld);
@@ -1106,8 +1143,8 @@ SX_LIB_API bool SGCore_OC_IsVisible(const float3 *pMax, const float3 *pMin)
 		aSSPoints[i].x = aSSPoints[i].x * 0.5 + 0.5;
 		aSSPoints[i].y = aSSPoints[i].y * (-0.5) + 0.5;
 
-		aSSPoints[i].x *= fWidth;
-		aSSPoints[i].y *= fHeight;
+		aSSPoints[i].x *= g_iOCWidth;
+		aSSPoints[i].y *= g_iOCHeight;
 
 		aSSPoints[i].x = int(aSSPoints[i].x);
 		aSSPoints[i].y = int(aSSPoints[i].y);
@@ -1316,18 +1353,18 @@ SX_LIB_API bool SGCore_OC_IsVisible(const float3 *pMax, const float3 *pMin)
 		);*/
 
 	bool isVisible = (
-		(OC_TriangleRasterize(aSSPoints[7], aSSPoints[6], aSSPoints[1], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[7], aSSPoints[1], aSSPoints[4], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[0], aSSPoints[5], aSSPoints[2], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[0], aSSPoints[3], aSSPoints[5], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[0], aSSPoints[1], aSSPoints[3], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[1], aSSPoints[6], aSSPoints[3], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[5], aSSPoints[4], aSSPoints[2], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[4], aSSPoints[5], aSSPoints[7], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[0], aSSPoints[2], aSSPoints[1], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[1], aSSPoints[2], aSSPoints[4], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[6], aSSPoints[5], aSSPoints[3], false, aSSPoints[0], vNearFar)) ||
-		(OC_TriangleRasterize(aSSPoints[5], aSSPoints[6], aSSPoints[7], false, aSSPoints[0], vNearFar))
+		(OC_FrustumCulling(aWPoints[7], aWPoints[6], aWPoints[1]) && OC_TriangleRasterize(aSSPoints[7], aSSPoints[6], aSSPoints[1], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[7], aWPoints[1], aWPoints[4]) && OC_TriangleRasterize(aSSPoints[7], aSSPoints[1], aSSPoints[4], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[0], aWPoints[5], aWPoints[2]) && OC_TriangleRasterize(aSSPoints[0], aSSPoints[5], aSSPoints[2], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[0], aWPoints[3], aWPoints[5]) && OC_TriangleRasterize(aSSPoints[0], aSSPoints[3], aSSPoints[5], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[0], aWPoints[1], aWPoints[3]) && OC_TriangleRasterize(aSSPoints[0], aSSPoints[1], aSSPoints[3], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[1], aWPoints[6], aWPoints[3]) && OC_TriangleRasterize(aSSPoints[1], aSSPoints[6], aSSPoints[3], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[5], aWPoints[4], aWPoints[2]) && OC_TriangleRasterize(aSSPoints[5], aSSPoints[4], aSSPoints[2], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[4], aWPoints[5], aWPoints[7]) && OC_TriangleRasterize(aSSPoints[4], aSSPoints[5], aSSPoints[7], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[0], aWPoints[2], aWPoints[1]) && OC_TriangleRasterize(aSSPoints[0], aSSPoints[2], aSSPoints[1], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[1], aWPoints[2], aWPoints[4]) && OC_TriangleRasterize(aSSPoints[1], aSSPoints[2], aSSPoints[4], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[6], aWPoints[5], aWPoints[3]) && OC_TriangleRasterize(aSSPoints[6], aSSPoints[5], aSSPoints[3], false, aSSPoints[0], vNearFar)) ||
+		(OC_FrustumCulling(aWPoints[5], aWPoints[6], aWPoints[7]) && OC_TriangleRasterize(aSSPoints[5], aSSPoints[6], aSSPoints[7], false, aSSPoints[0], vNearFar))
 		);
 
 	return isVisible;
diff --git a/source/gcore/sxgcore.h b/source/gcore/sxgcore.h
index 79b4702d3..6c55acb29 100644
--- a/source/gcore/sxgcore.h
+++ b/source/gcore/sxgcore.h
@@ -59,6 +59,8 @@ See the license in LICENSE
 #define SXGC_ERR_NON_DETECTED_D3D -1
 #define SXGC_ERR_FAILED_INIT_D3D -2
 
+class ISXFrustum;
+
 //! \name Базовые функции библиотеки 
 //!@{
 
@@ -258,7 +260,7 @@ SX_LIB_API void SGCore_SetFunc_MtlGroupRenderIsSingly(g_func_mtl_group_render_is
 SX_LIB_API void SGCore_OC_SetEnable(bool isEnable);
 
 //! обновление буфера глубины для теста, должна вызываться в старом кадре, к примеру после всего рендера (глубина и матрицы для текущего)
-SX_LIB_API void SGCore_OC_Update(ID idDepthMap);
+SX_LIB_API void SGCore_OC_Update(ID idDepthMap, const ISXFrustum *pFrustum);
 
 //! репроекция глубины, должна вызываться в новом кадре до основного рендера всего того, что подвергается тесту на загороженность, матрицы должны быть от нового кадра
 SX_LIB_API void SGCore_OC_Reprojection();
diff --git a/source/physics/PhyWorld.cpp b/source/physics/PhyWorld.cpp
index 08a819813..0522c6524 100644
--- a/source/physics/PhyWorld.cpp
+++ b/source/physics/PhyWorld.cpp
@@ -627,7 +627,46 @@ void PhyWorld::DebugDrawer::drawContactPoint(const btVector3 & PointOnB, const b
 
 void PhyWorld::DebugDrawer::reportErrorWarning(const char * warningString)
 {
-	LibReport(REPORT_MSG_LEVEL_WARNING, "%s\n", warningString);
+	if (m_bExpectObject)
+	{
+		m_bExpectObject = false;
+		btCollisionObject *pObj = (btCollisionObject*)warningString;
+
+		btVector3 vOrigin = pObj->getWorldTransform().getOrigin();
+		LibReport(REPORT_MSG_LEVEL_WARNING, "Object world position: %.2f, %.2f, %.2f\n", vOrigin.x(), vOrigin.y(), vOrigin.z());
+
+		btVector3 minAabb, maxAabb;
+		pObj->getCollisionShape()->getAabb(pObj->getWorldTransform(), minAabb, maxAabb);
+		LibReport(REPORT_MSG_LEVEL_WARNING, "AABBmin: %.2f, %.2f, %.2f\n", minAabb.x(), minAabb.y(), minAabb.z());
+		LibReport(REPORT_MSG_LEVEL_WARNING, "AABBmax: %.2f, %.2f, %.2f\n", maxAabb.x(), maxAabb.y(), maxAabb.z());
+		if (pObj->getCollisionShape()->getShapeType() == CAPSULE_SHAPE_PROXYTYPE)
+		{
+			btCapsuleShape *pCaps = (btCapsuleShape*)pObj->getCollisionShape();
+			LibReport(REPORT_MSG_LEVEL_WARNING, "Radius: %.2f; HalfHeight: %.2f\n", pCaps->getRadius(), pCaps->getHalfHeight());
+			SMMATRIX mat;
+			pObj->getWorldTransform().getOpenGLMatrix((float*)&mat);
+			LibReport(REPORT_MSG_LEVEL_WARNING, "Transform:\n");
+			LibReport(REPORT_MSG_LEVEL_WARNING, " %5.4f %5.4f %5.4f %5.4f\n", mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3]);
+			LibReport(REPORT_MSG_LEVEL_WARNING, " %5.4f %5.4f %5.4f %5.4f\n", mat.m[1][0], mat.m[1][1], mat.m[1][2], mat.m[1][3]);
+			LibReport(REPORT_MSG_LEVEL_WARNING, " %5.4f %5.4f %5.4f %5.4f\n", mat.m[2][0], mat.m[2][1], mat.m[2][2], mat.m[2][3]);
+			LibReport(REPORT_MSG_LEVEL_WARNING, " %5.4f %5.4f %5.4f %5.4f\n", mat.m[3][0], mat.m[3][1], mat.m[3][2], mat.m[3][3]);
+		}
+
+		if (!pObj->getUserPointer())
+		{
+			LibReport(REPORT_MSG_LEVEL_WARNING, "getUserPointer() is NULL.\n");
+			return;
+		}
+		Core_0ConsoleExecCmd("ent_dump_info %x", pObj->getUserPointer());
+		return;
+	}
+	if (!strcmp(warningString, "@@@obj"))
+	{
+		m_bExpectObject = true;
+		return;
+	}
+
+	LibReport(REPORT_MSG_LEVEL_WARNING, "%s", warningString);
 }
 
 void PhyWorld::DebugDrawer::draw3dText(const btVector3& location, const char* textString)
diff --git a/source/physics/PhyWorld.h b/source/physics/PhyWorld.h
index a884c5d1c..6581c80c9 100644
--- a/source/physics/PhyWorld.h
+++ b/source/physics/PhyWorld.h
@@ -78,7 +78,14 @@ public:
 		};
 		int m_iDebugMode;
 		Array<render_point, 16384> m_vDrawData;
+
+		bool m_bExpectObject;
 	public:
+		DebugDrawer():
+			m_bExpectObject(false)
+		{
+		}
+
 		void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
 
 		void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color);
diff --git a/source/render/render_func.cpp b/source/render/render_func.cpp
index f936fc291..a799ca304 100644
--- a/source/render/render_func.cpp
+++ b/source/render/render_func.cpp
@@ -113,7 +113,7 @@ void SXRenderFunc::SetRenderSceneFilterUn()
 
 //##########################################################################
 
-void SXRenderFunc::ComDeviceLost()
+void SXRenderFunc::ComDeviceLost(bool isSetWindowSize)
 {
 	static int *r_resize = (int*)GET_PCVAR_INT("r_resize");
 
@@ -121,7 +121,7 @@ void SXRenderFunc::ComDeviceLost()
 	static int *r_win_height = (int*)GET_PCVAR_INT("r_win_height");
 	static const bool *r_win_windowed = GET_PCVAR_BOOL("r_win_windowed");
 
-	if (*r_resize != RENDER_RESIZE_CHANGE)
+	if (isSetWindowSize && *r_resize != RENDER_RESIZE_CHANGE)
 	{
 		//получаем текущий размер окна в которое рисовали
 		RECT rect_scene;
@@ -410,23 +410,38 @@ void SXRenderFunc::SaveWorkTex()
 
 void SXRenderFunc::InitModeWindow()
 {
+	static int * r_win_width = (int*)GET_PCVAR_INT("r_win_width");
+	static int * r_win_height = (int*)GET_PCVAR_INT("r_win_height");
+
 	static const bool *r_win_windowed = GET_PCVAR_BOOL("r_win_windowed");
 
+	static DWORD dwStyle = GetWindowLong(GData::Handle3D, GWL_STYLE);
+
 	if (r_win_windowed == NULL)
 		return;
 
 	if (!(*r_win_windowed))
 	{
-		SetWindowLong(GData::Handle3D, GWL_STYLE, GetWindowLong(GData::Handle3D, GWL_STYLE) | WS_POPUP);
+		SetWindowLong(GData::Handle3D, GWL_STYLE, dwStyle | WS_POPUP);
 		ShowWindow(GData::Handle3D, SW_MAXIMIZE);
 	}
 	else
 	{
-		SetWindowLong(GData::Handle3D, GWL_STYLE, GetWindowLong(GData::Handle3D, GWL_STYLE) ^ WS_POPUP);
+		SetWindowLong(GData::Handle3D, GWL_STYLE, dwStyle);
+
+		/*RECT rc;
+		GetWindowRect(GData::Handle3D, &rc);*/
+
+		RECT rc2 = { 0, 0, *r_win_width, *r_win_height };
+		AdjustWindowRect(&rc2, dwStyle, false);
+
+		int iWidth = rc2.right - rc2.left;
+		int iHeight = rc2.bottom - rc2.top;
+		int iPosX = (GetSystemMetrics(SM_CXSCREEN) - iWidth) / 2;
+		int iPosY = (GetSystemMetrics(SM_CYSCREEN) - iHeight) / 2;
+		SetWindowPos(GData::Handle3D, HWND_NOTOPMOST, iPosX, iPosY, iWidth, iHeight, SWP_SHOWWINDOW);
 
-		RECT rc;
-		GetWindowRect(GData::Handle3D, &rc);
-		SetWindowPos(GData::Handle3D, HWND_NOTOPMOST, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW);
+		SetForegroundWindow(GData::Handle3D);
 	}
 }
 
diff --git a/source/render/render_func.h b/source/render/render_func.h
index ea806761f..712347180 100644
--- a/source/render/render_func.h
+++ b/source/render/render_func.h
@@ -55,7 +55,7 @@ namespace SXRenderFunc
 	//**********************************************************************
 
 	//! обработка потери и восстановление устройства
-	void ComDeviceLost();
+	void ComDeviceLost(bool isSetWindowSize);
 
 	//! обработка и установка основных матриц, обработка плоскостей отсечения
 	void UpdateView();						
diff --git a/source/render/sxrender.cpp b/source/render/sxrender.cpp
index 6b43a9238..987be6f37 100644
--- a/source/render/sxrender.cpp
+++ b/source/render/sxrender.cpp
@@ -254,9 +254,9 @@ SX_LIB_API ID SRender_EditorGetSelectTex()
 //##########################################################################
 
 
-SX_LIB_API void SRender_ComDeviceLost()
+SX_LIB_API void SRender_ComDeviceLost(bool isSetWindowSize)
 {
-	SXRenderFunc::ComDeviceLost();
+	SXRenderFunc::ComDeviceLost(isSetWindowSize);
 }
 
 SX_LIB_API void SRender_ComVisibleForLight()
@@ -372,7 +372,9 @@ SX_LIB_API void SRender_SaveWorkTex()
 
 SX_LIB_API void SRender_ChangeModeWindow()
 {
+	//LibReport(REPORT_MSG_LEVEL_NOTICE, "SRender_ChangeModeWindow\n");
 	SXRenderFunc::ChangeModeWindow();
+	//LibReport(REPORT_MSG_LEVEL_NOTICE, "SRender_ChangeModeWindow --\n");
 }
 
 SX_LIB_API void SRender_FullScreenChangeSizeAbs()
diff --git a/source/render/sxrender.h b/source/render/sxrender.h
index 0954ff53f..1b529bdc9 100644
--- a/source/render/sxrender.h
+++ b/source/render/sxrender.h
@@ -308,8 +308,8 @@ SX_LIB_API void SRender_UpdateEditorial(DWORD timeDelta);
 
 //##########################################################################
 
-//! обработка потери и восстановление устройства
-SX_LIB_API void SRender_ComDeviceLost();
+//! обработка потери и восстановление устройства, isSetWindowSize - устанавливать ли размеры окна (сделано для редакторов)
+SX_LIB_API void SRender_ComDeviceLost(bool isSetWindowSize);
 
 //! обработка видимости для источников света
 SX_LIB_API void SRender_ComVisibleForLight();
diff --git a/source/skyxengine.cpp b/source/skyxengine.cpp
index ee3716b21..36647bb2c 100644
--- a/source/skyxengine.cpp
+++ b/source/skyxengine.cpp
@@ -330,10 +330,21 @@ void SkyXEngine_Init(HWND hWnd3D, HWND hWndParent3D)
 	SRender_SetCamera(SXGame_GetActiveCamera());
 #endif
 
+
+#if defined(SX_GAME)
+	Core_0ConsoleExecCmd("exec ../config_sys.cfg");
+	Core_0ConsoleExecCmd("exec ../config_game.cfg");
+	Core_0ConsoleExecCmd("exec ../config_game_user.cfg");
+#endif
+
 #if !defined(SX_GAME)
-	Core_0ConsoleExecCmd("exec ../editor.cfg");
+	Core_0ConsoleExecCmd("exec ../config_sys.cfg");
+	Core_0ConsoleExecCmd("exec ../config_editor.cfg");
 #endif
 
+	Core_0ConsoleUpdate();
+
+
 #if defined(SX_GAME)
 	if (*r_win_windowed)
 		ShowWindow(hWnd3DCurr, SW_SHOW);
@@ -477,15 +488,6 @@ void SkyXEngine_CreateLoadCVar()
 	Core_0RegisterConcmd("change_mode_window_abs", SRender_FullScreenChangeSizeAbs);
 #endif
 
-	Core_0ConsoleExecCmd("exec ../sysconfig.cfg");
-	Core_0ConsoleExecCmd("exec ../userconfig.cfg");
-
-	Core_0ConsoleUpdate();
-	Core_0ConsoleUpdate();
-
-	Core_0ConsoleExecCmd("exec ../sysconfig.cfg");
-	Core_0ConsoleExecCmd("exec ../userconfig.cfg");
-
 	LibReport(REPORT_MSG_LEVEL_NOTICE, "CVar initialized\n");
 }
 
@@ -511,9 +513,22 @@ LRESULT CALLBACK SkyXEngine_WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LP
 	case WM_DESTROY:
 		PostQuitMessage(0);
 		break;
-		}
+	}
 
-	return(DefWindowProc(hWnd, uiMessage, wParam, lParam));
+	// системная обработка F10 (вызов меню) не надо, останавливает главный цикл
+	if ((uiMessage == WM_SYSKEYDOWN || uiMessage == WM_SYSKEYUP) && wParam == VK_F10)
+		return 0;
+
+	// системная обработка Alt (вызов меню) не надо, останавливает главный цикл
+	if (
+		(uiMessage == WM_SYSKEYDOWN || uiMessage == WM_SYSKEYUP) 
+		&& !GetAsyncKeyState(VK_TAB) 
+		&& (wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
+		)
+		return 0;
+
+	LRESULT lRes = DefWindowProc(hWnd, uiMessage, wParam, lParam);
+	return(lRes);
 }
 
 HWND SkyXEngine_CreateWindow(const char *szName, const char *szCaption, int iWidth, int iHeight)
@@ -620,7 +635,13 @@ void SkyXEngine_Frame(DWORD timeDelta)
 	{
 		//если не свернуто окно
 		if (!IsIconic(SRender_GetHandleWin3D()) && ((SRender_GetParentHandleWin3D() != 0 && !IsIconic(SRender_GetParentHandleWin3D())) || SRender_GetParentHandleWin3D() == 0))
-			SRender_ComDeviceLost();	//пытаемся восстановить
+		{
+#if defined(SX_GAME)
+			SRender_ComDeviceLost(false);	//пытаемся восстановить
+#else
+			SRender_ComDeviceLost(true);	//пытаемся восстановить
+#endif
+		}
 		return;
 	}
 
@@ -905,7 +926,7 @@ void SkyXEngine_Frame(DWORD timeDelta)
 
 
 	ttime = TimeGetMcsU(Core_RIntGet(G_RI_INT_TIMER_RENDER));
-	SGCore_OC_Update(SML_DSGetRT_ID(DS_RT_DEPTH0));
+	SGCore_OC_Update(SML_DSGetRT_ID(DS_RT_DEPTH0), SRender_GetCamera()->getFrustum());
 	DelayUpdateOC += TimeGetMcsU(Core_RIntGet(G_RI_INT_TIMER_RENDER)) - ttime;
 	
 
@@ -1114,7 +1135,11 @@ void SkyXEngind_UpdateDataCVar()
 
 				GetWindowRect(SRender_GetHandleWin3D(), &rc);
 
-				MoveWindow(SRender_GetHandleWin3D(), rc.left, rc.top, iWidth, iHeight, TRUE);
+				int iPosX = (GetSystemMetrics(SM_CXSCREEN) - iWidth) / 2;
+				int iPosY = (GetSystemMetrics(SM_CYSCREEN) - iHeight) / 2;
+
+				MoveWindow(SRender_GetHandleWin3D(), iPosX, iPosY, iWidth, iHeight, TRUE);
+				SetForegroundWindow(SRender_GetHandleWin3D());
 
 				static int *r_resize = (int*)GET_PCVAR_INT("r_resize");
 				*r_resize = RENDER_RESIZE_RESIZE;
@@ -1150,7 +1175,6 @@ void SkyXEngind_UpdateDataCVar()
 
 int SkyXEngine_CycleMain()
 {
-	//ID idSnd = SSCore_SndCreate2dInst("ak74_reload.ogg",SX_SOUND_CHANNEL_GAME);
 	MSG msg;
 	::ZeroMemory(&msg, sizeof(MSG));
 
@@ -1158,8 +1182,9 @@ int SkyXEngine_CycleMain()
 	{
 		if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
 		{
+			
 			::TranslateMessage(&msg);
-
+			
 #if !defined(SX_GAME)
 			IMSG imsg;
 			imsg.lParam = msg.lParam;
@@ -1168,7 +1193,6 @@ int SkyXEngine_CycleMain()
 
 			SSInput_AddMsg(imsg);
 #endif
-
 			::DispatchMessage(&msg);
 		}
 		else
@@ -1231,13 +1255,14 @@ int SkyXEngine_CycleMain()
 			}
 
 
-			if (Core_TimeWorkingGet(Core_RIntGet(G_RI_INT_TIMER_RENDER)) && (GetForegroundWindow() == SRender_GetHandleWin3D() || GetForegroundWindow() == (HWND)SRender_GetParentHandleWin3D() || GetForegroundWindow() == FindWindow(NULL, "sxconsole")))
+			if (Core_TimeWorkingGet(Core_RIntGet(G_RI_INT_TIMER_RENDER)) && 
+				(GetForegroundWindow() == SRender_GetHandleWin3D() || GetForegroundWindow() == (HWND)SRender_GetParentHandleWin3D() || GetForegroundWindow() == FindWindow(NULL, "sxconsole"))
+				)
 			{
 
 #if defined(SX_LEVEL_EDITOR)
 				SXLevelEditor_Transform(10);
 #endif
-
 				SkyXEngine_Frame(timeDelta);
 			}
 
@@ -1252,19 +1277,6 @@ int SkyXEngine_CycleMain()
 
 void SkyXEngine_Kill()
 {
-/*#if defined(SX_MATERIAL_EDITOR)
-	mem_delete(GData::Editors::SimModel);
-#endif
-
-#if !defined(SX_GAME)
-	mem_delete(GData::Editors::ObjGrid);
-	mem_delete(GData::Editors::ObjAxesStatic);
-	mem_release(GData::Editors::FigureBox);
-	mem_release(GData::Editors::FigureSphere);
-	mem_release(GData::Editors::FigureCone);
-	mem_delete(GData::Editors::ObjAxesHelper);
-#endif
-*/
 #if !defined(SX_PARTICLES_EDITOR)
 	SXGame_AKill();
 #endif
diff --git a/source/sxmaterialeditor/sxmaterialeditor.cpp b/source/sxmaterialeditor/sxmaterialeditor.cpp
index 06e19f1f8..a9fc8df22 100644
--- a/source/sxmaterialeditor/sxmaterialeditor.cpp
+++ b/source/sxmaterialeditor/sxmaterialeditor.cpp
@@ -430,6 +430,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLin
 	
 
 	SkyXEngine_Init(SXMaterialEditor::WindowRender->getHWND(), SXMaterialEditor::JobWindow->getHWND());
+	static int *r_win_width = (int*)GET_PCVAR_INT("r_win_width");
+	static int *r_win_height = (int*)GET_PCVAR_INT("r_win_height");
 	SkyXEngine_RunGenPreview();
 	Core_0SetCVarInt("r_final_image", DS_RT_SCENELIGHT);
 
-- 
GitLab