World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Vis.cpp
См. документацию.
1 #include "Engine/Graphics/Vis.h"
2 
3 #include <cstdlib>
4 
5 #include "Engine/Engine.h"
6 #include "Engine/IocContainer.h"
7 #include "Engine/LOD.h"
8 #include "Engine/OurMath.h"
9 
15 
16 #include "Engine/Objects/Actor.h"
17 
19 
21 
23  VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E1C
25  VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E30
27  0}; // 00F93E44
29  0x100000, 0}; // 00F93E58
31  VisObjectType_Sprite, OBJECT_Decoration, -1, 0, 4}; // 00F93E6C
33  0, 0}; // static to sub_44EEA7
34 
35 //----- (004C1026) --------------------------------------------------------
37  float pick_depth) {
38  // char *v4; // eax@4
39  // signed int v5; // ecx@4
40  RenderVertexSoft pRay[2]; // [sp+20h] [bp-70h]@17
41  // int v20; // [sp+84h] [bp-Ch]@10
42 
43  static Vis_SelectionList SelectedPointersList; // stru_F8FE00
44  SelectedPointersList.uNumPointers = 0;
45 
46  static bool _init_flag = false;
47  static RenderVertexSoft static_DetermineFacetIntersection_array_F8F200[64];
48  if (!_init_flag) {
49  _init_flag = true;
50  for (uint i = 0; i < 64; ++i)
51  static_DetermineFacetIntersection_array_F8F200[i].flt_2C = 0.0f;
52  }
53 
55  if ((signed int)face->uNumVertices > 0) {
56  for (int i = 0; i < face->uNumVertices; i++) {
57  static_DetermineFacetIntersection_array_F8F200[i]
58  .vWorldPosition.x =
59  (float)pIndoor->pVertices[face->pVertexIDs[i]].x;
60  static_DetermineFacetIntersection_array_F8F200[i]
61  .vWorldPosition.y =
62  (float)pIndoor->pVertices[face->pVertexIDs[i]].y;
63  static_DetermineFacetIntersection_array_F8F200[i]
64  .vWorldPosition.z =
65  (float)pIndoor->pVertices[face->pVertexIDs[i]].z;
66  }
67  }
69  uint bmodel_id = pid >> 9;
70  Vec3_int_ *v =
71  (Vec3_int_ *)pOutdoor->pBModels[bmodel_id].pVertices.pVertices;
72  for (uint i = 0; i < face->uNumVertices; ++i) {
73  static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.x =
74  (float)v[face->pVertexIDs[i]].x;
75  static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.y =
76  (float)v[face->pVertexIDs[i]].y;
77  static_DetermineFacetIntersection_array_F8F200[i].vWorldPosition.z =
78  (float)v[face->pVertexIDs[i]].z;
79  }
80  } else {
81  assert(false);
82  }
83 
85  static_DetermineFacetIntersection_array_F8F200, face->uNumVertices);
86  pIndoorCameraD3D->Project(static_DetermineFacetIntersection_array_F8F200,
87  face->uNumVertices, 1);
88 
89  SortVectors_x(static_DetermineFacetIntersection_array_F8F200, 0,
90  face->uNumVertices - 1);
91  if (static_DetermineFacetIntersection_array_F8F200[0].vWorldViewPosition.x >
92  pick_depth)
93  return nullptr;
94 
95  float screenspace_center_x, screenspace_center_y;
96  GetPolygonScreenSpaceCenter(static_DetermineFacetIntersection_array_F8F200,
97  face->uNumVertices, &screenspace_center_x,
98  &screenspace_center_y);
100  static_DetermineFacetIntersection_array_F8F200, face->uNumVertices,
101  screenspace_center_x, screenspace_center_y))
102  return nullptr;
103 
104  CastPickRay(pRay, screenspace_center_x, screenspace_center_y, pick_depth);
105 
107  PickOutdoorFaces_Mouse(pick_depth, pRay, &SelectedPointersList,
108  &vis_face_filter, true);
110  PickIndoorFaces_Mouse(pick_depth, pRay, &SelectedPointersList,
111  &vis_face_filter);
112  else
113  assert(false);
114 
115  SelectedPointersList.create_object_pointers();
116  sort_object_pointers(SelectedPointersList.object_pointers, 0,
117  SelectedPointersList.uNumPointers - 1);
118  if (!SelectedPointersList.uNumPointers) return nullptr;
119 
120  if (!SelectedPointersList.SelectionPointers(VisObjectType_Face, pid))
121  return nullptr;
122 
123  if (SelectedPointersList.uNumPointers)
124  return SelectedPointersList.object_pointers[0];
125  else
126  return nullptr;
127 }
128 // F91E08: using guessed type char
129 // static_DetermineFacetIntersection_byte_F91E08__init_flags;
130 
131 //----- (004C12C3) --------------------------------------------------------
133  int num_vertices, float x, float y) {
134  int v13 = -1;
135  // v5 = 0;
136 
137  // v6 = render->pBillboardRenderListD3D;
138  for (uint i = 0; i < render->uNumBillboardsToDraw; ++i) {
139  RenderBillboardD3D *billboard = &render->pBillboardRenderListD3D[i];
140  if (IsPointInsideD3DBillboard(billboard, x, y)) {
141  if (v13 == -1)
142  v13 = i;
143  else if (pBillboardRenderList[billboard->sParentBillboardID]
144  .screen_space_z <
145  pBillboardRenderList[render->pBillboardRenderListD3D[v13]
146  .sParentBillboardID]
148  v13 = i;
149  }
150  }
151 
152  if (v13 == -1) return false;
153 
154  // //Bounding rectangle(Ограничивающий
155  // прямоугольник)-------------------------
156  // v7 = 3.4028235e38;
157  float min_x = FLT_MAX;
158  // a4a = 3.4028235e38;
159  float min_y = FLT_MAX;
160  // a3a = -3.4028235e38;
161  float max_x = -FLT_MAX;
162  // thisb = -3.4028235e38;
163  float max_y = -FLT_MAX;
164  for (int i = 0; i < num_vertices; ++i) {
165  RenderVertexSoft *v = &vertices[i];
166 
167  if (v->vWorldViewProjX < min_x) min_x = v->vWorldViewProjX;
168  if (v->vWorldViewProjX > max_x) max_x = v->vWorldViewProjX;
169 
170  if (v->vWorldViewProjY < min_y) min_y = v->vWorldViewProjY;
171  if (v->vWorldViewProjY > max_y) max_y = v->vWorldViewProjY;
172  }
173  // //--------------------------------
174 
175  if (min_x < render->pBillboardRenderListD3D[v13].pQuads[0].pos.x ||
176  render->pBillboardRenderListD3D[v13].pQuads[0].pos.y > min_y ||
177  render->pBillboardRenderListD3D[v13].pQuads[3].pos.x < max_x ||
178  render->pBillboardRenderListD3D[v13].pQuads[1].pos.y < max_y)
179  return false;
180 
181  return true;
182 }
183 
184 //----- (004C1417) --------------------------------------------------------
186  unsigned int uNumVertices, float *pCenterX,
187  float *pCenterY) {
188  static RenderVertexD3D3 unk_F8EA00[64];
189 
190  memcpy(unk_F8EA00, pVertices, 32 * uNumVertices);
191 
192  SortVerticesByX(unk_F8EA00, 0, uNumVertices - 1);
193  *pCenterX =
194  (unk_F8EA00[uNumVertices - 1].pos.x - unk_F8EA00[0].pos.x) * 0.5 +
195  unk_F8EA00[0].pos.x;
196 
197  SortVerticesByY(unk_F8EA00, 0, uNumVertices - 1);
198  *pCenterY =
199  (unk_F8EA00[uNumVertices - 1].pos.y - unk_F8EA00[0].pos.y) * 0.5 +
200  unk_F8EA00[0].pos.y;
201 }
202 
203 //----- (004C1495) --------------------------------------------------------
205  int num_vertices, float *out_center_x,
206  float *out_center_y) {
207  // char *v5; // eax@2
208  // signed int v6; // ecx@2
209  // float *result; // eax@5
210 
211  static RenderVertexSoft static_sub_4C1495_array_F8DDF8[64];
212 
213  memcpy(static_sub_4C1495_array_F8DDF8, vertices, 48 * num_vertices);
214 
215  SortByScreenSpaceX(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1);
216  *out_center_x =
217  (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjX -
218  static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX) *
219  0.5 +
220  static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX;
221 
222  SortByScreenSpaceY(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1);
223  *out_center_y =
224  (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjY -
225  static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY) *
226  0.5 +
227  static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY;
228 }
229 
230 //----- (004C1542) --------------------------------------------------------
231 void Vis::PickBillboards_Mouse(float fPickDepth, float fX, float fY,
232  Vis_SelectionList *list,
234  for (uint i = 0; i < render->uNumBillboardsToDraw; ++i) {
235  RenderBillboardD3D *d3d_billboard = &render->pBillboardRenderListD3D[i];
236  if (is_part_of_selection((void *)i, filter) &&
237  IsPointInsideD3DBillboard(d3d_billboard, fX, fY)) {
238  if (DoesRayIntersectBillboard(fPickDepth, i)) {
239  RenderBillboard *billboard =
240  &pBillboardRenderList[d3d_billboard->sParentBillboardID];
241 
242  list->AddObject((void *)d3d_billboard->sParentBillboardID,
244  billboard->object_pid);
245  }
246  }
247  }
248 }
249 
250 //----- (004C1607) --------------------------------------------------------
252  /*Not the original implementation.
253  This function is redone to use Grayface's mouse pick implementation to take
254  only the visible
255  parts of billboards into account - I don't really have too much of an idea
256  how it actually works*/
257 
258  if (a1->sParentBillboardID == -1) return false;
259 
260  float drX = a1->pQuads[0].pos.x;
261  float drW = a1->pQuads[3].pos.x - drX;
262  float drY = a1->pQuads[0].pos.y;
263  float drH = a1->pQuads[1].pos.y - drY;
264 
265 
266 
267  // for small items dont bother with the per pixel checks
268  if (abs(drH) < 5 || abs(drW) < 5) {
269  if (drW < 0) { // sprite reversed
270  drX = a1->pQuads[3].pos.x;
271  drW = a1->pQuads[0].pos.x - drX;
272  }
273  if (x >= drX && x < (drW + drX) && y >= drY && y < (drH + drY)) { // simple bounds check
274  return 1;
275  } else {
276  return 0;
277  }
278  }
279 
280 
281  Sprite *ownerSprite = nullptr;
282  for (int i = 0; i < pSprites_LOD->uNumLoadedSprites; ++i) {
283  if ((void *)pSprites_LOD->pHardwareSprites[i].texture == a1->texture) {
284  ownerSprite = &pSprites_LOD->pHardwareSprites[i];
285  break;
286  }
287  }
288 
289  if (ownerSprite == nullptr) return false;
290 
291  int sx =
292  ownerSprite->uAreaX + int(ownerSprite->uAreaWidth * (x - drX) / drW);
293  int sy =
294  ownerSprite->uAreaY + int(ownerSprite->uAreaHeight * (y - drY) / drH);
295 
296  LODSprite *spriteHeader = ownerSprite->sprite_header;
297 
298  if (sy < 0 || sy >= spriteHeader->uHeight) return false;
299  if (sx < 0 || sx >= spriteHeader->uWidth) return false;
300 
301  return spriteHeader->bitmap[sy * spriteHeader->uWidth + sx] != 0;
302 }
303 
304 //----- (004C16B4) --------------------------------------------------------
306  Vis_SelectionList *list,
308  int v5; // eax@1
309  signed int pFaceID; // edi@2
310  // int v9; // eax@7
311  unsigned int *pNumPointers; // eax@7
312  Vis_ObjectInfo *v12; // edi@7
313  RenderVertexSoft a1; // [sp+Ch] [bp-44h]@1
314  // void *v15; // [sp+40h] [bp-10h]@7
315  int v17; // [sp+48h] [bp-8h]@1
316 
317  v5 = 0;
318  v17 = 0;
319  for (a1.flt_2C = 0.0; v17 < (signed int)pBspRenderer->num_faces; ++v17) {
320  pFaceID = pBspRenderer->faces[v5].uFaceID;
321  if (pFaceID >= 0) {
322  if (pFaceID < (signed int)pIndoor->uNumFaces) {
323  BLVFace *face = &pIndoor->pFaces[pFaceID];
325  if (!pIndoorCameraD3D->IsCulled(face)) {
326  if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1,
327  face, 0xFFFFFFFFu)) {
329  // v9 = fixpoint_from_float(/*v8,
330  // */a1.vWorldViewPosition.x); HEXRAYS_LOWORD(v9) =
331  // 0; v15 = (void *)((PID(OBJECT_BModel,pFaceID)) +
332  // v9);
333  pNumPointers = &list->uNumPointers;
334  v12 = &list->object_pool[list->uNumPointers];
335  v12->object = &pIndoor->pFaces[pFaceID];
336  v12->depth = a1.vWorldViewPosition.x;
337  v12->object_pid = PID(OBJECT_BModel, pFaceID);
339  ++*pNumPointers;
340  // logger->Info(L"raypass");
341  } else {
342  // __debugbreak();
343  // logger->Info(L"rayfaile");
344  }
345  }
346  }
347 
348  if (face->uAttributes & FACE_PICKED)
349  face->uAttributes |= FACE_OUTLINED;
350  else
351  face->uAttributes &= ~FACE_OUTLINED;
352  face->uAttributes &= ~FACE_PICKED;
353  }
354  }
355  v5 = v17 + 1;
356  }
357 }
358 
360  Vis_SelectionList *list,
362  bool only_reachable) {
363  if (!pOutdoor) return;
364 
365  for (BSPModel &model : pOutdoor->pBModels) {
366  int reachable;
367  if (!IsBModelVisible(&model, &reachable)) {
368  continue;
369  }
370  if (!reachable && only_reachable) {
371  continue;
372  }
373 
374  for (ODMFace &face : model.pFaces) {
376  BLVFace blv_face;
377  blv_face.FromODM(&face);
378 
379  RenderVertexSoft intersection;
380  if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &intersection,
381  &blv_face, model.index)) {
382  pIndoorCameraD3D->ViewTransform(&intersection, 1);
383  // int v13 = fixpoint_from_float(/*v12,
384  // */intersection.vWorldViewPosition.x); v13 &= 0xFFFF0000;
385  // v13 += PID(OBJECT_BModel, j | (i << 6));
386  uint32_t pid =
387  PID(OBJECT_BModel, face.index | (model.index << 6));
389  intersection.vWorldViewPosition.x, pid);
390  }
391 
392  if (blv_face.uAttributes & FACE_PICKED)
393  face.uAttributes |= FACE_OUTLINED;
394  else
395  face.uAttributes &= ~FACE_OUTLINED;
396  blv_face.uAttributes &= ~FACE_PICKED;
397  }
398  }
399  }
400 }
401 
402 //----- (004C1944) --------------------------------------------------------
403 unsigned short Vis::PickClosestActor(int object_id, unsigned int pick_depth,
404  int a4, int a5, int a6) {
405  Vis_SelectionFilter v8; // [sp+18h] [bp-20h]@3
406 
408 
410  v8.object_id = object_id;
411  v8.at_ai_state = a6;
412  v8.no_at_ai_state = a5;
413  v8.select_flags = a4;
416  &v8);
421 
424 }
425 
426 //----- (004C1A02) --------------------------------------------------------
427 void Vis::_4C1A02() {
428  RenderVertexSoft v1; // [sp+8h] [bp-C0h]@1
429  RenderVertexSoft v2; // [sp+38h] [bp-90h]@1
430  RenderVertexSoft v3; // [sp+68h] [bp-60h]@1
431  RenderVertexSoft v4; // [sp+98h] [bp-30h]@1
432 
433  v2.flt_2C = 0.0;
434  v2.vWorldPosition.x = 0.0;
435  v2.vWorldPosition.y = 65536.0;
436  v2.vWorldPosition.z = 0.0;
437 
438  v1.flt_2C = 0.0;
439  v1.vWorldPosition.x = 65536.0;
440  v1.vWorldPosition.y = 0.0;
441  v1.vWorldPosition.z = 0.0;
442 
443  v3.flt_2C = 0.0;
444  v3.vWorldPosition.x = 0.0;
445  v3.vWorldPosition.y = 65536.0;
446  v3.vWorldPosition.z = 0.0;
447 
448  v4.flt_2C = 0.0;
449  v4.vWorldPosition.x = 65536.0;
450  v4.vWorldPosition.y = 0.0;
451  v4.vWorldPosition.z = 0.0;
452 
453  memcpy(&this->stru_200C, &v1, 0x60u);
454  memcpy(&this->stru_206C, &v4, 0x60u);
455 }
456 
457 //----- (004C1ABA) --------------------------------------------------------
458 void Vis::SortVectors_x(RenderVertexSoft *pArray, int start, int end) {
459  int left_sort_index; // ebx@2
460  int right_sort_index; // ecx@2
461  RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8
462  RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2
463 
464  if (end > start) {
465  left_sort_index = start - 1;
466  right_sort_index = end;
467  memcpy(&max_array, &pArray[end], sizeof(max_array));
468  while (1) {
469  do {
470  ++left_sort_index;
471  } while (pArray[left_sort_index].vWorldViewPosition.x <
472  (double)max_array.vWorldViewPosition.x);
473  do {
474  --right_sort_index;
475  } while (pArray[right_sort_index].vWorldViewPosition.x >
476  (double)max_array.vWorldViewPosition.x);
477  if (left_sort_index >= right_sort_index) break;
478  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
479  memcpy(&pArray[left_sort_index], &pArray[right_sort_index],
480  sizeof(pArray[left_sort_index]));
481  memcpy(&pArray[right_sort_index], &temp_array,
482  sizeof(pArray[right_sort_index]));
483  }
484  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
485  memcpy(&pArray[left_sort_index], &pArray[end],
486  sizeof(pArray[left_sort_index]));
487  memcpy(&pArray[end], &temp_array, sizeof(pArray[end]));
488  SortVectors_x(pArray, start, left_sort_index - 1);
489  SortVectors_x(pArray, left_sort_index + 1, end);
490  }
491 }
492 
493 //----- (004C1BAA) --------------------------------------------------------
495  switch (info->object_type) {
497  case VisObjectType_Face: {
498  // return info->sZValue;
499 
500  struct {
501  unsigned short object_pid;
502  short depth;
503  } res;
504  res.depth = info->depth;
505  res.object_pid = info->object_pid;
506  return *(int *)&res;
507  }
508 
509  default:
510  log->Warning(
511  L"Undefined type requested for: CVis::get_object_zbuf_val()");
512  return -1;
513  }
514 }
515 
516 //----- (004C1BF1) --------------------------------------------------------
518  if (!default_list.uNumPointers) return -1;
519 
521 }
522 
523 //----- (004C1C0C) --------------------------------------------------------
525  RenderVertexSoft *pRayEnd, float *pDepth,
526  RenderVertexSoft *Intersection, BLVFace *pFace,
527  signed int pBModelID) {
528  float c1; // st5@6
529  float c2; // st7@11
530  Vec3_short_ IntersectPoint; // ST04_6@11
531 
532  if (pFace->Portal() || pFace->Invisible()) return false;
533 
534  int ray_dir_x = pRayEnd->vWorldPosition.x -
535  pRayStart->vWorldPosition
536  .x, // calculate the direction vector of the
537  // line(вычислим вектор направления линий)
538  ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y,
539  ray_dir_z = pRayEnd->vWorldPosition.z - pRayStart->vWorldPosition.z;
540 
541  // c1 = -d-(n*p0)
542  c1 = -pFace->pFacePlane.dist -
543  (pFace->pFacePlane.vNormal.x * pRayStart->vWorldPosition.x +
544  pFace->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y +
545  pFace->pFacePlane.vNormal.z * pRayStart->vWorldPosition.z);
546  if (c1 > 0) return false;
547 #define EPSILON 1e-6
548  // c2 = n*u
549  c2 = pFace->pFacePlane.vNormal.x *
550  ray_dir_y // get length of the line(Это дает нам длину линии)
551  + pFace->pFacePlane.vNormal.y * ray_dir_x +
552  pFace->pFacePlane.vNormal.z * ray_dir_z;
553  if (c2 > -EPSILON &&
554  c2 < EPSILON) // ray faces face's normal ( > 0) or parallel ( == 0)
555  return false;
556 
557  // t = -d-(n*p0)/n*u
558  float t = c1 / c2; // How far is crossing the line in percent for 0 to
559  // 1(Как далеко пересечение линии в процентах от 0 до 1 )
560 
561  if (t < 0 || t > 1) return false;
562 
563  // p(t) = p0 + tu;
564  Intersection->vWorldPosition.x =
565  pRayStart->vWorldPosition.x +
566  t * ray_dir_y; // add the interest to the start line(прибавляем процент
567  // линии к линии старта)
568  Intersection->vWorldPosition.y =
569  pRayStart->vWorldPosition.y + t * ray_dir_x;
570  Intersection->vWorldPosition.z =
571  pRayStart->vWorldPosition.z + t * ray_dir_z;
572 
573  IntersectPoint.x = Intersection->vWorldPosition.x;
574  IntersectPoint.y = Intersection->vWorldPosition.y;
575  IntersectPoint.z = Intersection->vWorldPosition.z;
576 
577  if (!CheckIntersectBModel(pFace, IntersectPoint, pBModelID)) return false;
578 
579  *pDepth = t; // Record the distance from the origin of the ray (Записываем
580  // дистанцию от начала луча)
581  return true;
582 }
583 
584 //----- (004C1D2B) --------------------------------------------------------
585 bool Vis::CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint,
586  signed int sModelID) {
587  int v5; // esi@10
588  bool v6; // edi@10
589  signed int v10; // ebx@14
590  // int v15; // [sp+10h] [bp-Ch]@10
591  signed int v16; // [sp+18h] [bp-4h]@10
592 
593  int a = 0, b = 0;
594 
595  if (IntersectPoint.x < pFace->pBounding.x1 ||
596  IntersectPoint.x > pFace->pBounding.x2 ||
597  IntersectPoint.y < pFace->pBounding.y1 ||
598  IntersectPoint.y > pFace->pBounding.y2 ||
599  IntersectPoint.z < pFace->pBounding.z1 ||
600  IntersectPoint.z > pFace->pBounding.z2)
601  return false;
602 
603  if (sModelID != -1)
606  intersect_face_vertex_coords_list_b.data(), &IntersectPoint, pFace,
607  sModelID);
608  else
611  intersect_face_vertex_coords_list_b.data(), &IntersectPoint, pFace);
612  v5 = 2 * pFace->uNumVertices;
613  v16 = 0;
619  if (v5 <= 0) return false;
620  for (int i = 0; i < v5; ++i) {
621  if (v16 >= 2) break;
622  if (v6 ^ (intersect_face_vertex_coords_list_b[i + 1] >= b)) {
624  v10 = 0;
625  else
626  v10 = 2;
627  v10 |= intersect_face_vertex_coords_list_a[i] < a ? 1 : 0;
628  if (v10 != 3) {
629  if (!v10) {
630  ++v16;
631  } else {
632  int _v1 = fixpoint_div(
637  int _v2 =
639  _v1) +
640  32768;
641 
642  if (intersect_face_vertex_coords_list_a[i] + (_v2 >> 16) >=
643  a)
644  ++v16;
645  }
646  }
647  }
648  v6 = intersect_face_vertex_coords_list_b[i + 1] >= b;
649  }
650 
651  if (v16 != 1) return false;
652 
653  if (engine->config->show_picked_face)
654  pFace->uAttributes |= FACE_PICKED;
655 
656 
657  return true;
658  /*
659  int v5; // esi@10
660  bool v6; // edi@10
661  signed int v10; // ebx@14
662  int v11; // edi@16
663  signed int v12; // ST28_4@18
664  signed __int64 v13; // qtt@18
665  signed int result; // eax@21
666  int v15; // [sp+10h] [bp-Ch]@10
667  signed int v16; // [sp+18h] [bp-4h]@10
668 
669  int a = 0, b = 0;
670 
671  if (IntersectPoint.x < pFace->pBounding.x1 || IntersectPoint.x >
672  pFace->pBounding.x2 || IntersectPoint.y < pFace->pBounding.y1 ||
673  IntersectPoint.y > pFace->pBounding.y2 || IntersectPoint.z <
674  pFace->pBounding.z1 || IntersectPoint.z > pFace->pBounding.z2 ) return
675  false;
676 
677  pFace->uAttributes |= 0x80000000;
678 
679  if (uModelID != -1)
680  ODM_CreateIntersectFacesVertexCoordList(&a, &b,
681  intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b,
682  &IntersectPoint, pFace, uModelID);
683  else
684  BLV_CreateIntersectFacesVertexCoordList(&a, &b,
685  intersect_face_vertex_coords_list_a, intersect_face_vertex_coords_list_b,
686  &IntersectPoint, pFace);
687  v5 = 2 * pFace->uNumVertices;
688  v16 = 0;
689  intersect_face_vertex_coords_list_a[v5] =
690  intersect_face_vertex_coords_list_a[0];
691  intersect_face_vertex_coords_list_b[v5] =
692  intersect_face_vertex_coords_list_b[0]; v6 =
693  intersect_face_vertex_coords_list_b[0] >= b; if (v5 <= 0) return false; for
694  ( uint i = 0; i < v5; ++i )
695  {
696  if ( v16 >= 2 )
697  break;
698  if ( v6 ^ intersect_face_vertex_coords_list_b[i + 1] >= b )
699  {
700  if ( intersect_face_vertex_coords_list_a[i + 1] >= a )
701  v10 = 0;
702  else
703  v10 = 2;
704  v11 = v10 | intersect_face_vertex_coords_list_a[i] < a;
705  if ( v11 != 3 )
706  {
707  if ( !v11
708  || (v12 = intersect_face_vertex_coords_list_a[i + 1] -
709  intersect_face_vertex_coords_list_a[i], LODWORD(v13) = v12 << 16,
710  HIDWORD(v13) = v12 >> 16,
711  intersect_face_vertex_coords_list_a[i]
712  + ((signed int)(((unsigned __int64)(v13 /
713  (intersect_face_vertex_coords_list_b[i + 1] -
714  intersect_face_vertex_coords_list_b[i])
715  * (signed int)((b -
716  intersect_face_vertex_coords_list_b[i]) << 16)) >> 16) + 32768) >> 16) >= a)
717  )
718  ++v16;
719  }
720  }
721  v6 = intersect_face_vertex_coords_list_b[i + 1] >= b;
722  }
723  result = true;
724  if ( v16 != 1 )
725  result = false;
726  return result;
727  }*/
728 }
729 
730 //----- (004C1EE5) --------------------------------------------------------
732  int *a, int *b, __int16 *intersect_face_vertex_coords_list_a,
733  __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint,
734  BLVFace *pFace) {
735  if (pFace->uAttributes & FACE_XY_PLANE) {
736  *a = IntersectPoint->x;
737  *b = IntersectPoint->y;
738 
739  for (uint i = 0; i < pFace->uNumVertices; ++i) {
741  pFace->pXInterceptDisplacements[i] +
742  pIndoor->pVertices[pFace->pVertexIDs[i]].x;
744  pFace->pXInterceptDisplacements[i + 1] +
745  pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x;
746 
748  pFace->pYInterceptDisplacements[i] +
749  pIndoor->pVertices[pFace->pVertexIDs[i]].y;
751  pFace->pYInterceptDisplacements[i + 1] +
752  pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y;
753  }
754  } else if (pFace->uAttributes & FACE_XZ_PLANE) {
755  *a = IntersectPoint->x;
756  *b = IntersectPoint->z;
757 
758  for (uint i = 0; i < pFace->uNumVertices; ++i) {
760  pFace->pXInterceptDisplacements[i] +
761  pIndoor->pVertices[pFace->pVertexIDs[i]].x;
763  pFace->pXInterceptDisplacements[i + 1] +
764  pIndoor->pVertices[pFace->pVertexIDs[i + 1]].x;
765 
767  pFace->pZInterceptDisplacements[i] +
768  pIndoor->pVertices[pFace->pVertexIDs[i]].z;
770  pFace->pZInterceptDisplacements[i + 1] +
771  pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z;
772  }
773  } else if (pFace->uAttributes & FACE_YZ_PLANE) {
774  *a = IntersectPoint->y;
775  *b = IntersectPoint->z;
776 
777  for (uint i = 0; i < pFace->uNumVertices; ++i) {
779  pFace->pYInterceptDisplacements[i] +
780  pIndoor->pVertices[pFace->pVertexIDs[i]].y;
782  pFace->pYInterceptDisplacements[i + 1] +
783  pIndoor->pVertices[pFace->pVertexIDs[i + 1]].y;
784 
786  pFace->pZInterceptDisplacements[i] +
787  pIndoor->pVertices[pFace->pVertexIDs[i]].z;
789  pFace->pZInterceptDisplacements[i + 1] +
790  pIndoor->pVertices[pFace->pVertexIDs[i + 1]].z;
791  }
792  } else {
793  assert(false);
794  }
795 }
796 
797 //----- (004C2186) --------------------------------------------------------
800  __int16 *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint,
801  BLVFace *pFace, unsigned int uModelID) {
802  if (pFace->uAttributes & FACE_XY_PLANE) {
803  *a = IntersectPoint->x;
804  *b = IntersectPoint->y;
805 
806  for (int i = 0; i < pFace->uNumVertices; ++i) {
808  pFace->pXInterceptDisplacements[i] +
809  pOutdoor->pBModels[uModelID]
810  .pVertices.pVertices[pFace->pVertexIDs[i]]
811  .x;
813  pFace->pXInterceptDisplacements[i + 1] +
814  pOutdoor->pBModels[uModelID]
815  .pVertices.pVertices[pFace->pVertexIDs[i + 1]]
816  .x;
817 
819  pFace->pYInterceptDisplacements[i] +
820  pOutdoor->pBModels[uModelID]
821  .pVertices.pVertices[pFace->pVertexIDs[i]]
822  .y;
824  pFace->pYInterceptDisplacements[i + 1] +
825  pOutdoor->pBModels[uModelID]
826  .pVertices.pVertices[pFace->pVertexIDs[i + 1]]
827  .y;
828  }
829  } else if (pFace->uAttributes & FACE_XZ_PLANE) {
830  *a = IntersectPoint->x;
831  *b = IntersectPoint->z;
832 
833  for (int i = 0; i < pFace->uNumVertices; ++i) {
835  pFace->pXInterceptDisplacements[i] +
836  pOutdoor->pBModels[uModelID]
837  .pVertices.pVertices[pFace->pVertexIDs[i]]
838  .x;
840  pFace->pXInterceptDisplacements[i + 1] +
841  pOutdoor->pBModels[uModelID]
842  .pVertices.pVertices[pFace->pVertexIDs[i + 1]]
843  .x;
844 
846  pFace->pZInterceptDisplacements[i] +
847  pOutdoor->pBModels[uModelID]
848  .pVertices.pVertices[pFace->pVertexIDs[i]]
849  .z;
851  pFace->pZInterceptDisplacements[i + 1] +
852  pOutdoor->pBModels[uModelID]
853  .pVertices.pVertices[pFace->pVertexIDs[i + 1]]
854  .z;
855  }
856  } else if (pFace->uAttributes & FACE_YZ_PLANE) {
857  *a = IntersectPoint->y;
858  *b = IntersectPoint->z;
859 
860  for (int i = 0; i < pFace->uNumVertices; ++i) {
862  pFace->pYInterceptDisplacements[i] +
863  pOutdoor->pBModels[uModelID]
864  .pVertices.pVertices[pFace->pVertexIDs[i]]
865  .y;
867  pFace->pYInterceptDisplacements[i + 1] +
868  pOutdoor->pBModels[uModelID]
869  .pVertices.pVertices[pFace->pVertexIDs[i + 1]]
870  .y;
871 
873  pFace->pZInterceptDisplacements[i] +
874  pOutdoor->pBModels[uModelID]
875  .pVertices.pVertices[pFace->pVertexIDs[i]]
876  .z;
878  pFace->pZInterceptDisplacements[i + 1] +
879  pOutdoor->pBModels[uModelID]
880  .pVertices.pVertices[pFace->pVertexIDs[i + 1]]
881  .z;
882  }
883  } else {
884  assert(false);
885  }
886 }
887 
888 //----- (0046A0A1) --------------------------------------------------------
889 int UnprojectX(int x) {
890  int v3; // [sp-4h] [bp-8h]@5
891 
893  // if ( render->pRenderD3D )
895  // else
896  // v3 = pIndoorCamera->fov_rad;
897  } else {
899  }
902 }
903 
904 //----- (0046A0F6) --------------------------------------------------------
905 int UnprojectY(int y) {
906  int v3; // [sp-4h] [bp-8h]@5
907 
909  // if ( render->pRenderD3D )
911  // else
912  // v3 = pIndoorCamera->fov_rad;
913  } else {
915  }
918 }
919 
920 //----- (004C248E) --------------------------------------------------------
921 void Vis::CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY,
922  float fPickDepth) {
923  int pRotY; // esi@1
924  Vec3_int_ pStartR; // ST08_12@1
925  int pRotX; // ST04_4@1
926  RenderVertexSoft v11[2]; // [sp+2Ch] [bp-74h]@1
927  int outx;
928  int outz; // [sp+94h] [bp-Ch]@1
929  int outy; // [sp+98h] [bp-8h]@1
930 
931  pRotY = pIndoorCameraD3D->sRotationY + UnprojectX(fMouseX);
932  pRotX = -pIndoorCameraD3D->sRotationX + UnprojectY(fMouseY);
933 
934  // log->Info(L"Roty: %d, Rotx: %d", pRotY, pRotX);
935 
936  pStartR.z = pIndoorCameraD3D->vPartyPos.z;
937  pStartR.x = pIndoorCameraD3D->vPartyPos.x;
938  pStartR.y = pIndoorCameraD3D->vPartyPos.y;
939 
940  v11[1].vWorldPosition.x = (double)pIndoorCameraD3D->vPartyPos.x;
941  v11[1].vWorldPosition.y = (double)pIndoorCameraD3D->vPartyPos.y;
942  v11[1].vWorldPosition.z = (double)pIndoorCameraD3D->vPartyPos.z;
943 
944  int depth = fixpoint_from_float(fPickDepth);
945  Vec3_int_::Rotate(depth, pRotY, pRotX, pStartR, &outx, &outy, &outz);
946 
947  v11[0].vWorldPosition.x = (double)outx;
948  v11[0].vWorldPosition.y = (double)outy;
949  v11[0].vWorldPosition.z = (double)outz;
950 
951  memcpy(pRay + 0, &v11[1], sizeof(RenderVertexSoft));
952  memcpy(pRay + 1, &v11[0], sizeof(RenderVertexSoft));
953 }
954 
955 //----- (004C2551) --------------------------------------------------------
957  int pid) {
958  // unsigned int v3; // esi@1
959  // signed int v4; // edx@1
960  // char *v5; // eax@2
961  // Vis_ObjectInfo *result; // eax@6
962 
963  // v3 = this->uNumPointers;
964  if (this->uNumPointers > 0) {
965  for (uint i = 0; i < this->uNumPointers; ++i) {
966  if (this->object_pool[i].object_type == pVisObjectType &&
967  this->object_pool[i].object_pid == pid)
968  return &this->object_pool[i];
969  }
970  }
971  return nullptr;
972 }
973 
974 //----- (004C2591) --------------------------------------------------------
976  switch (type) {
977  case All: {
978  for (uint i = 0; i < uNumPointers; ++i)
979  object_pointers[i] = &object_pool[i];
980  } break;
981 
982  case Unique: // seems quite retarted; the inner if condition will never
983  // trigger, since we compare pointers, not values.
984  // pointers will always be unique
985  { // but it may be decompilation error thou
986  bool create = true;
987 
988  for (uint i = 0; i < uNumPointers; ++i) {
989  for (uint j = 0; j < i; ++j) {
990  if (object_pointers[j] == &object_pool[i]) {
991  create = false;
992  break;
993  }
994  }
995 
996  if (create) object_pointers[i] = &object_pool[i];
997  }
998  } break;
999 
1000  default:
1001  logger->Warning(
1002  L"Unknown pointer creation flag passed to "
1003  L"::create_object_pointers()");
1004  }
1005 }
1006 
1007 //----- (004C264A) --------------------------------------------------------
1009  int end) { // сортировка
1010  int sort_start; // edx@1
1011  int forward_sort_index; // esi@2
1012  signed int backward_sort_index; // ecx@2
1013  unsigned int last_z_val; // eax@3
1014  unsigned int more_lz_val; // ebx@4
1015  unsigned int less_lz_val; // ebx@6
1016  Vis_ObjectInfo *temp_pointer; // eax@7
1017  // Vis_ObjectInfo *a3a; // [sp+14h] [bp+Ch]@2
1018 
1019  sort_start = start;
1020 
1021  if (end > start) {
1022  do {
1023  forward_sort_index = sort_start - 1;
1024  backward_sort_index = end;
1025  do {
1026  last_z_val = pPointers[end]->depth;
1027  do {
1028  ++forward_sort_index;
1029  more_lz_val = pPointers[forward_sort_index]->depth;
1030  } while (more_lz_val < last_z_val);
1031 
1032  do {
1033  if (backward_sort_index < 1) break;
1034  --backward_sort_index;
1035  less_lz_val = pPointers[backward_sort_index]->depth;
1036  } while (less_lz_val > last_z_val);
1037 
1038  temp_pointer = pPointers[forward_sort_index];
1039  if (forward_sort_index >= backward_sort_index) {
1040  pPointers[forward_sort_index] = pPointers[end];
1041  pPointers[end] = temp_pointer;
1042  } else {
1043  pPointers[forward_sort_index] =
1044  pPointers[backward_sort_index];
1045  pPointers[backward_sort_index] = temp_pointer;
1046  }
1047  } while (forward_sort_index < backward_sort_index);
1048 
1049  sort_object_pointers(pPointers, sort_start, forward_sort_index - 1);
1050  sort_start = forward_sort_index + 1;
1051  } while (end > forward_sort_index + 1);
1052  }
1053 }
1054 
1055 //----- (004C26D0) --------------------------------------------------------
1056 void Vis::SortVerticesByX(RenderVertexD3D3 *pArray, unsigned int uStart,
1057  unsigned int uEnd) {
1058  unsigned int left_sort_index; // ebx@2
1059  RenderVertexD3D3 temp_array; // [sp+4h] [bp-4Ch]@8
1060  RenderVertexD3D3 max_array; // [sp+24h] [bp-2Ch]@2
1061  unsigned int right_sort_index; // [sp+4Ch] [bp-4h]@2
1062 
1063  if ((signed int)uEnd > (signed int)uStart) {
1064  left_sort_index = uStart - 1;
1065  right_sort_index = uEnd;
1066  while (1) {
1067  memcpy(&max_array, &pArray[uEnd], sizeof(max_array));
1068  do {
1069  ++left_sort_index;
1070  } while (pArray[left_sort_index].pos.x < (double)max_array.pos.x);
1071  do {
1072  --right_sort_index;
1073  } while (pArray[right_sort_index].pos.x > (double)max_array.pos.x);
1074  if ((signed int)left_sort_index >= (signed int)right_sort_index)
1075  break;
1076  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1077  memcpy(&pArray[left_sort_index], &pArray[right_sort_index],
1078  sizeof(pArray[left_sort_index]));
1079  memcpy(&pArray[right_sort_index], &temp_array,
1080  sizeof(pArray[right_sort_index]));
1081  }
1082  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1083  memcpy(&pArray[left_sort_index], &pArray[uEnd],
1084  sizeof(pArray[left_sort_index]));
1085  memcpy(&pArray[uEnd], &temp_array, sizeof(pArray[uEnd]));
1086  SortVerticesByX(pArray, uStart, left_sort_index - 1);
1087  SortVerticesByX(pArray, left_sort_index + 1, uEnd);
1088  }
1089 }
1090 
1091 //----- (004C27AD) --------------------------------------------------------
1092 void Vis::SortVerticesByY(RenderVertexD3D3 *pArray, unsigned int uStart,
1093  unsigned int uEnd) {
1094  unsigned int left_sort_index; // ebx@2
1095  RenderVertexD3D3 temp_array; // [sp+4h] [bp-4Ch]@8
1096  RenderVertexD3D3 max_array; // [sp+24h] [bp-2Ch]@2
1097  unsigned int right_sort_index; // [sp+4Ch] [bp-4h]@2
1098 
1099  if ((signed int)uEnd > (signed int)uStart) {
1100  left_sort_index = uStart - 1;
1101  right_sort_index = uEnd;
1102  while (1) {
1103  memcpy(&max_array, &pArray[uEnd], sizeof(max_array));
1104  do {
1105  ++left_sort_index;
1106  } while (pArray[left_sort_index].pos.y < (double)max_array.pos.y);
1107  do {
1108  --right_sort_index;
1109  } while (pArray[right_sort_index].pos.y > (double)max_array.pos.y);
1110  if ((signed int)left_sort_index >= (signed int)right_sort_index)
1111  break;
1112  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1113  memcpy(&pArray[left_sort_index], &pArray[right_sort_index],
1114  sizeof(pArray[left_sort_index]));
1115  memcpy(&pArray[right_sort_index], &temp_array,
1116  sizeof(pArray[right_sort_index]));
1117  }
1118  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1119  memcpy(&pArray[left_sort_index], &pArray[uEnd],
1120  sizeof(pArray[left_sort_index]));
1121  memcpy(&pArray[uEnd], &temp_array, sizeof(pArray[uEnd]));
1122  SortVerticesByY(pArray, uStart, left_sort_index - 1);
1123  SortVerticesByY(pArray, left_sort_index + 1, uEnd);
1124  }
1125 }
1126 
1127 //----- (004C288E) --------------------------------------------------------
1129  RenderVertexSoft *pArray, int start,
1130  int end) { // сортировка по возрастанию экранных координат х
1131  int left_sort_index; // ebx@2
1132  int right_sort_index; // ecx@2
1133  RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8
1134  RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2
1135 
1136  if (end > start) {
1137  left_sort_index = start - 1;
1138  right_sort_index = end;
1139  memcpy(&max_array, &pArray[end], sizeof(max_array));
1140  while (1) {
1141  do {
1142  ++left_sort_index;
1143  } while (pArray[left_sort_index].vWorldViewProjX <
1144  (double)max_array.vWorldViewProjX);
1145  do {
1146  --right_sort_index;
1147  } while (pArray[right_sort_index].vWorldViewProjX >
1148  (double)max_array.vWorldViewProjX);
1149  if (left_sort_index >= right_sort_index) break;
1150  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1151  memcpy(&pArray[left_sort_index], &pArray[right_sort_index],
1152  sizeof(pArray[left_sort_index]));
1153  memcpy(&pArray[right_sort_index], &temp_array,
1154  sizeof(pArray[right_sort_index]));
1155  }
1156  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1157  memcpy(&pArray[left_sort_index], &pArray[end],
1158  sizeof(pArray[left_sort_index]));
1159  memcpy(&pArray[end], &temp_array, sizeof(pArray[end]));
1160  Vis::SortByScreenSpaceX(pArray, start, left_sort_index - 1);
1161  Vis::SortByScreenSpaceX(pArray, left_sort_index + 1, end);
1162  }
1163 }
1164 
1165 //----- (004C297E) --------------------------------------------------------
1167  int left_sort_index; // ebx@2
1168  int right_sort_index; // ecx@2
1169  RenderVertexSoft temp_array; // [sp+4h] [bp-6Ch]@8
1170  RenderVertexSoft max_array; // [sp+34h] [bp-3Ch]@2
1171 
1172  if (end > start) {
1173  left_sort_index = start - 1;
1174  right_sort_index = end;
1175  memcpy(&max_array, &pArray[end], sizeof(max_array));
1176  while (1) {
1177  do {
1178  ++left_sort_index;
1179  } while (pArray[left_sort_index].vWorldViewProjY <
1180  (double)max_array.vWorldViewProjY);
1181  do {
1182  --right_sort_index;
1183  } while (pArray[right_sort_index].vWorldViewProjY >
1184  (double)max_array.vWorldViewProjY);
1185  if (left_sort_index >= right_sort_index) break;
1186  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1187  memcpy(&pArray[left_sort_index], &pArray[right_sort_index],
1188  sizeof(pArray[left_sort_index]));
1189  memcpy(&pArray[right_sort_index], &temp_array,
1190  sizeof(pArray[right_sort_index]));
1191  }
1192  memcpy(&temp_array, &pArray[left_sort_index], sizeof(temp_array));
1193  memcpy(&pArray[left_sort_index], &pArray[end],
1194  sizeof(pArray[left_sort_index]));
1195  memcpy(&pArray[end], &temp_array, sizeof(pArray[end]));
1196  Vis::SortByScreenSpaceY(pArray, start, left_sort_index - 1);
1197  Vis::SortByScreenSpaceY(pArray, left_sort_index + 1, end);
1198  }
1199 }
1200 
1201 //----- (004C04AF) --------------------------------------------------------
1203  this->log = EngineIoc::ResolveLogger();
1204 
1205 
1206  RenderVertexSoft v3; // [sp+Ch] [bp-60h]@1
1207  RenderVertexSoft v4; // [sp+3Ch] [bp-30h]@1
1208 
1209  v3.flt_2C = 0.0;
1210  v3.vWorldPosition.x = 0.0;
1211  v3.vWorldPosition.y = 65536.0;
1212  v3.vWorldPosition.z = 0.0;
1213  v4.flt_2C = 0.0;
1214  v4.vWorldPosition.x = 65536.0;
1215  v4.vWorldPosition.y = 0.0;
1216  v4.vWorldPosition.z = 0.0;
1217  memcpy(&stru_200C, &v4, sizeof(stru_200C));
1218 
1219  v4.flt_2C = 0.0;
1220  v4.vWorldPosition.x = 0.0;
1221  v4.vWorldPosition.y = 65536.0;
1222  v4.vWorldPosition.z = 0.0;
1223  memcpy(&stru_203C, &v3, sizeof(stru_203C));
1224 
1225  v3.flt_2C = 0.0;
1226  v3.vWorldPosition.x = 65536.0;
1227  v3.vWorldPosition.y = 0.0;
1228  v3.vWorldPosition.z = 0.0;
1229  memcpy(&stru_206C, &v3, sizeof(stru_206C));
1230  memcpy(&stru_209C, &v4, sizeof(stru_209C));
1231 
1232  keyboard_pick_depth = 512;
1233 }
1234 
1235 //----- (004C055C) --------------------------------------------------------
1237  for (uint i = 0; i < 512; ++i) {
1238  object_pool[i].object = nullptr;
1239  object_pool[i].depth = -1;
1240  object_pool[i].object_pid = PID_INVALID;
1242  }
1243  uNumPointers = 0;
1244 }
1245 
1246 //----- (004C05CC) --------------------------------------------------------
1248  Vis_SelectionFilter *sprite_filter,
1249  Vis_SelectionFilter *face_filter) {
1250  if (!list) list = &default_list;
1251  list->uNumPointers = 0;
1252 
1253  PickBillboards_Keyboard(keyboard_pick_depth, list, sprite_filter);
1255  PickIndoorFaces_Keyboard(keyboard_pick_depth, list, face_filter);
1257  PickOutdoorFaces_Keyboard(keyboard_pick_depth, list, face_filter);
1258  else
1259  assert(false);
1260 
1262  sort_object_pointers(list->object_pointers, 0, list->uNumPointers - 1);
1263 
1264  return true;
1265 }
1266 
1267 //----- (004C0646) --------------------------------------------------------
1268 bool Vis::PickMouse(float fDepth, float fMouseX, float fMouseY,
1269  Vis_SelectionFilter *sprite_filter,
1270  Vis_SelectionFilter *face_filter) {
1271  RenderVertexSoft pMouseRay[2]; // [sp+1Ch] [bp-60h]@1
1272 
1274  CastPickRay(pMouseRay, fMouseX, fMouseY, fDepth);
1275 
1276  // log->Info(L"Sx: %f, Sy: %f, Sz: %f \n Fx: %f, Fy: %f, Fz: %f", pMouseRay->vWorldPosition.x, pMouseRay->vWorldPosition.y, pMouseRay->vWorldPosition.z,
1277  // (pMouseRay+1)->vWorldPosition.x, (pMouseRay + 1)->vWorldPosition.y, (pMouseRay + 1)->vWorldPosition.z);
1278 
1279  PickBillboards_Mouse(fDepth, fMouseX, fMouseY, &default_list, sprite_filter);
1280 
1282  PickIndoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter);
1283  } else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) {
1284  PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter,
1285  false);
1286  } else {
1287  log->Warning(
1288  L"Picking mouse in undefined level"); // picking in main menu is
1289  // default (buggy) game
1290  // behaviour. should've
1291  // returned false in
1292  // Game::PickMouse
1293  return false;
1294  }
1298 
1299  return true;
1300 }
1301 
1302 //----- (004C06F8) --------------------------------------------------------
1305  for (uint i = 0; i < render->uNumBillboardsToDraw; ++i) {
1306  RenderBillboardD3D *d3d_billboard = &render->pBillboardRenderListD3D[i];
1307 
1308  if (is_part_of_selection((void *)i, filter)) {
1309  if (DoesRayIntersectBillboard(pick_depth, i)) {
1310  RenderBillboard *billboard =
1311  &pBillboardRenderList[d3d_billboard->sParentBillboardID];
1312 
1313  list->AddObject((void *)d3d_billboard->sParentBillboardID,
1315  billboard->object_pid);
1316  }
1317  }
1318  }
1319 }
1320 
1321 // tests the object against selection filter to determine whether it can be
1322 // picked or not
1323 //----- (004C0791) --------------------------------------------------------
1324 bool Vis::is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace,
1326  switch (filter->object_type) {
1327  case VisObjectType_Any:
1328  return true;
1329 
1330  case VisObjectType_Sprite: {
1331  // v5 = filter->select_flags;
1332  int object_idx = PID_ID(
1334  [render
1335  ->pBillboardRenderListD3D[(
1336  int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace]
1337  .sParentBillboardID]
1338  .object_pid);
1339  int object_type = PID_TYPE(
1341  [render
1342  ->pBillboardRenderListD3D[(
1343  int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace]
1344  .sParentBillboardID]
1345  .object_pid);
1346  if (filter->select_flags & 2) {
1347  if (object_type == filter->object_id) return false;
1348  return true;
1349  }
1350  if (filter->select_flags & 4) {
1351  // v8 = filter->object_id;
1352  if (object_type != filter->object_id) return true;
1353  if (filter->object_id != OBJECT_Decoration) {
1354  log->Warning(
1355  L"Unsupported \"exclusion if no event\" type in "
1356  L"CVis::is_part_of_selection");
1357  return true;
1358  }
1359  if (pLevelDecorations[object_idx].uCog ||
1360  pLevelDecorations[object_idx].uEventID)
1361  return true;
1362  return pLevelDecorations[object_idx].IsInteractive();
1363  }
1364  if (object_type == filter->object_id) {
1365  if (object_type != OBJECT_Actor) {
1366  log->Warning(L"Default case reached in VIS");
1367  return true;
1368  }
1369 
1370  // v10 = &pActors[object_idx];
1371  int result = 1 << HEXRAYS_LOBYTE(pActors[object_idx].uAIState);
1372  if (result & filter->no_at_ai_state ||
1373  !(result & filter->at_ai_state) ||
1374  filter->select_flags & 8 &&
1376  pActors[object_idx].pMonsterInfo.uID,
1377  MONSTER_SUPERTYPE_UNDEAD)) == 0)
1378  return false;
1379  if (!(filter->select_flags & 1)) return true;
1380 
1381  result = pActors[object_idx].GetActorsRelation(nullptr);
1382  if (result == 0) return false;
1383  return true;
1384  }
1385  return false;
1386  }
1387 
1388  case VisObjectType_Face: {
1389  uint face_attrib = 0;
1390  bool no_event = true;
1392  ODMFace *face = (ODMFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace;
1393  no_event = face->sCogTriggeredID == 0;
1394  face_attrib = face->uAttributes;
1395  } else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) {
1396  BLVFace *face = (BLVFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace;
1397  no_event = pIndoor->pFaceExtras[face->uFaceExtraID].uEventID == 0;
1398  face_attrib = face->uAttributes;
1399  } else {
1400  assert(false);
1401  }
1402 
1403  if (filter->object_id != OBJECT_BLVDoor) return true;
1404  if (no_event ||
1405  face_attrib &
1406  filter->no_at_ai_state) // face_attrib = 0x2009408 incorrect
1407  return false;
1408  return (face_attrib & filter->at_ai_state) != 0;
1409  }
1410 
1411  default:
1412  assert(false);
1413  return false;
1414  }
1415 }
1416 
1417 //----- (004C091D) --------------------------------------------------------
1419  unsigned int uD3DBillboardIdx) {
1420  int v3; // eax@3
1421  // signed int v5; // ecx@4
1422  // float v6; // ST04_4@6
1423  // float v7; // ST00_4@7
1424  // int v8; // eax@10
1425  // unsigned int v9; // eax@12
1426  // int v10; // eax@17
1427  // double v11; // st6@18
1428  // double v12; // st7@18
1429  // double v13; // st4@18
1430  // float v14; // ST0C_4@22
1431  // float v15; // ST08_4@22
1432  // float v16; // ST04_4@23
1433  // float v17; // ST00_4@24
1434  // signed int v18; // eax@27
1435  // unsigned int v19; // eax@29
1436  // double v20; // st6@32
1437  // double v21; // st7@32
1438  // int v22; // eax@32
1439  // double v23; // st7@36
1440  // void *v24; // esi@40
1441  // float v25; // ST08_4@40
1442  // float v26; // ST04_4@41
1443  // float v27; // ST00_4@42
1444  // int v28; // eax@45
1445  // unsigned int v29; // eax@47
1446  // char result; // al@48
1447  struct RenderVertexSoft pPickingRay[2];
1448  // int v31; // [sp+20h] [bp-DCh]@5
1449  struct RenderVertexSoft local_80[2];
1450 
1451  float test_x;
1452  float test_y;
1453 
1454  float t1_x;
1455  float t1_y;
1456  float t2_x;
1457  float t2_y;
1458  float swap_temp;
1459  // int v37; // [sp+F0h] [bp-Ch]@5
1460 
1461  signed int v40; // [sp+108h] [bp+Ch]@17
1462 
1463  /*static*/ Vis_SelectionList Vis_static_stru_F91E10;
1464  Vis_static_stru_F91E10.uNumPointers = 0;
1465  v3 = render->pBillboardRenderListD3D[uD3DBillboardIdx].sParentBillboardID;
1466  if (v3 == -1) return false;
1467 
1468  if (pBillboardRenderList[v3].screen_space_z > fDepth) return false;
1469 
1470  GetPolygonCenter(render->pBillboardRenderListD3D[/*v3*/uD3DBillboardIdx].pQuads, 4, &test_x, &test_y);
1471  // why check parent id v3? parent ID are wrong becasue of switching between pBillboardRenderListD3D and pBillboardRenderList
1472 
1473  CastPickRay(pPickingRay, test_x, test_y, fDepth);
1475  PickIndoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10,
1476  &vis_face_filter);
1477  else
1478  PickOutdoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10,
1479  &vis_face_filter, false);
1480  Vis_static_stru_F91E10.create_object_pointers();
1481  sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0,
1482  Vis_static_stru_F91E10.uNumPointers - 1);
1483  if (Vis_static_stru_F91E10.uNumPointers) {
1484  if (Vis_static_stru_F91E10.object_pointers[0]->depth >
1486  return true;
1487  } else if ((double)(pViewport->uScreen_TL_X) <= test_x &&
1488  (double)pViewport->uScreen_BR_X >= test_x &&
1489  (double)pViewport->uScreen_TL_Y <= test_y &&
1490  (double)pViewport->uScreen_BR_Y >= test_y) {
1491  return true;
1492  }
1493 
1494  for (v40 = 0; v40 < 4; ++v40) {
1495  test_x =
1496  render->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[v40].pos.x;
1497  test_y =
1498  render->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[v40].pos.y;
1499  if ((double)(pViewport->uScreen_TL_X) <= test_x &&
1500  (double)pViewport->uScreen_BR_X >= test_x &&
1501  (double)pViewport->uScreen_TL_Y <= test_y &&
1502  (double)pViewport->uScreen_BR_Y >= test_y) {
1503  CastPickRay(local_80, test_x, test_y, fDepth);
1505  PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10,
1506  &vis_face_filter);
1507  else
1508  PickOutdoorFaces_Mouse(fDepth, local_80,
1509  &Vis_static_stru_F91E10,
1510  &vis_face_filter, false);
1511  Vis_static_stru_F91E10.create_object_pointers();
1512  sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0,
1513  Vis_static_stru_F91E10.uNumPointers - 1);
1514  if (!Vis_static_stru_F91E10.uNumPointers) return true;
1515  if (Vis_static_stru_F91E10.object_pointers[0]->depth >
1517  return true;
1518  }
1519  }
1520 
1521  if (v40 >= 4) {
1522  // if (uCurrentlyLoadedLevelType != LEVEL_Outdoor) return false;
1523  t1_x =
1524  render->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[0].pos.x;
1525  t2_x =
1526  render->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[3].pos.x;
1527 
1528  t1_y =
1529  render->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[0].pos.y;
1530  t2_y =
1531  render->pBillboardRenderListD3D[uD3DBillboardIdx].pQuads[1].pos.y;
1532  if (t1_x > t2_x) {
1533  swap_temp = t1_x;
1534  t1_x = t2_x;
1535  t2_x = swap_temp;
1536  }
1537  if (t1_y > t2_y)
1538  test_y = t1_y;
1539  else
1540  test_y = t2_y;
1541 
1542  Vis_static_stru_F91E10.uNumPointers = 0;
1543 
1544  test_x = (t2_x - t1_x) * 0.5;
1545  if ((double)(pViewport->uScreen_TL_X) <= test_x &&
1546  (double)pViewport->uScreen_BR_X >= test_x &&
1547  (double)pViewport->uScreen_TL_Y <= test_y &&
1548  (double)pViewport->uScreen_BR_Y >= test_y) {
1549  CastPickRay(local_80, test_x, test_y, fDepth);
1551  PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10,
1552  &vis_face_filter);
1553  else
1554  PickOutdoorFaces_Mouse(fDepth, local_80,
1555  &Vis_static_stru_F91E10,
1556  &vis_face_filter, false);
1557  Vis_static_stru_F91E10.create_object_pointers();
1558  sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0,
1559  Vis_static_stru_F91E10.uNumPointers - 1);
1560  if (!Vis_static_stru_F91E10.uNumPointers) return true;
1561  if (Vis_static_stru_F91E10.object_pointers[0]->depth >
1563  return true;
1564  }
1565  }
1566  return false;
1567 }
1568 // F93E18: using guessed type char static_byte_F93E18_init;
1569 
1570 //----- (004C0D32) --------------------------------------------------------
1573  int result; // eax@1
1574  signed int pFaceID; // esi@2
1575  BLVFace *pFace; // edi@4
1576  // unsigned int v7; // eax@6
1577  Vis_ObjectInfo *v8; // eax@6
1578  signed int i; // [sp+18h] [bp-8h]@1
1579 
1580  result = 0;
1581  for (i = 0; i < (signed int)pBspRenderer->num_faces; ++i) {
1582  pFaceID = pBspRenderer->faces[result].uFaceID;
1583  if (pFaceID >= 0) {
1584  if (pFaceID < (signed int)pIndoor->uNumFaces) {
1585  pFace = &pIndoor->pFaces[pFaceID];
1586  if (!pIndoorCameraD3D->IsCulled(&pIndoor->pFaces[pFaceID])) {
1587  if (is_part_of_selection(pFace, filter)) {
1589  pFace, PID(OBJECT_BModel, pFaceID), pick_depth);
1590  if (v8)
1591  list->AddObject(v8->object, v8->object_type,
1592  v8->depth, v8->object_pid);
1593  }
1594  }
1595  }
1596  }
1597  result = i + 1;
1598  }
1599 }
1600 
1603  for (BSPModel &model : pOutdoor->pBModels) {
1604  int reachable;
1605  if (IsBModelVisible(&model, &reachable)) {
1606  if (reachable) {
1607  for (ODMFace &face : model.pFaces) {
1608  if (is_part_of_selection(&face, filter)) {
1609  BLVFace blv_face;
1610  blv_face.FromODM(&face);
1611 
1612  int pid =
1613  PID(OBJECT_BModel, face.index | (model.index << 6));
1614  if (Vis_ObjectInfo *object_info =
1615  DetermineFacetIntersection(&blv_face, pid,
1616  pick_depth)) {
1617  list->AddObject(
1618  object_info->object, object_info->object_type,
1619  object_info->depth, object_info->object_pid);
1620  }
1621  }
1622  }
1623  }
1624  }
1625  }
1626 }
Vis::IsPolygonOccludedByBillboard
bool IsPolygonOccludedByBillboard(struct RenderVertexSoft *vertices, int num_vertices, float x, float y)
Definition: Vis.cpp:132
Vis_SelectionList::SelectionPointers
Vis_ObjectInfo * SelectionPointers(int a2, int a3)
Definition: Vis.cpp:956
MONSTER_SUPERTYPE_UNDEAD
@ MONSTER_SUPERTYPE_UNDEAD
Definition: Monsters.h:70
BLVFace::Portal
bool Portal() const
Definition: Indoor.h:448
Engine_::IocContainer
Definition: IocContainer.h:15
face
GLenum GLuint GLint GLenum face
Definition: SDL_opengl_glext.h:3022
Vis::PickIndoorFaces_Mouse
void PickIndoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter)
Definition: Vis.cpp:305
IocContainer.h
pLevelDecorations
std::array< LevelDecoration, 3000 > pLevelDecorations
Definition: Decoration.cpp:8
Vis::SortByScreenSpaceX
void SortByScreenSpaceX(struct RenderVertexSoft *pArray, int start, int end)
Definition: Vis.cpp:1128
int16_t
signed __int16 int16_t
Definition: SDL_config.h:36
Viewport.h
BLVFace::uNumVertices
uint8_t uNumVertices
Definition: Indoor.h:488
IndoorCameraD3D::sRotationY
int sRotationY
Definition: IndoorCameraD3D.h:247
v
const GLdouble * v
Definition: SDL_opengl.h:2064
Vis::IsPointInsideD3DBillboard
bool IsPointInsideD3DBillboard(struct RenderBillboardD3D *a1, float x, float y)
Definition: Vis.cpp:251
LOD.h
Vis_SelectionFilter::no_at_ai_state
int no_at_ai_state
Definition: Vis.h:16
Vis::log
Log * log
Definition: Vis.h:156
Vec2::x
T x
Definition: VectorTypes.h:12
BspRenderer::num_faces
unsigned int num_faces
Definition: Indoor.h:812
Vis::is_part_of_selection
bool is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, Vis_SelectionFilter *filter)
Definition: Vis.cpp:1324
OutdoorLocation::pBModels
BSPModelList pBModels
Definition: Outdoor.h:119
Vis::stru_200C
RenderVertexSoft stru_200C
Definition: Vis.h:150
pSprites_LOD
LODFile_Sprites * pSprites_LOD
Definition: LOD.cpp:20
BLVFace::pVertexIDs
uint16_t * pVertexIDs
Definition: Indoor.h:476
vis_sprite_filter_1
Vis_SelectionFilter vis_sprite_filter_1
Definition: Vis.cpp:22
end
GLuint GLuint end
Definition: SDL_opengl.h:1571
OBJECT_Item
@ OBJECT_Item
Definition: Actor.h:66
Vec3_float_::x
float x
Definition: VectorTypes.h:89
BSPModel::index
unsigned int index
Definition: BSPModel.h:167
vis_sprite_filter_3
Vis_SelectionFilter vis_sprite_filter_3
Definition: Vis.cpp:30
Vis_ObjectInfo::object_pid
uint16_t object_pid
Definition: Vis.h:33
RenderVertexD3D3::pos
Vec3_float_ pos
Definition: IRender.h:130
Vis::CheckIntersectBModel
bool CheckIntersectBModel(BLVFace *pFace, Vec3_short_ IntersectPoint, signed int sModelID)
Definition: Vis.cpp:585
Engine_::IocContainer::ResolveLogger
static Log * ResolveLogger()
Definition: IocContainer.cpp:51
Vis_SelectionList::AddObject
void AddObject(void *object, VisObjectType type, int depth, int pid)
Definition: Vis.h:51
fixpoint_div
__int64 fixpoint_div(int a1, int a2)
Definition: OurMath.cpp:147
BBox_short_::x1
int16_t x1
Definition: VectorTypes.h:114
BLVFace::pXInterceptDisplacements
int16_t * pXInterceptDisplacements
Definition: Indoor.h:477
engine
std::shared_ptr< Engine > engine
Definition: Engine.cpp:130
IndoorLocation::pFaceExtras
struct BLVFaceExtra * pFaceExtras
Definition: Indoor.h:632
RenderBillboardD3D
Definition: IRender.h:138
vis_face_filter
Vis_SelectionFilter vis_face_filter
Definition: Vis.cpp:26
Vis::CastPickRay
void CastPickRay(RenderVertexSoft *pRay, float fMouseX, float fMouseY, float fPickDepth)
Definition: Vis.cpp:921
stru193_math::uIntegerHalfPi
static const unsigned int uIntegerHalfPi
Definition: OurMath.h:89
BLVFaceExtra::uEventID
uint16_t uEventID
Definition: Indoor.h:512
Vis_SelectionList::object_pool
Vis_ObjectInfo object_pool[512]
Definition: Vis.h:61
BLVFace::FromODM
void FromODM(struct ODMFace *face)
Definition: Indoor.cpp:372
IndoorCameraD3D::sRotationX
int sRotationX
Definition: IndoorCameraD3D.h:248
Viewport::uScreen_TL_X
int uScreen_TL_X
Definition: Viewport.h:18
RenderVertexD3D3
Definition: IRender.h:129
BBox_short_::y1
int16_t y1
Definition: VectorTypes.h:116
Vis::get_object_zbuf_val
int get_object_zbuf_val(Vis_ObjectInfo *info)
Definition: Vis.cpp:494
RenderBillboard::screen_space_z
int16_t screen_space_z
Definition: IRender.h:41
LODSpriteHeader::uWidth
uint16_t uWidth
Definition: LOD.h:186
ODMFace::sCogTriggeredID
int16_t sCogTriggeredID
Definition: BSPModel.h:147
OBJECT_Decoration
@ OBJECT_Decoration
Definition: Actor.h:69
VisObjectType_Any
@ VisObjectType_Any
Definition: Vis.h:5
Sprite::texture
Texture * texture
Definition: Sprites.h:28
vis_door_filter
Vis_SelectionFilter vis_door_filter
Definition: Vis.cpp:28
Vec3_float_::y
float y
Definition: VectorTypes.h:90
Vec3_float_::z
float z
Definition: VectorTypes.h:91
Vis_SelectionFilter::at_ai_state
int at_ai_state
Definition: Vis.h:15
RenderVertexSoft::vWorldViewProjY
float vWorldViewProjY
Definition: IRender.h:119
Vis::get_picked_object_zbuf_val
int get_picked_object_zbuf_val()
Definition: Vis.cpp:517
BBox_short_::z2
int16_t z2
Definition: VectorTypes.h:119
Vis::GetPolygonCenter
void GetPolygonCenter(struct RenderVertexD3D3 *pVertices, unsigned int uNumVertices, float *pCenterX, float *pCenterY)
Definition: Vis.cpp:185
UnprojectX
int UnprojectX(int x)
Definition: Vis.cpp:889
pIndoor
IndoorLocation * pIndoor
Definition: Indoor.cpp:49
Engine.h
Plane_float_::vNormal
struct Vec3_float_ vNormal
Definition: VectorTypes.h:136
Sprite
Definition: Sprites.h:10
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
OBJECT_Actor
@ OBJECT_Actor
Definition: Actor.h:67
Vis::DoesRayIntersectBillboard
bool DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx)
Definition: Vis.cpp:1418
Vis::SortVerticesByY
void SortVerticesByY(struct RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd)
Definition: Vis.cpp:1092
Vis::DetermineFacetIntersection
Vis_ObjectInfo * DetermineFacetIntersection(struct BLVFace *face, unsigned int a3, float pick_depth)
Definition: Vis.cpp:36
Actor.h
Vis_SelectionList::All
@ All
Definition: Vis.h:43
filter
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: SDL_opengl_glext.h:1187
Viewport::uScreen_TL_Y
int uScreen_TL_Y
Definition: Viewport.h:19
Sprite::uAreaY
int uAreaY
Definition: Sprites.h:30
RenderVertexSoft::vWorldViewPosition
Vec3_float_ vWorldViewPosition
Definition: IRender.h:117
Vis_ObjectInfo::object
void * object
Definition: Vis.h:29
Vis::GetPolygonScreenSpaceCenter
void GetPolygonScreenSpaceCenter(struct RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y)
Definition: Vis.cpp:204
pVertices
struct RenderVertexD3D3 pVertices[50]
Definition: Render.cpp:50
y
EGLSurface EGLint EGLint y
Definition: SDL_egl.h:1596
Viewport::uScreen_BR_Y
int uScreen_BR_Y
Definition: Viewport.h:21
IndoorCameraD3D::vPartyPos
Vec3< int > vPartyPos
Definition: IndoorCameraD3D.h:253
Plane_float_::dist
float dist
Definition: VectorTypes.h:137
Vec2::y
T y
Definition: VectorTypes.h:13
intersect_face_vertex_coords_list_a
std::array< int16_t, 104 > intersect_face_vertex_coords_list_a
Definition: mm7_data.cpp:786
RenderVertexSoft::vWorldViewProjX
float vWorldViewProjX
Definition: IRender.h:118
Vis::SortByScreenSpaceY
void SortByScreenSpaceY(struct RenderVertexSoft *pArray, int start, int end)
Definition: Vis.cpp:1166
RenderBillboard
Definition: IRender.h:26
UnprojectY
int UnprojectY(int y)
Definition: Vis.cpp:905
RenderBillboard::object_pid
uint16_t object_pid
Definition: IRender.h:42
BspFace::uFaceID
uint16_t uFaceID
Definition: Indoor.h:793
OBJECT_BModel
@ OBJECT_BModel
Definition: Actor.h:70
BLVFace::pZInterceptDisplacements
int16_t * pZInterceptDisplacements
Definition: Indoor.h:479
vis_sprite_filter_2
Vis_SelectionFilter vis_sprite_filter_2
Definition: Vis.cpp:24
x
EGLSurface EGLint x
Definition: SDL_egl.h:1596
Vis_SelectionFilter
Definition: Vis.h:12
vis_sprite_filter_4
Vis_SelectionFilter vis_sprite_filter_4
Definition: Vis.cpp:32
Vis_SelectionList::Unique
@ Unique
Definition: Vis.h:43
BBox_short_::y2
int16_t y2
Definition: VectorTypes.h:117
Viewport::uScreen_BR_X
int uScreen_BR_X
Definition: Viewport.h:20
BLVFace
Definition: Indoor.h:424
VisObjectType_Sprite
@ VisObjectType_Sprite
Definition: Vis.h:6
Vis::PickIndoorFaces_Keyboard
void PickIndoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter)
Definition: Vis.cpp:1571
Vis::_4C1A02
void _4C1A02()
Definition: Vis.cpp:427
BspRenderer::faces
BspFace faces[1000]
Definition: Indoor.h:814
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:694
Sprite::uAreaWidth
int uAreaWidth
Definition: Sprites.h:33
BLVFace::pFacePlane
struct Plane_float_ pFacePlane
Definition: Indoor.h:470
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
fixpoint_from_float
int fixpoint_from_float(float val)
Definition: OurMath.cpp:154
LODSprite
Definition: LOD.h:197
IndoorCameraD3D::Project
void Project(int x, int y, int z, int *screenspace_x, int *screenspace_y)
Definition: IndoorCameraD3D.cpp:1137
Vis_SelectionList::PointerCreationType
PointerCreationType
Definition: Vis.h:43
Vis::Intersect_Ray_Face
bool Intersect_Ray_Face(struct RenderVertexSoft *pRayStart, struct RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *Intersection, BLVFace *pFace, signed int pBModelID)
Definition: Vis.cpp:524
fixpoint_mul
__int64 fixpoint_mul(int a1, int a2)
Definition: OurMath.cpp:138
pActors
std::array< Actor, 500 > pActors
Definition: Actor.cpp:38
Vis::stru_206C
RenderVertexSoft stru_206C
Definition: Vis.h:152
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
type
EGLenum type
Definition: SDL_egl.h:850
Vis::PickOutdoorFaces_Keyboard
void PickOutdoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter)
Definition: Vis.cpp:1601
Vis::PickBillboards_Keyboard
void PickBillboards_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter)
Definition: Vis.cpp:1303
LODFile_Sprites::uNumLoadedSprites
unsigned int uNumLoadedSprites
Definition: LOD.h:228
Vis::SortVerticesByX
void SortVerticesByX(struct RenderVertexD3D3 *pArray, unsigned int uStart, unsigned int uEnd)
Definition: Vis.cpp:1056
LODSpriteHeader::uHeight
uint16_t uHeight
Definition: LOD.h:187
LEVEL_Outdoor
@ LEVEL_Outdoor
Definition: Indoor.h:287
Viewport::uScreenCenterY
int uScreenCenterY
Definition: Viewport.h:29
Vis::stru_203C
RenderVertexSoft stru_203C
Definition: Vis.h:151
IndoorLocation::uNumFaces
unsigned int uNumFaces
Definition: Indoor.h:629
Vis_ObjectInfo
Definition: Vis.h:28
Vis_SelectionList::Vis_SelectionList
Vis_SelectionList()
Definition: Vis.cpp:1236
depth
GLint GLint GLsizei GLsizei GLsizei depth
Definition: SDL_opengl.h:1572
BLVFace::Invisible
bool Invisible() const
Definition: Indoor.h:444
start
GLuint start
Definition: SDL_opengl.h:1571
RenderVertexSoft::flt_2C
float flt_2C
Definition: IRender.h:123
BLVFace::pBounding
struct BBox_short_ pBounding
Definition: Indoor.h:486
t
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
RenderBillboardD3D::texture
Texture * texture
Definition: IRender.h:158
Vis_SelectionFilter::object_id
int object_id
Definition: Vis.h:14
Outdoor.h
LEVEL_Indoor
@ LEVEL_Indoor
Definition: Indoor.h:286
LODSprite::bitmap
uint8_t * bitmap
Definition: LOD.h:206
Vis::SortVectors_x
void SortVectors_x(RenderVertexSoft *pArray, int start, int end)
Definition: Vis.cpp:458
pViewport
struct Viewport * pViewport
Definition: mm7_data.cpp:21
MonsterStats::BelongsToSupertype
static bool BelongsToSupertype(unsigned int uMonsterInfoID, enum MONSTER_SUPERTYPE eSupertype)
Definition: Monsters.cpp:1200
VisObjectType_Face
@ VisObjectType_Face
Definition: Vis.h:7
Sprite::sprite_header
struct LODSprite * sprite_header
Definition: Sprites.h:36
pODMRenderParams
ODMRenderParams * pODMRenderParams
Definition: Outdoor.cpp:49
BLVFace::pYInterceptDisplacements
int16_t * pYInterceptDisplacements
Definition: Indoor.h:478
Vis::PickClosestActor
unsigned short PickClosestActor(int object_id, unsigned int pick_depth, int a4, int a5, int a6)
Definition: Vis.cpp:403
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1112
stru193_math::Atan2
unsigned int Atan2(int x, int y)
Definition: OurMath.cpp:46
Vis::BLV_CreateIntersectFacesVertexCoordList
void BLV_CreateIntersectFacesVertexCoordList(int *a, int *b, int16_t *intersect_face_vertex_coords_list_a, int16_t *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace)
Definition: Vis.cpp:731
Sprite::uAreaX
int uAreaX
Definition: Sprites.h:29
Vis_static_sub_4C1944_stru_F8BDE8
static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8
Definition: Vis.cpp:20
Viewport::uScreenCenterX
int uScreenCenterX
Definition: Viewport.h:28
Vis::PickOutdoorFaces_Mouse
void PickOutdoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool only_reachable)
Definition: Vis.cpp:359
Texture.h
IsBModelVisible
bool IsBModelVisible(BSPModel *model, int *reachable)
Definition: Render.cpp:5516
IndoorCameraD3D::IsCulled
bool IsCulled(struct BLVFace *pFace)
Definition: IndoorCameraD3D.cpp:128
Vis_SelectionList::create_object_pointers
void create_object_pointers(PointerCreationType type=All)
Definition: Vis.cpp:975
v2
GLfloat GLfloat GLfloat v2
Definition: SDL_opengl_glext.h:695
Vis::PickMouse
bool PickMouse(float fDepth, float fMouseX, float fMouseY, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter)
Definition: Vis.cpp:1268
uint
unsigned int uint
Definition: MM7.h:4
IndoorCameraD3D::fov
float fov
Definition: IndoorCameraD3D.h:189
v3
GLfloat GLfloat GLfloat GLfloat v3
Definition: SDL_opengl_glext.h:696
BSPModel::pFaces
std::vector< ODMFace > pFaces
Definition: BSPModel.h:190
RenderVertexSoft::vWorldPosition
Vec3_float_ vWorldPosition
Definition: IRender.h:116
ODMFace
Definition: BSPModel.h:93
OBJECT_Any
@ OBJECT_Any
Definition: Actor.h:64
OBJECT_BLVDoor
@ OBJECT_BLVDoor
Definition: Actor.h:65
Decoration.h
stru_5C6E00
struct stru193_math * stru_5C6E00
Definition: mm7_data.cpp:19
Vis_SelectionFilter::object_type
VisObjectType object_type
Definition: Vis.h:13
Vis::keyboard_pick_depth
int keyboard_pick_depth
Definition: Vis.h:154
IndoorLocation::pVertices
struct Vec3_short_ * pVertices
Definition: Indoor.h:628
Vis_SelectionFilter::select_flags
int select_flags
Definition: Vis.h:17
OurMath.h
LODFile_Sprites::pHardwareSprites
Sprite * pHardwareSprites
Definition: LOD.h:233
pBillboardRenderList
RenderBillboard pBillboardRenderList[500]
Definition: RenderOpenGL.cpp:54
Vis::PickKeyboard
bool PickKeyboard(Vis_SelectionList *list, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter)
Definition: Vis.cpp:1247
uCurrentlyLoadedLevelType
LEVEL_TYPE uCurrentlyLoadedLevelType
Definition: Indoor.cpp:52
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1112
ODMRenderParams::int_fov_rad
int int_fov_rad
Definition: IRender.h:79
Vis_ObjectInfo::depth
int16_t depth
Definition: Vis.h:34
Vis::PickBillboards_Mouse
void PickBillboards_Mouse(float fPickDepth, float fX, float fY, Vis_SelectionList *list, Vis_SelectionFilter *filter)
Definition: Vis.cpp:231
IndoorLocation::pFaces
struct BLVFace * pFaces
Definition: Indoor.h:630
Vis_SelectionList::uNumPointers
unsigned int uNumPointers
Definition: Vis.h:63
IndoorCameraD3D::ViewTransform
void ViewTransform(int x, int y, int z, int *transformed_x, int *transformed_y, int *transformed_z)
Definition: IndoorCameraD3D.cpp:184
BBox_short_::x2
int16_t x2
Definition: VectorTypes.h:115
BSPModel
Definition: BSPModel.h:163
RenderVertexSoft
Definition: IRender.h:113
Vis::Vis
Vis()
Definition: Vis.cpp:1202
logger
Log * logger
Definition: IocContainer.cpp:47
RenderBillboardD3D::sParentBillboardID
int sParentBillboardID
Definition: IRender.h:167
Vis_ObjectInfo::object_type
VisObjectType object_type
Definition: Vis.h:37
Vis_SelectionList
Definition: Vis.h:42
res
GLuint res
Definition: SDL_opengl_glext.h:7940
pOutdoor
OutdoorLocation * pOutdoor
Definition: Outdoor.cpp:48
BBox_short_::z1
int16_t z1
Definition: VectorTypes.h:118
RenderBillboardD3D::pQuads
RenderVertexD3D3 pQuads[4]
Definition: IRender.h:160
pIndoorCameraD3D
IndoorCameraD3D * pIndoorCameraD3D
Definition: IndoorCameraD3D.cpp:21
uint32_t
unsigned __int32 uint32_t
Definition: SDL_config.h:39
Vis::stru_209C
RenderVertexSoft stru_209C
Definition: Vis.h:153
Vis::sort_object_pointers
void sort_object_pointers(Vis_ObjectInfo **pPointers, int start, int end)
Definition: Vis.cpp:1008
Vis_SelectionList::object_pointers
Vis_ObjectInfo * object_pointers[512]
Definition: Vis.h:62
BLVFace::uAttributes
unsigned int uAttributes
Definition: Indoor.h:475
Sprites.h
Sprite::uAreaHeight
int uAreaHeight
Definition: Sprites.h:34
Vec3::z
T z
Definition: VectorTypes.h:27
Vis::ODM_CreateIntersectFacesVertexCoordList
void ODM_CreateIntersectFacesVertexCoordList(int *a, int *b, int16_t *intersect_face_vertex_coords_list_a, int16_t *intersect_face_vertex_coords_list_b, Vec3_short_ *IntersectPoint, BLVFace *pFace, unsigned int uModelID)
Definition: Vis.cpp:798
intersect_face_vertex_coords_list_b
std::array< int16_t, 104 > intersect_face_vertex_coords_list_b
Definition: mm7_data.cpp:787
Vis.h
pBspRenderer
BspRenderer * pBspRenderer
Definition: Indoor.cpp:57
Vis::default_list
Vis_SelectionList default_list
Definition: Vis.h:149
render
std::shared_ptr< IRender > render
Definition: RenderOpenGL.cpp:52