Mercurial > mm7
diff Engine/Graphics/stru10.cpp @ 2496:5abd8fc8f1c6
for ITEM_ARTIFACT_LADYS_ESCORT
author | Ritor1 |
---|---|
date | Thu, 18 Sep 2014 17:38:54 +0600 |
parents | |
children | 68cdef6879a0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/stru10.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,860 @@ +#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> + +#define _CRT_SECURE_NO_WARNINGS +#include "stru10.h" +#include "Indoor.h" +#include "Game.h" +#include "Party.h" +#include "ErrorHandling.h" + + + +int _49CE9E_sub0_x(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) +{ + float max_val = FLT_MAX; + int idx = -1; + + float temp_val; + for (uint i = 0; i < uNumVertices; ++i) + { + if (pVertices[i].vWorldPosition.x <= test_val) + temp_val = test_val - pVertices[i].vWorldPosition.x; + else + temp_val = pVertices[i].vWorldPosition.x - test_val; + + if (temp_val < max_val) + { + max_val = temp_val; + idx = i; + } + } + return idx; +} + + +int _49CE9E_sub0_y(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) +{ + float max_val = FLT_MAX; + int idx = -1; + + float temp_val; + for (uint i = 0; i < uNumVertices; ++i) + { + if (pVertices[i].vWorldPosition.y <= test_val) + temp_val = test_val - pVertices[i].vWorldPosition.y; + else + temp_val = pVertices[i].vWorldPosition.y - test_val; + + if (temp_val < max_val) + { + max_val = temp_val; + idx = i; + } + } + return idx; +} + + +int _49CE9E_sub0_z(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val) +{ + float max_val = FLT_MAX; + int idx = -1; + + float temp_val; + for (uint i = 0; i < uNumVertices; ++i) + { + if (pVertices[i].vWorldPosition.z <= test_val) + temp_val = test_val - pVertices[i].vWorldPosition.z; + else + temp_val = pVertices[i].vWorldPosition.z - test_val; + + if (temp_val < max_val) + { + max_val = temp_val; + idx = i; + } + } + return idx; +} + +//----- (0049CE9E) -------------------------------------------------------- +void stru10::_49CE9E(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits) +{ + Assert(sizeof(RenderVertexSoft) == 0x30); + + RenderVertexSoft pLimits[64]; + stru10::CalcPolygonLimits(pFace, pLimits); + + if (pFace->uAttributes & FACE_XY_PLANE) + { + memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[1].vWorldPosition.y)], 0x30); + memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[3].vWorldPosition.y)], 0x30); + } + else if (pFace->uAttributes & FACE_XZ_PLANE) + { + memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30); + memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30); + memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30); + } + else if (pFace->uAttributes & FACE_YZ_PLANE) + { + memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[0].vWorldPosition.y)], 0x30); + memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[2].vWorldPosition.y)], 0x30); + memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30); + memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30); + } +} + +//----- (0049D379) -------------------------------------------------------- +void stru10::CalcPolygonLimits(BLVFace *pFace, RenderVertexSoft *pOutVertices) +{ + struct + { + float x; + float y; + int c; + } v46[40]; //[sp+0C]; + + if (pFace->uAttributes & FACE_XY_PLANE) + { + 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 & FACE_XZ_PLANE) + { + 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]].z + pFace->pZInterceptDisplacements[i]; + v46[i].c = i; + } + } + if (pFace->uAttributes & FACE_YZ_PLANE) + { + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pYInterceptDisplacements[i]; + v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].z + pFace->pZInterceptDisplacements[i]; + v46[i].c = i; + } + } + + float x_min = v46[0].x; + uint x_min_idx = 0; + + float x_max = v46[0].x; + uint x_max_idx = 0; + + float y_min = v46[0].y; + uint y_min_idx = 0; + + float y_max = v46[0].y; + 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; + } + } + + RenderVertexSoft v1; // [sp+30Ch] [bp-54h]@24 + v1.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].x; + v1.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].y; + v1.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[x_min_idx]].z; + memcpy(&pOutVertices[0], &v1, sizeof(RenderVertexSoft)); + + RenderVertexSoft v2; // [sp+30Ch] [bp-54h]@24 + v2.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].x; + v2.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].y; + v2.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[y_min_idx]].z; + memcpy(&pOutVertices[1], &v2, sizeof(RenderVertexSoft)); + + RenderVertexSoft v3; // [sp+30Ch] [bp-54h]@24 + v3.vWorldPosition.x = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].x; + v3.vWorldPosition.y = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].y; + v3.vWorldPosition.z = (float)pIndoor->pVertices[pFace->pVertexIDs[x_max_idx]].z; + memcpy(&pOutVertices[2], &v3, sizeof(RenderVertexSoft)); + + RenderVertexSoft v4; // [sp+30Ch] [bp-54h]@24 + v4.vWorldPosition.x = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].x; + v4.vWorldPosition.y = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].y; + v4.vWorldPosition.z = (double)pIndoor->pVertices[pFace->pVertexIDs[y_max_idx]].z; + memcpy(&pOutVertices[3], &v4, sizeof(RenderVertexSoft)); +} + + +//----- (0049C9E3) -------------------------------------------------------- +bool stru10::CalcFaceBounding(BLVFace *pFace, RenderVertexSoft *pFaceLimits, unsigned int uNumVertices, RenderVertexSoft *pOutBounding) +{ + //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; + switch (pFace->uPolygonType) + { + case 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; + break; + + case POLYGON_Floor: + case POLYGON_Ceiling: + a1.x = 1; + a1.y = 0; + a1.z = 0.0f; + + var_28 = 1; + var_24 = 0; + break; + + default: + Error("Invalid polygon type (%u)", pFace->uPolygonType); + } + + + float face_center_x; + float face_center_y; + float face_center_z; + float a3; + float var_8; + + if (pFace->uAttributes & FACE_XY_PLANE) + { + face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2; + face_center_y = (pFaceLimits[3].vWorldPosition.y + pFaceLimits[1].vWorldPosition.y) / 2; + face_center_z = (pFaceLimits[0].vWorldPosition.z + pFaceLimits[2].vWorldPosition.z) / 2; + + a3 = face_center_x - pFaceLimits[0].vWorldPosition.x; + var_8 = face_center_y - pFaceLimits[1].vWorldPosition.y; + } + if (pFace->uAttributes & FACE_XZ_PLANE) + { + face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2;// центр полигона + face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2; + face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2; + + a3 = face_center_x - pFaceLimits[0].vWorldPosition.x;//от центра до верхнего края + var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z;// высота от центра + + if (pFace->uPolygonType == POLYGON_VerticalWall) + a3 /= a1.x; + } + if (pFace->uAttributes & FACE_YZ_PLANE) + { + face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2; + face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2; + face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2; + + a3 = face_center_y - pFaceLimits[0].vWorldPosition.y; + var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z; + // [0.5] + if (pFace->uPolygonType == POLYGON_VerticalWall) + { + if (a1.x != 1.0f) + a3 /= a1.y; + } + } + + + + + //_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; + +/* + + + +.text:0049CBB3 fld [ebp+var_8] 0 var8 +.text:0049CBB6 1 fmul ds:flt_4D84E8 0 var8 * flt_4D84E8 + +.text:0049CBBC 1 fld [ebp+var_8] 0 var8 + 1 var8 * flt_4D84E8 + +.text:0049CBBF 2 fmul [ebp+var_28] 0 var8 * var28 + 1 var8 * flt_4D84E8 + +.text:0049CBC2 2 fld [ebp+var_8] 0 var8 + 1 var8 * var28 + 2 var8 * flt_4D84E8 + +.text:0049CBC5 3 fmul [ebp+var_24] 0 var8 * var24 768 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + +.text:0049CBD5 3 fst [ebp+var_20] 0 var8 * var24 768 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + [var20] var8 * var24 768 + +.text:0049CBD8 3 fld [ebp+a3] 0 a3 -1984 + 1 var8 * var24 768 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CBDB 4 fmul [ebp+a1.x] 0 a3 * a1.x 1984 + 1 var8 * var24 768 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CBDE 4 fld [ebp+a3] 0 a3 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + +.text:0049CBE1 5 fmul [ebp+a1.y] 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 +.text:0049CBE4 5 fld [ebp+a3] +.text:0049CBE7 6 fmul [ebp+a1.z] 0 a3 * a1.z 0 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 + +.text:0049CBEC 6 fstp [ebp+var_8] + var8 <- a3 * a1.z 0 + +.text:0049CBEF 5 fld [ebp+arg4] 0 arg4 -1700 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 + +.text:0049CBF2 6 fsub st, st(2) 0 arg4 - a3 * a1.x -3684 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 + +.text:0049CBF4 6 fld st 0 arg4 - a3 * a1.x -3684 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + +.text:0049CBF6 7 fadd st, st(6) 0 arg4 - a3 * a1.x + var8 * flt_4D84E8 -3684 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 +.text:0049CBF8 7 fstp dword ptr [ebx] + [0].x <- arg4 - a3 * a1.x + var8 * flt_4D84E8 -3684 + +.text:0049CBFA 6 fld [ebp+var_18] 0 var18 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + +.text:0049CBFD 7 fsub st, st(2) 0 var18 - a3 * a1.y 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + +.text:0049CBFF 7 fld st 0 var18 - a3 * a1.y 1480 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 + +.text:0049CC01 8 fadd st, st(6) 0 var18 - a3 * a1.y + var8 * var28 1480 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 + +.text:0049CC03 8 fstp dword ptr [ebx+4] + [0].y <- var18 - a3 * a1.y + var8 * var28 1480 + +.text:0049CC06 7 fld [ebp+var_4] +.text:0049CC09 8 fsub [ebp+var_8] 0 var4 - a3 * a1.z 768 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 +.text:0049CC0C 8 fst [ebp+a3] + a3 <- var4 - a3 * a1.z 768 + +.text:0049CC0F 8 fadd st, st(5) +.text:0049CC11 8 fstp dword ptr [ebx+8] + [0].z <- var4 - a3 * a1.z + var8 * var24 1536 + + 0 var18 - a3 * a1.y 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 + + + + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] var4 - a3 * a1.z 768 + + +.text:0049CC14 7 fld st(1) +.text:0049CC16 8 fsub st, st(7) 0 arg4 - a3 * a1.x - var8 * flt_4D84E8 -3684 + 1 var18 - a3 * a1.y 1480 + 2 arg4 - a3 * a1.x -3684 + 3 a3 * a1.y 0 + 4 a3 * a1.x 1984 + 5 var8 * var24 768 + 6 var8 * var28 0 + 7 var8 * flt_4D84E8 0 +.text:0049CC18 8 fstp dword ptr [ebx+30h] + [1].x <- arg4 - a3 * a1.x - var8 * flt_4D84E8 -3684 + + 0 var18 - a3 * a1.y 1480 + 1 arg4 - a3 * a1.x -3684 + 2 a3 * a1.y 0 + 3 a3 * a1.x 1984 + 4 var8 * var24 768 + 5 var8 * var28 0 + 6 var8 * flt_4D84E8 0 +.text:0049CC1B 7 fsub st, st(5) +.text:0049CC1D 7 fstp dword ptr [ebx+34h] + [1].y <- var18 - a3 * a1.y - var8 * var28 1480 +.text:0049CC20 6 fstp st + 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] var4 - a3 * a1.z 768 + +.text:0049CC22 5 fld [ebp+a3] 0 var4 - a3 * a1.z 768 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 +.text:0049CC25 6 fsub st, st(3) +.text:0049CC27 6 fstp dword ptr [ebx+38h] + [1].z <- var4 - a3 * a1.z - var8 * var24 768 - 768 = 0 + + 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + + +.text:0049CC2A fld st(1) +.text:0049CC2C 6 fadd [ebp+arg4] 0 arg4 + a3 * a1.x 284 + 1 a3 * a1.y 0 + 2 a3 * a1.x 1984 + 3 var8 * var24 768 + 4 var8 * var28 0 + 5 var8 * flt_4D84E8 0 +.text:0049CC2F 6 fst [ebp+a3] + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] arg4 + a3 * a1.x 284 +.text:0049CC32 6 fsub st, st(5) +.text:0049CC34 6 fstp dword ptr [ebx+60h] + [2].x <- arg4 + a3 * a1.x - var8 * flt_4D84E8 284 + + 0 a3 * a1.y 0 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + +.text:0049CC37 5 fadd [ebp+var_18] 0 var18 + a3 * a1.y 1480 + 1 a3 * a1.x 1984 + 2 var8 * var24 768 + 3 var8 * var28 0 + 4 var8 * flt_4D84E8 0 + +.text:0049CC3A 5 fstp st(2) 0 a3 * a1.x 1984 + 1 var18 + a3 * a1.y 1480 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CC3C 4 fstp st 0 var18 + a3 * a1.y 1480 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + +.text:0049CC3E 3 fld st 0 var18 + a3 * a1.y 1480 + 1 var18 + a3 * a1.y 1480 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 +.text:0049CC40 4 fsub st, st(2) +.text:0049CC42 4 fstp dword ptr [ebx+64h] + [2].y <- var18 + a3 * a1.y - var8 * var28 1480 + + 0 var18 + a3 * a1.y 1480 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + + [var20] var8 * var24 768 + [var8] a3 * a1.z + [a3] arg4 + a3 * a1.x 284 +.text:0049CC45 3 fld [ebp+var_8] +.text:0049CC48 4 fadd [ebp+var_4] 0 var4 + a3 * a1.z 768 + 1 var18 + a3 * a1.y 1480 + 2 var8 * var28 0 + 3 var8 * flt_4D84E8 0 + +.text:0049CC4B 4 fst [ebp+arg0] + [var20] var8 * var24 768 + [arg0] var4 + a3 * a1.z 768 + [var8] a3 * a1.z 0 + [a3] arg4 + a3 * a1.x 284 + +.text:0049CC4E 4 fsub [ebp+var_20] +.text:0049CC51 4 fstp dword ptr [ebx+68h] + [2].z <- var4 + a3 * a1.z - var8 * var24 0 + + + + [var20] var8 * var24 768 + [arg0] var4 + a3 * a1.z 768 + [var8] a3 * a1.z 0 + [a3] arg4 + a3 * a1.x 284 + + + 0 var18 + a3 * a1.y 1480 + 1 var8 * var28 0 + 2 var8 * flt_4D84E8 0 + +.text:0049CC54 3 fld [ebp+a3] +.text:0049CC57 4 fadd st, st(3) +.text:0049CC59 4 fstp dword ptr [ebx+90h] + [3].x <- arg4 + a3 * a1.x + var8 * flt_4D84E8 284 + +.text:0049CC5F 3 fadd st, st(1) +.text:0049CC61 3 fstp dword ptr [ebx+94h] + [3].y <- var18 + a3 * a1.y + var8 * var28 1480 + +.text:0049CC67 2 fstp st +.text:0049CC69 1 fstp st + 0 empty +.text:0049CC6B 0 fld [ebp+arg0] +.text:0049CC6E 1 fadd [ebp+var_20] +.text:0049CC71 1 fstp dword ptr [ebx+98h] + [3].z <- var4 + a3 * a1.z + var8 * var24 1536 + + 0 empty +*/ + + pOutBounding[0].vWorldPosition.x = face_center_x - a3 * a1.x + var_8 * flt_4D84E8; + pOutBounding[0].vWorldPosition.y = face_center_y - a3 * a1.y + var_8 * var_28; + pOutBounding[0].vWorldPosition.z = face_center_z - a3 * a1.z + var_8 * var_24; + + pOutBounding[1].vWorldPosition.x = face_center_x - a3 * a1.x - var_8 * flt_4D84E8; + pOutBounding[1].vWorldPosition.y = face_center_y - a3 * a1.y - var_8 * var_28; + pOutBounding[1].vWorldPosition.z = face_center_z - a3 * a1.z - var_8 * var_24; + + pOutBounding[2].vWorldPosition.x = face_center_x + a3 * a1.x - var_8 * flt_4D84E8; + pOutBounding[2].vWorldPosition.y = face_center_y + a3 * a1.y - var_8 * var_28; + pOutBounding[2].vWorldPosition.z = face_center_z + a3 * a1.z - var_8 * var_24; + + pOutBounding[3].vWorldPosition.x = face_center_x + a3 * a1.x + var_8 * flt_4D84E8; + pOutBounding[3].vWorldPosition.y = face_center_y + a3 * a1.y + var_8 * var_28; + pOutBounding[3].vWorldPosition.z = face_center_z + a3 * a1.z + var_8 * var_24; + + a1.x = 0.0f; + a1.y = 0.0f; + a1.z = 0.0f; + a3 = face_center_x + a3 * a1.x; + + if (!FindFacePlane(pOutBounding, &a1, &a3)) + return false; + + + + RenderVertexSoft v25; // [sp+10h] [bp-90h]@20 + memcpy(&v25, pOutBounding, sizeof(RenderVertexSoft)); + + float _dp = (v25.vWorldPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) * a1.x + + (v25.vWorldPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) * a1.y + + (v25.vWorldPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) * a1.z; + if (fabs(_dp) < 1e-6f) + { + memcpy(&v25, &pOutBounding[1], sizeof(RenderVertexSoft)); + memcpy(&pOutBounding[1], &pOutBounding[3], sizeof(RenderVertexSoft)); + memcpy(&pOutBounding[3], &v25, sizeof(RenderVertexSoft)); + } + + //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + //{ + RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 + if ( draw_portals_loops ) + { + if (!bDoNotDrawPortalFrustum) + { + v26.vWorldPosition.x = pParty->vPosition.x; + v26.vWorldPosition.y = pParty->vPosition.y; + v26.vWorldPosition.z = pParty->vPosition.z + pParty->sEyelevel; // frustum + + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF0000u, &pOutBounding[0], 0xFF0000u, 0, 0); + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF00u, &pOutBounding[1], 0xFF00u, 0, 0); + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFu, &pOutBounding[2], 0xFFu, 0, 0); + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFFFFFu, &pOutBounding[3], 0xFFFFFFu, 0, 0); + bDoNotDrawPortalFrustum = true; + } + pGame->pIndoorCameraD3D->debug_outline_sw(pOutBounding, uNumVertices, 0x1EFF1Eu, 0.00019999999); // bounding + } + //} + + //pGame->pIndoorCameraD3D->debug_outline_sw(pFaceLimits, 4, 0xFFF14040, 0.000099999997); // limits + + /*if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + { + RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 + v26.vWorldPosition.x = face_center_x; // corner to center + v26.vWorldPosition.y = face_center_y; + v26.vWorldPosition.z = face_center_z; + + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(pFaceLimits, 0xFF00u, &v26, 0xFF0000u, 0, 0); + }*/ + + + /*if ( byte_4D864C ) + { + if ( pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)*/ + { + RenderVertexSoft v25; // [sp+10h] [bp-90h]@20 + RenderVertexSoft v26; // [sp+40h] [bp-60h]@20 + + v25.vWorldPosition.x = face_center_x; // portal normal + v25.vWorldPosition.y = face_center_y; + v25.vWorldPosition.z = face_center_z; + + v26.vWorldPosition.x = face_center_x + a1.x * 400.0f; + v26.vWorldPosition.y = face_center_y + a1.y * 400.0f; + v26.vWorldPosition.z = face_center_z + a1.z * 400.0f; + + if ( draw_portals_loops ) + pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v25, -1, &v26, 0xFFFF00u, 0, 0); + } + //} + + return true; +} + + + +//----- (0049C5B0) -------------------------------------------------------- +stru10::stru10() +{ + this->bDoNotDrawPortalFrustum = false; +} + +//----- (0049C5BD) -------------------------------------------------------- +stru10::~stru10() +{ +} + +//----- (0049C5DA) -------------------------------------------------------- +char stru10::_49C5DA(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int *pNumVertices, IndoorCameraD3D_Vec4 *a5, RenderVertexSoft *pOutBounding) +{ + RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1 + + _49CE9E(pFace, pVertices, *pNumVertices, pLimits); + + //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + // pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4u, 0xFF1E1Eu, 0.000099999997); + if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding)) + return _49C720(pOutBounding, a5); + return false; +} +// 4D864C: using guessed type char byte_4D864C; + +//----- (0049C681) -------------------------------------------------------- +bool stru10::CalcPortalShape(BLVFace *pFace, IndoorCameraD3D_Vec4 *pPortalDataFrustum, RenderVertexSoft *pOutBounding) +{ + RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1 + + CalcPolygonLimits(pFace, pLimits);//определение границ портала + //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS) + // pGame->pIndoorCameraD3D->debug_outline_sw(pLimits, 4, 0xFF1E1E, 0.000099999997); + if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding)) + return _49C720(pOutBounding, pPortalDataFrustum) != 0; + return false; +} + +// 4D864C: using guessed type char byte_4D864C; + +//----- (0049C720) -------------------------------------------------------- +char stru10::_49C720(RenderVertexSoft *pFaceBounding, IndoorCameraD3D_Vec4 *pPortalDataFrustum) +{ + Vec3_float_ pRayStart; // [sp+4h] [bp-34h]@1 + pRayStart.x = (double)pGame->pIndoorCameraD3D->vPartyPos.x; + pRayStart.y = (double)pGame->pIndoorCameraD3D->vPartyPos.y; + pRayStart.z = (double)pGame->pIndoorCameraD3D->vPartyPos.z; + + if (FindFaceNormal(&pFaceBounding[0], &pFaceBounding[1], &pRayStart, &pPortalDataFrustum[0]) && + FindFaceNormal(&pFaceBounding[1], &pFaceBounding[2], &pRayStart, &pPortalDataFrustum[1]) && + FindFaceNormal(&pFaceBounding[2], &pFaceBounding[3], &pRayStart, &pPortalDataFrustum[2]) && + FindFaceNormal(&pFaceBounding[3], &pFaceBounding[0], &pRayStart, &pPortalDataFrustum[3])) + return true; + return false; +} + +//----- (0049C7C5) -------------------------------------------------------- +bool stru10::FindFaceNormal(RenderVertexSoft *pFaceBounding1, RenderVertexSoft *pFaceBounding2, Vec3_float_ *pRayStart, IndoorCameraD3D_Vec4 *pPortalDataFrustum) +{ + Vec3_float_ ray_dir; // [sp+4h] [bp-48h]@1 + Vec3_float_ pRay2; // [sp+10h] [bp-3Ch]@1 + + ray_dir.x = pFaceBounding1->vWorldPosition.x - pRayStart->x;//get ray for cmera to bounding1 + ray_dir.y = pFaceBounding1->vWorldPosition.y - pRayStart->y; + ray_dir.z = pFaceBounding1->vWorldPosition.z - pRayStart->z; + Vec3_float_::Cross(&ray_dir, &pRay2, pFaceBounding2->vWorldPosition.x - pFaceBounding1->vWorldPosition.x, + pFaceBounding2->vWorldPosition.y - pFaceBounding1->vWorldPosition.y, + pFaceBounding2->vWorldPosition.z - pFaceBounding1->vWorldPosition.z); + + float sqr_mag = pRay2.x * pRay2.x + pRay2.y * pRay2.y + pRay2.z * pRay2.z; + if (fabsf(sqr_mag) > 1e-6f) + { + float inv_mag = 1.0f / sqrtf(sqr_mag); + pRay2.x *= inv_mag; + pRay2.y *= inv_mag; + pRay2.z *= inv_mag; + pRay2.Normalize(); + + pPortalDataFrustum->x = pRay2.x; + pPortalDataFrustum->y = pRay2.y; + pPortalDataFrustum->z = pRay2.z; + pPortalDataFrustum->dot = pRayStart->z * pRay2.z + pRayStart->y * pRay2.y + pRayStart->x * pRay2.x; + return true; + } + return false; +} + +//----- (0049C8DC) -------------------------------------------------------- +bool stru10::FindFacePlane(RenderVertexSoft *arg0, Vec3_float_ *a2, float *a3) +{ + Vec3_float_ v1; // [sp+8h] [bp-3Ch]@1 + Vec3_float_ v2; // [sp+14h] [bp-30h]@1 + + v1.x = arg0[1].vWorldPosition.x - arg0[0].vWorldPosition.x; + v1.y = arg0[1].vWorldPosition.y - arg0[0].vWorldPosition.y; + v1.z = arg0[1].vWorldPosition.z - arg0[0].vWorldPosition.z; + + Vec3_float_::Cross(&v1, &v2, arg0[2].vWorldPosition.x - arg0[1].vWorldPosition.x, + arg0[2].vWorldPosition.y - arg0[1].vWorldPosition.y, + arg0[2].vWorldPosition.z - arg0[1].vWorldPosition.z); + + float sqr_mag = v2.x * v2.x + v2.y * v2.y + v2.z * v2.z; + if (fabsf(sqr_mag) > 1e-6f) + { + //v2.Normalize(); + float inv_mag = 1.0f / sqrtf(sqr_mag); + v2.x *= inv_mag; + v2.y *= inv_mag; + v2.z *= inv_mag; + + a2->x = v2.x; + a2->y = v2.y; + a2->z = v2.z; + *a3 = -(arg0[0].vWorldPosition.z * v2.z + arg0[0].vWorldPosition.y * v2.y + arg0[0].vWorldPosition.x * v2.x); + return true; + } + return false; +}