view stru10.cpp @ 83:2d5d13376e91

Merge
author Nomad
date Mon, 29 Oct 2012 00:49:33 +0200
parents 41cbaabde2cb
children
line wrap: on
line source

#include "stru10.h"
#include "Render.h"
#include "Indoor.h"
#include "Game.h"
#include "Party.h"

#include "mm7_data.h"




//----- (0049CE9E) --------------------------------------------------------
void stru10::_49CE9E(BLVFace *pFace, RenderVertexSoft *a2, signed int a3, RenderVertexSoft *a4)
{
  char *v5; // eax@1
  signed int v6; // edx@1
  unsigned int v7; // eax@3
  signed int v8; // ecx@11
  signed int v9; // esi@11
  RenderVertexSoft *v10; // edx@12
  double v11; // st6@14
  RenderVertexSoft *v12; // edx@19
  signed int v13; // ecx@19
  signed int v14; // esi@19
  RenderVertexSoft *v15; // edi@20
  double v16; // st6@22
  signed int v17; // ecx@27
  signed int v18; // edi@27
  char *v19; // esi@28
  double v20; // st6@30
  signed int v21; // ecx@35
  signed int v22; // edi@35
  char *v23; // esi@36
  double v24; // st7@38
  signed int v25; // ecx@45
  signed int v26; // esi@45
  RenderVertexSoft *v27; // edx@46
  double v28; // st6@48
  signed int v29; // ecx@53
  signed int v30; // esi@53
  RenderVertexSoft *v31; // edi@54
  double v32; // st6@56
  signed int v33; // ecx@61
  signed int v34; // edi@61
  char *v35; // esi@62
  double v36; // st6@64
  signed int v37; // edi@69
  char *v38; // esi@70
  double v39; // st7@72
  RenderVertexSoft *v40; // esi@77
  signed int v41; // ecx@79
  signed int v42; // esi@79
  char *v43; // edx@80
  double v44; // st6@82
  RenderVertexSoft *v45; // eax@87
  signed int v46; // ecx@87
  signed int v47; // edi@87
  char *v48; // esi@88
  double v49; // st6@90
  signed int v50; // ecx@96
  signed int v51; // edi@96
  char *v52; // esi@97
  double v53; // st6@99
  signed int v54; // ecx@105
  signed int v55; // edi@105
  char *v56; // esi@106
  double v57; // st7@108
  RenderVertexSoft a2a[64]; // [sp+0h] [bp-C18h]@1
  float v59; // [sp+C00h] [bp-18h]@4
  float v60; // [sp+C04h] [bp-14h]@9
  float v61; // [sp+C08h] [bp-10h]@4
  float v62; // [sp+C0Ch] [bp-Ch]@9
  float v63; // [sp+C10h] [bp-8h]@4
  float v64; // [sp+C14h] [bp-4h]@4
  float a1a; // [sp+C20h] [bp+8h]@11
  float a1b; // [sp+C20h] [bp+8h]@19
  float a1c; // [sp+C20h] [bp+8h]@27
  float a1d; // [sp+C20h] [bp+8h]@35
  float a1e; // [sp+C20h] [bp+8h]@45
  float a1f; // [sp+C20h] [bp+8h]@53
  float a1g; // [sp+C20h] [bp+8h]@61
  float a1h; // [sp+C20h] [bp+8h]@69
  float a1i; // [sp+C20h] [bp+8h]@79
  float a1j; // [sp+C20h] [bp+8h]@87
  float a1k; // [sp+C20h] [bp+8h]@96
  float a1l; // [sp+C20h] [bp+8h]@105

  v5 = (char *)&a2a[0].flt_2C;
  v6 = 64;
  do
  {
    *(float *)v5 = 0.0;
    v5 += 48;
    --v6;
  }
  while ( v6 );
  stru10::CalcPolygonBoundingBox(pFace, a2a);
  v7 = pFace->uAttributes;
  if ( v7 & 0x100 )
  {
    v63 = a2a[0].vWorldPosition.x;
    v59 = a2a[2].vWorldPosition.x;
    v61 = a2a[1].vWorldPosition.y;
    v64 = a2a[3].vWorldPosition.y;
    goto LABEL_10;
  }
  if ( v7 & 0x200 )
  {
    v63 = a2a[0].vWorldPosition.x;
    v59 = a2a[2].vWorldPosition.x;
  }
  else
  {
    if ( !(v7 & 0x400) )
      goto LABEL_10;
    v61 = a2a[0].vWorldPosition.y;
    v64 = a2a[2].vWorldPosition.y;
  }
  v62 = a2a[1].vWorldPosition.z;
  v60 = a2a[3].vWorldPosition.z;
LABEL_10:
  if ( v7 & 0x100 )
  {
    v8 = -1;
    a1a = 3.4028235e38;
    v9 = 0;
    if ( a3 > 0 )
    {
      v10 = a2;
      do
      {
        if ( v10->vWorldPosition.x <= (double)v63 )
          v11 = v63 - v10->vWorldPosition.x;
        else
          v11 = v10->vWorldPosition.x - v63;
        if ( v11 < a1a )
        {
          a1a = v11;
          v8 = v9;
        }
        ++v9;
        ++v10;
      }
      while ( v9 < a3 );
    }
    v12 = a4;
    a1b = 3.4028235e38;
    memcpy(a4, &a2[v8], 0x30u);
    v13 = -1;
    v14 = 0;
    if ( a3 > 0 )
    {
      v15 = a2;
      do
      {
        if ( v15->vWorldPosition.x <= (double)v59 )
          v16 = v59 - v15->vWorldPosition.x;
        else
          v16 = v15->vWorldPosition.x - v59;
        if ( v16 < a1b )
        {
          a1b = v16;
          v13 = v14;
        }
        ++v14;
        ++v15;
      }
      while ( v14 < a3 );
    }
    a1c = 3.4028235e38;
    memcpy(&a4[2], &a2[v13], sizeof(a4[2]));
    v17 = -1;
    v18 = 0;
    if ( a3 > 0 )
    {
      v19 = (char *)&a2->vWorldPosition.y;
      do
      {
        if ( *(float *)v19 <= (double)v61 )
          v20 = v61 - *(float *)v19;
        else
          v20 = *(float *)v19 - v61;
        if ( v20 < a1c )
        {
          a1c = v20;
          v17 = v18;
        }
        ++v18;
        v19 += 48;
      }
      while ( v18 < a3 );
    }
    a1d = 3.4028235e38;
    memcpy(&a4[1], &a2[v17], sizeof(a4[1]));
    v21 = -1;
    v22 = 0;
    if ( a3 > 0 )
    {
      v23 = (char *)&a2->vWorldPosition.y;
      do
      {
        if ( *(float *)v23 <= (double)v64 )
          v24 = v64 - *(float *)v23;
        else
          v24 = *(float *)v23 - v64;
        if ( v24 < a1d )
        {
          a1d = v24;
          v21 = v22;
        }
        ++v22;
        v23 += 48;
      }
      while ( v22 < a3 );
    }
LABEL_77:
    v40 = &a2[v21];
    goto LABEL_115;
  }
  if ( v7 & 0x200 )
  {
    v25 = -1;
    a1e = 3.4028235e38;
    v26 = 0;
    if ( a3 > 0 )
    {
      v27 = a2;
      do
      {
        if ( v27->vWorldPosition.x <= (double)v63 )
          v28 = v63 - v27->vWorldPosition.x;
        else
          v28 = v27->vWorldPosition.x - v63;
        if ( v28 < a1e )
        {
          a1e = v28;
          v25 = v26;
        }
        ++v26;
        ++v27;
      }
      while ( v26 < a3 );
    }
    v12 = a4;
    a1f = 3.4028235e38;
    memcpy(a4, &a2[v25], 0x30u);
    v29 = -1;
    v30 = 0;
    if ( a3 > 0 )
    {
      v31 = a2;
      do
      {
        if ( v31->vWorldPosition.x <= (double)v59 )
          v32 = v59 - v31->vWorldPosition.x;
        else
          v32 = v31->vWorldPosition.x - v59;
        if ( v32 < a1f )
        {
          a1f = v32;
          v29 = v30;
        }
        ++v30;
        ++v31;
      }
      while ( v30 < a3 );
    }
    a1g = 3.4028235e38;
    memcpy(&a4[2], &a2[v29], sizeof(a4[2]));
    v33 = -1;
    v34 = 0;
    if ( a3 > 0 )
    {
      v35 = (char *)&a2->vWorldPosition.z;
      do
      {
        if ( *(float *)v35 <= (double)v62 )
          v36 = v62 - *(float *)v35;
        else
          v36 = *(float *)v35 - v62;
        if ( v36 < a1g )
        {
          a1g = v36;
          v33 = v34;
        }
        ++v34;
        v35 += 48;
      }
      while ( v34 < a3 );
    }
    a1h = 3.4028235e38;
    memcpy(&a4[1], &a2[v33], sizeof(a4[1]));
    v21 = -1;
    v37 = 0;
    if ( a3 > 0 )
    {
      v38 = (char *)&a2->vWorldPosition.z;
      do
      {
        if ( *(float *)v38 <= (double)v60 )
          v39 = v60 - *(float *)v38;
        else
          v39 = *(float *)v38 - v60;
        if ( v39 < a1h )
        {
          a1h = v39;
          v21 = v37;
        }
        ++v37;
        v38 += 48;
      }
      while ( v37 < a3 );
    }
    goto LABEL_77;
  }
  if ( !(v7 & 0x400) )
    return;
  v41 = -1;
  a1i = 3.4028235e38;
  v42 = 0;
  if ( a3 > 0 )
  {
    v43 = (char *)&a2->vWorldPosition.y;
    do
    {
      if ( *(float *)v43 <= (double)v61 )
        v44 = v61 - *(float *)v43;
      else
        v44 = *(float *)v43 - v61;
      if ( v44 < a1i )
      {
        a1i = v44;
        v41 = v42;
      }
      ++v42;
      v43 += 48;
    }
    while ( v42 < a3 );
  }
  v45 = a2;
  v12 = a4;
  a1j = 3.4028235e38;
  memcpy(a4, &a2[v41], 0x30u);
  v46 = -1;
  v47 = 0;
  if ( a3 > 0 )
  {
    v48 = (char *)&a2->vWorldPosition.y;
    do
    {
      if ( *(float *)v48 <= (double)v64 )
        v49 = v64 - *(float *)v48;
      else
        v49 = *(float *)v48 - v64;
      if ( v49 < a1j )
      {
        a1j = v49;
        v46 = v47;
      }
      ++v47;
      v48 += 48;
    }
    while ( v47 < a3 );
    v45 = a2;
  }
  a1k = 3.4028235e38;
  memcpy(&a4[2], &v45[v46], sizeof(a4[2]));
  v50 = -1;
  v51 = 0;
  if ( a3 > 0 )
  {
    v52 = (char *)&v45->vWorldPosition.z;
    do
    {
      if ( *(float *)v52 <= (double)v62 )
        v53 = v62 - *(float *)v52;
      else
        v53 = *(float *)v52 - v62;
      if ( v53 < a1k )
      {
        a1k = v53;
        v50 = v51;
      }
      ++v51;
      v52 += 48;
    }
    while ( v51 < a3 );
    v45 = a2;
  }
  a1l = 3.4028235e38;
  memcpy(&a4[1], &v45[v50], sizeof(a4[1]));
  v54 = -1;
  v55 = 0;
  if ( a3 > 0 )
  {
    v56 = (char *)&v45->vWorldPosition.z;
    do
    {
      if ( *(float *)v56 <= (double)v60 )
        v57 = v60 - *(float *)v56;
      else
        v57 = *(float *)v56 - v60;
      if ( v57 < a1l )
      {
        a1l = v57;
        v54 = v55;
      }
      ++v55;
      v56 += 48;
    }
    while ( v55 < a3 );
    v45 = a2;
  }
  v40 = &v45[v54];
LABEL_115:
  memcpy(&v12[3], v40, sizeof(v12[3]));
}

//----- (0049D379) --------------------------------------------------------
void stru10::CalcPolygonBoundingBox(BLVFace *pFace, RenderVertexSoft *pOutVertices)
{
  struct
  {
    float x;
    float y;
    int c;
  } v46[40]; //[sp+0C];

  if (pFace->uAttributes & 0x0100)
  {
    for (uint i = 0; i < pFace->uNumVertices; ++i)
    {
      v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pXInterceptDisplacements[i];
      v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pYInterceptDisplacements[i];
      v46[i].c = i;
    }
  }
  if (pFace->uAttributes & 0x0200)
  {
    for (uint i = 0; i < pFace->uNumVertices; ++i)
    {
      v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pXInterceptDisplacements[i];
      v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pZInterceptDisplacements[i];
      v46[i].c = i;
    }
  }
  if (pFace->uAttributes & 0x0400)
  {
    for (uint i = 0; i < pFace->uNumVertices; ++i)
    {
      v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pYInterceptDisplacements[i];
      v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pZInterceptDisplacements[i];
      v46[i].c = i;
    }
  }

  float x_min = FLT_MAX;
  uint  x_min_idx = 0;

  float x_max = FLT_MIN;
  uint  x_max_idx = 0;

  float y_min = FLT_MAX;
  uint  y_min_idx = 0;

  float y_max = FLT_MIN;
  uint  y_max_idx = 0;

  for (uint i = 0; i < pFace->uNumVertices; ++i)
  {
    if (v46[i].x < x_min)
    {
      x_min = v46[i].x;
      x_min_idx = v46[i].c;
    }
    if (v46[i].x > x_max)
    {
      x_max = v46[i].x;
      x_max_idx = v46[i].c;
    }

    if (v46[i].y < y_min)
    {
      y_min = v46[i].y;
      y_min_idx = v46[i].c;
    }
    if (v46[i].y > y_max)
    {
      y_max = v46[i].y;
      y_max_idx = v46[i].c;
    }
  }



  auto p1 = &pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]];
  RenderVertexSoft v1; // [sp+30Ch] [bp-54h]@24
  v1.vWorldPosition.x = (float)p1->x;
  v1.vWorldPosition.y = (float)p1->y;
  v1.vWorldPosition.z = (float)p1->z;
  memcpy(pOutVertices + 0, &v1, sizeof(RenderVertexSoft));

  auto p2 = &pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]];
  RenderVertexSoft v2; // [sp+30Ch] [bp-54h]@24
  v2.vWorldPosition.x = (float)p2->x;
  v2.vWorldPosition.y = (float)p2->y;
  v2.vWorldPosition.z = (float)p2->z;
  memcpy(pOutVertices + 1, &v2, sizeof(RenderVertexSoft));

  auto p3 = &pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]];
  RenderVertexSoft v3; // [sp+30Ch] [bp-54h]@24
  v3.vWorldPosition.x = (float)p3->x;
  v3.vWorldPosition.y = (float)p3->y;
  v3.vWorldPosition.z = (float)p3->z;
  memcpy(pOutVertices + 2, &v3, sizeof(RenderVertexSoft));

  auto p4 = &pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]];
  RenderVertexSoft v4; // [sp+30Ch] [bp-54h]@24
  v4.vWorldPosition.x = (double)p4->x;
  v4.vWorldPosition.y = (double)p4->y;
  v4.vWorldPosition.z = (double)p4->z;
  memcpy(pOutVertices + 3, &v4, sizeof(RenderVertexSoft));
}


//----- (0049C9E3) --------------------------------------------------------
bool stru10::_49C9E3(BLVFace *pFace, RenderVertexSoft *pFaceBounding, unsigned int uNumVertices, RenderVertexSoft *arg0)
{
  //IndoorCameraD3D *v6; // edi@1
  //PolygonType v7; // al@1
  //unsigned int v8; // edx@7
  //char v10; // zf@10
  //float v13; // ST14_4@20
  //stru10 *v15; // ecx@21
  //RenderVertexSoft *v16; // ST0C_4@21
  //bool result; // eax@21
  //float v18; // ST14_4@24
  //stru10 *v19; // edi@29
  //float v20; // ST14_4@30
  //float v21; // ST14_4@30
  //float v22; // ST14_4@30
  //float v23; // ST14_4@30
  //float v24; // ST14_4@31
  //RenderVertexSoft v25; // [sp+10h] [bp-90h]@24
  //RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
  //IndoorCameraD3D *thisa; // [sp+70h] [bp-30h]@1
  //stru10 *v31; // [sp+84h] [bp-1Ch]@1
  float v32; // [sp+88h] [bp-18h]@8
  Vec3_float_ a1; // [sp+8Ch] [bp-14h]@1
  float v35; // [sp+9Ch] [bp-4h]@8

  //auto a3 = pFace;
  //auto arg4 = pFaceBounding;

  //_ESI = a3;
  //v31 = this;
  //v6 = pGame->pIndoorCameraD3D;
  //v7 = a3->uPolygonType;

  a1.x = 0.0f;
  a1.y = 0.0f;
  a1.z = 0.0f;

  float var_28;
  float var_24;
  if (pFace->uPolygonType == POLYGON_VerticalWall)
  {
    a1.x = -pFace->pFacePlane.vNormal.y;
    a1.y = pFace->pFacePlane.vNormal.x;
    a1.z = 0.0f;
    a1.Normalize();

    var_28 = 0;
    var_24 = 1;
  }
  else if (pFace->uPolygonType == POLYGON_Floor ||
           pFace->uPolygonType == POLYGON_Ceiling)
  {
    a1.x = 1;
    a1.y = 0;
    a1.z = 0.0f;

    var_28 = 1;
    var_24 = 0;
  }


  float arg_4;
  float var_18;
  float var_4;
  float a3;
  float var_8;
  //v8 = _ESI->uAttributes;
  //_ECX = pFaceBounding;
  //__asm { fld     0.5 }
  if (pFace->uAttributes & 0x0100)
  {
    arg_4 = (pFaceBounding[0].vWorldPosition.x + pFaceBounding[2].vWorldPosition.x) / 2;
    var_18 = (pFaceBounding[3].vWorldPosition.y + pFaceBounding[1].vWorldPosition.y) / 2;
    var_4 = (pFaceBounding[0].vWorldPosition.z + pFaceBounding[2].vWorldPosition.z) / 2;

    a3 = arg_4 - pFaceBounding[0].vWorldPosition.x;
    var_8 = var_18 - pFaceBounding[1].vWorldPosition.y;
  }
  if (pFace->uAttributes & 0x0200)
  {
    arg_4 = (pFaceBounding[0].vWorldPosition.x + pFaceBounding[2].vWorldPosition.x) / 2;
    var_18 = (pFaceBounding[0].vWorldPosition.y + pFaceBounding[2].vWorldPosition.y) / 2;
    var_4 = (pFaceBounding[1].vWorldPosition.z + pFaceBounding[3].vWorldPosition.z) / 2;

    a3 = arg_4 - pFaceBounding[0].vWorldPosition.x;
    var_8 = var_4 - pFaceBounding[1].vWorldPosition.z;

    if (pFace->uPolygonType == POLYGON_VerticalWall)
      a3 /= a1.x;
  }
  if (pFace->uAttributes & 0x0400)
  {
    arg_4 = (pFaceBounding[0].vWorldPosition.x + pFaceBounding[2].vWorldPosition.x) / 2;
    var_18 = (pFaceBounding[0].vWorldPosition.y + pFaceBounding[2].vWorldPosition.y) / 2;
    var_4 = (pFaceBounding[1].vWorldPosition.z + pFaceBounding[3].vWorldPosition.z) / 2;

    a3 = var_18 - pFaceBounding[0].vWorldPosition.y;
    var_8 = var_4 - pFaceBounding[1].vWorldPosition.z;
                                       // [0.5]
    if (pFace->uPolygonType == POLYGON_VerticalWall)
    {
      if (a1.x != 1.0f)
        a3 /= a1.y;
    }
  }


  if ( byte_4D864C && pGame->uFlags & 8 )
  {
    RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
    v26.vWorldPosition.x = arg_4;
    v26.vWorldPosition.y = v32;
    v26.vWorldPosition.z = v35;

    pGame->pIndoorCameraD3D->do_draw_debug_line_sw(pFaceBounding, 0xFF00u, &v26, 0xFF0000u, 0, 0);
  }

  //_EBX = arg0;
  //v15 = v31;
  //v16 = arg0;
  float var_20 = var_8 * var_24;
  var_8 = a3 * a1.z;
  float arg_0 = var_8 + var_4;

  arg0[0].vWorldPosition.x = arg_4 - a3 * a1.x + var_8 * flt_4D84E8;
  arg0[0].vWorldPosition.y = var_18 - a3 * a1.y + var_8 * var_28;
  arg0[0].vWorldPosition.z = var_4 - var_8 + var_8 * var_24;
  arg0[1].vWorldPosition.x = arg_4 - a3 * a1.x - var_8 * flt_4D84E8;
  arg0[1].vWorldPosition.y = var_18 - a3 * a1.y - var_8 * var_28;
  arg0[1].vWorldPosition.z = (var_4 - var_8) - var_8 * var_24;
  arg0[2].vWorldPosition.x = a3 * a1.x + arg_4 - var_8 * flt_4D84E8;
  arg0[2].vWorldPosition.y = a3 * a1.y + var_18 - var_8 * var_28;
  arg0[2].vWorldPosition.z = var_8 + var_4 - var_20;
  arg0[3].vWorldPosition.x = (a3 * a1.x + arg_4) + var_8 * flt_4D84E8;
  arg0[3].vWorldPosition.y = a3 * a1.y + var_18 + var_8 * var_28;
  arg0[3].vWorldPosition.z = arg_0 + var_20;

  a3 = (var_4 - var_8);
  a3 = (a3 * a1.x + arg_4);

  a1.x = 0.0f;
  a1.y = 0.0f;
  a1.z = 0.0f;

  if (!_49C8DC(arg0, &a1, &a3))
    return false;


  if ( byte_4D864C )
  {
      if ( pGame->uFlags & 8 )
      {
        RenderVertexSoft v25; // [sp+10h] [bp-90h]@20
        RenderVertexSoft v26; // [sp+40h] [bp-60h]@20

        v25.vWorldPosition.x = arg_4;
        v25.vWorldPosition.y = v32;
        v25.vWorldPosition.z = v35;

        v26.vWorldPosition.x = a1.x * 30.0f;
        v26.vWorldPosition.y = a1.y * 30.0f;
        v26.vWorldPosition.z = a1.z * 30.0f;

        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v25, 0xFFFFFFFFu, &v26, 0xFFFF00u, 0, 0);
      }
  }


  RenderVertexSoft v25; // [sp+10h] [bp-90h]@20
  memcpy(&v25, arg0, sizeof(RenderVertexSoft));

  float _dp = (v25.vWorldPosition.x - pBLVRenderParams->vPartyPos.x) * a1.x +
              (v25.vWorldPosition.y - pBLVRenderParams->vPartyPos.y) * a1.y +
              (v25.vWorldPosition.z - pBLVRenderParams->vPartyPos.z) * a1.z;
  if (fabs(_dp) < 1e-6f)
  {
    memcpy(&v25, arg0 + 1, sizeof(RenderVertexSoft));
    memcpy(arg0 + 1, arg0 + 3, sizeof(RenderVertexSoft));
    memcpy(arg0 + 3, &v25, sizeof(RenderVertexSoft));
  }

    if ( byte_4D864C && pGame->uFlags & 8 )
    {
      RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
      if ( !LOBYTE(field_4) )
      {
        v26.vWorldPosition.x = pParty->vPosition.x;
        v26.vWorldPosition.y = pParty->vPosition.y;
        v26.vWorldPosition.z = pParty->vPosition.z + pParty->sEyelevel;

        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF0000u, arg0, 0xFF0000u, 0, 0);
        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF00u, arg0 + 1, 0xFF00u, 0, 0);
        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFu, arg0 + 2, 0xFFu, 0, 0);
        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFFFFFu, arg0 + 3, 0xFFFFFFu, 0, 0);
        LOBYTE(field_4) = 1;
      }
      pGame->pIndoorCameraD3D->debug_outline_sw(arg0, uNumVertices, 0x1EFF1Eu, 0.00019999999);
    }
  return true;
}



//----- (0049C5B0) --------------------------------------------------------
stru10::stru10()
{
  LOBYTE(this->field_4) = 0;
}

//----- (0049C5BD) --------------------------------------------------------
stru10::~stru10()
{
}

//----- (0049C5DA) --------------------------------------------------------
char stru10::_49C5DA(BLVFace *a2, RenderVertexSoft *a3, int *a4, IndoorCameraD3D_Vec4 *a5, RenderVertexSoft *a6)
{
  stru10 *v6; // edi@1
  char *v7; // eax@1
  signed int v8; // ecx@1
  IndoorCameraD3D *v9; // esi@3
  char result; // al@6
  RenderVertexSoft a4a[4]; // [sp+Ch] [bp-C0h]@1

  v6 = this;
  v7 = (char *)&a4a[0].flt_2C;
  v8 = 4;
  do
  {
    *(float *)v7 = 0.0;
    v7 += 48;
    --v8;
  }
  while ( v8 );
  v9 = pGame->pIndoorCameraD3D;
  _49CE9E(a2, a3, *a4, a4a);
  if ( byte_4D864C && pGame->uFlags & 8 )
    pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4u, 0xFF1E1Eu, 0.000099999997);
  result = _49C9E3(a2, a4a, 4u, a6);
  if ( result )
    result = _49C720(a6, a5);
  return result;
}
// 4D864C: using guessed type char byte_4D864C;

//----- (0049C681) --------------------------------------------------------
char stru10::_49C681_DrawDebugStuff(BLVFace *pFace, IndoorCameraD3D_Vec4 *a3, RenderVertexSoft *pArrayOf4)
{
  RenderVertexSoft pBounding[4]; // [sp+Ch] [bp-C0h]@1

  CalcPolygonBoundingBox(pFace, pBounding);
  if ( byte_4D864C && pGame->uFlags & 8 )
    pGame->pIndoorCameraD3D->debug_outline_sw(pBounding, 4, 0xFF1E1E, 0.000099999997);
  if (_49C9E3(pFace, pBounding, 4, pArrayOf4))
    return _49C720(pArrayOf4, a3);
  return false;
}
// 4D864C: using guessed type char byte_4D864C;

//----- (0049C720) --------------------------------------------------------
char stru10::_49C720(RenderVertexSoft *a2, IndoorCameraD3D_Vec4 *a4)
{
  char result; // al@2
  Vec3_float_ a3; // [sp+4h] [bp-34h]@1
  float v5; // [sp+30h] [bp-8h]@1
  stru10 *thisa; // [sp+34h] [bp-4h]@1

  v5 = 0.0;
  a3.x = (double)pBLVRenderParams->vPartyPos.x;
  a3.y = (double)pBLVRenderParams->vPartyPos.y;
  thisa = this;
  a3.z = (double)pBLVRenderParams->vPartyPos.z;
  if ( _49C7C5(a2, a2 + 1, &a3, a4)
    && _49C7C5(a2 + 1, a2 + 2, &a3, a4 + 1)
    && _49C7C5(a2 + 2, a2 + 3, &a3, a4 + 2) )
    result = _49C7C5(a2 + 3, a2, &a3, a4 + 3) != 0;
  else
    result = 0;
  return result;
}

//----- (0049C7C5) --------------------------------------------------------
bool stru10::_49C7C5(RenderVertexSoft *a1, RenderVertexSoft *a2, Vec3_float_ *a3, IndoorCameraD3D_Vec4 *a4)
{
  double v5; // st7@1
  double v6; // st6@1
  double v7; // st5@1
  Vec3_float_ *result; // eax@1
  __int16 v9; // fps@3
  char v10; // c0@3
  char v11; // c2@3
  char v12; // c3@3
  float v13; // ecx@5
  double v14; // st7@5
  double v15; // st6@5
  Vec3_float_ v1; // [sp+4h] [bp-48h]@1
  Vec3_float_ v2; // [sp+10h] [bp-3Ch]@1
  float v18; // [sp+20h] [bp-2Ch]@1
  float v19; // [sp+24h] [bp-28h]@1
  Vec3_float_ v20; // [sp+28h] [bp-24h]@1
  Vec3_float_ v21; // [sp+34h] [bp-18h]@1
  Vec3_float_ a1a; // [sp+40h] [bp-Ch]@1

  a1a.x = 0.0;
  a1a.y = 0.0;
  a1a.z = 0.0;
  v21.x = a3->x;
  v21.y = a3->y;
  v21.z = a3->z;
  v5 = a1->vWorldPosition.x;
  v6 = a1->vWorldPosition.y;
  v2.z = a1->vWorldPosition.z;
  v7 = a2->vWorldPosition.x;
  v18 = a2->vWorldPosition.y;
  v19 = a2->vWorldPosition.z;
  v20.x = v5 - v21.x;
  v20.y = v6 - v21.y;
  v20.z = v2.z - v21.z;
  LODWORD(v1.x) = (int)v20.x;
  v1.y = v20.y;
  v1.z = v20.z;
  v20.x = v7 - v5;
  v20.y = v18 - v6;
  v20.z = v19 - v2.z;
  result = Vec3_float_::Cross(&v1, &v2, v20.x, v20.y, v20.z);
  a1a.x = result->x;
  a1a.y = result->y;
  a1a.z = result->z;
  if ( a1a.x != 0.0
    || a1a.y != 0.0
    || (/*UNDEF(v9),*/ v10 = a1a.z < 0.0, v11 = 0, v12 = a1a.z == 0.0, BYTE1(result) = HIBYTE(v9), a1a.z != 0.0) )
  {
    a1a.Normalize();
    result = (Vec3_float_ *)a4;
    v13 = a1a.y;
    a4->x = a1a.x;
    v14 = v21.z * a1a.z;
    v15 = v21.y * a1a.y;
    a4->y = v13;
    a4->z = a1a.z;
    a4->dot = v14 + v15 + v21.x * a1a.x;
    LOBYTE(result) = 1;
  }
  else
  {
    LOBYTE(result) = 0;
  }
  return (bool)result;
}

//----- (0049C8DC) --------------------------------------------------------
bool stru10::_49C8DC(RenderVertexSoft *arg0, Vec3_float_ *a2, float *a3)
{
  double v4; // st7@1
  double v5; // st6@1
  double v6; // st5@1
  Vec3_float_ *result; // eax@1
  __int16 v8; // fps@3
  char v9; // c0@3
  char v10; // c2@3
  char v11; // c3@3
  float v12; // ecx@5
  double v13; // st7@5
  double v14; // st6@5
  Vec3_float_ v1; // [sp+8h] [bp-3Ch]@1
  Vec3_float_ v2; // [sp+14h] [bp-30h]@1
  float v17; // [sp+24h] [bp-20h]@1
  float v18; // [sp+28h] [bp-1Ch]@1
  float v19; // [sp+2Ch] [bp-18h]@1
  float v20; // [sp+30h] [bp-14h]@1
  float v21; // [sp+34h] [bp-10h]@1
  Vec3_float_ a1; // [sp+38h] [bp-Ch]@1

  v19 = arg0->vWorldPosition.x;
  v20 = arg0->vWorldPosition.y;
  v21 = arg0->vWorldPosition.z;
  v4 = arg0[1].vWorldPosition.x;
  v5 = arg0[1].vWorldPosition.y;
  v2.z = arg0[1].vWorldPosition.z;
  v6 = arg0[2].vWorldPosition.x;
  v17 = arg0[2].vWorldPosition.y;
  v18 = arg0[2].vWorldPosition.z;
  a1.x = v4 - v19;
  a1.y = v5 - v20;
  a1.z = v2.z - v21;
  LODWORD(v1.x) = (int)a1.x;
  v1.y = a1.y;
  v1.z = a1.z;
  a1.x = v6 - v4;
  a1.y = v17 - v5;
  a1.z = v18 - v2.z;
  result = Vec3_float_::Cross(&v1, &v2, a1.x, a1.y, a1.z);
  a1.x = result->x;
  a1.y = result->y;
  a1.z = result->z;
  if ( a1.x != 0.0
    || a1.y != 0.0
    || (/*UNDEF(v8),*/ v9 = a1.z < 0.0, v10 = 0, v11 = a1.z == 0.0, /*BYTE1(result) = HIBYTE(v8),*/ a1.z != 0.0) )
  {
    a1.Normalize();
    v12 = a1.y;
    a2->x = a1.x;
    v13 = v21 * a1.z;
    v14 = v20 * a1.y;
    a2->y = v12;
    a2->z = a1.z;
    result = (Vec3_float_ *)a3;
    *a3 = -(v13 + v14 + v19 * a1.x);
    return true;
  }
  return false;
}