diff Vis.cpp @ 327:a7f15da53e82

Слияние
author Ritor1
date Wed, 20 Feb 2013 11:27:06 +0600
parents d720a13e2273
children 5cfb5dadf330
line wrap: on
line diff
--- a/Vis.cpp	Wed Feb 20 11:26:54 2013 +0600
+++ b/Vis.cpp	Wed Feb 20 11:27:06 2013 +0600
@@ -386,21 +386,20 @@
 }
 
 //----- (004C17CF) --------------------------------------------------------
-void Vis::PickOutdoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool one_sided)
+void Vis::PickOutdoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool only_reachable)
 {  
   if (!pOutdoor)
     return;
 
   for (uint i = 0; i < pOutdoor->uNumBModels; ++i)
   {
-    int v24;
-    if (!IsBModelVisible(i, &v24))
+    int reachable;
+    if (!IsBModelVisible(i, &reachable))
       continue;
-    if (one_sided && !v24)
+    if (!reachable && only_reachable)
       continue;
 
     auto bmodel = &pOutdoor->pBModels[i];
-
     for (uint j = 0; j < bmodel->uNumFaces; ++j)
     {
       auto face = bmodel->pFaces + j;
@@ -414,10 +413,15 @@
         {
           pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1u);
           int v13 = _48B561_mess_with_scaling_along_z(/*v12, */intersection.vWorldViewPosition.x);
-          LOWORD(v13) = (8 * (j | (i << 6)) | OBJECT_BModel) + v13;
+          v13 += (8 * (j | (i << 6)) | OBJECT_BModel);
 
           list->AddObject(face, VisObjectType_Face, v13);
         }
+
+        if (blv_face.uAttributes & 0x80000000)
+          face->uAttributes |= FACE_OUTLINED;
+        else
+          face->uAttributes &= ~FACE_OUTLINED;
       }
     }
   }
@@ -575,62 +579,118 @@
 //----- (004C1C0C) --------------------------------------------------------
 bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6)
 {
-  BLVFace *v7; // ebx@1
-  bool result; // eax@1
+  //BLVFace *v7; // ebx@1
+  //bool result; // eax@1
   double v9; // st7@3
-  __int16 v10; // fps@3
-  char v11; // c0@3
-  char v12; // c2@3
-  char v13; // c3@3
-  __int16 v14; // fps@5
-  char v15; // c0@5
-  char v16; // c2@5
-  char v17; // c3@5
+  //__int16 v10; // fps@3
+  //char v11; // c0@3
+  //char v12; // c2@3
+  //char v13; // c3@3
+  //__int16 v14; // fps@5
+  //char v15; // c0@5
+  //char v16; // c2@5
+  //char v17; // c3@5
   double v18; // st5@6
-  __int16 v19; // fps@6
-  char v20; // c0@6
-  char v21; // c2@6
-  char v22; // c3@6
-  unsigned __int8 v23; // c0@6
-  char v24; // c2@6
-  unsigned __int8 v25; // c3@6
-  char v26; // zf@6
+  //__int16 v19; // fps@6
+  //char v20; // c0@6
+  //char v21; // c2@6
+  //char v22; // c3@6
+  //unsigned __int8 v23; // c0@6
+  //char v24; // c2@6
+  //unsigned __int8 v25; // c3@6
+  //char v26; // zf@6
   double v27; // st6@10
-  __int16 v28; // fps@10
-  unsigned __int8 v29; // c0@10
-  char v30; // c2@10
-  unsigned __int8 v31; // c3@10
-  double v32; // st7@11
+  //__int16 v28; // fps@10
+  //unsigned __int8 v29; // c0@10
+  //char v30; // c2@10
+  //unsigned __int8 v31; // c3@10
+  //double v32; // 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
+  //float a5a; // [sp+30h] [bp+18h]@10
+  //float a5b; // [sp+30h] [bp+18h]@13
+
+  if (a5->TwoSided() || a5->Invisible())
+    return false;
+
+  
+  int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x,
+      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;
+  if (v9 >= 0)   // ray faces face's normal ( > 0) or parallel ( == 0)
+    return false;
+
+//ray   = t dir + start
+//plane = (p - vertex) normal = -d
+//
+//
+//(t dir + start - vertex) normal = -d
+//
+//      -d - (start - vertex) norm
+//t =       --------------------
+//               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;
+
+  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;
 
-  v7 = a5;
-  result = a5->uAttributes;
-  if ( result & 1
-    || BYTE1(result) & 0x20
-    || (v9 = pRayEnd->vWorldPosition.z * a5->pFacePlane.vNormal.z
-           + a5->pFacePlane.vNormal.y * pRayEnd->vWorldPosition.y
-           + pRayEnd->vWorldPosition.x * a5->pFacePlane.vNormal.x,
-        //UNDEF(v10),
-        v11 = v9 < 0.0,
-        v12 = 0,
-        v13 = v9 == 0.0,
-        BYTE1(result) = HIBYTE(v10),
-        v9 == 0.0)
-    || (/*UNDEF(v14),*/ v15 = v9 < 0.0, v16 = 0, v17 = v9 == 0.0, BYTE1(result) = HIBYTE(v14), v9 > 0.0) )// ray's away (>) from face surface or parallel (==)
-    goto LABEL_12;
-  v18 = -(a5->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y// ray-plane intersection
+  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;
+
+  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)
+  {
+    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)
+        return false;
+
+    a5->uAttributes |= 0x80000000;
+    return true;
+  }
+
+  
+  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;
+  //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;
@@ -648,32 +708,37 @@
       LOBYTE(result) = 0;
       return result;
     }
-  }
-  a5a = v18;
-  v27 = a5a / v9;
-  HIWORD(result) = HIWORD(pDepth);
+  }*/
+
+  //a5a = v18;
+  v27 = v18 / v9;
+  //HIWORD(result) = HIWORD(pDepth);
   //UNDEF(v28);
-  v29 = v27 < *pDepth;
-  v30 = 0;
-  v31 = v27 == *pDepth;
-  BYTE1(result) = HIBYTE(v28);
-  if ( !(v29 | v31)
-    || (a4->vWorldPosition.x = v27 * pRayEnd->vWorldPosition.x + pRayStart->vWorldPosition.x,
-        a4->vWorldPosition.y = v27 * pRayEnd->vWorldPosition.y + pRayStart->vWorldPosition.y,
-        v32 = v27 * pRayEnd->vWorldPosition.z + pRayStart->vWorldPosition.z,
-        a4->vWorldPosition.z = v32,
-        v33.x = (signed __int64)a4->vWorldPosition.x,
-        v33.y = (signed __int64)a4->vWorldPosition.y,
-        *(int *)&v34.x = v33.x,
-        v34.z = (signed __int64)v32,
-        result = _4C1D2B(v7, v34, a6),
-        *(float *)&result == 0.0) )
-    goto LABEL_12;
-  *(float *)&result = v27;
-  a5b = v27;
-  *(int *)pDepth = LODWORD(a5b);
-  LOBYTE(result) = 1;
-  return result;
+  //v29 = v27 < *pDepth;
+  //v30 = 0;
+  //v31 = v27 == *pDepth;
+  //BYTE1(result) = HIBYTE(v28);
+
+  if (v27 > *pDepth)
+    return false;
+
+  a5->uAttributes |= 0x80000000;
+
+  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;
+        
+  if ( _4C1D2B(a5, v34, a6) == 0.0)
+    return false;
+
+  //a5b = v27;
+  *pDepth = v27;
+  return true;
 }
 
 //----- (004C1D2B) --------------------------------------------------------
@@ -694,63 +759,54 @@
   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
-    || (uModelID != -1 ? _4C2186_BLV_IntersectBModel(
-                           (int *)&pFace,
-                           (int *)&uModelID,
-                           &word_F8BC48_displaced_face_intersect_plane_coords_a,
-                           &word_F8BD18_displaced_face_intersect_plane_coords_b,
-                           &a2,
-                           pFace,
-                           uModelID) : _4C1EE5_BLV_IntersectBModel_2(
-                                         (int *)&pFace,
-                                         (int *)&uModelID,
-                                         &word_F8BC48_displaced_face_intersect_plane_coords_a,
-                                         &word_F8BD18_displaced_face_intersect_plane_coords_b,
-                                         &a2,
-                                         pFace),
-        v5 = 2 * v4->uNumVertices,
-        v16 = 0,
-        *(&word_F8BC48_displaced_face_intersect_plane_coords_a + v5) = word_F8BC48_displaced_face_intersect_plane_coords_a,
-        *(&word_F8BD18_displaced_face_intersect_plane_coords_b + v5) = word_F8BD18_displaced_face_intersect_plane_coords_b,
-        v15 = 0,
-        v6 = word_F8BD18_displaced_face_intersect_plane_coords_b >= (signed int)uModelID,
-        v5 <= 0) )
-    goto LABEL_25;
+  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)
+    return false;
+
+  if (uModelID != -1)
+    _4C2186_BLV_IntersectBModel((int *)&pFace, (int *)&uModelID,
+                                word_F8BC48_displaced_face_intersect_plane_coords_a,
+                                word_F8BD18_displaced_face_intersect_plane_coords_b,
+                                &a2, pFace, uModelID);
+  else
+    _4C1EE5_BLV_IntersectBModel_2((int *)&pFace, (int *)&uModelID,
+                                  word_F8BC48_displaced_face_intersect_plane_coords_a,
+                                  word_F8BD18_displaced_face_intersect_plane_coords_b,
+                                  &a2, pFace);
+  
+  v5 = 2 * v4->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];
+  v15 = 0;
+  v6 = word_F8BD18_displaced_face_intersect_plane_coords_b[0] >= (signed int)uModelID;
+  if (v5 <= 0)
+    return false;
+
   do
   {
     if ( v16 >= 2 )
       break;
     v7 = 2 * v15;
-    v8 = *(&word_F8BD18_displaced_face_intersect_plane_coords_b + v15 + 1);
+    v8 = word_F8BD18_displaced_face_intersect_plane_coords_b[ + v15 + 1];
     if ( v6 ^ v8 >= (signed int)uModelID )
     {
-      v9 = *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7 + 2);
+      v9 = word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2 + 1];
       if ( v9 >= (signed int)pFace )
         v10 = 0;
       else
         v10 = 2;
-      v11 = v10 | *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7) < (signed int)pFace;
+      v11 = v10 | word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2] < (signed int)pFace;
       if ( v11 != 3 )
       {
         if ( !v11
-          || (v12 = v9 - *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7),
+          || (v12 = v9 - word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2],
               LODWORD(v13) = v12 << 16,
               HIDWORD(v13) = v12 >> 16,
-              *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7)
-            + ((signed int)(((unsigned __int64)(v13
-                                              / (v8
-                                               - *(__int16 *)((char *)&word_F8BD18_displaced_face_intersect_plane_coords_b
-                                                            + v7))
-                                              * (signed int)((uModelID
-                                                            - *(__int16 *)((char *)&word_F8BD18_displaced_face_intersect_plane_coords_b
-                                                                         + v7)) << 16)) >> 16)
-                          + 32768) >> 16) >= (signed int)pFace) )
+              word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2]
+            + ((signed int)(((unsigned __int64)(v13 / (v8 - word_F8BD18_displaced_face_intersect_plane_coords_b[v7/2])
+                                              * (signed int)((uModelID - word_F8BD18_displaced_face_intersect_plane_coords_b[v7/2]) << 16)) >> 16) + 32768) >> 16) >= (signed int)pFace) )
           ++v16;
       }
     }
@@ -1484,7 +1540,7 @@
     PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false);
   else
   {
-    Log::Warning(L"Picking mouse in undefined level"); // picking in main menu is default (buggy) game behavious. should've returned false in Game::PickMouse
+    Log::Warning(L"Picking mouse in undefined level"); // picking in main menu is default (buggy) game behaviour. should've returned false in Game::PickMouse
     return false;
   }
   default_list.create_object_pointers(Vis_SelectionList::All);