changeset 1025:8b492d4722d4

Intersection
author Ritor1
date Tue, 21 May 2013 12:42:57 +0600
parents d353bd3009d9
children 6afa77761a00
files Indoor.cpp Indoor.h VectorTypes.h Vis.cpp Vis.h mm7_3.cpp mm7_4.cpp mm7_5.cpp
diffstat 8 files changed, 238 insertions(+), 365 deletions(-) [+]
line wrap: on
line diff
--- a/Indoor.cpp	Wed May 15 09:32:39 2013 +0600
+++ b/Indoor.cpp	Tue May 21 12:42:57 2013 +0600
@@ -395,36 +395,36 @@
 }
 
 //----- (004C0EF2) --------------------------------------------------------
-void BLVFace::FromODM(ODMFace *a2)
+void BLVFace::FromODM(ODMFace *face)
 {
-  this->pFacePlane_old.vNormal.x = a2->pFacePlane.vNormal.x;
-  this->pFacePlane_old.vNormal.y = a2->pFacePlane.vNormal.y;
-  this->pFacePlane_old.vNormal.z = a2->pFacePlane.vNormal.z;
-  this->pFacePlane_old.dist = a2->pFacePlane.dist;
-  this->pFacePlane.vNormal.x = (double)(a2->pFacePlane.vNormal.x & 0xFFFF) * 0.000015259022
-                             + (double)(a2->pFacePlane.vNormal.x >> 16);
-  this->pFacePlane.vNormal.y = (double)(a2->pFacePlane.vNormal.y & 0xFFFF) * 0.000015259022
-                             + (double)(a2->pFacePlane.vNormal.y >> 16);
-  this->pFacePlane.vNormal.z = (double)(a2->pFacePlane.vNormal.z & 0xFFFF) * 0.000015259022
-                             + (double)(a2->pFacePlane.vNormal.z >> 16);
-  this->pFacePlane.dist = (double)(a2->pFacePlane.dist & 0xFFFF) * 0.000015259022 + (double)(a2->pFacePlane.dist >> 16);
-  this->uAttributes = a2->uAttributes;
-  this->pBounding.x1 = a2->pBoundingBox.x1;
-  this->pBounding.y1 = a2->pBoundingBox.y1;
-  this->pBounding.z1 = a2->pBoundingBox.z1;
-  this->pBounding.x2 = a2->pBoundingBox.x2;
-  this->pBounding.y2 = a2->pBoundingBox.y2;
-  this->pBounding.z2 = a2->pBoundingBox.z2;
-  this->zCalc1 = a2->zCalc1;
-  this->zCalc2 = a2->zCalc2;
-  this->zCalc3 = a2->zCalc3;
-  this->pXInterceptDisplacements = a2->pXInterceptDisplacements;
-  this->pYInterceptDisplacements = a2->pYInterceptDisplacements;
-  this->pZInterceptDisplacements = a2->pZInterceptDisplacements;
-  this->uPolygonType = (PolygonType)a2->uPolygonType;
-  this->uNumVertices = a2->uNumVertices;
-  this->uBitmapID = a2->uTextureID;
-  this->pVertexIDs = a2->pVertexIDs;
+  this->pFacePlane_old.vNormal.x = face->pFacePlane.vNormal.x;
+  this->pFacePlane_old.vNormal.y = face->pFacePlane.vNormal.y;
+  this->pFacePlane_old.vNormal.z = face->pFacePlane.vNormal.z;
+  this->pFacePlane_old.dist = face->pFacePlane.dist;
+  this->pFacePlane.vNormal.x = (double)(face->pFacePlane.vNormal.x & 0xFFFF) * 0.000015259022
+                             + (double)(face->pFacePlane.vNormal.x >> 16);
+  this->pFacePlane.vNormal.y = (double)(face->pFacePlane.vNormal.y & 0xFFFF) * 0.000015259022
+                             + (double)(face->pFacePlane.vNormal.y >> 16);
+  this->pFacePlane.vNormal.z = (double)(face->pFacePlane.vNormal.z & 0xFFFF) * 0.000015259022
+                             + (double)(face->pFacePlane.vNormal.z >> 16);
+  this->pFacePlane.dist = (double)(face->pFacePlane.dist & 0xFFFF) * 0.000015259022 + (double)(face->pFacePlane.dist >> 16);
+  this->uAttributes = face->uAttributes;
+  this->pBounding.x1 = face->pBoundingBox.x1;
+  this->pBounding.y1 = face->pBoundingBox.y1;
+  this->pBounding.z1 = face->pBoundingBox.z1;
+  this->pBounding.x2 = face->pBoundingBox.x2;
+  this->pBounding.y2 = face->pBoundingBox.y2;
+  this->pBounding.z2 = face->pBoundingBox.z2;
+  this->zCalc1 = face->zCalc1;
+  this->zCalc2 = face->zCalc2;
+  this->zCalc3 = face->zCalc3;
+  this->pXInterceptDisplacements = face->pXInterceptDisplacements;
+  this->pYInterceptDisplacements = face->pYInterceptDisplacements;
+  this->pZInterceptDisplacements = face->pZInterceptDisplacements;
+  this->uPolygonType = (PolygonType)face->uPolygonType;
+  this->uNumVertices = face->uNumVertices;
+  this->uBitmapID = face->uTextureID;
+  this->pVertexIDs = face->pVertexIDs;
 }
 
 //----- (004B0A25) --------------------------------------------------------
--- a/Indoor.h	Wed May 15 09:32:39 2013 +0600
+++ b/Indoor.h	Tue May 21 12:42:57 2013 +0600
@@ -283,7 +283,7 @@
 
   char _get_normals(Vec3_int_ *a2, Vec3_int_ *a3);
   struct Texture *GetTexture();
-  void FromODM(struct ODMFace *a2);
+  void FromODM(struct ODMFace *face);
 
   inline bool Invisible() const {return uAttributes & FACE_INVISIBLE;}
   inline bool Visible() const   {return !Invisible();}
--- a/VectorTypes.h	Wed May 15 09:32:39 2013 +0600
+++ b/VectorTypes.h	Tue May 21 12:42:57 2013 +0600
@@ -16,20 +16,15 @@
   void Normalize();
 
   
-  //----- (0049B32D) --------------------------------------------------------
-  static Vec3_float_ *Vec3_float_::Cross(Vec3_float_ *v1, Vec3_float_ *pOut, float x, float y, float z)
-  {
-    double v6; // st7@1
-    double v7; // st6@1
+//----- (0049B32D) --------------------------------------------------------
+static Vec3_float_ *Vec3_float_::Cross(Vec3_float_ *v1, Vec3_float_ *pOut, float x, float y, float z)
+{
+  pOut->x = z * v1->y - y * v1->z;
+  pOut->y = x * v1->z - z * v1->x;
+  pOut->z = y * v1->x - x * v1->y;
+  return pOut;
+}
 
-    v6 = x * v1->z - z * v1->x;
-    v7 = y * v1->x - x * v1->y;
-    pOut->x = z * v1->y - y * v1->z;
-    pOut->y = v6;
-    pOut->z = v7;
-    return pOut;
-  }
- 
   //----- (0049B02E) --------------------------------------------------------
   inline static float NegDot(Vec3_float_ *a1, Vec3_float_ *a2, float *a3)
   {
--- a/Vis.cpp	Wed May 15 09:32:39 2013 +0600
+++ b/Vis.cpp	Tue May 21 12:42:57 2013 +0600
@@ -366,6 +366,8 @@
     auto bmodel = &pOutdoor->pBModels[i];
     for (uint j = 0; j < bmodel->uNumFaces; ++j)
     {
+		//if ( i == 77 && j == 17 )//
+		  //__debugbreak();//
       auto face = &bmodel->pFaces[j];
       if (is_part_of_selection(face, filter))
       {
@@ -541,7 +543,7 @@
 }
 
 //----- (004C1C0C) --------------------------------------------------------
-bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6)
+bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, unsigned int pBModelID)
 {
   //BLVFace *v7; // ebx@1
   //bool result; // eax@1
@@ -554,7 +556,7 @@
   //char v15; // c0@5
   //char v16; // c2@5
   //char v17; // c3@5
-  double v18; // st5@6
+  double c1; // st5@6
   //__int16 v19; // fps@6
   //char v20; // c0@6
   //char v21; // c2@6
@@ -568,25 +570,24 @@
   //unsigned __int8 v29; // c0@10
   //char v30; // c2@10
   //unsigned __int8 v31; // c3@10
-  //double v32; // st7@11
-  Vec2_short_ v33; // ST1E_4@11
+  double c2; // st7@11
+  //Vec2_short_ v33; // ST1E_4@11
   Vec3_short_ v34; // ST04_6@11
   //float a5a; // [sp+30h] [bp+18h]@10
   //float a5b; // [sp+30h] [bp+18h]@13
 
-  if (a5->Portal() || a5->Invisible())
+  if (pFace->Portal() || pFace->Invisible())
     return false;
 
-  
-  int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,
-      ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y,
+  int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,//dir_x y z это вектор направления
+      ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y,//точка В - точка А  = вектор из А в В
       ray_dir_z = pRayEnd->vWorldPosition.z - pRayStart->vWorldPosition.z;
 
-  v9 =   ray_dir_z * a5->pFacePlane.vNormal.z
-           + ray_dir_y  * a5->pFacePlane.vNormal.y
-           + ray_dir_x * a5->pFacePlane.vNormal.x;
+  /*v9 =   ray_dir_z * pFace->pFacePlane.vNormal.z
+           + ray_dir_y  * pFace->pFacePlane.vNormal.y//скалярное произведение направления луча и нормали к полигону
+           + ray_dir_x * pFace->pFacePlane.vNormal.x;//= косинус угла между двумя векторами
   if (v9 >= 0)   // ray faces face's normal ( > 0) or parallel ( == 0)
-    return false;
+    return false;*/
 
 //ray   = t dir + start
 //plane = (p - vertex) normal = -d
@@ -599,116 +600,84 @@
 //               dir norm
 
 
-  float dir_mag = sqrtf(ray_dir_x * ray_dir_x + ray_dir_y * ray_dir_y + ray_dir_z * ray_dir_z);
-  float ndir_x = ray_dir_x / dir_mag,
-        ndir_y = ray_dir_y / dir_mag,
-        ndir_z = ray_dir_z / dir_mag;
+  /*float dir_mag = sqrtf(ray_dir_x * ray_dir_x + ray_dir_y * ray_dir_y + ray_dir_z * ray_dir_z);//модуль вектора
+  float ndir_x = ray_dir_x / dir_mag,//ndir - нормализованное направление
+        ndir_y = ray_dir_y / dir_mag,//В результате нормализации получается вектор, направление которого совпадает с исходным, а модуль равен единице (единичный вектор).
+        ndir_z = ray_dir_z / dir_mag;//Чтобы нормализовать произвольный вектор, достаточно разделить каждый компонент вектора на модуль вектора
 
-  int face_center_x = (a5->pBounding.x1 + a5->pBounding.x2) / 2,
-      face_center_y = (a5->pBounding.y1 + a5->pBounding.y2) / 2,
-      face_center_z = (a5->pBounding.z1 + a5->pBounding.z2) / 2;
+  int face_center_x = (pFace->pBounding.x1 + pFace->pBounding.x2) / 2,//усреднённые координаты баундинга
+      face_center_y = (pFace->pBounding.y1 + pFace->pBounding.y2) / 2,
+      face_center_z = (pFace->pBounding.z1 + pFace->pBounding.z2) / 2;
 
-  int to_plane_x = pRayStart->vWorldPosition.x - face_center_x,
+  int to_plane_x = pRayStart->vWorldPosition.x - face_center_x,//вектор из глас к середине фейса
       to_plane_y = pRayStart->vWorldPosition.y - face_center_y,
-      to_plane_z = pRayStart->vWorldPosition.z - face_center_z;
+      to_plane_z = pRayStart->vWorldPosition.z - face_center_z;*/
 
-  float t = /*-a5->pFacePlane.dist*/ - (to_plane_x * a5->pFacePlane.vNormal.x + to_plane_y * a5->pFacePlane.vNormal.y + to_plane_y * a5->pFacePlane.vNormal.z) /
-                   (ndir_x * a5->pFacePlane.vNormal.x + ndir_y * a5->pFacePlane.vNormal.y + ndir_z * a5->pFacePlane.vNormal.z);
-  if (t <= *pDepth)
+  //float t = /*-pFace->pFacePlane.dist*/ - (to_plane_x * pFace->pFacePlane.vNormal.x + to_plane_y * pFace->pFacePlane.vNormal.y + to_plane_y * pFace->pFacePlane.vNormal.z) /
+            //       (ndir_x * pFace->pFacePlane.vNormal.x + ndir_y * pFace->pFacePlane.vNormal.y + ndir_z * pFace->pFacePlane.vNormal.z);//насколько сильно луч из камеры отклоняется от луча до центра фейса
+/*  if (t <= *pDepth)
   {
     int intersection_x = pRayStart->vWorldPosition.x + ndir_x * t,
         intersection_y = pRayStart->vWorldPosition.y + ndir_y * t,
         intersection_z = pRayStart->vWorldPosition.z + ndir_z * t;
 
-    if (intersection_x < a5->pBounding.x1 || intersection_x > a5->pBounding.x2 ||
-        intersection_y < a5->pBounding.y1 || intersection_y > a5->pBounding.y2 ||
-        intersection_z < a5->pBounding.z1 || intersection_z > a5->pBounding.z2)
+    if (intersection_x < pFace->pBounding.x1 || intersection_x > pFace->pBounding.x2 ||
+        intersection_y < pFace->pBounding.y1 || intersection_y > pFace->pBounding.y2 ||
+        intersection_z < pFace->pBounding.z1 || intersection_z > pFace->pBounding.z2)
         return false;
 
-    a5->uAttributes |= 0x80000000;
+    pFace->uAttributes |= 0x80000000;
     return true;
   }
 
-  
-  return false;
+  return false;*/
 
-//  v7 = a5;
-  //result = a5->uAttributes;
-  v9 =   pRayEnd->vWorldPosition.z * a5->pFacePlane.vNormal.z
-           + pRayEnd->vWorldPosition.y * a5->pFacePlane.vNormal.y
-           + pRayEnd->vWorldPosition.x * a5->pFacePlane.vNormal.x;
-  if (v9 >= 0)   // ray faces face's normal ( > 0) or parallel ( == 0)
-    return false;
-  
-  a5->uAttributes |= 0x80000000;
-  return false;
 
-  v18 = -(a5->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y
-        + pRayStart->vWorldPosition.x * a5->pFacePlane.vNormal.x
-        + pRayStart->vWorldPosition.z * a5->pFacePlane.vNormal.z
-        + a5->pFacePlane.dist);
-  if (v18 > 0)
-    return false;
-  //UNDEF(v19);
-  //v20 = v9 < 0.0;
-  //v21 = 0;
-  //v22 = v9 == 0.0;
-  //BYTE1(result) = HIBYTE(v19);
-  /*v23 = v18 < 0.0;
-  v24 = 0;
-  v25 = v18 == 0.0;
-  v26 = (BYTE1(result) & 0x41) == 0;
-  BYTE1(result) = HIBYTE(v19);
-  if ( v26 )
-  {
-    if ( v18 < 0.0 )
-      goto LABEL_12;
-  }
-  else
-  {
-    if ( !(v23 | v25) )
-    {
-LABEL_12:
-      LOBYTE(result) = 0;
-      return result;
-    }
-  }*/
-
-  //a5a = v18;
-  v27 = v18 / v9;
-  //HIWORD(result) = HIWORD(pDepth);
-  //UNDEF(v28);
-  //v29 = v27 < *pDepth;
-  //v30 = 0;
-  //v31 = v27 == *pDepth;
-  //BYTE1(result) = HIBYTE(v28);
-
-  if (v27 > *pDepth)
+//c1 = -d-(n*p0)
+  c1 = -pFace->pFacePlane.dist -(pFace->pFacePlane.vNormal.x * pRayStart->vWorldPosition.x
+        + pFace->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y
+        + pFace->pFacePlane.vNormal.z * pRayStart->vWorldPosition.z);
+  //if (c1 > 0)
+    //return false;
+#define EPSILON 0.000001
+//c2 = n*u
+  c2 = pFace->pFacePlane.vNormal.x * ray_dir_y
+       + pFace->pFacePlane.vNormal.y * ray_dir_x 
+       + pFace->pFacePlane.vNormal.z * ray_dir_z;
+  if (c2 > -EPSILON && c2 < EPSILON)   // ray faces face's normal ( > 0) or parallel ( == 0)
     return false;
 
-  a5->uAttributes |= 0x80000000;
+//t = -d-(n*p0)/n*u
+  double t = c1 / c2;//точка соприкосновения
+
+  //if (t < 0 || t > 1)
+    //return false;
 
-  a4->vWorldPosition.x = v27 * pRayEnd->vWorldPosition.x + pRayStart->vWorldPosition.x;
-  a4->vWorldPosition.y = v27 * pRayEnd->vWorldPosition.y + pRayStart->vWorldPosition.y;
-  a4->vWorldPosition.z = v27 * pRayEnd->vWorldPosition.z + pRayStart->vWorldPosition.z;
-  v33.x = (signed __int64)a4->vWorldPosition.x;
-  v33.y = (signed __int64)a4->vWorldPosition.y;
-  v34.x = v33.x;
-  v34.y = 0;
-  v34.z = (signed __int64)a4->vWorldPosition.z;
+  // p(t) = p0 + tu;
+  // p(t) - вектор указывающий в точку на плоскости
+  // p0 -  начало вектора, точка наблюдателя, камеры
+  // t - 
+  // u - вектор направления
+  Intersection->vWorldPosition.x = pRayStart->vWorldPosition.x + t * ray_dir_y;//12432 < X < 12656
+  Intersection->vWorldPosition.y = pRayStart->vWorldPosition.y + t * ray_dir_x;//-96 < Y < 1088
+  Intersection->vWorldPosition.z = pRayStart->vWorldPosition.z + t * ray_dir_z;//Z == 192
+
+  v34.x = (signed __int64)Intersection->vWorldPosition.x;
+  v34.y = (signed __int64)Intersection->vWorldPosition.y;
+  v34.z = (signed __int64)Intersection->vWorldPosition.z;
         
-  if ( _4C1D2B(a5, v34, a6) == 0.0)
+  if ( !_4C1D2B(pFace, v34, pBModelID) )
     return false;
 
   //a5b = v27;
-  *pDepth = v27;
+  //*pDepth = t;
   return true;
 }
 
 //----- (004C1D2B) --------------------------------------------------------
-int Vis::_4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID)
+bool Vis::_4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID)
 {
-  BLVFace *v4; // esi@1
+  //BLVFace *v4; // esi@1
   int v5; // esi@10
   bool v6; // edi@10
   int v7; // ecx@12
@@ -722,14 +691,16 @@
   int v15; // [sp+10h] [bp-Ch]@10
   signed int v16; // [sp+18h] [bp-4h]@10
 
-  v4 = pFace;
-  if (a2.z < pFace->pBounding.z1 || a2.z > pFace->pBounding.z2 ||
-      a2.x < pFace->pBounding.x1 || a2.x > pFace->pBounding.x2 ||
-      a2.y < pFace->pBounding.y1 || a2.y > pFace->pBounding.y2)
+  //v4 = pFace;
+  if (a2.x < pFace->pBounding.x1 || a2.x > pFace->pBounding.x2 ||
+      a2.y < pFace->pBounding.y1 || a2.y > pFace->pBounding.y2 ||
+      a2.z < pFace->pBounding.z1 || a2.z > pFace->pBounding.z2 )
     return false;
 
+  pFace->uAttributes |= 0x80000000;
+  return true;
   if (uModelID != -1)
-    _4C2186_BLV_IntersectBModel((int *)&pFace, (int *)&uModelID,
+    _4C2186_BLV_IntersectBModel(pFace, uModelID,
                                 word_F8BC48_displaced_face_intersect_plane_coords_a,
                                 word_F8BD18_displaced_face_intersect_plane_coords_b,
                                 &a2, pFace, uModelID);
@@ -739,7 +710,7 @@
                                   word_F8BD18_displaced_face_intersect_plane_coords_b,
                                   &a2, pFace);
   
-  v5 = 2 * v4->uNumVertices;
+  v5 = 2 * pFace->uNumVertices;
   v16 = 0;
   word_F8BC48_displaced_face_intersect_plane_coords_a[v5] = word_F8BC48_displaced_face_intersect_plane_coords_a[0];
   word_F8BD18_displaced_face_intersect_plane_coords_b[v5] = word_F8BD18_displaced_face_intersect_plane_coords_b[0];
@@ -886,172 +857,131 @@
 }
 
 //----- (004C2186) --------------------------------------------------------
-bool Vis::_4C2186_BLV_IntersectBModel(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *a6, unsigned int uModelID)
+bool Vis::_4C2186_BLV_IntersectBModel(BLVFace *pFace, unsigned int ModelID, __int16 *displaced_face_intersect_plane_coords_a, __int16 *displaced_face_intersect_plane_coords_b, Vec3_short_ *a5, BLVFace *face, unsigned int uModelID)
 {
   bool result; // eax@1
-  int *v9; // esi@1
-  unsigned int v10; // ecx@1
-  unsigned int v11; // edx@3
-  signed int v12; // ecx@4
+  //int *v9; // esi@1
+  //unsigned int v10; // ecx@1
+  //unsigned int v11; // edx@3
+  //signed int v12; // ecx@4
   __int16 v13; // si@4
   __int16 *v14; // ecx@4
   unsigned int v15; // edx@8
-  signed int v16; // ecx@9
+  //signed int v16; // ecx@9
   __int16 v17; // si@9
   __int16 *v18; // ecx@9
   unsigned int v19; // edx@12
-  signed int v20; // ecx@13
+  //signed int v20; // ecx@13
   __int16 v21; // si@13
   __int16 *v22; // ecx@13
-  signed int a1a; // [sp+14h] [bp+8h]@1
+  //signed int a1a; // [sp+14h] [bp+8h]@1
   __int16 *a5a; // [sp+24h] [bp+18h]@3
   __int16 *a5b; // [sp+24h] [bp+18h]@8
   __int16 *a5c; // [sp+24h] [bp+18h]@12
 
-  result = (bool)a6;
-  v9 = a1;
-  v10 = a6->uAttributes;
-  a1a = 0;
-  if ( BYTE1(v10) & 1 )
+  //result = (bool)a6;
+  //v9 = pFace;
+  //v10 = pFace->uAttributes;
+  //a1a = 0;
+  if ( BYTE1(pFace->uAttributes) & 1 )
   {
-    *v9 = a5->x;
-    *a2 = a5->y;
-    if ( a6->uNumVertices )
+    pFace->pFacePlane.vNormal.x = a5->x;
+    pFace->pFacePlane.vNormal.y = a5->y;
+    if ( pFace->uNumVertices )
     {
-      v11 = 188 * uModelID + 72;
-      a5a = a4 + 1;
-      do
+      //v11 = 188 * ModelID + 72;
+      a5a = displaced_face_intersect_plane_coords_b + 1;
+      for ( uint i = 0; i < pFace->uNumVertices; ++i )
       {
-        v12 = a1a;
-        a3[2 * a1a] = a6->pXInterceptDisplacements[a1a]
-//                    + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[a1a]);
-					  + pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[a1a]].x;
-        *(a5a - 1) = a6->pYInterceptDisplacements[v12]
-//                   + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[v12] + 4);
-					 + pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[v12]].y;
-        *(__int16 *)((char *)a5a + (int)(char *)a3 - (char *)a4) = a6->pXInterceptDisplacements[v12 + 1]
-//                                                            + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11]
-//                                                                       + 12 * a6->pVertexIDs[v12 + 1]);
-		+ pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[v12+1]].x;
-        v13 = a6->pYInterceptDisplacements[v12 + 1]
-//            + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v11] + 12 * a6->pVertexIDs[v12 + 1] + 4);
-		+ pOutdoor->pBModels[v11].pVertices.pVertices[a6->pVertexIDs[v12 + 1]].y;
+        displaced_face_intersect_plane_coords_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x;
+        displaced_face_intersect_plane_coords_b[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+        *(__int16 *)((char *)a5a + (int)(char *)displaced_face_intersect_plane_coords_a - (char *)displaced_face_intersect_plane_coords_b) = 
+          pFace->pXInterceptDisplacements[i + 1] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
+        v13 = pFace->pYInterceptDisplacements[i + 1] + pOutdoor->pBModels[ModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
         v14 = a5a;
-        ++a1a;
         a5a += 2;
         *v14 = v13;
       }
-      while ( a1a < a6->uNumVertices );
     }
   }
   else
   {
-    if ( BYTE1(v10) & 2 )
+    if ( BYTE1(pFace->uAttributes) & 2 )
     {
-      *v9 = a5->x;
-      *a2 = a5->z;
-      if ( a6->uNumVertices )
+      pFace->pFacePlane.vNormal.x = a5->x;
+      pFace->pFacePlane.vNormal.z = a5->z;
+      if ( pFace->uNumVertices )
       {
         v15 = 188 * uModelID + 72;
-        a5b = a4 + 1;
-        do
+        a5b = displaced_face_intersect_plane_coords_b + 1;
+        for ( uint i = 0; i < pFace->uNumVertices; ++i )
         {
-          v16 = a1a;
-          a3[2 * a1a] = a6->pXInterceptDisplacements[a1a]
-//                      + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[a1a]);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[a1a]].x;
-          *(a5b - 1) = a6->pZInterceptDisplacements[v16]
-//                     + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[v16] + 8);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[v16]].y;
-		  *(__int16 *)((char *)a5b + (int)a3 - (int)a4) = a6->pXInterceptDisplacements[v16 + 1]
-//                                                              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15]
-//                                                                         + 12 * a6->pVertexIDs[v16 + 1]);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[v16+1]].x;
-          v17 = a6->pZInterceptDisplacements[v16 + 1]
-//              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v15] + 12 * a6->pVertexIDs[v16 + 1] + 8);
-		  + pOutdoor->pBModels[v15].pVertices.pVertices[a6->pVertexIDs[v16+1]].z;
+          displaced_face_intersect_plane_coords_a[2 * i] = pFace->pXInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].x;
+          *(a5b - 1) = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+          *(__int16 *)((char *)a5b + (int)displaced_face_intersect_plane_coords_a - (int)displaced_face_intersect_plane_coords_b) = pFace->pXInterceptDisplacements[i + 1]
+                + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
+          v17 = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z;
           v18 = a5b;
-          ++a1a;
           a5b += 2;
           *v18 = v17;
         }
-        while ( a1a < a6->uNumVertices );
       }
     }
     else
     {
-      *v9 = a5->y;
-      *a2 = a5->z;
-      if ( a6->uNumVertices )
+      pFace->pFacePlane.vNormal.y = a5->y;
+      pFace->pFacePlane.vNormal.z = a5->z;
+      if ( pFace->uNumVertices )
       {
         v19 = 188 * uModelID + 72;
-        a5c = a4 + 1;
-        do
+        a5c = displaced_face_intersect_plane_coords_b + 1;
+        for ( uint i = 0; i < pFace->uNumVertices; ++i )
         {
-          v20 = a1a;
-          a3[2 * a1a] = a6->pYInterceptDisplacements[a1a]
-//                      + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[a1a] + 4);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[a1a]].y;
-          *(a5c - 1) = a6->pZInterceptDisplacements[v20]
-//                     + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[v20] + 8);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[a1a]].z;
-          *(__int16 *)((char *)a5c + (int)(char *)a3 - (char *)a4) = a6->pYInterceptDisplacements[v20 + 1]
-//                                                              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19]
-//                                                                         + 12 * a6->pVertexIDs[v20 + 1]
-//                                                                         + 4);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[v20+1]].y;
-		  v21 = a6->pZInterceptDisplacements[v20 + 1]
-//              + *(short *)(*(int *)&pOutdoor->pBModels->pModelName[v19] + 12 * a6->pVertexIDs[v20 + 1] + 8);
-		  + pOutdoor->pBModels[v19].pVertices.pVertices[a6->pVertexIDs[v20+1]].z;
+          displaced_face_intersect_plane_coords_a[2 * i] = pFace->pYInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].y;
+          *(a5c - 1) = pFace->pZInterceptDisplacements[i] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i]].z;
+          *(__int16 *)((char *)a5c + (int)(char *)displaced_face_intersect_plane_coords_a - (char *)displaced_face_intersect_plane_coords_b) = pFace->pYInterceptDisplacements[i + 1]
+                + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
+          v21 = pFace->pZInterceptDisplacements[i + 1] + pOutdoor->pBModels[uModelID].pVertices.pVertices[pFace->pVertexIDs[i + 1]].z;
           v22 = a5c;
-          ++a1a;
           a5c += 2;
           *v22 = v21;
         }
-        while ( a1a < a6->uNumVertices );
       }
     }
   }
-  LOBYTE(result) = 1;
-  return result;
+  return true;
 }
 
 //----- (004C248E) --------------------------------------------------------
 void Vis::CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth)
 {
-  int v5; // ebx@1
-  int v6; // edi@1
-  int v7; // esi@1
-  Vec3_int_ v8; // ST08_12@1
-  int v9; // ST04_4@1
-  int v10; // eax@1
+  int pRotY; // esi@1
+  Vec3_int_ pStartR; // ST08_12@1
+  int pRotX; // ST04_4@1
+  int pDepth; // eax@1
   RenderVertexSoft v11[2]; // [sp+2Ch] [bp-74h]@1
-  int v12; // [sp+8Ch] [bp-14h]@1
-  int v13; // [sp+90h] [bp-10h]@1
+  int outx;
   int outz; // [sp+94h] [bp-Ch]@1
   int outy; // [sp+98h] [bp-8h]@1
-  int v16; // [sp+9Ch] [bp-4h]@1
 
-  v5 = pIndoorCamera->pos.y;
-  v6 = pIndoorCamera->pos.x;
-  v13 = pIndoorCamera->pos.x;
-  v12 = pIndoorCamera->pos.y;
-  v16 = pIndoorCamera->pos.z;
-  v7 = pIndoorCamera->sRotationY + UnprojectX((signed __int64)fMouseX);
-  v8.z = v16;
-  v8.x = v6;
-  v8.y = v5;
-  v9 = pIndoorCamera->sRotationX + UnprojectY((signed __int64)fMouseY);
-  v10 = _48B561_mess_with_scaling_along_z(/*(int)&fMouseX, */fPickDepth);
-  Vec3_int_::Rotate(v10, v7, v9, v8, (int *)&fMouseX, &outy, &outz);
+  pRotY = pIndoorCamera->sRotationY + UnprojectX((signed __int64)fMouseX);
+  pStartR.z = pIndoorCamera->pos.z;
+  pStartR.x = pIndoorCamera->pos.x;
+  pStartR.y = pIndoorCamera->pos.y;
+  pRotX = pIndoorCamera->sRotationX + UnprojectY((signed __int64)fMouseY);
+  pDepth = _48B561_mess_with_scaling_along_z(/*(int)&fMouseX, */fPickDepth);
+  Vec3_int_::Rotate(pDepth, pRotY, pRotX, pStartR, &outx, &outy, &outz);
+
   v11[0].flt_2C = 0.0;
-  v11[0].vWorldPosition.x = (double)SLODWORD(fMouseX);
+  v11[0].vWorldPosition.x = (double)outx;
   v11[0].vWorldPosition.y = (double)outy;
   v11[0].vWorldPosition.z = (double)outz;
+
   v11[1].flt_2C = 0.0;
-  v11[1].vWorldPosition.x = (double)v13;
-  v11[1].vWorldPosition.y = (double)v12;
-  v11[1].vWorldPosition.z = (double)v16;
+  v11[1].vWorldPosition.x = (double)pIndoorCamera->pos.x;
+  v11[1].vWorldPosition.y = (double)pIndoorCamera->pos.y;
+  v11[1].vWorldPosition.z = (double)pIndoorCamera->pos.z;
+
   memcpy(pRay, &v11[1], 0x30u);
   memcpy(&pRay[1], v11, sizeof(pRay[1]));
 }
--- a/Vis.h	Wed May 15 09:32:39 2013 +0600
+++ b/Vis.h	Tue May 21 12:42:57 2013 +0600
@@ -110,10 +110,10 @@
   bool SortVectors_x(RenderVertexSoft *a2, int a3, int a4);
   int get_object_zbuf_val(Vis_ObjectInfo *info);
   int get_picked_object_zbuf_val();
-  bool Intersect_Ray_Face(struct RenderVertexSoft *pRayStart, struct RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6);
-  int _4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID);
+  bool Intersect_Ray_Face(struct RenderVertexSoft *pRayStart, struct RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, unsigned int pBModelID);
+  bool _4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID);
   bool _4C1EE5_BLV_IntersectBModel_2(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *pFace);
-  bool _4C2186_BLV_IntersectBModel(int *a1, int *a2, __int16 *a3, __int16 *a4, Vec3_short_ *a5, BLVFace *a6, unsigned int uModelID);
+  bool _4C2186_BLV_IntersectBModel(BLVFace *pFace, unsigned int ModelID, __int16 *displaced_face_intersect_plane_coords_a, __int16 *displaced_face_intersect_plane_coords_b, Vec3_short_ *a5, BLVFace *face, unsigned int uModelID);
   void CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth);
   void sort_object_pointers(Vis_ObjectInfo **pPointers, int left, int right);
   bool SortVerticesByX(struct RenderVertexD3D3 *a2, unsigned int uStart, unsigned int uEnd);
--- a/mm7_3.cpp	Wed May 15 09:32:39 2013 +0600
+++ b/mm7_3.cpp	Tue May 21 12:42:57 2013 +0600
@@ -10429,7 +10429,7 @@
 //----- (00486089) --------------------------------------------------------
 void stru148::_486089_normalize_v_18()
 {
-  stru148 *v1; // esi@1
+  //stru148 *v1; // esi@1
   double v2; // st7@1
   double v3; // st6@1
   float v4; // ST18_4@2
@@ -10445,7 +10445,7 @@
   double v14; // ST0C_8@2
   float v15; // [sp+20h] [bp-8h]@1
 
-  v1 = this;
+  //v1 = this;
   v2 = (double)this->v_18.x;
   v15 = v2;
   v3 = (double)this->v_18.y;
@@ -10453,24 +10453,24 @@
   v7 = sqrt(v5 * v5 + v3 * v3 + v2 * v2);
   if ( v7 == 0.0 )
   {
-    v1->v_18.x = 0;
-    v1->v_18.y = 0;
-    v1->v_18.z = 65536;
+    this->v_18.x = 0;
+    this->v_18.y = 0;
+    this->v_18.z = 65536;
   }
   else
   {
     v8 = 1.0 / v7;
     v9 = v8 * v15 * 65536.0;
     v10 = v9 + 6.7553994e15;
-    v1->v_18.x = LODWORD(v10);
+    this->v_18.x = LODWORD(v10);
     v4 = v3;
     v11 = v8 * v4 * 65536.0;
     v12 = v11 + 6.7553994e15;
-    v1->v_18.y = LODWORD(v12);
+    this->v_18.y = LODWORD(v12);
     v6 = v5;
     v13 = v8 * v6 * 65536.0;
     v14 = v13 + 6.7553994e15;
-    v1->v_18.z = LODWORD(v14);
+    this->v_18.z = LODWORD(v14);
   }
 }
 
@@ -14638,7 +14638,7 @@
 //----- (0044C362) --------------------------------------------------------
 void Vec3_int_::Normalize_float()
 {
-  Vec3_int_ *v1; // esi@1
+  //Vec3_int_ *v1; // esi@1
   double v2; // st6@1
   float v3; // ST20_4@1
   double v4; // st5@1
@@ -14653,7 +14653,7 @@
   float v13; // ST14_4@1
   double v14; // ST0C_8@1
 
-  v1 = this;
+  //v1 = this;
   v2 = (double)this->x * 0.000015258789;
   v3 = v2;
   v4 = (double)this->y * 0.000015258789;
@@ -14663,13 +14663,13 @@
   v8 = 1.0 / sqrt(v6 * v6 + v4 * v4 + v2 * v2);
   v9 = v8 * v3 * 65536.0;
   v10 = v9 + 6.7553994e15;
-  v1->x = LODWORD(v10);
+  this->x = LODWORD(v10);
   v11 = v8 * v5 * 65536.0;
   v12 = v11 + 6.7553994e15;
-  v1->y = LODWORD(v12);
+  this->y = LODWORD(v12);
   v13 = v8 * v7 * 65536.0;
   v14 = v13 + 6.7553994e15;
-  v1->z = LODWORD(v14);
+  this->z = LODWORD(v14);
 }
 
 //----- (00401000) --------------------------------------------------------
--- a/mm7_4.cpp	Wed May 15 09:32:39 2013 +0600
+++ b/mm7_4.cpp	Tue May 21 12:42:57 2013 +0600
@@ -1801,7 +1801,7 @@
 {
   //v2 = a2 - 0.5;
   //v3 = v2 + 6.7553994e15;
-  int v4 = floorf(a2 - 0.5f + 0.5f);
+  int v4 = floorf((a2 - 0.5f) + 0.5f);
   //v7 = (a2 - (double)SLODWORD(v3)) * 65536.0;
   //v5 = v7 + 6.7553994e15;
   //return LODWORD(v5) | (v4 << 16);
--- a/mm7_5.cpp	Wed May 15 09:32:39 2013 +0600
+++ b/mm7_5.cpp	Tue May 21 12:42:57 2013 +0600
@@ -47,7 +47,7 @@
 void __cdecl GameUI_MsgProc()
 {
   //signed int v0; // edi@6
-  char *v1; // esi@6
+  //char *v1; // esi@6
   unsigned int v2; // edx@7
   Actor *pActor; // ecx@13
   int v4; // ecx@18
@@ -280,7 +280,7 @@
   }
   if ( pMessageQueue_50CBD0->uNumMessages )
   {
-    v1 = "";
+    //v1 = "";
     while ( 2 )
     {
       if ( !pMessageQueue_50CBD0->uNumMessages )
@@ -549,48 +549,48 @@
           pGUIWindow_CurrentMenu->CreateButton(22, 270,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[2])->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[2])->uTextureHeight,
-                                               1, 0, UIMSG_SetTurnSpeed, 0x80, 0, v1, 0);
+                                               1, 0, UIMSG_SetTurnSpeed, 0x80, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(93, 270,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[1])->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[1])->uTextureHeight,
-                                               1, 0, UIMSG_SetTurnSpeed, 0x40u, 0, v1, 0);
+                                               1, 0, UIMSG_SetTurnSpeed, 0x40u, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(164, 270,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[0])->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[0])->uTextureHeight,
-                                               1, 0, UIMSG_SetTurnSpeed, 0, 0, v1, 0);
+                                               1, 0, UIMSG_SetTurnSpeed, 0, 0, "", 0);
 
           pGUIWindow_CurrentMenu->CreateButton(20, 303,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_WalkSound)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_WalkSound)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleWalkSound, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleWalkSound, 0, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(128, 303,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ShowDamage)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ShowDamage)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleShowDamage, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleShowDamage, 0, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(20, 325,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_AlwaysRun)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_AlwaysRun)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleAlwaysRun, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleAlwaysRun, 0, 0, "", 0);
           pGUIWindow_CurrentMenu->CreateButton(128, 325,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_FlipOnExit)->uTextureWidth,
                                                pIcons_LOD->GetTexture(options_menu_skin.uTextureID_FlipOnExit)->uTextureHeight,
-                                               1, 0, UIMSG_ToggleFlipOnExit, 0, 0, v1, 0);
-
-          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 4, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 5, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
-          pGUIWindow_CurrentMenu->CreateButton(263, 162, 172, 17, 1, 0, UIMSG_ChangeSoundVolume, 0, 0, v1, 0);
-
-          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 4, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 5, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
-          pGUIWindow_CurrentMenu->CreateButton(263, 216, 172, 17, 1, 0, UIMSG_ChangeMusicVolume, 0, 0, v1, 0);
-
-          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 4, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 5, 0, v1, pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
-          pGUIWindow_CurrentMenu->CreateButton(263, 270, 172, 17, 1, 0, UIMSG_ChangeVoiceVolume, 0, 0, v1, 0);
+                                               1, 0, UIMSG_ToggleFlipOnExit, 0, 0, "", 0);
+
+          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 4, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 162, 16, 16, 1, 0, UIMSG_ChangeSoundVolume, 5, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
+          pGUIWindow_CurrentMenu->CreateButton(263, 162, 172, 17, 1, 0, UIMSG_ChangeSoundVolume, 0, 0, "", 0);
+
+          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 4, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 216, 16, 16, 1, 0, UIMSG_ChangeMusicVolume, 5, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
+          pGUIWindow_CurrentMenu->CreateButton(263, 216, 172, 17, 1, 0, UIMSG_ChangeMusicVolume, 0, 0, "", 0);
+
+          pBtn_SliderLeft  = pGUIWindow_CurrentMenu->CreateButton(243, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 4, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowLeft), 0);
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(435, 270, 16, 16, 1, 0, UIMSG_ChangeVoiceVolume, 5, 0, "", pIcons_LOD->GetTexture(options_menu_skin.uTextureID_ArrowRight), 0);
+          pGUIWindow_CurrentMenu->CreateButton(263, 270, 172, 17, 1, 0, UIMSG_ChangeVoiceVolume, 0, 0, "", 0);
 
           pGUIWindow_CurrentMenu->CreateButton(241, 302, 214, 40, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[619], 0); // "Return to Game"
-          pGUIWindow_CurrentMenu->CreateButton( 19, 140, 214, 40, 1, 0, UIMSG_OpenKeyMappingOptions, 0, 0x4Bu, v1, 0);
-          pGUIWindow_CurrentMenu->CreateButton( 19, 194, 214, 40, 1, 0, UIMSG_OpenVideoOptions, 0, 86, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton( 19, 140, 214, 40, 1, 0, UIMSG_OpenKeyMappingOptions, 0, 0x4Bu, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton( 19, 194, 214, 40, 1, 0, UIMSG_OpenVideoOptions, 0, 86, "", 0);
           continue;
 
         case UIMSG_OpenKeyMappingOptions://Open
@@ -629,7 +629,7 @@
           memset(KeyButtonFlagChangesArray, 0, sizeof(KeyButtonFlagChangesArray));
           //*(_WORD *)KeyButtonArray[28] = 0;
           memcpy(pPrevVirtualCidesMapping, pKeyActionMap->pVirtualKeyCodesMapping, 0x78u);
-          v1 = "";
+          //v1 = "";
           //v0 = 1;
           continue;
         case UIMSG_ChangeKeyButton:
@@ -706,21 +706,21 @@
           uTextureID_507C54 = pIcons_LOD->LoadTexture("opvdG-cl", TEXTURE_16BIT_PALETTE);
           uTextureID_507C58 = pIcons_LOD->LoadTexture("opvdG-tn", TEXTURE_16BIT_PALETTE);
           pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_VideoOptions, 0, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, 1, 0, UIMSG_Escape, 0, 0, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, 1, 0, UIMSG_Escape, 0, 0, "", 0);
           if ( pRenderer->pRenderD3D )
           {
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x118u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleBloodsplats, 0, 0, v1, 0);
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x12Eu, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleColoredLights, 0, 0, v1, 0);
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x144u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleTint, 0, 0, v1, 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x118u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleBloodsplats, 0, 0, "", 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x12Eu, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleColoredLights, 0, 0, "", 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x144u, 0xD6u, 0x12u, 1, 0, UIMSG_ToggleTint, 0, 0, "", 0);
           }
           if ( !pRenderer->bWindowMode )
           {
             //v0 = 1;
             if ( GammaController::IsGammaSupported() )
             {
-              pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0x15u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 4u, 0, v1, pIcons_LOD->GetTexture(uTextureID_507C20), 0);
-              pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0xD5u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 5u, 0, v1, pIcons_LOD->GetTexture(uTextureID_507C24), 0);
-              pGUIWindow_CurrentMenu->CreateButton(42, 162, 170, 18, 1, 0, UIMSG_1A9, 0, 0, v1, 0);
+              pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0x15u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 4u, 0, "", pIcons_LOD->GetTexture(uTextureID_507C20), 0);
+              pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0xD5u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 5u, 0, "", pIcons_LOD->GetTexture(uTextureID_507C24), 0);
+              pGUIWindow_CurrentMenu->CreateButton(42, 162, 170, 18, 1, 0, UIMSG_1A9, 0, 0, "", 0);
             }
           }
           continue;
@@ -2294,10 +2294,7 @@
             pNPCData4 = (NPCData *)((signed int)pGames_LOD->uNumSubDirs / 2);
             v70 = atoi(v216.pProperties[0]);
             if ( v70 <= 0 || v70 >= 77 )
-            {
-              v1 = "";
               continue;
-            }
             v71 = v70;
             strcpy(Str2, pMapStats->pInfos[v70].pFilename);
             pNPCData3 = 0;
@@ -2318,7 +2315,6 @@
                 dword_6BE364_game_settings_1 |= 1u;
                 uGameState = GAME_STATE_2;
                 OnMapLeave();
-                v1 = "";
                 continue;
               }
             }
@@ -2328,10 +2324,7 @@
           else
           {
             if ( v216.uPropCount != 3 )
-            {
-              v1 = "";
               continue;
-            }
             v74 = atoi(v216.pProperties[0]);
             thisi = atoi(v216.pProperties[1]);
             v75 = atoi(v216.pProperties[2]);
@@ -2345,7 +2338,6 @@
                 pParty->vPosition.y = v77;
                 pParty->vPosition.z = v76;
                 pParty->uFallStartY = v76;
-                v1 = "";
                 continue;
               }
             }
@@ -2364,7 +2356,6 @@
                       pParty->vPosition.y = v77;
                       pParty->vPosition.z = v76;
                       pParty->uFallStartY = v76;
-                      v1 = "";
                       continue;
                     }
                   }
@@ -2375,7 +2366,6 @@
             v73 = "Can't jump to that location!";
           }
           ShowStatusBarString(v73, 6u);
-          v1 = "";
           continue;
         case UIMSG_CastQuickSpell:
           if ( bUnderwater == 1 )
@@ -2385,10 +2375,7 @@
             continue;
           }
           if ( !uActiveCharacter || (pPlayer2 = pPlayers[uActiveCharacter], pPlayer2->uTimeToRecovery) )
-          {
-            v1 = "";
             continue;
-          }
           _42777D_CastSpell_UseWand_ShootArrow(pPlayer2->uQuickSpell, uActiveCharacter - 1, 0, 0, uActiveCharacter);
           continue;
         case UIMSG_CastSpell_Monster_Improvement:
@@ -2407,10 +2394,7 @@
           v44 = (unsigned __int16)v81;
           v84 = v83 >> 16;
           if ( PID_TYPE(v44) != 3 || v84 >= 5120 )
-          {
-            v1 = "";
             continue;
-          }
           pSpellInfo = (CastSpellInfo *)pGUIWindow_Settings->ptr_1C;
           if ( uMessage == UIMSG_CastSpell_Shoot_Monster )
           {
@@ -2436,10 +2420,7 @@
         case UIMSG_1C:
 			__debugbreak();
           if ( !uActiveCharacter || pCurrentScreen )
-          {
-            v1 = "";
             continue;
-          }
           ptr_507BC8 = GUIWindow::Create(0, 0, 640, 480, WINDOW_68, uMessageParam, 0);
           pCurrentScreen = SCREEN_19;
           pEventTimer->Pause();
@@ -2447,10 +2428,7 @@
         case UIMSG_1B:
 			__debugbreak();
           if ( !uActiveCharacter )
-          {
-            v1 = "";
             continue;
-          }
           if ( pParty->bTurnBasedModeOn != 1 )
           {
             if ( pActors[uMessageParam].uAIState == 5 )
@@ -2460,10 +2438,7 @@
             continue;
           }
           if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3 )
-          {
-            v1 = "";
             continue;
-          }
           if ( !(pTurnEngine->field_18 & 2) )
           {
             if ( pActors[uMessageParam].uAIState == 5 )
@@ -2475,20 +2450,14 @@
 
         case UIMSG_Attack:
           if ( !uActiveCharacter )
-          {
-            v1 = "";
             continue;
-          }
           if ( pParty->bTurnBasedModeOn != 1 )
           {
             _42ECB5_PlayerAttacksActor();
             continue;
           }
           if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 3 )
-          {
-            v1 = "";
             continue;
-          }
           if ( !(pTurnEngine->field_18 & 2) )
             _42ECB5_PlayerAttacksActor();
           continue;
@@ -2551,10 +2520,7 @@
               v88 = pGlobalTXT_LocalizationStrings[479];// "You can't rest here!"
             ShowStatusBarString(v88, 2);
             if ( !uActiveCharacter )
-            {
-              v1 = "";
               continue;
-            }
             pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)13, 0);
             continue;
           }
@@ -2578,10 +2544,7 @@
             v88 = pGlobalTXT_LocalizationStrings[479];// "You can't rest here!"
           ShowStatusBarString(v88, 2u);
           if ( !uActiveCharacter )
-          {
-            v1 = "";
             continue;
-          }
           pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)13, 0);
           continue;
         case UIMSG_Rest8Hour:
@@ -2942,7 +2905,7 @@
           pCharacterScreen_DetalizBtn = pGUIWindow_CurrentMenu->CreateButton(v121, v123, v125, v128, 1, 0, UIMSG_ChangeDetaliz, 0, 0,
                          pGlobalTXT_LocalizationStrings[64],// "Detail Toggle"
                          0);
-          pCharacterScreen_DollBtn = pGUIWindow_CurrentMenu->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_ClickPaperdoll, 0, 0, v1, 0);
+          pCharacterScreen_DollBtn = pGUIWindow_CurrentMenu->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_ClickPaperdoll, 0, 0, "", 0);
           viewparams->bRedrawGameUI = 1;
           continue;
         case UIMSG_ClickPaperdoll:
@@ -3664,15 +3627,9 @@
 //----- (004369DB) --------------------------------------------------------
 void Vec3_float_::Normalize()
 {
-  Vec3_float_ *v1; // esi@1
-  double v2; // st7@1
-
-  auto a1 = this;
-  v1 = a1;
-  v2 = 1.0 / sqrt(a1->x * a1->x + a1->y * a1->y + a1->z * a1->z);
-  v1->x = v2 * v1->x;
-  v1->y = v2 * v1->y;
-  v1->z = v2 * v1->z;
+  this->x = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->x;
+  this->y = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->y;
+  this->z = (1.0 / sqrt(this->x * this->x + this->y * this->y + this->z * this->z)) * this->z;
 }
 
 //----- (004385B5) --------------------------------------------------------
@@ -5396,41 +5353,32 @@
   int v8; // ST14_4@1
   int v9; // edi@1
   int anglea; // [sp+20h] [bp+8h]@1
+
   v7 = sRotX;
   v8 = sDepth;
   v9 = sRotY;
   anglea = (unsigned __int64)(stru_5C6E00->SinCos(sRotX) * (signed __int64)sDepth) >> 16;
-  *outx = v.x + ((unsigned __int64)(stru_5C6E00->SinCos(v9) * (signed __int64)anglea) >> 16);
-  *outy = v.y
-        + ((unsigned __int64)(stru_5C6E00->SinCos(v9 - stru_5C6E00->uIntegerHalfPi)
-                            * (signed __int64)anglea) >> 16);
-  *outz = v.z
-        + ((unsigned __int64)(stru_5C6E00->SinCos(v7 - stru_5C6E00->uIntegerHalfPi) * (signed __int64)v8) >> 16);*/
+  *outx = v.x + ((unsigned __int64)(stru_5C6E00->SinCos(sRotY) * (signed __int64)anglea) >> 16);
+  *outy = v.y + ((unsigned __int64)(stru_5C6E00->SinCos(sRotY - stru_5C6E00->uIntegerHalfPi) * (signed __int64)anglea) >> 16);
+  *outz = v.z + ((unsigned __int64)(stru_5C6E00->SinCos(sRotX - stru_5C6E00->uIntegerHalfPi) * (signed __int64)sDepth) >> 16);*/
 
  float cosf_x = cosf(3.14159265f * sRotX / 1024.0f),
+       sinf_x = sinf(3.14159265f * sRotX / 1024.0f),
        cosf_y = cosf(3.14159265f * sRotY / 1024.0f),
-       sinf_x = sinf(3.14159265f * sRotX / 1024.0f),
        sinf_y = sinf(3.14159265f * sRotY / 1024.0f);
-
- *outx = v.x + ((unsigned __int64)((double)sDepth * cosf_y * cosf_x) >> 16);
- *outy = v.y + ((unsigned __int64)((double)sDepth * sinf_y * cosf_x) >> 16);
- *outz = v.z + ((unsigned __int64)((double)sDepth * sinf_x) >> 16);
+ sDepth = 14000000;
+ *outx = v.x + ((unsigned __int64)(sinf_y * (signed __int64)((unsigned __int64)(cosf_x * (signed __int64)sDepth)>> 16)));
+ *outy = v.y + ((unsigned __int64)(cosf_y * (signed __int64)((unsigned __int64)(cosf_x * (signed __int64)sDepth)>> 16)));
+ *outz = v.z + ((unsigned __int64)(sinf_x * (signed __int64)sDepth) >> 16);
 
 }
 
 //----- (0043AB61) --------------------------------------------------------
 void Vec3_int_::Normalize(int *x, int *y, int *z)
 {
-  int *v3; // edi@1
-  int *v4; // esi@1
-  signed int v5; // eax@1
-
-  v3 = x;
-  v4 = y;
-  v5 = integer_sqrt(*y * *y + *z * *z + *x * *x);
-  *v3 *= 65536 / (v5 | 1);
-  *v4 *= 65536 / (v5 | 1);
-  *z *= 65536 / (v5 | 1);
+  *x *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
+  *y *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
+  *z *= 65536 / (integer_sqrt(*y * *y + *z * *z + *x * *x) | 1);
 }
 
 //----- (0043AE12) --------------------------------------------------------